包中的互斥选项

包中的互斥选项

是否存在标准方法来定义包中的互斥选项?

有人可以提供一个简单的例子吗?

目前我最感兴趣的是 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 文档类采用onesidedtwosideddraftfinaltitlepage作为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}}

:

相关内容