Я пишу файл класса, который принимает опцию 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
. Эти параметры по умолчанию пересылаются в каждый пакет, который загружается после \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
, либо использовать разные имена. Из-за этого ниже предлагается использовать параметр ключ=значение с отдельным именем параметра (который гораздо менее вероятно будет конфликтовать) для вашего языка шаблонов. Я использую expkv-opt
для этого, но то же самое можно было бы также достичь с помощью pgfkeys
with pgfopts
, или l3keys
and l3keys2e
, или kvoptions
, или.... (существует много решений key=value).
Следующие реализации 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
также можем вам в этом помочь.