與自訂類別中的“english”選項和“babel”發生衝突

與自訂類別中的“english”選項和“babel”發生衝突

我正在編寫一個類別文件,它採用一個選項english,然後加載該類別articleenglish新類別中定義的選項不是傳遞給 article。但是,如果我載入babeloption 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 解決方案)。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)對用戶設定的語言做出反應,那可能是最好的。

不幸的是,目前有兩個用於 LaTeXbabelpolyglossia.兩者在某些方面的做法略有不同,並且沒有統一的介面。不久前,有人試圖提供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,translatortranslations也可以幫助您解決這個問題。

相關內容