是否存在标准方法来定义包中的互斥选项?
有人可以提供一个简单的例子吗?
目前我最感兴趣的是 LaTeX2e,但如果能看到 LaTeX3 的实现就更好了。
答案1
该kvoptions
包提供了键值类型选项,也可以定义补充选项:
\DeclareBoolOption{draft}
\DeclareComplementaryOption{final}{draft}
这会生成一个 if-switch,由 设置为 true,draft
但由 设置为 false final
。
但是,如果您指的是互斥选项,例如三个选项中只有一个可用,那么最好定义三个 if 开关,并由其对应的选项设置为 true。然后,这些选项要么将其他选项的 if 开关设置为 false,要么如果其中一个 if 开关已设置为 true,则引发错误或警告。
% package 'foo'
% Example: three mutually options alpha, beta, gamma; last one
\newif\iffoo@alpha
\newif\iffoo@beta
\newif\iffoo@gamma
\DeclareOption{alpha}{\foo@alphatrue\foo@betafalse\foo@gammafalse}
\DeclareOption{beta}{\foo@alphafalse\foo@betatrue\foo@gammafalse}
\DeclareOption{gamma}{\foo@alphafalse\foo@betafalse\foo@gammatrue}
\ProcessOptions*% process options it the order the user provides them
% package body:
\iffoo@alpha
% alpha code
\fi
\iffoo@beta
% beta code
\fi
\iffoo@gamma
% gamma code
\fi
或者出现错误消息:
\def\foo@mutopterr{%
\PackageError{foo}{Options 'alpha', 'beta' and 'gamma' are mutually exclusive.}{}%
}%
\DeclareOption{alpha}{%
\iffoo@beta\foo@mutopterr\fi
\iffoo@gamma\foo@mutopterr\fi
\foo@alphatrue\foo@betafalse\foo@gammafalse
}
\DeclareOption{beta}{%
\iffoo@alpha\foo@mutopterr\fi
\iffoo@gamma\foo@mutopterr\fi
\foo@alphafalse\foo@betatrue\foo@gammafalse
}
\DeclareOption{gamma}{%
\iffoo@alpha\foo@mutopterr\fi
\iffoo@beta\foo@mutopterr\fi
\foo@alphafalse\foo@betafalse\foo@gammatrue
}
答案2
有人可以提供一个简单的例子吗?
标准 LaTeX 文档类采用onesided
和twosided
、draft
和final
和titlepage
作为notitlepage
选项,每对都是互斥的。还有互斥的选项来指定纸张大小和点大小,但这里有多个选项而不是两个。这些选项的实现是一个简单的 `\DeclareOption'。虚构的 foo/nofoo 选项的示例:
\newif\@foo
\@footrue % Makes foo the default; use \@foofalse if the default is nofoo
\DeclareOption{foo}{\@footrue}
\DeclareOption{nofoo}{\@foofalse}
一个关键问题:如何处理指定矛盾选项的用户?例如,指定twosided,final,onesided,draft
为基本 LaTeX 文档类之一的选项,您将获得(没有任何抱怨)以最终模式格式化的双面文档。
这是因为基本 LaTeX 文档类用于\ProcessOption
处理选项。\ProcessOption
按照选项声明的顺序遍历选项。 如果使用这些类\ProcessOption*
代替\ProcessOption
,则结果twosided,final,onesided,draft
将是草稿形式的单方面文档。 发生\ProcessOption
冲突时,获胜者是包本身,而\ProcessOption*
发生冲突时,获胜者是包的用户。
如果您希望实现因用户指定互斥选项而责骂用户,那么您将必须做一些更复杂的事情。
答案3
下面是我使用的选项列表的示例,其中只有一个选项可以处于活动状态。您还可以指定默认选项。
\newcommand\opt@select[1]{@#1@select}
\newcommand\opt@ifpre[1]{@#1@}
\newcommand\DeclareOptionList[3]{%
\@namedef{\opt@select{#1}}{#3}%-- default
\edef\opt@list{\zap@space#2 \@empty}%
\@for\opt@item:=\opt@list\do{%
\expandafter\newif\csname if\opt@ifpre{#1}\opt@item\endcsname
\edef\opt@temp{%
\noexpand\DeclareOption{\opt@item}%
{\def\expandafter\noexpand\csname\opt@select{#1}\endcsname{\opt@item}}}%
\opt@temp}}
\newcommand\SetListOption[1]{%
\def\opt@set{\@nameuse{\opt@select{#1}}}%
\@nameuse{\opt@ifpre{#1}\opt@set true}}
\newcommand\IfListOption[3]{%
\csname if\opt@ifpre{#1}#2\endcsname #3\fi}
%____ Process options ___________________________________________
\DeclareOptionList{layout}{goldenblock,a5block,wideblock,stdblock}{goldenblock}
\DeclareOptionList{fonts}{cm,charter,fourier,times}{cm}
\ProcessOptions*\relax
\AtEndOfPackage{\let\@unprocessedoptions\relax}
\SetListOption{layout}%--- Activate layout option
\SetListOption{fonts}%---- Activate font option
%____ Page Layout _______________________________________________
\RequirePackage[a4paper]{geometry}
\IfListOption{layout}{goldenblock}{%
\geometry{text={0.6667\paperwidth, 1.0787\paperwidth}}%
\geometry{hmarginratio=1:1}%
\geometry{vmarginratio=2:3}%
\geometry{marginparwidth=50pt}}
\IfListOption{layout}{a5block}{%
\geometry{text={0.5\paperheight, \paperwidth}}%
\geometry{hmarginratio=1:1}%
\geometry{vmarginratio=2:3}%
\geometry{marginparwidth=50pt}}
\IfListOption{layout}{wideblock}{%
\geometry{margin=25mm}%
\geometry{marginparwidth=50pt}}
\IfListOption{layout}{stdblock}{}%----- Latex default type block ----
%____ Fonts _________________________________________________________
\IfListOption{fonts}{cm}{%
\RequirePackage[T1]{fontenc}
\RequirePackage{textcomp}
\RequirePackage{lmodern}
\RequirePackage{bm}}
: