我正在编写一个类文件,它接受一个选项english
,然后加载该类article
。english
新类中定义的选项是不是已传递给 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
的包提供仅传递本地选项列表的机制)。pgfopts
l3keys2e
expkv-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 解决方案)。pgfkeys
pgfopts
l3keys
l3keys2e
kvoptions
以下实现english
和german
作为的选择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 文档本地化的系统,babel
和polyglossia
。两者在某些方面的方法略有不同,并且没有统一的界面。不久前曾有人努力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>
宏已经存在并且我们的更改不会被覆盖。把握好时机可能会有点麻烦。)
类似套餐tracklang
,iflang
,translator
和translations
也可以帮助你解决这个问题。