2

I'm using xstring (and \IfStrEqCase) to choose from a set of file paths (as the bellow example). I have two problems:

  1. Even if package documentation states that underscore is allowed, if I introduce it the macro doesn't work (needs the escape \). (Example Case 1).

  2. If I try to use the command \dothis{0} as argument for write it gives and error (missing }).

Can anyone help me on this?

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage{xstring}

\newcommand{\dothis}[1]{%
    \IfStrEqCase{#1}{
        {0}{c:/Temp/myfile.txt}
        {1}{c:/Temp\_new/myfile.txt}    %require \ for underscore!!!
        {2}{c:/Temp/my-1file.txt}
        {3}{c:/Temp\_2/my-some-\_file2.txt}
        {4}{me@somewhere}
        }
    [nope]
}



\begin{document}

    % Test each option
    \dothis{0} \newline
    \dothis{1} \newline
    \dothis{2} \newline
    \dothis{3} \newline
    \dothis{4} \newline


\immediate\write18{copy /y c:/Temp/myfile.txt  c:/Temp/newtmp0.temp}

% Command not working:
%\immediate\write18{copy /y \dothis{0}  c:/Temp/newtmp1.temp


\end{document}
3

Your evaluation is integer-based and starts from 0. As such, it presents an ideal opportunity to use the expandable \ifcase switch:

\documentclass{article}

\newcommand{\dothis}[1]{%
  \ifcase#1 %
        c:/Temp/myfile.txt%             0
    \or c:/Temp\_new/myfile.txt%        1
    \or c:/Temp/my-1file.txt%           2
    \or c:/Temp\_2/my-some-\_file2.txt% 3
    \or me@somewhere%                   4
    \else nope%                         other
  \fi
}

\begin{document}

% Test each option
\dothis{0} \newline
\dothis{1} \newline
\dothis{2} \newline
\dothis{3} \newline
\dothis{4} \newline

\immediate\write17{copy /y c:/Temp/myfile.txt c:/Temp/newtmp0.temp}

\immediate\write17{copy /y \dothis{0} c:/Temp/newtmp1.temp}

\end{document}

The log outputs:

copy /y c:/Temp/myfile.txt c:/Temp/newtmp0.temp
copy /y c:/Temp/myfile.txt c:/Temp/newtmp1.temp

I use \write17 to \typeout the execution. However, for \write18 you should not escape _ and therefore use

\newcommand{\dothis}[1]{%
  \ifcase#1 %
        c:/Temp/myfile.txt%           0
    \or c:/Temp_new/myfile.txt%       1
    \or c:/Temp/my-1file.txt%         2
    \or c:/Temp_2/my-some-_file2.txt% 3
    \or me@somewhere%                 4
    \else nope%                       other
  \fi
}

An equivalent LaTeX3 implementation:

\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\dothis}{m}{%
  \int_case:nnF { #1 }
  {
    { 0 } { c:/Temp/myfile.txt }
    { 1 } { c:/Temp_new/myfile.txt }
    { 2 } { c:/Temp/my-1file.txt }
    { 3 } { c:/Temp_2/my-some-_file2.txt }
    { 4 } { me@somewhere }
  }
  { nope }
}
\ExplSyntaxOff

Since _ is already treated differently under \ExplSyntaxOn, there is no need to escape it.

  • Underscores should not be escaped, if the purpose is using the paths in a \write18 command – egreg Nov 24 '16 at 7:15
  • @egreg: Wow, that's ugly output! I've mentioned this in my answer. Thanks. – Werner Nov 24 '16 at 7:25
1
  1. Underscore is allowed in the strings to be compared. The rest is just normal TeX text, thus underscored must be escaped there, just like $, & and # etc.

  2. \IfStrEqCase, like most if the macros of the package, is not expandable, and therefore cannot be used in a \write. So you must rewrite your macro to store the outcome in a macro (that you can pass as the second parameter). And then use that in the write.

\newcommand{\dothis}[2]{%
  \IfStrEqCase{#1}{
    {0}{\def#2{c:/Temp/myfile.txt}}
    {1}{\def#2{c:/Temp\_new/myfile.txt}}
    {2}{\def#2{c:/Temp/my-1file.txt}}
    {3}{\def#2{c:/Temp\_2/my-some-\_file2.txt}}
    {4}{\def#2{me@somewhere}}
    }
  [\def#2{nope}]
}

\dothis{0}{\Result}
\immediate\write18{copy /y \Result\space  c:/Temp/newtmp1.temp}

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.