There are several possibilities. I'll present four different ways. The first two use directly or indirectly the macros \captions<lang>
or \extras<lang>
which are provided both by babel
and polyglossia
. babel
says the following about those two:
\captions<lang>
: The macro \captions<lang>
defines the macros that hold the texts to replace the original hard-wired texts.
\extras<lang>
: The macro \extras<lang>
contains all the extra definitions needed for a specific language. This macro [...] is a hook – you can add things to it, but it must not be used directly.
the babel
manual uses \extras<lang>
for examples of user defined definitions for the language <lang>
. The main difference to \captions<lang>
from a user perspective is that \extras<lang>
is set later. So if both define the same macro for a language the definition in \extras<lang>
»wins«.
\addto\captions<...>
You can check if babel
or polyglossia
have been loaded and if they are add the translations to \captions<lang>
or \extras<lang>
:
\newcommand*\mytitle{Title}
\@ifpackageloaded{babel}
{\addto\captionsngerman{\def\mytitle{Titel}}}
{
\@ifpackageloaded{polyglossia}
{\addto\captionsngerman{\def\mytitle{Titel}}}
{}
}
This could be wrapped up in a more convenient conditional, of course, in order not to have to duplicate code.
This is an expandable solution which means that \mytitle
can also be used in PDF bookmarks or other places where this is useful.
A possible drawback: with this solution you have to provide translations for each »dialect«. For example if you set \addto\captionsngerman
but a user chooses the language german
he won't see the translation.
\RequirePackage{filecontents}
\begin{filecontents*}{mypackage.sty}
\ProvidesPackage{mypackage}[2014/07/27 v0.0 my new package]
\newcommand*\iflanguagepackage[1]{%
\@ifpackageloaded{babel}
{#1}
{%
\@ifpackageloaded{polyglossia}
{#1}
{}%
}%
}
\newcommand*\mytitle{Title}
\iflanguagepackage{%
\addto\captionsenglish{\def\mytitle{Title}}%
\addto\captionsngerman{\def\mytitle{Titel}}%
\addto\captionsfrench{\def\mytitle{Titre}}%
}
\end{filecontents*}
\documentclass{article}
\usepackage[english,french,ngerman]{babel}
\usepackage{mypackage}
\begin{document}
\mytitle
\selectlanguage{french}
\mytitle
\selectlanguage{english}
\mytitle
\end{document}
scrbase
The KOMA-Script classes or more precisely the KOMA-Script support package scrbase
provides \providecaptionname
. With this macro you don't have to check for the language packages. Otherwise it is pretty much the same:
\newcommand*\mytitle{Title}
\providecaptionname{ngerman}\mytitle{Titel}
It has the same advantages and drawbacks as the first solution (expandability, dialects, ...).
\RequirePackage{filecontents}
\begin{filecontents*}{mypackage.sty}
\ProvidesPackage{mypackage}[2014/07/27 v0.0 my new package]
\RequirePackage{scrbase}
\newcommand*\mytitle{Title}
\providecaptionname{english}\mytitle{Title}
\providecaptionname{ngerman}\mytitle{Titel}
\providecaptionname{french}\mytitle{Titre}
\end{filecontents*}
\documentclass{article}
\usepackage[english,french,ngerman]{babel}
\usepackage{mypackage}
\begin{document}
\mytitle
\selectlanguage{french}
\mytitle
\selectlanguage{english}
\mytitle
\end{document}
It has advantages over the pure babel
/polyglossia
way, though: for one thing the first argument of \providecaptionname
can be a comma separated list of languages so it is more convenient to provide translations for dialects or language aliases. Also there are a number of related commands that allow finer control:
\defcaptionname{<list of languages>}{<macro>}{<translation>}
: define the translation no matter what. (Like \def
)
\providecaptionname{<list of languages>}{<macro>}{<translation>}
: define a caption name for a language in <list of languages>
if there isn't one, yet. (Like \providecommand
)
\newcaptionname{<list of languages>}{<macro>}{<translation>}
: define a caption name for a language in <list of languages>
if there isn't one, yet, throw an error otherwise. (like \newcommand
)
\renewcaptionname{<list of languages>}{<macro>}{<translation>}
: renew an existing caption name for a language in <list of languages>
. If there isn't one, yet, throw an error. (like \renewcommand
)
Those commands decide themselves if it is better to add the translations to \captions<lang>
or \extras<lang>
except if you use their starred variants which will always use \extras<lang>
. With v3.12 those macros defer the definitions at begin document.
translator
The translator
package (part of beamer
) is a more general solution.
The beamer
manual says this:
The translator
package is a LaTeX package that provides a flexible
mechanism for translating individual words into different languages.
For example, it can be used to translate a word like “figure” into,
say, the German word “Abbildung”. Such a translation mechanism is
useful when the author of some package would like to localize the
package such that texts are correctly translated into the language
preferred by the user. The translator
package is not intended to be
used to automatically translate more than a few words.
You may wonder
whether the translator
package is really necessary since there is the
(very nice) babel
package available for LaTeX. This package already
provides translations for words like “figure”. Unfortunately, the
architecture of the babel
package was designed in such a way that
there is no way of adding translations of new words to the (very
short) list of translations directly built into babel
.
Although we know now this is not entirely true the translator
package is nevertheless a very useful generalization. The basic usage is as follows:
\newcommand*\mytitle{\translate{mypackage-title}}
\newtranslation[to=English]{mypackage-title}{Title}
\newtranslation[to=German]{mypackage-title}{Titel}
With it you also don't have to check for babel
or polyglossia
yourself. However, for the translating to work correctly the translator
package needs to get the used language as package option which means a user should use the language as global option:
\documentclass[german]{article}
\usepackage{mypackage}
So a package using it should probably tell users about this. On the plus side: \newtranslation[to=German]
works for german
and ngerman
automatically. If a language is used where no translation is given the English translation is used as fallback.
On the minus side: \translate
is not expandable which might or might not cause trouble (e.g. when used in a \section
and hyperref
is used for PDF bookmarks).
One other possible advantage: it comes with dictionaries which already provide quite a number of translations.
Besides \newtranslation
translator
provides a number of similar commands:
\deftranslation[to=<lang>]{<string>}{<translation>}
: provide a new translation to <string>
for language <lang>
no matter what. (like \def
)
\newtranslation[to=<lang>]{<string>}{<translation>}
: provide a new translation to <string>
for language <lang>
. Throw an error if it already exists. (like \newcommand
)
\providetranslation[to=<lang>]{<string>}{<translation>}
: provide a new translation to <string>
for language <lang>
if it doesn't exist, yet. (like \providecommand
)
\renewtranslation[to=<lang>]{<string>}{<translation>}
: renew an existing translation to <string>
for language <lang>
. Throw an error if it doesn't exist, yet. (like \renewcommand
)
\RequirePackage{filecontents}
\begin{filecontents*}{mypackage.sty}
\ProvidesPackage{mypackage}[2014/07/27 v0.0 my new package]
\RequirePackage{translator}
\newcommand*\mytitle{\translate{mypackage-title}}
\newtranslation[to=English]{mypackage-title}{Title}
\newtranslation[to=German]{mypackage-title}{Titel}
\newtranslation[to=French]{mypackage-title}{Titre}
\end{filecontents*}
\documentclass[english,french,ngerman]{article}
\usepackage{babel}
\usepackage{mypackage}
\begin{document}
\mytitle
\selectlanguage{french}
\mytitle
\selectlanguage{english}
\mytitle
\end{document}
translations
You might also want to have a look at the translations
package.
It's usage is very similar to translator
. It has a few advantages, though:
- its
\GetTranslation
is expandable
- the chosen language is recognized also if not given as global option
- it knows the concept of dialects
From the manual:
This package provides means for package authors to have an easy
interface for internationalization of their packages. The
functionality of this package is in many parts also covered by the
package translator
(part of the beamer
bundle).
Internationalization is also possible with babel
and it’s
\addto\captions<language>
mechanism or KOMA-Script's
\providecaptionname
and similar commands. However, I believe that
translations
is more flexible than all of these. Unlike translator
it
detects the used (babel
or polyglossia
) language itself and
provides expandable retrieving of the translated key. translations
also provides support for language dialects which means package
authors can for example distinguish between British, Australian,
Canadian and US English.
translations
provides a number of macros for defining and retrieving translated strings. Most of the times
\DeclareTranslationFallback{<string>}{<translation>}
,
\DeclareTranslation{<language>}{<string>}{<translation>}
and
\GetTranslation{<string>}
will suffice, though.
There are also
\NewTranslation{<language>}{<string>}{<translation>}
,
\ProvideTranslation{<language>}{<string>}{<translation>}
and
\RenewTranslation{<language>}{<string>}{<translation>}
with the same consequences as mentioned for scrbase
's and translator
's macros.
Each string should at least have a »fallback translation« which is used whenever no language package is present or the user has chosen a language for which no translation has been provided.
Like the translator
package translations
also knows dictionaries and already provides a number of translations.
\RequirePackage{filecontents}
\begin{filecontents*}{mypackage.sty}
\ProvidesPackage{mypackage}[2014/07/27 v0.0 my new package]
\RequirePackage{translations}
\newcommand*\mytitle{\GetTranslation{mypackage-title}}
% translations for `mypackage-title':
\DeclareTranslationFallback {mypackage-title}{Title}
\DeclareTranslation{English}{mypackage-title}{Title}
\DeclareTranslation{French} {mypackage-title}{Titre}
\DeclareTranslation{German} {mypackage-title}{Titel}
\end{filecontents*}
\documentclass{article}
\usepackage[english,french,ngerman]{babel}
\usepackage{mypackage}
\begin{document}
\mytitle
\selectlanguage{french}
\mytitle
\selectlanguage{english}
\mytitle
\end{document}
All complete examples give