# \ifcase and macro expansion

There are some code. I strip out unrelated parts and get test one:

\documentclass[a4paper,11pt]{extarticle}
\begin{document}

\newcommand{\mystrA}{%
a%
\or b%
\or c%
\else d%
}
\newcommand{\mystrB}{%
e%
\or f%
\else g%
}
\newcommand{\mystr}{\mystrA}

\newcounter{str}

\newcommand{\usestr}{%
\ifcase\value{str}\mystr\fi%
}

\usestr,\usestr,\usestr,\usestr,\usestr
\end{document}


and after compilation with pdflatex I get:

But I was expecting to get "a,b,c,d," as result...

So question. What is going wrong? Why \ifcase provide nothing for values of counter more than zero?

And how right rewrite the code to get I expected?

 \ifcase\value{str}\mystr\fi%


So TeX expands \value to get a number to test with \ifcase if that is >0 it skips ahead not expanding to find a matching \or or \fi and finds the \fi so the expansion of is empty.

I would use

\documentclass[a4paper,11pt]{extarticle}
\begin{document}

\newcommand{\mystrA}[1]{%
\ifcase#1%
a%
\or b%
\or c%
\else d%
\fi
}
\newcommand{\mystrB}[1]{%
\ifcase#1%
e%
\or f%
\else g%
\fi
}
\newcommand{\mystr}{\mystrA}

\newcounter{str}

\newcommand{\usestr}{%
\mystr{\value{str}}%
}

\usestr,\usestr,\usestr,\usestr,\usestr
\end{document}

• can I use (abd how) something like \expandafter to get \mystr expanded before \ifcase will look it? – Dimitry Mar 10 '17 at 11:39
• @Dimitry yes you could, although I wouldn't, having the macros with trailing unmatched \fi will always leave you open to weird bugs. But \ifcase\expandafter\c@str\mystr\fi% would do what you ask. – David Carlisle Mar 10 '17 at 12:40

TeX never sees \or, except when str has value 0.

You can force full expansion of \mystr before the conditional is evaluated. Beware that if \mystrA starts with a digit, you'd get unexpected results.

\documentclass{article}

\newcommand{\mystrA}{%
a%
\or b%
\or c%
\else d%
}
\newcommand{\mystrB}{%
e%
\or f%
\else g%
}
\newcommand{\mystr}{\mystrA}

\newcounter{str}

\newcommand{\usestr}{%
\ifcase\number\value{str}\mystr\fi
}

\begin{document}

\usestr,\usestr,\usestr,\usestr,\usestr

\end{document}


Here's a more flexible setup:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\definecasesmacro}{O{str}mmm}
{
\cs_new:Npn #2
{
\int_case:nnF { \value{#1} } { #3 } { #4 }
}
}
\ExplSyntaxOff

\newcounter{str}

\definecasesmacro{\mystr}
{
{0}{a}
{1}{b}
{2}{c}
{4}{Hey!}
}
{d}

\newcommand{\usestr}{\mystr\stepcounter{str}}

\begin{document}

\usestr,\usestr,\usestr,\usestr,\usestr

\end{document}


• In reality it start from a digit ...and with digit it do not work :( – Dimitry Mar 10 '17 at 11:57
• @Dimitry That's what I suspected; the alternative approach doesn't suffer from the problem. – egreg Mar 10 '17 at 12:44