自定义类和“babel”中的“English”选项发生冲突

自定义类和“babel”中的“English”选项发生冲突

我正在编写一个类文件,它接受一个选项english,然后加载该类articleenglish新类中定义的选项不是已传递给 article。但是,如果我babel使用选项加载USenglish,则会收到警告

Package Babel Warning: The package option `english' should not be used
(Babel)                with a more specific one (like `USenglish')

就像english是传给了article班级一样。

以下是我将选项传递给班级的方法:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2020/11/07 myclass template]

\newif\ifEnglish\Englishfalse

\DeclareOption{english}{\Englishtrue}
\DeclareOption*{\ClassWarning{myclass}{Unknown option `\CurrentOption'}}
\ProcessOptions\relax

\LoadClass[10pt, a4paper, oneside]{article}

代码

\documentclass[english]{myclass}
\usepackage[USenglish]{babel}

产生babel上述警告。 我怎样才能解决这个问题?

我理解警告不是错误,但是 (1) 我想确保english我定义的选项的范围仅限于myclass并且不会被继承article,(2) 我真的希望有一个没有警告的模板,(3) 我想加载尽可能少的包(因此我想避免silence仅仅为了这个而调用)。

答案1

将我的评论转化为答案。

LaTeX 维护一个全局选项列表(称为\@classoptionslist),其中包含传递给 的选项\documentclass。默认情况下,这些选项会转发给之后加载的每个包(这取决于不同包中使用的接口,标准 LaTeX 接口会获取全局选项,但像、或 这样\documentclass的包提供仅传递本地选项列表的机制)。pgfoptsl3keys2eexpkv-opt

您可以\@classoptionslist使用 LaTeX 宏从中删除选项\@removeelement,该宏接受三个参数:应删除的元素、完整列表和应存储过滤列表的宏。

利用这些知识,你可以修改你的类文件以使用

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2020/11/07 myclass template]

\newif\ifEnglish\Englishfalse

\DeclareOption{english}
  {%
    \Englishtrue
    \@expandtwoargs\@removeelement{english}\@classoptionslist\@classoptionslist
  }
\DeclareOption*{\ClassWarning{myclass}{Unknown option `\CurrentOption'}}
\ProcessOptions\relax

\LoadClass[10pt, a4paper, oneside]{article}

english这将从全局选项列表中删除。


但是,正如其他人所指出的(感谢@moewe),与 合作或使用不同的名称可能是一个更好的主意babel。 因此,以下内容建议在模板语言中使用具有不同选项名称(不太可能发生冲突)的 key=value 选项。 我使用它,但也可以通过使用with 、或and 、或、或...expkv-opt来实现相同的效果(有很多 key=value 解决方案)。pgfkeyspgfoptsl3keysl3keys2ekvoptions

以下实现englishgerman作为的选择template-language

myclass.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2020/11/07 myclass template]

\RequirePackage{expkv-opt, expkv-def}
\ekvdefinekeys{myclass}
  {
    choice template-language =
      {
        ,english = \Englishtrue  \Germanfalse
        ,german  = \Englishfalse \Germantrue
      }
  }

\newif\ifEnglish\Englishfalse
\newif\ifGerman\Germanfalse

\ekvoProcessGlobalOptions{myclass}
\ekvoProcessLocalOptions {myclass}

\LoadClass[10pt, a4paper, oneside]{article}

文档:

\documentclass[template-language=english]{myclass}

\usepackage[USenglish]{babel}

\begin{document}
\ifEnglish English \fi
\ifGerman Deutscher \fi
Test
\end{document}

在此处输入图片描述

答案2

babel这将取决于您的模板的具体性质和模板提供的本地化,但对于某一类本地化功能,如果您的模板可以简单地对用户通过(可能polyglossia)设置的语言做出反应,那可能是最好的。

不幸的是,目前有两种用于 LaTeX 文档本地化的系统,babelpolyglossia。两者在某些方面的方法略有不同,并且没有统一的界面。不久前曾有人努力babel在 中提供 - 等效功能,polyglossia以便开发人员更轻松地编写可识别本地环境的包,但仍然必须为babel和编写不同的代码polyglossia

对于字符串的简单翻译,babel您可以执行以下操作。

\begin{filecontents}[overwrite]{myclass.cls}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2020/11/07 myclass template]

\RequirePackage{etoolbox}

\newcommand*{\rabbit}{\textbf{??? rabbit is missing a translation}}

\AtBeginDocument{%
  \appto\captionsenglish{%
    \renewcommand{\rabbit}{rabbit}%
  }%
  \appto\captionsUSenglish{%
    \renewcommand{\rabbit}{rabbit}%
  }%
  \appto\captionsgerman{%
    \renewcommand{\rabbit}{Hase}%
  }%
  \appto\captionsngerman{%
    \renewcommand{\rabbit}{Hase}%
  }%
}

\LoadClass[10pt, a4paper, oneside]{article}
\end{filecontents}

\documentclass{myclass}

\usepackage[USenglish]{babel}

\begin{document}
Ohh, \rabbit!
\end{document}

您只需为字符串定义一个新的宏,然后使用\appto它将其语言翻译注入即可<language>\captions<language>(这在钩子中完成,\AtBeginDocument以确保\captions<language>宏已经存在并且我们的更改不会被覆盖。把握好时机可能会有点麻烦。)

类似套餐tracklangiflangtranslatortranslations也可以帮助你解决这个问题。

相关内容