4

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}
2
  • 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. Sep 14, 2019 at 13:24
  • Yeah, the command is not supposed to be expandable. Only to expand the arguments =) Sep 14, 2019 at 13:26

1 Answer 1

10

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}
4
  • Perhaps \NewDocumentCommand or at least \cs_new_protected:Npn, since \selectlanguage doesn't expand. Sep 14, 2019 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, 2019 at 13:36
  • 2
    Explainer for beginners: \str_foldcase:e doesn't exist by default and needs creating with the \cs_generate_variant statement. This generate_variant must be executed before the \selectLang command is used otherwise you get an error. This is independent of the order in which the code is written. As a beginner myself I found it helpful to put the generate_variant physically before the \NewDocumentCommand that makes use of it.
    – Doc Octal
    Aug 20, 2021 at 8:23
  • 2
    Another two traps for beginners I fell into. First the \selectlanguage command might not work well if executed (as opposed to just written as it is in the answer) from the preamble, that is executed before \begin{document} Second I had problems by executing commands in the preamble that tried to typeset text. I was so enchanted and frustrated by expl3 that I forgot you can't put text into a document that hasn't started yet. These two things seem obvious now but they absolutely weren't at the time.
    – Doc Octal
    Aug 20, 2021 at 8:38

You must log in to answer this question.

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