使用 switch-case 环境评估自定义包中的键值选项字符串

使用 switch-case 环境评估自定义包中的键值选项字符串

我正在尝试编写一个自定义包我的Unicode字体我想在其中存储各种字体设置数学字体罗马字体(后来还有mono和sans)。

在我的文档中,我打算使用键值选项来选择字体,例如:

\documentclass{article}

\usepackage[math=xits,roman=myriad]{MyUnicodefonts}
\usepackage{blindtext}

\begin{document}

\blindmathpaper

\end{document}

对于包文件我的Unicode字体我使用了这个答案对我来说,它似乎很方便,而且我不明白其他答案。我尝试将它应用于字符串比较。

使用kv选项我的打包文件最终如下所示:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyUnicodefonts}[2015/06/21 Load fonts]

\RequirePackage{fontspec}

\RequirePackage{kvoptions}
\DeclareStringOption[minion]{roman}
\DeclareStringOption[xits]{math}
\ProcessKeyvalOptions*

\RequirePackage{xifthen}
\newcommand{\ifequals}[3]{\ifthenelse{\ifstrequal{#1}{#2}{TRUE}{}}{#3}{}}
\newcommand{\case}[2]{#1 #2} % Dummy, so \renewcommand has something to overwrite...
\newenvironment{switch}[1]{\renewcommand{\case}{\ifequals{#1}}}{}

\begin{switch}{\MyUnicodefonts@roman}
    \case{minion}{\setmainfont[Numbers = OldStyle,
                               Ligatures = TeX,
                              ]{Minion Pro}}
    \case{myriad}{\setmainfont[Numbers={Uppercase,OldStyle},
                              ]{Myriad Pro}}
\end{switch}
\begin{switch}{\MyUnicodefonts@math}
    \case{xits}{%
        \RequirePackage{unicode-math}
        \setmathfont{XITS Math}
        \setmathfont[range={"002B,"002D,"003A-"003E} ]{MnSymbol} % + - < = >
        }
    \case{iwona}{%
        \RequirePackage[math]{iwona}
        \RequirePackage[mathscr]{eucal}
        }
\end{switch}

\endinput

作为kvoptions 手册缺乏全面的例子,我无法确定出现的原因未定义的控制序列错误

如果我在切换之前也加载,错误就会消失unicode-math,但我不希望这样,因为在某些情况下,我不想使用 unicode-math 字体。然而出现了一个新错误:

!缺失数字,视为零。\begingroup l.18 \case{myriad}{\setmainfont{Myriad Pro}} 这里应该有一个数字;我插入了“0”。(如果您不明白我为什么需要看到一个数字,请在 TeXbook 索引中查找“奇怪的错误”。)

我不明白这一点,因为我用\equal{#1}{#2}原始开关(参见链接答案)替换了\ifstrequal{#1}{#2}{TRUE}{}

我希望您能帮助我找出错误或者建议一种完全不同的方法。

答案1

问题中的代码存在一些问题:

  • \ifstrequal未定义,如错误消息所示。它由包定义etoolbox

  • 环境switch组成一个组,环境结束后所有本地设置都会丢失。

有很多方法可以实现“开关”,这是不是由包覆盖kvoptions,力求简单且易于使用。

实现基于简单文本字符串的开关的经典方法是使用 TeX 的哈希表。以下示例将选项值的实现放在名称形式为 的宏中\<prefix>@<option>@<value>。 的选项设置kvoptions将值存储在 中\<prefix>@<option>。然后使用 进行简单测试检查\@ifundefined选项/值实现是否存在,如果选项值不受支持或未知,则抛出错误。

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyUnicodefonts}[2015/06/21 Load fonts]

\RequirePackage{fontspec}

\RequirePackage{kvoptions}
\DeclareStringOption[minion]{roman}
\DeclareStringOption[xits]{math}
\ProcessKeyvalOptions*

% Implementations for option "roman"
\@namedef{MyUnicodefonts@roman@minion}{%
  \setmainfont[
    Numbers = OldStyle,
    Ligatures = TeX,
  ]{Minion Pro}%
}
\@namedef{MyUnicodefonts@roman@myriad}{%
  \setmainfont[
    Numbers={Uppercase,OldStyle},
  ]{Myriad Pro}%
}

% Implementations for option "math"
\@namedef{MyUnicodefonts@math@xits}{%
  \RequirePackage{unicode-math}%
  \setmathfont{XITS Math}%
  \setmathfont[range={"002B,"002D,"003A-"003E}]{MnSymbol}%
}
\@namedef{MyUnicodefonts@math@iwona}{%
  \RequirePackage[math]{iwona}%
  \RequirePakcage[mathscr]{eucal}%
}

% Evaluate option settings
\newcommand*{\MyUnicodefonts@evaluate}[1]{%
  % Check, if option value in \<prefix>@<option> exists
  \@ifundefined{MyUnicodefonts@#1}{%
    % Should not happen
    \PackageError{MyUnicodefonts}{Evaluating unknown option `#1'}\@ehc
  }{%
    % Check, if there is an implementation for the value of the option
    % in macro \<prefix>@<option>@<value>
    \@ifundefined{MyUnicodefonts@#1@\csname MyUnicodefonts@#1\endcsname}{%
      \PackageError{MyUnicodefonts}{%
        Unknown option setting: #1=%
        \csname MyUnicodefonts@#1\endcsname
      }\@ehc
    }{%
      % Call the implementation for the value
      \csname MyUnicodefonts@#1@%
              \csname MyUnicodefonts@#1\endcsname
      \endcsname
      \relax
    }%
  }%
}
\MyUnicodefonts@evaluate{roman}
\MyUnicodefonts@evaluate{math}

\endinput

答案2

您可以使用l3keys2e

文件myunicodefonts.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{myunicodefonts}[2015/06/21 Load fonts]

\RequirePackage{fontspec}
\RequirePackage{l3keys2e}

\ExplSyntaxOn
\bool_new:N \g_myunicodefonts_mathfont_bool
\tl_new:N \g_myunicodefonts_textfont_tl
\tl_new:N \g_myunicodefonts_mathfont_tl

\keys_define:nn { myunicodefonts }
 {
  textfont .choice:,
  textfont/minion .code:n = \tl_gset:Nn \g_myunicodefonts_textfont_tl {Minion~Pro},
  textfont/myriad .code:n = \tl_gset:Nn \g_myunicodefonts_textfont_tl {Myriad~Pro},
  textfont .initial:n = minion,
  textoptions .tl_gset:N = \g_myunicodefonts_textfont_options_tl,
  mathfont .choice:,
  mathfont/xits .code:n =
   {
    \bool_gset_true:N \g_myunicodefonts_mathfont_bool
    \tl_gset:Nn \g_myunicodefonts_mathfont_tl {XITS~Math}
   },
  mathfont/asana .code:n =
   { 
    \bool_gset_true:N \g_myunicodefonts_mathfont_bool
    \tl_gset:Nn \g_myunicodefonts_mathfont_tl {Asana~Math}
   },
  mathoptions .tl_gset:N = \g_myunicodefonts_mathfont_options_tl,
 }


\ProcessKeysPackageOptions{myunicodefonts}

\use:x
 {
  \setmainfont{\g_myunicodefonts_textfont_tl}[\g_myunicodefonts_textfont_options_tl]
 }

\bool_if:NT \g_myunicodefonts_mathfont_bool
 {
  \RequirePackage{unicode-math}
  \use:x
   {
    \setmathfont[\g_myunicodefonts_mathfont_options_tl]{\g_myunicodefonts_mathfont_tl}
   }
 }
\ExplSyntaxOff

\endinput

myunicodefonts.tex测试文件

\documentclass{article}

\usepackage[
  mathfont=xits,
  textfont=myriad,
  textoptions={Scale=0.8},
]{myunicodefonts}
\usepackage{blindtext}

\begin{document}

\blindmathpaper

\end{document}

我们可以通过对错误选项进行错误检查来补充这一点。

不同的代码

如果您想自己设置字体选项,只需在.case:n代码中进行设置即可。

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyUnicodefonts}[2015/06/21 Load fonts]

\RequirePackage{fontspec}
\RequirePackage{l3keys2e}

\ExplSyntaxOn

\keys_define:nn { myunicodefonts }
 {
  textfont .choice:,
  textfont/minion .code:n =
   {
    \setmainfont{Minion~Pro}[
      Numbers = OldStyle,
      Ligatures = TeX,
    ]
   },
  textfont/myriad .code:n =
   {
    \setmainfont{Myriad~Pro}[
      Numbers={Uppercase,OldStyle},
    ]
   },
  textfont .initial:n = minion,
  mathfont .choice:,
  mathfont/xits .code:n =
   {
    \RequirePackage{unicode-math}
    \setmathfont{XITS~Math}
    \setmathfont[range={"002B,"002D,"003A-"003E}]{MnSymbol} % + - < = >
   },
  mathfont/iwona .code:n =
   { 
    \RequirePackage[math]{iwona}
    \RequirePackage[mathscr]{eucal}
   },
 }

\ProcessKeysPackageOptions{myunicodefonts}
\ExplSyntaxOff

\endinput

相关内容