11

It's been a while since I asked an embarrassing question, and am pretty sure this is another one of those: This code below attempts to use \IfStrEqCase from the xstring package and results in:

Runaway argument? 
{document} \par \par \par \documentclass {article} \usepackage {pgfpl\ETC.
! File ended while scanning use of \@xs@testcase.

for the case where none of the cases match, but I don't know why.

Notes:

Code:

\documentclass{article}
\usepackage{xstring}

%\newcommand{\CaseVar}{case A}% This works %\newcommand{\CaseVar}{case B}% This works \newcommand{\CaseVar}{case C}% This does NOT!!!

\begin{document} \IfStrEqCase{\CaseVar}{% {case A}{Found Case A} {case B}{Found Case B} }[Oppsss, unknown case '\CaseVar'.] \end{document}

Peter Grill
  • 223,288
  • Ok, it seems as I need to actually go through the effort of posting a question before figuring out a solution. It seems that adding a % after the Case b closing } solves it, but why????? – Peter Grill Feb 20 '14 at 22:19

2 Answers2

12

The internal macro that checks the cases is \@xs@testcase. Using \tracingmacros=1 with your original input, we find:

\@xs@testcase #1#2#3\@xs@nil ->\@xs@reserved@E {\CaseVar }{#1}{#2}{\@xs@ifempty
 {#3}{Oppsss, unknown case '\CaseVar '.}{\@xs@testcase #3\@xs@nil }}
#1<-case A
#2<-Found Case A
#3<- {case B}{Found Case B} 

for the first test; you can see the blank space resulting from the end-of-line after {Found Case A}. This is not a problem, because this space will not be considered at the next test:

\@xs@testcase #1#2#3\@xs@nil ->\@xs@reserved@E {\CaseVar }{#1}{#2}{\@xs@ifempty
 {#3}{Oppsss, unknown case '\CaseVar '.}{\@xs@testcase #3\@xs@nil }}
#1<-case B
#2<-Found Case B
#3<- 

Do you see the problem? The third argument to \@xs@testcase is delimited by \@xs@nil and in this case a blank space is as good as an argument as any list of tokens. TeX disregards spaces only when looking for undelimited arguments.

Add % at the end of lines, if you use that kind of input style.

Probably xstring should use a test for \ifblank rather than \ifempty.

egreg
  • 1,121,712
0

Here a workaround: redefine \IfStrEqCase so that it always includes a matching case. The same approach also works for \IfEqCase.

\documentclass{article}
\usepackage{xstring}

%\newcommand{\CaseVar}{case A}% This works
%\newcommand{\CaseVar}{case B}%  This works
\newcommand{\CaseVar}{case C}% Prints "Unknown case 'case C'."

% redefine \IfStrEqCase
\let\XstringIfStrEqCase\IfStrEqCase
\renewcommand\IfStrEqCase[2]{%
    \XstringIfStrEqCase{#1}{%
        #2%
        {#1}{Unknown case '#1'.}%
    }%
}

\begin{document}
    \IfStrEqCase{\CaseVar}{%
        {case A}{Found Case A}
        {case B}{Found Case B}
    }
\end{document}