我正在編寫一個類別文件,它採用一個選項english
,然後加載該類別article
。english
新類別中定義的選項是不是傳遞給 article
。但是,如果我載入babel
option 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
。這些選項預設轉發到之後加載的每個包\documentclass
(這取決於不同包中使用的接口,標準 LaTeX 接口選擇全局選項,但是像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 、 or和、 or 、 or...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
)對用戶設定的語言做出反應,那可能是最好的。
不幸的是,目前有兩個用於 LaTeXbabel
和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
也可以幫助您解決這個問題。