2

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
2

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:

enter image description here

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:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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