Ich schreibe eine Klassendatei, die eine Option annimmt und dann die Klasse english
lädt . Die in der neuen Klasse definierte Optionarticle
english
Istnichtweitergereicht an article
. Wenn ich dann jedoch babel
mit Option lade USenglish
, dann bekomme ich die Warnung
Package Babel Warning: The package option `english' should not be used
(Babel) with a more specific one (like `USenglish')
als ob english
es an die article
Klasse weitergegeben worden wäre.
So übergebe ich die Optionen an meine Klasse:
\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}
Der Code
\documentclass[english]{myclass}
\usepackage[USenglish]{babel}
erzeugt die babel
obige Warnung.
Wie kann ich das beheben?
Mir ist bewusst, dass eine Warnung kein Fehler ist, aber (1) ich möchte sicherstellen, dass der Umfang der english
von mir definierten Option auf beschränkt ist myclass
und nicht von geerbt wird article
, (2) ich hätte wirklich gern eine Vorlage ohne Warnungen und (3) ich möchte so wenig Pakete wie möglich laden (deshalb möchte ich einen Aufruf silence
nur hierfür vermeiden).
Antwort1
Meinen Kommentar in eine Antwort umwandeln.
LaTeX verwaltet eine Liste globaler Optionen (diese wird genannt \@classoptionslist
), die die an übergebenen Optionen enthält \documentclass
. Diese Optionen werden standardmäßig an jedes Paket weitergeleitet, das danach geladen wird \documentclass
(dies hängt von der in den verschiedenen Paketen verwendeten Schnittstelle ab; die Standardschnittstelle von LaTeX übernimmt die globalen Optionen, aber Pakete wie oder pgfopts
bieten Mechanismen, um nur die lokale Optionsliste zu übergeben).l3keys2e
expkv-opt
Sie können Optionen entfernen, \@classoptionslist
indem Sie das LaTeX-Makro verwenden, \@removeelement
das drei Argumente annimmt: das zu entfernende Element, die vollständige Liste und das Makro, in dem die gefilterte Liste gespeichert werden soll.
Mit diesem Wissen können Sie Ihre Klassendatei ändern, um
\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
wodurch es aus der Liste der globalen Optionen entfernt wird .
Wie jedoch andere bereits angemerkt haben (danke @moewe), ist es möglicherweise eine bessere Idee, entweder mit zusammenzuarbeiten babel
oder andere Namen zu verwenden. Aus diesem Grund wird im Folgenden vorgeschlagen, für Ihre Vorlagensprache eine Schlüssel=Wert-Option mit einem eindeutigen Optionsnamen zu verwenden (bei dem Konflikte viel seltener auftreten). Ich verwende hierfür, aber dasselbe könnte auch mit mit , oder und , oder , oder ... expkv-opt
erreicht werden (es gibt viele Schlüssel=Wert-Lösungen).pgfkeys
pgfopts
l3keys
l3keys2e
kvoptions
Die folgenden Geräte english
und german
Optionen stehen für zur Verfügung 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}
Dokumentieren:
\documentclass[template-language=english]{myclass}
\usepackage[USenglish]{babel}
\begin{document}
\ifEnglish English \fi
\ifGerman Deutscher \fi
Test
\end{document}
Antwort2
Dies hängt von der genauen Art Ihrer Vorlage und der von Ihrer Vorlage bereitgestellten Lokalisierung ab, aber für eine bestimmte Klasse von Lokalisierungsfunktionen wäre es wahrscheinlich am besten, wenn Ihre Vorlage einfach auf die vom Benutzer über babel
(und möglicherweise polyglossia
) eingestellte Sprache reagieren könnte.
Leider gibt es derzeit zwei Systeme zur Lokalisierung von Dokumenten in LaTeX, babel
und polyglossia
. Die beiden haben in einigen Bereichen leicht unterschiedliche Ansätze und keine einheitliche Schnittstelle. Vor nicht allzu langer Zeit gab es den Versuch, babel
äquivalente Funktionen in anzubieten polyglossia
, um Entwicklern das Schreiben von lokalisierungsfähigen Paketen zu erleichtern, aber man muss immer noch unterschiedlichen Code für babel
und schreiben polyglossia
.
Für einfache Übersetzungen von Zeichenfolgen babel
können Sie beispielsweise Folgendes tun.
\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}
Sie definieren einfach ein neues Makro für Ihren String und verwenden dann , \appto
um die Übersetzung für die Sprache <language>
in einzufügen \captions<language>
. (Dies geschieht in einem \AtBeginDocument
Hook, um sicherzustellen, dass die \captions<language>
Makros bereits vorhanden sind und unsere Änderungen nicht überschrieben werden. Das richtige Timing hinzubekommen, kann etwas mühsam sein.)
Pakete wietracklang
,iflang
,translator
Undtranslations
kann Ihnen hierbei ebenfalls behilflich sein.