2

Multilingual Document

Question

I would like to follow the principle of "don't repeat yourself" and create a single list of inputs, which are actually various versions of the same document in different languages. This question is related to this.


This question is part of a trail of questions. The goal mine was to use this list inside of a tikz node, but I removed that from this question in the interest of keeping it simple. So, for those interested, here is a quick list for reference:

Related Question for making a macro that can handle post-parsing-inputted list items, see:

For that same solution with tikz node support, see:


UPDATE 2015-03-08: The following code based on egreg's answer

works 50% of the time

see How can I use a list stored in aux and insert its output into a tikz node?

Situation

I'd like to create a command that has:

  • iso 639-1 code as #1
  • language name in native tongue as #2
  • input file as #3

example: \inputlanguagefile{En}{English}{./Languages/en.tex}

Then I would like to create a list of the language codes from these inputs that can be used in my custom \maketitle command (warning: \maketitle inputs are sent directly to tikz nodes)

Problem

The difficulty lies in the fact that the list is called before it is created. I would probably need to create some kind of command to loop through the inputs beforehand. The document would look something like this:

%\maketitle[subtitle]{title}
\maketitle[listoflanguagecodes]{Multilingual Document}
\inputlanguagefile{En}{English}{./Languages/en.tex}
\inputlanguagefile{Da}{Dansk}{./Languages/da.tex}
\inputlanguagefile{De}{Deutsch}{./Languages/de.tex}
\inputlanguagefile{It}{Italiano}{./Languages/it.tex}
\inputlanguagefile{Hu}{Magyarország}{./Languages/hu.tex}

Redefined \maketitle

\maketitle[subtitle]{title} \maketitle[\listoflanguagecodes]{Title}

\renewcommand{\maketitle}[2][]{%
\thispagestyle{empty}
 #1\\
 #2
\clearpage
\setcounter{page}{1}
}%

The second argument i.e. the actual language names are only used to create a language directory with etoc.

MWE

I am trying to put together a minimal working example of a complex setup. Work in progress.

autolanglist/
├── Languages
│   ├── da.tex
│   ├── de.tex
│   └── en.tex
└── usermanual.tex

1 directory, 4 files

Contents usermanual.tex

\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\usepackage[explicit]{titlesec}
\usepackage{tocloft}
\usepackage{etoc}
\usepackage{lipsum}
\usepackage{hyperref}

\newcounter{runningsectioncounter}
\setcounter{runningsectioncounter}{0}
\titleformat{\section}[hang]{\color{red}\Huge\bfseries}{}{0pt}{\thesection\quad#1}[\stepcounter{runningsectioncounter}]

% Use this \newlangfile{<code>}{<name>}{<file>} to add external language varieties
\newcommand{\inputlanguagefile}[3]{%
  \newpage\pdfbookmark{#2}{bkm#1}%
  \etoctoccontentsline{part}{#2}%
  \setcounter{runningsectioncounter}{\value{section}}
  \setcounter{section}{0}
  \renewcommand*{\theHsection}{chX.\the\value{runningsectioncounter}} % Keeps hyperref happy (provides unique section numbers instead of using the section counter)
  \input{#3}%
}

\renewcommand{\maketitle}[2][]{%
    #1\\
    #2

\clearpage
}%

\newcommand{\usermanualfrontmatter}{%
    \maketitle[En, Da, De]{User Manual} % NOTE: This is the list of language codes should be automated!
    \newpage
    \setcounter{tocdepth}{0} % make ToC contain only parts
    \renewcommand{\contentsname}{Language Directory} % change ToC Title
    \tableofcontents
    \newpage
    \setcounter{tocdepth}{4}
    \renewcommand{\contentsname}{Table of Contents} % reset ToC Title back to default
}%

\begin{document}
\usermanualfrontmatter{}
\inputlanguagefile{En}{English}{./Languages/en.tex}
\inputlanguagefile{Da}{Dansk}{./Languages/da.tex}
\inputlanguagefile{De}{Deutsch}{./Languages/de.tex}
\end{document}

Contents of ./Languages/da.tex

\maketitle[da]{Brugsanvisning}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]

Contents of ./Languages/de.tex

\maketitle[de]{Gebrauchsanweisung}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]

Contents of ./Languages/en.tex

\maketitle[en]{User Manual}
\localtableofcontents
\clearpage
\section{Test}
\lipsum[50]

Output

The first page is scaled down A4 paper, but the rest were resized too 100mm x 150mm to save screen real estate on this website :) I attempted to clearly show which list should be generated automatically. The contents of which are not added until later in the document (\inputlanguagefile).

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

  • I don't think that such an extensive change to your question is along the guidelines of the site. One should avoid edits that invalidate existing answers. – egreg Mar 8 '15 at 21:00
  • Alright. I was actually opening a new question as you typed that. It seems like the question is becoming convoluted. You are right. – Jonathan Komar Mar 8 '15 at 21:01
  • 1
    @cfr I meant to do that yesterday but fell asleep. Now it should be restored to a pre-tikz state where egreg's answer applies. – Jonathan Komar Mar 9 '15 at 6:43
5

You have to write the data in the .aux file for having the information available at the next run; we exploit the fact that the .aux file is read as part of \begin{document}, so \manuallanguages will have the requested value (at the next run) when \maketitle is issued.

\documentclass{article}

\makeatletter 
\newcommand{\manuallanguages}{\@gobble} % initialization
\newcommand{\inputlanguagefile}[1]{%
  \input{\manualfile{#1}}%
  \protected@write\@auxout{}{\string\used@language{#1}}%
}
\AtEndDocument{\let\used@language\@gobble}
\newcommand{\used@language}[1]{%
  \g@addto@macro\manuallanguages{\language@sep\format@language{#1}}%
}
\newcommand{\language@sep}{, }% separator
\newcommand{\format@language}[1]{%
  \expandafter\expandafter\expandafter\@secondoftwo % or \@firstoftwo
  \csname language@#1\endcsname
}
\newcommand\definemanuallanguage[2]{%
  \@namedef{language@#1}{{#1}{#2}}%
}
\makeatother

\newcommand\manualfile[1]{./UserManual_#1}% use your own

\definemanuallanguage{en}{English}
\definemanuallanguage{de}{Deutsch}
\definemanuallanguage{da}{Dansk}

\begin{document}

\title{User Manuals\\
  \manuallanguages}

\author{macmadness86}

\maketitle

\inputlanguagefile{en}

\inputlanguagefile{da}

\inputlanguagefile{de}

\end{document}

Each \inputlanguagefile adds a note in the .aux file in the form

\used@language{xy}

where xy is the argument to \inputlanguagefile.

Define \manualfile to work according to your setup, here I have the manual files in the same directory as the main file.

If you prefer to have just the ISO abbreviations (which are lowercase), change \@secondoftwo into \@firstoftwo.

enter image description here

  • So, do you have any options that are less verbose :D – Jonathan Komar Mar 4 '15 at 8:26
  • I am struggling to keep my commands the way they are and make this work. I know it is possible now. I have a redefined \maketitle command that accepts an optional argument as its subtitle. I will post the code above. Maybe you can help me if it isn't too much trouble. – Jonathan Komar Mar 4 '15 at 14:36
  • @macmadness86 \title[\manuallanguages]{User Manuals} should work. – egreg Mar 4 '15 at 15:57
  • It works without tikz. I think the problem I am having deals with the @gobble and my \maketitle command, which contains \tikz nodes. I get ! Argument of \@gobble has an extra } I will try to reproduce the problem and put some code in my question. – Jonathan Komar Mar 4 '15 at 16:21
  • Would you mind having a look at my new MWE? My knowledge is not advanced enough to understand your answer. i.e. \inputlanguagefile[1] should be \inputlanguagefile[3]. I don't know where to go from there... – Jonathan Komar Mar 8 '15 at 18:46
2
+50

last update: shows how to adapt the concrete code which was added to the Question in an edit. See bottom.

As you mentioned etoc, I will explain that with it you can achieve what you want without having to write things to the aux file.

I have also added hyperref just to show that hyperlinks will be there.

The idea is that with etoc you can print your comma separated list of used languages via the command \tableofcontents, and placing this command as a node in a TikZ picture is no problem.

Update adds a variant.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{tikz}
\usetikzlibrary{calc, positioning}

\usepackage{etoc}

% in this example, user manuals are each printed in their own
% \part. If there were no other parts, we would not need to define 
% a special division called "languagefile", we would simply use "part".

% I use a \part below in \inputlanguagefile
% to provide an hyperref target.

% Else, without \part, one would only need define a counter 
% and do \refstepcounter in the \inputlanguagefile command.

% Without hyperref, there is no need to do anything extra.
\etocsetlevel{languagefile}{6}

\usepackage{hyperref}% just to check compatibility

\makeatletter

\newcommand\manualfile[1]% #1 = typically, two-letter abbrev for language
           {./UserManual_#1.tex }% use your own preferred location


\newcommand\declaremanuallanguage[2]% #1 = abbrev, #2 = full name
          {\@namedef{languagename@#1}{#2}}


\newcommand{\inputlanguagefile}[1]{%
     \part{\@nameuse{languagename@#1}}
     \etoctoccontentsline{languagefile}{\@nameuse{languagename@#1}}%
     \input{\manualfile{#1}}}

\makeatother

\declaremanuallanguage{en}{English}
\declaremanuallanguage{de}{Deutsch}
\declaremanuallanguage{da}{Dansk}

\newcommand{\manuallanguages}{%
    \begingroup
      \etocsetnexttocdepth {-1}% limit the TOC to what we want
      \etocsetlevel {part}{0}% move parts out of the way
      \etocsetlevel {languagefile}{-1}% only interested in them
      \etocsetstyle {languagefile}
                    % do the trick to get a separator, this is executed once
                    {\def\manual@sep{\def\manual@sep{, }}}
                    % then each entry will do ", " except the first
                    {\manual@sep\etocname}{}{}%
      \etocsettocstyle {}{}% suppress standard Contents heading
% we will be in vertical mode.
\begin{tikzpicture}
    \node [font=\Huge\bfseries] (title) at 
      ($ (current page.north)!.25!(current page.south) $) {User manuals};
    \node [font=\Large\bfseries] (subtitle) [below= 2cm of title] 
          {\tableofcontents};% etoc's magic ! Each entry is a link.
\end{tikzpicture}
    \endgroup
%\clearpage
\setcounter{page}{1}
}%


% only for sample code, remove from final version
% as we don't provide an extension, .tex  suffix is appended.
\usepackage{filecontents}
\begin{filecontents}{UserManual_en}
This is the English manual.
\end{filecontents}
\begin{filecontents}{UserManual_de}
Dies ist die deutsche Bedienungsanleitung.
\end{filecontents}
\begin{filecontents}{UserManual_da}
Dette er den danske manual.
\end{filecontents}
\begin{filecontents}{UserManual_fr}
Ceci est le manuel français.
\end{filecontents}

\title{\manuallanguages}

\author{macmadness86}

\begin{document}\pagestyle{empty}% only for cropping pages for png's

\maketitle\thispagestyle{empty}

\vskip1cm
\hrule
\clearpage

\inputlanguagefile{en}

\vskip1cm
\hrule
\clearpage

\inputlanguagefile{da}

\vskip1cm
\hrule
\clearpage

\inputlanguagefile{de}
\vskip1cm
\hrule

\end{document}

first page second page third page fourth page

(the rules are only for the pages to be the same width even after cropping to produce the images)

Variant:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{tikz}
\usetikzlibrary{calc, positioning}

\usepackage{etoc}

\usepackage{hyperref}% just to check compatibility

% location of user manuals
\newcommand\manualfile[1]{./UserManualv2_#1.tex }%

% innocent wrapper
\newcommand{\inputlanguagefile}[1]{\input{\manualfile{#1}}}

% a fictional sectioning unit,
\etocsetlevel{languagefile}{6}

\newcommand{\thisismanualfor}[1]{% 
    \part{#1}% convenient way to create an hyperref target
    \etoctoccontentsline{languagefile}{#1}%
}%

\newcommand{\manuallanguages}{%
    \begingroup
      \etocsetnexttocdepth {-1}% limit the TOC to what we want
      \etocsetlevel {part}{0}% move parts out of the way
      \etocsetlevel {languagefile}{-1}% only interested in them
      \etocsetstyle {languagefile}
                    % do the trick to get a separator, this is executed once
                    {\def\manual@sep{\def\manual@sep{, }}}
                    % then each entry will do ", " except the first
                    {\manual@sep\etocname}{}{}%
      \etocsettocstyle {}{}% suppress standard Contents heading
% for the record: etoc always does a \par when doing \tableofcontents,
% which can be turned off via \etocinline command; it turns out
% we don't need to worry about this in the TikZ's node.
\begin{tikzpicture}
    \node [font=\Huge\bfseries] (title) at 
      ($ (current page.north)!.25!(current page.south) $) {User manuals};
    \node [font=\Large\bfseries] (subtitle) [below= .5cm of title] 
          {\tableofcontents};% etoc's magic ! Each entry is a link.
\end{tikzpicture}
    \endgroup
}%


% ONLY for sample code, REMOVE from final version
% as we don't provide an extension, .tex  suffix is appended.
\usepackage{filecontents}
\begin{filecontents}{UserManualv2_en}
\thisismanualfor{English}%
This is the English manual.
\end{filecontents}
\begin{filecontents}{UserManualv2_de}
\thisismanualfor{Deutsch}%
Dies ist die deutsche Bedienungsanleitung.
\end{filecontents}
\begin{filecontents}{UserManualv2_da}
\thisismanualfor{Dansk}%
Dette er den danske manual.
\end{filecontents}
\begin{filecontents}{UserManualv2_fr}
\thisismanualfor{Français}%
Ceci est le manuel français.
\end{filecontents}

\title{\manuallanguages}

\author{macmadness86}

\begin{document}

\maketitle

\part{Introduction}

\inputlanguagefile{fr}

\inputlanguagefile{en}

\inputlanguagefile{da}

\part{Conclusion}

\hrule

\end{document}

etoc to list automatically input files


Now that the question has complete code sample I can provide an answer addressing more directly the specific aims.

This is a copy of the code with additions tagged by % ADD THIS lines.

\documentclass{article}
%% \usepackage{fontspec} % commented out to compile with pdflatex
\usepackage{tikz}
\usetikzlibrary{calc,positioning}
\usepackage[explicit]{titlesec}
\usepackage{tocloft}
\usepackage{etoc}
% ADDTHIS
    \etocsetlevel{languageabbrev}{6}
%
\usepackage{lipsum}
\usepackage{hyperref}

\newcounter{runningsectioncounter}
\setcounter{runningsectioncounter}{0}
\titleformat{\section}[hang]{\color{red}\Huge\bfseries}{}{0pt}{\thesection\quad#1}[\stepcounter{runningsectioncounter}]

% Use this \newlangfile{<code>}{<name>}{<file>} to add external language varieties
\newcommand{\inputlanguagefile}[3]{%
  \newpage\pdfbookmark{#2}{bkm#1}%
  \etoctoccontentsline{part}{#2}%
% ADDTHIS
\etoctoccontentsline{languageabbrev}{#1}%
%
  \setcounter{runningsectioncounter}{\value{section}}
  \setcounter{section}{0}
  \renewcommand*{\theHsection}{chX.\the\value{runningsectioncounter}} % Keeps hyperref happy (provides unique section numbers instead of using the section counter)
  \input{#3}%
}

\renewcommand{\maketitle}[2][]{%
    \begin{tikzpicture}[remember picture, overlay]
        \node [font=\Huge] (title) at ($ (current page.north)!.25!(current page.south) $) {#2};
        \node [font=\Large,below=2cm of title] (subtitle) {#1};
        %\node [color=red,draw,below=1cm of subtitle] (note) {This list should be generated automatically.};
        %\draw [->,ultra thick,red] (note) -- (subtitle);
    \end{tikzpicture}
\clearpage
}%

\newcommand{\usermanualfrontmatter}{%
% ADDTHIS
    \GetUsedLanguages
%
    \maketitle[\UsedLanguages]{User Manual}
    \newpage
    \setcounter{tocdepth}{0} % make ToC contain only parts
    \renewcommand{\contentsname}{Language Directory} % change ToC Title
    \tableofcontents
    \newpage
    \setcounter{tocdepth}{4}
    \renewcommand{\contentsname}{Table of Contents} % reset ToC Title back to default
}%

% ADDTHIS
\makeatletter % to use \g@addto@macro from LaTeX's kernel
\newcommand{\GetUsedLanguages}{%
  \begingroup % work in a group to undo our changes automatically on exit
      \etocsetnexttocdepth {-1}% limit the TOC to what we want
      \etocsetlevel {part}{0}% move parts out of the way
      \etocsetlevel {languageabbrev}{-1}% only interested in them
      \etocsetstyle {languageabbrev}
                    {\gdef\UsedLanguages{}\etocskipfirstprefix}
                    {\g@addto@macro\UsedLanguages{, }}
                    {\expandafter\g@addto@macro\expandafter\UsedLanguages
                     \expandafter{\etocthename}}%
                    {}%
      \etocsettocstyle {}{}% suppress standard Contents heading
      \etocinline % suppress \par, thus TOC does not typeset anything at all
      \tableofcontents % fill up \UsedLanguages
  \endgroup
}
\makeatother



% ONLY FOR ALL IN ONE CODE SAMPLE
%
\usepackage{filecontents}

\begin{filecontents}{da.tex}
\maketitle[da]{Brugsanvisning}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
\end{filecontents}

\begin{filecontents}{de.tex}
\maketitle[de]{Gebrauchsanweisung}
\newpage
\localtableofcontents
\newpage
\section{Test}
\lipsum[50]
\end{filecontents}

\begin{filecontents}{en.tex}
\maketitle[en]{User Manual}
\localtableofcontents
\clearpage
\section{Test}
\lipsum[50]
\end{filecontents}

\begin{document}
\usermanualfrontmatter{}
\inputlanguagefile{En}{English}{./en.tex}
\inputlanguagefile{Da}{Dansk}{./da.tex}
\inputlanguagefile{De}{Deutsch}{./de.tex}
\end{document}

etoc title with languages

  • Cool answer! I have to emphasize though that I am looking for a solution following the "don't repeat yourself' principle. i.e. I am very against these declarations. I just want one command to call each file, its language code and corresponding language name. – Jonathan Komar Mar 5 '15 at 6:55
  • do you mean the filecontents declarations? there are only there to allow people to copy-paste the code if they want to test it, with no need of manually creating the files. If however, you mean the \declaremanuallanguage, their only rôle is to map abbreviations to full names. If the \etoctoccontentsline things are moved to inside the respective language manuals, then nothing at all will be in the main .tex file, only the \input instructions. – user4686 Mar 5 '15 at 7:08
  • @macmadness86 I think jfbu forgot to ping you...? – cfr Mar 6 '15 at 23:25
  • @jfbu I meant the \declaremanuallanguage. But Actually, I am not looking for an answer with etoc—so sorry about that! You clearly put some time into your answer. This is because I have many documents that are not compatible with etoc. Nonetheless, your answer is nice. I was hoping to draw more attention to this queston by starting a bounty. – Jonathan Komar Mar 8 '15 at 18:44
  • @macmadness86 no need to be sorry :-), I understand. My question here was actually before I posted the last update to my answer which used the code you added to your question. The main incompatibility I know for etoc is with beamer class. – user4686 Mar 8 '15 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.