Conflito com a opção `english` na classe personalizada e `babel`

Conflito com a opção `english` na classe personalizada e `babel`

Estou escrevendo um arquivo de classe que usa uma opção englishe depois carrega a articleclasse. A englishopção definida na nova classeénãopassado para article. No entanto, se eu carregar babelcom option USenglish, recebo o aviso

Package Babel Warning: The package option `english' should not be used
(Babel)                with a more specific one (like `USenglish')

como se englishtivesse sido passado para a articleturma.

Aqui está como eu passo as opções para minha classe:

\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}

O código

\documentclass[english]{myclass}
\usepackage[USenglish]{babel}

produz o babelaviso acima. Como posso consertar isso?

Entendo que um aviso não é um erro, mas (1) quero ter certeza de que o escopo da englishopção que defino é limitado myclasse não é herdado por article, (2) eu realmente gostaria de ter um modelo sem avisos e (3) gostaria de carregar o mínimo de pacotes possível (portanto, gostaria de evitar invocar silenceapenas para isso).

Responder1

Transformando meu comentário em uma resposta.

LaTeX mantém uma lista de opções globais (isso é chamado de \@classoptionslist) contendo as opções passadas para \documentclass. Estas opções são por padrão encaminhadas para cada pacote que é carregado depois \documentclass(isso depende da interface usada nos diferentes pacotes, a interface padrão do LaTeX pega as opções globais, mas pacotes como pgfopts, l3keys2eou expkv-optfornecem mecanismos para passar apenas a lista de opções locais ).

Você pode remover opções \@classoptionslistusando a macro LaTeX \@removeelementque leva três argumentos, o elemento que deve ser removido, a lista completa e a macro na qual a lista filtrada deve ser armazenada.

Usando esse conhecimento você pode alterar seu arquivo de classe para usar

\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}

que removeria englishda lista de opções globais.


No entanto, como outros observaram (obrigado @moewe), pode ser uma ideia melhor cooperar babelou usar nomes diferentes. Por causa disso, o seguinte sugere usar uma opção key=value com um nome de opção distinto (que tem muito menos probabilidade de entrar em conflito) para o idioma do seu modelo. Eu uso expkv-optpara isso, mas o mesmo também pode ser alcançado usando pgfkeyswith pgfopts, or l3keysand l3keys2e, or kvoptions, or.... (existem muitas soluções chave=valor por aí).

A seguir implementamos englishe germancomo opções para o 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}

Documento:

\documentclass[template-language=english]{myclass}

\usepackage[USenglish]{babel}

\begin{document}
\ifEnglish English \fi
\ifGerman Deutscher \fi
Test
\end{document}

insira a descrição da imagem aqui

Responder2

Dependerá da natureza exata do seu modelo e da localização que ele fornece, mas para uma determinada classe de recursos de localização provavelmente seria melhor se o seu modelo pudesse simplesmente reagir ao idioma definido pelo usuário por meio de babel(e possivelmente polyglossia).

Infelizmente, existem atualmente dois sistemas para localização de documentos em LaTeX, babele polyglossia. Os dois têm abordagens ligeiramente diferentes em algumas áreas e nenhuma interface unificada. Houve um esforço não muito tempo atrás para oferecer babelrecursos equivalentes para polyglossiatornar mais fácil para os desenvolvedores escreverem pacotes com reconhecimento de localidade, mas ainda é necessário escrever códigos diferentes para babele polyglossia.

Para traduções simples de strings, babelvocê poderia fazer algo como o seguinte.

\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}

Você simplesmente define uma nova macro para sua string e depois usa \apptopara injetar sua tradução para o idioma <language>no arquivo \captions<language>. (Isso é feito em um \AtBeginDocumentgancho para garantir que as \captions<language>macros já existam e que nossas alterações não sejam substituídas. Acertar o tempo pode ser um pouco trabalhoso.)

Pacotes comotracklang,iflang,translatoretranslationstambém pode ajudá-lo com isso.

informação relacionada