在类级别而不是(词汇表)包级别传递的缩写词选项不起作用

在类级别而不是(词汇表)包级别传递的缩写词选项不起作用

我非常确定在类级别传递的选项(包括未知选项)也传递给了已加载的包。因此我不明白为什么以下 MCE 如此有效:

\documentclass{article}
\usepackage[acronym,nomain]{glossaries}
\makeglossaries
\newacronym{at}{at}{Acronym test}
\begin{document}
\glsaddall
\printglossary[type=\acronymtype]
\end{document}

但不是以下将acronym选项传递给类而不是glossaries包的情况:

\documentclass[acronym]{article}
\usepackage[nomain]{glossaries}
\makeglossaries
\newacronym{at}{at}{Acronym test}
\begin{document}
\glsaddall
\printglossary[type=\acronymtype]
\end{document}

这确实会导致以下错误消息:

! Missing \endcsname inserted.
<to be read again>
                   \glsdefaulttype
l.6 \newacronym{at}{at}{Acronym test}

? s
OK, entering \scrollmode...
! Missing \endcsname inserted.
<to be read again>
                   \glsdefaulttype
l.6 \newacronym{at}{at}{Acronym test}

! Missing \endcsname inserted.
<to be read again>
                   \glsdefaulttype
l.6 \newacronym{at}{at}{Acronym test}


! Package glossaries Error: Glossary type '\glsdefaulttype ' has not
been defined.

[...]

请注意以下 MCE(acronym选项传递给类,但没有nomain glossaries选项):

\documentclass[acronym]{myclass}
\usepackage{glossaries}
\makeglossaries
\newacronym{at}{at}{Acronym test}
\begin{document}
\glsaddall
%
\printglossary[type=\acronymtype]
\end{document}

确实有效(嗯,主要是:词汇表的名称是“词汇表”,而如果acronym选项不是传递给类而是glossaries直接传递给类,则它是“首字母缩略词”)。

顺便说一句,在个人类中明确传递(感谢\PassOptionsToPackageacronym 类选项会产生同样的错误:glossaries

\begin{filecontents*}{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
\newif\if@acronym\@acronymfalse
\DeclareOption{acronym}{\@acronymtrue}
\ProcessOptions\relax
\LoadClass{article}
%
\RequirePackage{filehook}
\RequirePackage{hopatch}
%
\hopatch@AfterPackage{glossaries}{%
  \if@acronym
  \PassOptionsToPackage{acronym}{glossaries}%
  \fi
}
\endinput
\end{filecontents*}

\documentclass[acronym]{myclass}
\usepackage[nomain]{glossaries}
\makeglossaries
\newacronym{at}{at}{Acronym test}
\begin{document}
\glsaddall
%
\printglossary[type=\acronymtype]
\end{document}

答案1

下面是一个可以说明这个问题的一般示例。假设我编写了一个名为的包,如下所示test

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{test}

\RequirePackage{xkeyval}
\RequirePackage{etoolbox}

\define@boolkey{test.sty}[test]{bold}[true]{}

\newcommand*{\test@animal}{parrot}
\newcommand*{\test@parrot@sound}{squawk}
\newcommand*{\test@dog@sound}{woof}
\newcommand*{\test@duck@sound}{quack}
\newcommand*{\test@cow@sound}{moo}

\define@choicekey{test.sty}{animal}{dog,duck,cow}{%
  \renewcommand*{\test@animal}{#1}%
}

\newcommand*{\test@adj}{silly}

\define@key{test.sty}{adj}{\renewcommand*{\test@adj}{#1}}

\ProcessOptionsX

\newcommand*{\test}{{\iftestbold \bfseries \fi The \test@adj\ 
\test@animal\ said ``\csuse{test@\test@animal @sound}!''}}

\endinput

以下是使用此类的示例文档:

\documentclass{article}

\usepackage[bold,adj={giant killer},animal=duck]{test}

\begin{document}
\test
\end{document}

得出的结果为:

巨型杀手鸭“嘎嘎”叫了一声。

但是,正如评论中提到的,这些选项不能通过文档类选项传递。如果我尝试:

\documentclass[animal=duck]{article}

我收到警告:

LaTeX Warning: Unused global option(s):
    [animal=duck].

更糟糕的是,如果我尝试:

\documentclass[animal={duck}]{article}

我收到错误:

! LaTeX Error: Missing \begin{document}.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.123 \input
            {size1\@ptsize.clo}

总的来说,我不太喜欢指定包选项的想法,因为\documentclass可能有多个包具有相同的选项。如果用户没有意识到这一点,可能会出现意外结果。(这从这里或其他网站或新闻组中用户提出的问题次数就可以看出,他们不明白为什么他们包含的图像都处于草稿模式。)事实上,babel语言选项是我建议与文档类选项一起传递的唯一选项(但仅仅是因为babel没有提供方便的加载语言列表)。

那么还有哪些替代方案呢?

软件包通常会提供可以代替软件包选项使用的命令。以下是对软件包设计的改进:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{test}

\RequirePackage{xkeyval}
\RequirePackage{etoolbox}

\define@boolkey{test.sty}[test]{bold}[true]{}

\newcommand*{\test@animal}{parrot}
\newcommand*{\test@parrot@sound}{squawk}
\newcommand*{\test@dog@sound}{woof}
\newcommand*{\test@duck@sound}{quack}
\newcommand*{\test@cow@sound}{moo}

\newcommand*{\setanimal}[1]{%
  \ifcsdef{test@#1@sound}%
  {%
     \renewcommand*{\test@animal}{#1}%
  }%
  {%
     \PackageError{test}{Unknown animal `#1'}{}%
  }%
}

\define@choicekey{test.sty}{animal}{dog,duck,cow}{%
  \setanimal{#1}%
}

\newcommand*{\test@adj}{silly}

\newcommand*{\setadj}[1]{\renewcommand*{\test@adj}{#1}}

\define@key{test.sty}{adj}{\setadj{#1}}

\ProcessOptionsX

\newcommand*{\setuptest}[1]{\setkeys{test.sty}{#1}}

\newcommand*{\test}{{\iftestbold \bfseries \fi The \test@adj\ 
\test@animal\ said ``\csuse{test@\test@animal @sound}!''}}

\endinput

现在,如果我无法在加载包时设置选项(例如,该包由另一个包自动加载),我可以通过这些新命令指定我的选项。例如:

\documentclass{article}

\usepackage{test}

\setuptest{bold,adj={giant killer},animal=duck}

\begin{document}
\test
\end{document}

不幸的是,有些时候必须在加载包时设置选项,这又回到了glossaries。大多数包选项都有一个等效的命令或一组可实现相同效果的命令。例如,shortcuts可以通过命令 实现 选项\DefineAcronymSynonyms。该acronym选项稍微复杂一些:

\documentclass{article}

\usepackage{glossaries}

\newglossary[alg]{acronym}{acr}{acn}{\acronymname}%
\renewcommand*{\acronymtype}{acronym}%
\DeclareAcronymList{acronym}

\newglossaryentry{sample}{name=sample,description={an example}}
\newacronym{abc}{ABC}{Sample}

\makeglossaries

\begin{document}
\gls{sample}
\gls{abc}

\printglossaries
\end{document}

在加载包时,实际上只有两个选项必须设置:makeindexxindy。在 4.01 版本中,您还可以使用makeindexxindygloss(相当于xindy没有值的选项)作为类选项。

编辑:

请注意,使用定义的包选项\DeclareOptionX也不能通过文档类传递。例如,假设我的测试包现在是:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{test}

\RequirePackage{xkeyval}
\RequirePackage{etoolbox}

\newcommand*{\test@shape}{}

\DeclareOptionX{em}{\renewcommand*{\test@shape}{\em}}

\define@boolkey{test.sty}[test]{bold}[true]{}

\newcommand*{\test@animal}{parrot}
\newcommand*{\test@parrot@sound}{squawk}
\newcommand*{\test@dog@sound}{woof}
\newcommand*{\test@duck@sound}{quack}
\newcommand*{\test@cow@sound}{moo}

\newcommand*{\setanimal}[1]{%
  \ifcsdef{test@#1@sound}%
  {%
     \renewcommand*{\test@animal}{#1}%
  }%
  {%
     \PackageError{test}{Unknown animal `#1'}{}%
  }%
}

\define@choicekey{test.sty}{animal}{dog,duck,cow}{%
  \setanimal{#1}%
}

\newcommand*{\test@adj}{silly}

\newcommand*{\setadj}[1]{\renewcommand*{\test@adj}{#1}}

\define@key{test.sty}{adj}{\setadj{#1}}

\ProcessOptionsX

\newcommand*{\setuptest}[1]{\setkeys{test.sty}{#1}}

\newcommand*{\test}{{\test@shape \iftestbold \bfseries \fi The \test@adj\ 
\test@animal\ said ``\csuse{test@\test@animal @sound}!''}}

\endinput

测试文档为:

\documentclass[em]{article}

\usepackage{test}

\begin{document}

\test

\end{document}

em选项将被忽略并发出警告:

LaTeX Warning: Unused global option(s):
    [em].

\documentclass我能想到的唯一允许通过或传递此选项的方法\usepackage是使用两者定义它\DeclareOptionX\DeclareOption然后\ProcessOptionsX像这样处理类选项:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{test}

\RequirePackage{xkeyval}
\RequirePackage{etoolbox}

\newcommand*{\test@shape}{}

\DeclareOptionX{em}{\renewcommand*{\test@shape}{\em}}
\DeclareOption{em}{\renewcommand*{\test@shape}{\em}}

\define@boolkey{test.sty}[test]{bold}[true]{}

\newcommand*{\test@animal}{parrot}
\newcommand*{\test@parrot@sound}{squawk}
\newcommand*{\test@dog@sound}{woof}
\newcommand*{\test@duck@sound}{quack}
\newcommand*{\test@cow@sound}{moo}

\newcommand*{\setanimal}[1]{%
  \ifcsdef{test@#1@sound}%
  {%
     \renewcommand*{\test@animal}{#1}%
  }%
  {%
     \PackageError{test}{Unknown animal `#1'}{}%
  }%
}

\define@choicekey{test.sty}{animal}{dog,duck,cow}{%
  \setanimal{#1}%
}

\newcommand*{\test@adj}{silly}

\newcommand*{\setadj}[1]{\renewcommand*{\test@adj}{#1}}

\define@key{test.sty}{adj}{\setadj{#1}}

\@for\CurrentOption :=\@declaredoptions\do{%
  \ifx\CurrentOption\@empty
  \else
    \@expandtwoargs
      \in@ {,\CurrentOption ,}{,\@classoptionslist,\@curroptions,}%
    \ifin@ \@use@ption
      \expandafter \let\csname ds@\CurrentOption\endcsname\@empty
    \fi
  \fi
}

\ProcessOptionsX

\newcommand*{\setuptest}[1]{\setkeys{test.sty}{#1}}

\newcommand*{\test}{{\test@shape \iftestbold \bfseries \fi The \test@adj\ 
\test@animal\ said ``\csuse{test@\test@animal @sound}!''}}

\endinput

现在以下两个文档产生相同的输出:

示例 1:

\documentclass[em]{article}

\usepackage[bold,adj={giant killer},animal=duck]{test}

\begin{document}

\test

\end{document}

示例 2:

\documentclass{article}

\usepackage[em,bold,adj={giant killer},animal=duck]{test}

\begin{document}

\test

\end{document}

两种情况下的结果都是:

生成的文档的图像

相关内容