Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

The following mwe throws the error You haven't defined the language lang yet.

\documentclass{article}
\usepackage[american]{babel}
\newcommand{\lang}{american}
\selectlanguage{\lang}
\begin{document}
Hello!
\end{document}

I can see that \lang is not being expanded properly inside \selectlanguage, but why does this happen and how do I fix it?

I also tried putting a space before \lang, in which case it does get expanded, but Babel now does not recognize the language because of the space.

share|improve this question

3 Answers 3

up vote 13 down vote accepted

The definition of \selectlanguage is equivalent to

\newcommand{\selectlanguage}[1]{%
  \bbl@push@language
  \aftergroup\bbl@pop@language
  \bbl@set@language{#1}%
}

where \bbl@push@language and \bbl@pop@language are maintenance macros to do and undo the language specific adjustments. Now, let's look at the important macro, which is defined by something equivalent to

\newcommand\bbl@set@language[1]{%
  \edef\languagename{%
    \ifnum\escapechar=\expandafter`\string#1%
      \@empty
    \else
      \string#1\@empty
    \fi
  }%
  \select@language{\languagename}
  [...]
}

where I omit the rest, which is inessential. The macro \select@language will expand its argument before doing anything else.

The code makes the assumption that \escapechar is set to its normal value (that is, 92). This complicated approach has historic reasons; in olden times, before LaTeX2e, there were a number of extensions to LaTeX for coping with different languages; for being friendly to the users accustomed to write \german whenever they wanted to switch to German, \selectlanguage was defined to accept both

\selectlanguage{german}

and

\selectlanguage{\german}

Let's see what happens with your \selectlanguage{\lang}. LaTeX does

\edef\languagename{%
  \ifnum\escapechar=\expandafter`\string\lang%
    \@empty
  \else
    \string#1\@empty
  \fi
}%

The conditional \ifnum wants to see a number and finds \escapechar (a numeric parameter), a relation symbol (<, = or >) and finds =, then another number; TeX performs expansion when looking for a number, so it expands \expandafter, which triggers the expansion of \string. After this expansion, what remains on the input stream is

\ifnum\escapechar=`\lang

where \lang are five tokens, because the macro name \lang has been “stringified”. The conditional is true, because `\ (when \ has category code 12) is an alternative way to say 92. Thus the “true branch” is followed, which makes lang\@empty remain on the input stream and so we get the equivalent of

\def\languagename{lang\@empty}

The \@empty will be get rid of later. This explains your error message.

If you say \selectlanguage{american}, instead, the conditional would be false and TeX would follow the “false branch” ending with

\def\languagename{american\@empty}

which is what's wanted.

What to do? If you want to use such a syntax, define your own version of \selectlanguage:

\newcommand{\xselectlanguage}[1]{%
  \begingroup\edef\x{\endgroup
    \noexpand\selectlanguage{#1}}\x
}

so you'll even be free to have more complex setups like

\newcommand{\lang}{\UKorUS english}
\newif\ifUK % conditional start out false
\newcommand{\UKorUS}{\ifUK UK\else US\fi}
%\UKtrue

[...]

\xselectlanguage{\lang}

and you'll get USenglish until you uncomment the \UKtrue line.

share|improve this answer

Use \expandafter trick:

\documentclass{article}
\usepackage[american]{babel}
\newcommand{\lang}{american}
\expandafter\selectlanguage\expandafter{\lang}
\begin{document}
Hello!
\end{document}

Note: In babel package, \selectlanguage{\foo} is equivalent to \selectlanguage{foo}. This is a feature by design “for historial reasons”. See the remarks of command \bbl@set@language in the document of babel.

share|improve this answer

Try this:

\documentclass{article}
\usepackage[greek, american]{babel}
\def\lang#1{\selectlanguage{#1}}
\begin{document}
\lang{american}
Hello!
\lang{greek}
Hello!
\end{document}
share|improve this answer
    
This doesn't answer the question (see the title). –  pts Oct 6 '13 at 18:33
    
@pts Sorry I should have expanded on the answer. \lang{\greek} or \lang{\american} also works. –  Yiannis Lazarides Oct 6 '13 at 18:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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