47

Consider that you are working on a standard that should be translated into some other languages. The document structure (figures, table structures, ...) is constant among languages. Is there any facility/technique/strategy/package to streamline multilingual documents production?

Is it possible to use a gettex-like method in (la)tex?

5

7 Answers 7

39

There is another way to support internationalization within your LaTeX documents. For instance, below is the support for english and german languages I made some time ago:

\newif\ifen
\newif\ifde

\newcommand{\en}[1]{\ifen#1\fi}
\newcommand{\de}[1]{\ifde#1\fi}

Next, if you need you can define different commands for months, date formats, etc:

\newcommand{\jan}{%
  \en{January}%
  \de{Januar}%
}

Finally, in text you can write something like this:

\en{English text.}
\de{Deutscher Text.}

After all, when you've created the whole document you can simple switch between languages setting in the document preamble either \entrue or \detrue. All this allows you to keep multilingual texts up-to-dated near each other.

1
  • Won't this be very volatile depending on what kinds of content you want to enclose? Apr 25, 2019 at 20:04
17

One possible problem you may have is keeping the different language versions up-to-date with respect to each other.

One possible solution is to write your document as a parallel text, with the different languages mixed together in small lumps so that the writer sees multiple languages in the same window.

A good (simple) way to handle this is to use the `comment' package. Here's the outline of an example using English and Portuguese:

English master document:

\includecomment{xengl}
\excludecomment{xport}
\input{commonbody}

Portuguese master document:

\excludecomment{xengl}
\includecomment{xport}
\input{commonbody}

Common body:

\begin{xengl}
Some English text, maybe up to a whole paragraph or list
\end{xengl}

\begin{xport}
Algum texto em português, talvez até um parágrafo
\end{xport}

Common, language-independent text can live outside of either environment, and will be included in both language versions.

0
7

Preamble: I hope I understand you correct: You have multiple documents, each document is written in one language, the content is the same. There is no language mixture inside one document.

I would create a directory per language. The I separate the document in small files (a file per chapter, perhaps per section. tables and figures in there own files).

Something like this:

english
english/main
english/preamble
english/chapter1
english/chapter2
german
german/main
german/preamble
german/chapter1
german/chapter2
french
french/main
french/preamble
french/chapter1
french/chapter2

Then I would start with a main document (English or the language you know best). Inside the document I add comments as sync point.

After this you need a diff-tool to compare the directories and files. The sync comments inside the document align the texts during comparison.

For the graphics I would create:

english/graphics
german/graphics
french/graphics
graphics

graphics contains the language independent graphics. If you have language depending graphics (e.g. with legends) you can add the to the subdirectories.

Then you define:

\graphicspath{{german/graphics}{../graphics}}

With a bit more work, you may write a script, that creates a new bi- (or more) lingual document using the parallel.sty. The you can use a printed document version instead the diff tool.

6

The "multilang" package (https://ctan.org/pkg/multilang) allows you to maintain multiple translations for content that is provided as an argument to a macro. Example from the package documentation:

\usepackage[languages={english,german}]{multilang}
% ...
\NewMultilangCmd{\Sec}{command=\section, margs=title}
\Sec{
  title/english={Foobar},
  title/german ={Dingsda}
}

Depending on the language selected for babel or polyglossia in the document, the above produces the equivalent of a "\section{Foobar}" or a "\section{Dingsda}". More than two languages are supported.

For ordinary paragraph text, which normally is not provided as a macro argument, one could define an artificial macro, like as follows:

\NewMultilangCmd{\Para}{command=\empty, margs=text}
\Para{
  text/english={This is an english-language paragraph of text.},
  text/german ={Dies ist ein deutschsprachiger Absatz.}
}

Using the package might be tedious, if the arguments to many macros shall be translated. I developed and used the package for CVs, in which the number of macros used is rather limited. See multilang package documentation and the komacv-multilang package for further information and examples.

5

Was wondering this myself and found a working solution with GNU gettext. A tool called po4a works with Tex/LaTeX files.

po4a has a few seperate commands:

  • po4a-gettextize, convert an original file (and its translation) to a PO file
  • po4a-normalize, normalize a documentation file by parsing it in po4a, and writing it back
  • po4a-translate, convert a PO file back to documentation format
  • po4a-updatepo, update the translation (in PO format) of documentation

So and example would look like this

po4a-gettextize -f latex -m main.tex -p xx.po -M UTF-8

The master file (-m) main.tex is the source file and we get an output (-p) of xx.po, and UTF-8 (-M) as the file encoding for non-english language support.

Where the latex format (-f) tells po4a to use latex environments and commands, if the tex format where to be used all environments and commands would need to be added manually.

So we can do everything we need to support several language versions for on or more documents.

To further on use the rest of the commands look at the man page for po4a

New environments and commands

If we would like to use custom commands or make new environments we need to declare them in the .tex document as the following according to the man page.

% Tells po4a that we have a non standard environment called tightemize
% po4a: environment tightemize

% tightemize is a custom list environment where we want each \item to be a separate translation object
% po4a: separator tightemize "\\\\item"

%rest of document
\documentclass{arcticle}
etc....
\begin(document)
\begin{tightemize}
\item Item 1
\item Item 2
\item Item 3
\end{tightemize}

Its also possible to change the LaTeX.pm module file, located in /usr/share/perl5/vendor_perl/Locale/Po4a as such

% Original environment
$env_separators{'itemize'} = "\\\\item";
% Here we can just copy the environment we want our new one to work as
$env_separators{'tightemize'} = "\\\\item";
% and adding it to the foreach abow
foreach (qw(abstract align align* cases center description displaymath document enumerate tightemize etc...

Edit PO files

To edit the files there exists many programs online or native ones, look at the Arch list.

2
  • I am just starting out with po4a. I created a .pot file using po4a-gettextize. It mostly works, but it is tokenizing a lot of LaTeX macros, for example: msgid "\\KOMAoptions{parskip=half}" msgstr "" How do I deal with that? It's a bit messy to just copy them unchanged in the .po file. Can I just delete them in the .pot file? Jan 12, 2021 at 14:27
  • Adding them to the .tex source using parser magic doesn't have any effect, they still appear in the .pot file, even if I specify that no parameters are to be translated. Jan 12, 2021 at 15:04
2

I assume you intend to maintain different language alternatives in a single LaTeX document. Then to be able to use syntax like

\en{English text.}
\de{Deutscher Text.}
\nl{Nederlands tekst.}

simply define macros like those in LaTeX

\newcommand\en[1]{#1}
\newcommand\de[1]{}
\newcommand\nl[1]{}

In which macro definition you put #1 determines the language choice.

2
  • 1
    This is essentially what darkled's answer does, but in that answer you just flip one switch, rather than redefining multiple commands Dec 8, 2018 at 11:40
  • 1
    Yes, the advantage of the present solution is avoiding the external dependency loaded from package ifthen. By the way, here is a similar thread and another variant of the solution: stackoverflow.com/questions/2043316/… Dec 9, 2018 at 13:50
0

Combining the answers of @darkled and @Bernardo with https://latex.org/forum/viewtopic.php?t=10792

I came to the following solution:

\documentclass[10pt,a5paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[TU]{fontenc}
\usepackage[english,german,french]{babel}

\newcommand\en[1]{\iflanguage{english}{#1}{}}
\newcommand\de[1]{\iflanguage{german}{#1}{}}
\newcommand\fr[1]{\iflanguage{french}{#1}{}}

\begin{document}

\selectlanguage{french}

    \en{English}
    \de{Deutsch}
    \fr{Français}
    
\end{document}

Babel provides two interesting elements:

\selectalnguage{<language>}, which you need for switching between built-in designations like "Table of Contents", "Inhaltsverzeichnis" and "Table de matières" anyways.

The \iflanguage{<selected language>}{<then>}{<else>} acts like @darkled's solution, without having to define additional booleans, but querying the language selected by \selectlanguage.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .