12

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

  • Which error? I have no problems. – Marco Daniel Jan 30 '12 at 13:30
  • I get an error saying Error: Missing \begin{document} – D.Roepo Jan 30 '12 at 13:32
  • Is that your first error. Please provide also the File List produced in the log-File by \listfiles. – Marco Daniel Jan 30 '12 at 13:40
  • No, you don't; but you surely get lots of spurious spaces. – egreg Jan 30 '12 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 '12 at 17:46
12

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

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.