# How to expand condition on \IfEqCase before evaluation?

I'm trying to do a simple task (as in the MWE below). When a given text is given (a filename) it outputs a given color.

To work as I intended, \IfEqCase should only evaluate the file extension, as presented in the commented lines. Unfortunately, it seems that \IfEqCase breaks when I try to add other commands as parameters.

Can you give a help on this?

Best Regards

\documentclass{article}

% General settings
\usepackage[utf8]{inputenc}     % Input encoding
\usepackage[T1]{fontenc}        % Output encoding
\usepackage{xstring}
\usepackage{xparse}

\newcommand{\selColor}[1]{%
\IfEqCase{#1}{%
%       \IfEqCase{\StrGobbleLeft{#1}{\StrPosition{#1}{.}}}{%
{Snip00.tex}{black}%
{Snip00.doc}{red}%
%       {tex}{black}%
%       {doc}{red}%
}[\PackageError{colorErr}{Undefined color option: #1}{}]%
}

\begin{document}

Start document here

\selColor{Snip00.tex}
\selColor{Snip00.doc}

End the document

\end{document}

• Does \fullexpandargs\IfEqCase{..} help? – user31729 Feb 4 at 15:23

The xstring commands aren't expandable, so they can't be easily passed as arguments to other commands. Instead, the package allows you to use a trailing optional argument to which the result of the macro is saved:

\documentclass{article}
\usepackage{xstring}

\newcommand{\selColor}[1]{%
\StrPosition{#1}{.}[\tempa]%
\StrGobbleLeft{#1}{\tempa}[\tempb]%
\IfEqCase{\tempb}{%
{tex}{black}%
{doc}{red}%
}[\PackageError{colorErr}{Undefined color option: #1}{}]%
}

\begin{document}

Start document here

\selColor{Snip00.tex}
\selColor{Snip00.doc}

End the document

\end{document}


This prints:

without the error message.

An alternative approach with expl3 that doesn't require saving the commands in intermediate steps:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\selColor{m}
{ \__acombo_sel_color:n {#1} }
\cs_new:Npn \__acombo_sel_color:n #1
{
\str_case:fnF { \__acombo_extension:n {#1} }
{
{ tex } { black }
{ doc } { red }
}
{ \PackageError{colorErr}{Undefined~color~option:~#1}{} }
}
\cs_generate_variant:Nn \str_case:nnF { f }
\cs_new:Npn \__acombo_extension:n #1
{ \__acombo_extension:w #1 \q_stop }
\cs_new:Npn \__acombo_extension:w #1 . #2 \q_stop {#2}
\ExplSyntaxOff

\begin{document}

Start document here

\selColor{Snip00.tex}
\selColor{Snip00.doc}

End the document

\end{document}


Here I used a command \__acombo_extension:n which will exclude everything until the first ., then passed it to \str_case:fnF which will try to match that with each extension you give. If it doesn't find a match the error is raised.

For both approaches (xstring and expl3) the behaviour is undefined when there are multiple . or no . in the argument to \SelColor. Here's a version which:

• If there's no dot, the string used is the whole argument (i.e.: \selColor{tex} is the same as \selColor{Snip00.tex});

• If there's more than one dot, the extension used is the one which starts with the last dot (i.e.: \selColor{Snip00.hello.doc} is the same as \selColor{Snip00.doc});

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\selColor{m}
{ \__acombo_sel_color:n {#1} }
\cs_new:Npn \__acombo_sel_color:n #1
{
\str_case:fnF { \__acombo_extension:n {#1} }
{
{ tex } { black }
{ doc } { red }
}
{ \PackageError{colorErr}{Undefined~color~option:~#1}{} }
}
\cs_generate_variant:Nn \str_case:nnF { f }
\cs_new:Npn \__acombo_extension:n #1
{ \__acombo_extension:w #1 . \q_stop }
\cs_new:Npn \__acombo_extension:w #1 . #2 \q_stop
{
\tl_if_empty:nTF {#2}
{#1}
{ \__acombo_extension:w #2 \q_stop }
}
\ExplSyntaxOff

\begin{document}
\pagestyle{empty}

Start document here

\selColor{Snip00.tex}
\selColor{Snip00.doc}
\selColor{tex}
\selColor{Snip00.hello.doc}

End the document

\end{document}


which prints: