# Expandable case insensitive switch case for string comparison

I have spent the last few hours trying to come up with a good solution for my problem, but alas all solutions falls short. I want to create a switchcase for a function (In reality I need many different kinds, not just one for language, but I added it as an concrete example.)

My ideal switch case function has the following functionality

• It accepts commands as inputs (fully expandable)
• It is case insensitive

My code below is a switch case, but it fails both of the above requirements. Any help figuring out a proper way to do this is more than welcome.

\documentclass{article}

\usepackage[norsk,nynorsk,british,samin]{babel}
\usepackage{pdftexcmds}

% This allows the user to switch languages using a myriad of synonyms
% The four provided languages are: English, Norsk, Nynorsk and Samin
\makeatletter
\newcommand*{\selectLang}[1]{%
\stringcases%
{#1}%
{%
% English synonyms
{english}{\selectlanguage{british}}%
%
% Norsk (Bokmål) synonyms
{norsk}{\selectlanguage{norsk}}%
%
% Nynorsk synonyms
{nynorsk}{\selectlanguage{nynorsk}}%
%
% Samin synonyms
{samisk}{\selectlanguage{samin}}%
{samin}{\selectlanguage{samin}}%
}%
{}%
}

% Helper functions to create the switch case above
\newcommand{\stringcases}[3]{%
\romannumeral
\str@case{#1}#2{#1}{#3}\q@stop
}
\newcommand{\str@case}[3]{%
\ifnum\pdf@strcmp{\unexpanded{#1}}{\unexpanded{#2}}=\z@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\str@case@end{#3}}
{\str@case{#1}}%
}
\newcommand{\str@case@end}{}
\long\def\str@case@end#1#2\q@stop{\z@#1}
\makeatother

\newcommand{\temptwo}{nynorsk}

\begin{document}

\newcommand{\temp}{\temptwo}

\languagename

\selectLang{english}

\languagename % Displays english as it should

\selectLang{Norsk}

\languagename % This should display norsk

\selectLang{\temp}

\languagename % This should display nynorsk

\end{document}

• I think you don't want the command to be expandable (since \selectlanguage is not). I think you want it to expand it's argument, right? In that case, simply remove the two \unexpanded in the definition of \str@case. – Phelype Oleinik Sep 14 '19 at 13:24
• Yeah, the command is not supposed to be expandable. Only to expand the arguments =) – N3buchadnezzar Sep 14 '19 at 13:26

With the kind help of expl3, this is expandable (if the code of the cases is, so with the normal definition of \selectlanguage it isn't).

EDIT: as pointed out by @JosephWright, \str_foldcase:e is to be used for this kind of task. As a general rule of thumb: For processing use \str_foldcase:n, for text which should be printed out use \str_lowercase:n.

\documentclass[]{article}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \selectLang { m }
{
\str_case_e:nn { \str_foldcase:e { #1 } }
{
{ english } { \selectlanguage{british} }
{ norsk }   { \selectlanguage{norsk} }
{ nynorsk } { \selectlanguage{nynorsk} }
{ samisk }  { \selectlanguage{samisk} }
{ samin }   { \selectlanguage{samin} }
}
}
\cs_generate_variant:Nn \str_foldcase:n { e }
\ExplSyntaxOff

\renewcommand\selectlanguage{} % just to show that it works

\begin{document}
Chosen language: \selectLang{EnGlIsH}

\def\foo{NOrsK}
Chosen language: \selectLang{\foo}
\end{document}

• Perhaps \NewDocumentCommand or at least \cs_new_protected:Npn, since \selectlanguage doesn't expand. – Phelype Oleinik Sep 14 '19 at 13:35
• @PhelypeOleinik yes, that would be correct with the normal definition of \selectlanguage (not with the redefinition). I'll change it :) – Skillmon Sep 14 '19 at 13:36