19

I would like to define a command that slightly differs depending on the currently selected language in my document. My code:

\documentclass{article} 
\usepackage[english,french,german]{babel}

\newcommand{\mynewcommand}[4]{%
    \newcommand{#1}{%
        \iflanguage{english}{#2}{%
        \iflanguage{french}{#3}{%
        \iflanguage{german}{#4}{}%
        }}%
    }%
}
 
\mynewcommand{\uno}{one}{une}{eins}
\newcommand{\whatever}{whatever} % if this is commented out the code works as desired

\begin{document} 

\selectlanguage{english}
\uno
\selectlanguage{french}
\uno

\end{document}

Why do I get an error thrown at \newcommand{\whatever}{whatever} and how do I avoid that?

Note:

In an earlier version I oversimplified my MWE using only two languages, in that case no error is thrown

8
  • Which error? I have no problems. Jan 30, 2012 at 13:30
  • I get an error saying Error: Missing \begin{document}
    – D.Roepo
    Jan 30, 2012 at 13:32
  • Is that your first error. Please provide also the File List produced in the log-File by \listfiles. Jan 30, 2012 at 13:40
  • No, you don't; but you surely get lots of spurious spaces.
    – egreg
    Jan 30, 2012 at 13:40
  • You're missing a closing brace in the modified example. That's why I proposed a different approach: counting braces is difficult.
    – egreg
    Jan 30, 2012 at 17:46

1 Answer 1

18

The definition seems to be "almost" correct, in that it gives almost the expected result, apart from spurious spaces:

\newcommand{\mynewcommand}[3]{%
    \newcommand{#1}{%
        \iflanguage{english}{#2}{%
        \iflanguage{french}{#3}{}
        }%
    }%
}

However this is error prone if one wanted to augment the supported languages; with xparse it's easier:

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\mynewcommand}{m m m}
  {
   \cs_new:Npn #1
     {
      \str_case:onF { \languagename }
        {
         {english}{#2}
         {french}{#3}
        }
        {``No~def~of~\texttt{\token_to_str:N #1}~for~\languagename''}
     }
  }
\ExplSyntaxOff

If other languages were desired it would be sufficient to add an argument to \mynewcommand and the suitable line along the same scheme.

An alternative way might be to define different commands:

\makeatletter
\newcommand{\newlanguagecommand}[1]{%
  \newcommand#1{%
    \@ifundefined{\string#1\languagename}
      {``No def of \texttt{\string#1} for \languagename''}
      {\@nameuse{\string#1\languagename}}%
  }%
}
\newcommand{\addtolanguagecommand}[3]{%
  \@namedef{\string#1#2}{#3}}
\makeatother
\newlanguagecommand{\uno}
\addtolanguagecommand{\uno}{english}{one}
\addtolanguagecommand{\uno}{french}{une}

Unknown languages will result in "No def of \command for language"

With \newlanguagecommand{\uno} one defines the command so that its expansion is \\uno<languagename>; for example, when the language is French, writing \uno will use \\unofrench which is defined by \addtolanguagecommand{\uno}{french}{une} to expand to "une".

This should give no problems also in moving arguments as long as the replacement text doesn't contain fragile commands (text is OK).


A revamped expl3 implementation. The translations are stored in a property list and used according to the current language.

The defined command can receive an optional argument, which should be a valid language name, to force using the corresponding translation independent of the current language.

\documentclass{article}
\usepackage[french,ngerman,english]{babel}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\newlanguagecommand}{mm}
 {% #1 = command to define
  % #2 = key-value list
  \prop_new:c { \__roepo_nlc_strip:N #1 }
  \prop_gset_from_keyval:cn { \__roepo_nlc_strip:N #1 } { #2 }
  \NewDocumentCommand{#1}{o}
   {
    \IfNoValueTF { ##1 }
     {
      \roepo_nlc:NV #1 \languagename
     }
     {
      \roepo_nlc:Nn #1 { ##1 }
     }
   }
 }

\cs_new:Nn \roepo_nlc:Nn
 {
  \prop_if_in:cnTF { \__roepo_nlc_strip:N #1 } { #2 }
   {
    \prop_item:cn { \__roepo_nlc_strip:N #1 } { #2 }
   }
   {
    UNSET~TRANSLATION
   }
 }
\cs_generate_variant:Nn \roepo_nlc:Nn { NV }

% syntactic sugar
\cs_new:Nn \__roepo_nlc_strip:N { g_roepo_nlc_ \cs_to_str:N #1 _prop }

\ExplSyntaxOff

\newlanguagecommand{\uno}{
  english=one,
  ngerman=eins,
  french=un
}
\newlanguagecommand{\duck}{
  english=duck,
  ngerman=Ente,
}

\begin{document}

English: \uno{} and \duck{} (\duck[ngerman])

\selectlanguage{ngerman}

Deutsch: \uno{} und \duck{} (\duck[english])

\selectlanguage{french}

Français: \uno{} et \duck{} (\duck[english])

\end{document}

enter image description here

You must log in to answer this question.

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