Конфликт с опцией `english` в пользовательском классе и `babel`

Конфликт с опцией `english` в пользовательском классе и `babel`

Я пишу файл класса, который принимает опцию 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для этого, но то же самое можно было бы также достичь с помощью pgfkeyswith pgfopts, или l3keysand 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также можем вам в этом помочь.

Связанный контент