Estou escrevendo um arquivo de classe que usa uma opção english
e depois carrega a article
classe. A english
opção definida na nova classeénãopassado para article
. No entanto, se eu carregar babel
com 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 english
tivesse sido passado para a article
turma.
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 babel
aviso acima.
Como posso consertar isso?
Entendo que um aviso não é um erro, mas (1) quero ter certeza de que o escopo da english
opção que defino é limitado myclass
e 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 silence
apenas 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
, l3keys2e
ou expkv-opt
fornecem mecanismos para passar apenas a lista de opções locais ).
Você pode remover opções \@classoptionslist
usando a macro LaTeX \@removeelement
que 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 english
da lista de opções globais.
No entanto, como outros observaram (obrigado @moewe), pode ser uma ideia melhor cooperar babel
ou 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-opt
para isso, mas o mesmo também pode ser alcançado usando pgfkeys
with pgfopts
, or l3keys
and l3keys2e
, or kvoptions
, or.... (existem muitas soluções chave=valor por aí).
A seguir implementamos english
e german
como 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}
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, babel
e 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 babel
recursos equivalentes para polyglossia
tornar mais fácil para os desenvolvedores escreverem pacotes com reconhecimento de localidade, mas ainda é necessário escrever códigos diferentes para babel
e polyglossia
.
Para traduções simples de strings, babel
você 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 \appto
para injetar sua tradução para o idioma <language>
no arquivo \captions<language>
. (Isso é feito em um \AtBeginDocument
gancho 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
,translator
etranslations
também pode ajudá-lo com isso.