9

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%
  \addtocounter{str}{1}%
}

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

and after compilation with pdflatex I get:

The resalt of compilation

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?

8
 \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}}%
  \addtocounter{str}{1}%
}

\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
7

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
  \addtocounter{str}{1}%
}

\begin{document}

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

\end{document}

enter image description here

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}

enter image description here

  • 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

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.