IfLanguageName versus iflanguage

Package babel knows more than four languages of the family English:

\DeclareOption{american}{\bbl@load@language{english}}
\DeclareOption{australian}{\bbl@load@language{english}}
\DeclareOption{british}{\bbl@load@language{english}}
\DeclareOption{canadian}{\bbl@load@language{english}}
\DeclareOption{newzealand}{\bbl@load@language{english}}
\DeclareOption{UKenglish}{\bbl@load@language{english}}
\DeclareOption{USenglish}{\bbl@load@language{english}}

And babel knows lots of hyphenation patterns (macro \l@<language>), from english.ldf

\ifx\l@english\@undefined
  \ifx\l@UKenglish\@undefined
    \ifx\l@british\@undefined
      \ifx\l@american\@undefined
        \ifx\l@USenglish\@undefined
          \ifx\l@canadian\@undefined
            \ifx\l@australian\@undefined
              \ifx\l@newzealand\@undefined

A detection of an English language would have to test either eight language names or eight hyphenation patterns.

Non-expandable \IfLangEnglish

The following example defines \IfLangEnglish using LaTeX's \in@ to check if an argument can be found in a list:

\documentclass{article}
\usepackage[USenglish,british,canadian,australian,ngerman]{babel}

\makeatletter
\newcommand*{\LanguageEnglishList}{%
  ,american,australian,british,canadian,english,newzealand,UKenglish,USenglish,%
}
\@onelevel@sanitize\LanguageEnglishList
\DeclareRobustCommand*{\IfLangEnglish}{%
  \let\@LanguageName@\languagename
  \@onelevel@sanitize\@LanguageName@
  \edef\@next{%
    \noexpand\in@{,\@LanguageName@,}{\LanguageEnglishList}%
  }\@next
  \ifin@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

\begin{document}
  \def\test#1/#2 {%
    \par \textbf{\IfLangEnglish{yes}{no}} (#1/\textbf{#2})\par
  }%
  \test start document/ngerman
  \foreignlanguage{USenglish}{%
    \test foreignlanguage/USenglish
  }
  \begin{otherlanguage}{british}
    \test otherlanguage/british
  \end{otherlanguage}
  \begin{otherlanguage*}{canadian}
    \test otherlanguage*/canadian
  \end{otherlanguage*}
  \selectlanguage{australian}
  \test selectlanguage/australian
  \selectlanguage{ngerman}
  \test selectlanguage/ngerman
\end{document}

The categories of the letters inside \languagename can be 11 (letter) or 12 (other) or even a mixup (e.g. first character has 12, the others 11). Therefore \@onelevel@sanitize normalizes the characters to category 12 for the comparison.

Result:

Result

Expandable \IfLangEnglish

The former \IfLangEnglish is not fully expandable because of assignments and definitions.

Therefore I would use the following definition for \IfLangEnglish based on the expandable \IfLanguageName of package iflang:

\documentclass{article}
\usepackage[USenglish,british,canadian,australian,ngerman]{babel}

\usepackage{iflang}

\makeatletter
\newcommand*{\IfLangEnglish}{%
  % The order can be optimized by putting more often used names first.
  \IfLanguageName{american}\@firstoftwo{%
  \IfLanguageName{australian}\@firstoftwo{%
  \IfLanguageName{british}\@firstoftwo{%
  \IfLanguageName{canadian}\@firstoftwo{%
  \IfLanguageName{english}\@firstoftwo{%
  \IfLanguageName{newzealand}\@firstoftwo{%
  \IfLanguageName{UKenglish}\@firstoftwo{%
  \IfLanguageName{USenglish}\@firstoftwo\@secondoftwo}}}}}}}%
}
\makeatother

\begin{document}
  \def\test#1/#2 {%
    \par
    \csname if\IfLangEnglish{true}{false}\endcsname
      \textbf{yes}
    \else
      \textbf{no}
    \fi
    (#1/\textbf{#2})\par
  }%
  \test start document/ngerman
  \foreignlanguage{USenglish}{%
    \test foreignlanguage/USenglish
  }
  \begin{otherlanguage}{british}
    \test otherlanguage/british 
  \end{otherlanguage}
  \begin{otherlanguage*}{canadian}
    \test otherlanguage*/canadian 
  \end{otherlanguage*}
  \selectlanguage{australian}
  \test selectlanguage/australian
  \selectlanguage{ngerman}
  \test selectlanguage/ngerman
\end{document}

Result

Package iflang 2014/04/29 v1.7

The new version of iflang is available here until it hits CTAN. (The .dtx file is embedded as PDF attachment, run it through plain TeX to get the unpacked package file.)

The new version provides test commands for language families:

\IfLanguageFamilyEnglish{<yes>}{<no>}

The implementation is based on the expandable \IfLangEnglish macro.

See the documentation for the supported language families and their included languages.


The translations package offers the (expandable)

\ifcurrentbaselanguage{<lang>}{<true>}{<false>}

test where <lang> is the name of what translations calls a base language. »English« is one of them. Other languages are dialects or aliases as far as translations is concerned. \ifcurrentbaselanguage{english}{<true>}{<false>} puts the <true> branch in the input stream as long as the current babel language is either english or an alias (English) or a dialect (british, ...) or an alias of a dialect (UKenglish, ...)

All the tests in the following example print yes except for the first one where the current language is ngerman:

\documentclass{article}
\usepackage[USenglish,british,canadian,australian,newzealand,UKenglish,american,ngerman]{babel}

\usepackage{translations}

\begin{document}

% ngerman
\ifcurrentbaselanguage{English}{yes}{no}

\begin{otherlanguage}{british}
  \ifcurrentbaselanguage{English}{yes}{no}
\end{otherlanguage}

\begin{otherlanguage*}{canadian}
  \ifcurrentbaselanguage{English}{yes}{no}
\end{otherlanguage*}

\selectlanguage{australian}
\ifcurrentbaselanguage{English}{yes}{no}

\selectlanguage{american}
\ifcurrentbaselanguage{English}{yes}{no}

\selectlanguage{newzealand}
\ifcurrentbaselanguage{English}{yes}{no}

\selectlanguage{USenglish}
\ifcurrentbaselanguage{English}{yes}{no}

\selectlanguage{UKenglish}
\ifcurrentbaselanguage{English}{yes}{no}

% this shows that the test is expandable:
\edef\foo{\ifcurrentbaselanguage{English}{yes}{no}}
\show\foo
% > \foo=macro:
% ->yes.
% l.32 \show\foo

\end{document}

enter image description here