我想编写一个提供许多命令的包。该包应接受选项,并且其中一些选项应可用作命令选项。用法应如下:
...
\usepackage[optA=val1,optB=val2]{mypackage}
\begin{document}
\mycommand[optB=val3]
...
看起来好像该xkeyval
包可以做到这一点,但我不确定具体应该如何做。
答案1
让我提供一个简单(但完整)的例子:
\ProvidesPackage{myemph}[2011/03/12 v1.0 a test package]
\providecommand\my@emphstyle{\em}
% Note that the argument must be expandable,
% or use xkvltxp package before \documentclass (see manual of xkeyval)
\RequirePackage{xkeyval}
\DeclareOptionX{style}{%
\def\my@emphstyle{\csname my@style@#1\endcsname}}
% predefined styles
\providecommand\my@style@default{\em}
\providecommand\my@style@bold{\bfseries}
\ProcessOptionsX
% For simple key-value commands, keyval would suffie
\define@key{myemph}{code}{%
\def\my@emphstyle{#1}}
\define@key{myemph}{style}{%
\def\my@emphstyle{\csname my@style@#1\endcsname}}
\newcommand\setemph[1]{%
\setkeys{myemph}{#1}}
\renewcommand\emph[1]{%
{\my@emphstyle #1}}
\endinput
测试文件:
\documentclass{article}
\usepackage[style=default]{myemph}
\begin{document}
Something \emph{important}
\setemph{style=bold}
Something \emph{important}
\setemph{code=\Large\sffamily}
Something \emph{important}
\end{document}
答案2
接受键值输入可以使用许多包来完成,并且所有包的一般方法都是相同的:我在TUGboat 文章。本质上,你需要做三件事
- 定义一个或多个键;
- 告诉 LaTeX 使用这些键处理包选项;
- 提供一个用于在包加载后设置按键的宏。
在问题中,你提到了xkeyval
包,其中包括kvoptions
,pgfkeys
(加pgfopts
) 和 LaTeX3 键系统l3keys
(加l3keys2e
)。我过去曾使用过所有这些,我更倾向于pgfkeys
(如果您不想使用 LaTeX3)或 LaTeX3 键实现(如果您乐于使用expl3
)。原因是,在我看来,这两个方法具有定义键的最佳整体方法。(我应该补充一点,我编写了大部分 LaTeX3 键系统,这最初是基于这种pgfkeys
方法的。)
由于问题要求一种xkeyval
方法,我将在这里概述一种方法。当然,首先,您需要加载包。
\usepackage{xkeyval}
这还会加载父keyval
包,它提供了一些基本机制。要定义键,基本宏是\define@key
:
\define@key{mypkg}{optA}{<code for optA>} % 'mypkg' is the 'family' for the keys
\define@key{mypkg}{optB}{<code for optB>}
在代码中,#1
将传递给键的值。您可以使用各种xkeyval
宏定义具有更丰富验证的键类型(例如布尔键)。正如我所说,这种xkeyval
方法相当密集,如果您想了解更多信息,我认为“每个键类型一个问题”可能是最好的选择!
第二阶段是处理软件包选项。为此,\ProcessOptions
您可以使用\ProcessOptionsX<mypkg>
。这将遍历软件包选项,为每个选项查找定义的键并执行找到的代码。
最后,要定义一个宏来使用包加载后的键,您需要\setkeys
:
\newcommand\mymacro[1]{\setkeys{mypkg}{#1}}
这里需要注意的是,键值包选项只是\ProcessOptionsX
使用宏时定义的键。因此,可以将键仅定义为包选项,然后通过\defin@key
再次执行来禁用它们。也可以定义仅在后包加载,只需放置\define@key
在之后即可\ProcessOptionsX
。
答案3
来自文档的一些代码示例
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[12/03/2011]
\RequirePackage{xkeyval}
\DeclareOptionX{parindent}[20pt]{\setlength\parindent{#1}}
\ExecuteOptionsX{parindent=0pt}
\ProcessOptionsX\relax
% etc.
\endinput
\DeclareOptionX
相当于(感谢 Ahmed Musa 的修正)
\define@key{mypackage.sty}{parindent}[20pt]{\setlength\parindent{#1}}