Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am having trouble using \IfStrEqCase from xstring inside \num from siunitx:

\documentclass{article}
\usepackage{xstring}
\usepackage{siunitx}

\newcommand{\bla}[1]{%
\IfStrEqCase{#1}{{a}{1}%
    {b}{2}%
    {c}{3}}%
    [0]%
}
\newcommand{\blubb}[1]{1}

\begin{document}
|\num{\blubb{a}}|
|\bla{a}|
|\num{\bla{a}}|    
\end{document}

Will fail at |\num{\bla{a}}| with:

pdflatex.exe> ! TeX capacity exceeded, sorry [input stack size=5000].
pdflatex.exe> \reserved@a ->\def \reserved@a 
pdflatex.exe>                                *{\let \@xs@assign\@xs@expand@and@detokenize...
pdflatex.exe> l.16 |\num{\bla{a}}
pdflatex.exe>                    |
pdflatex.exe> !  ==> Fatal error occurred, no output PDF file produced!

How can I overcome this? Solutions that do not include IfStrEqCase but provide some other way to do switch/case are welcome.

share|improve this question
    
Could you explain what you are trying to achieve as an outcome? The \num command is meant to format 'numbers', not really 'expressions' and certainly not things that can't be expanded to numbers. You input (e.g. a) doesn't look at all like a number! –  Joseph Wright Mar 11 at 14:03
    
@JosephWright I am going to have the definition of \bla outsourced in an included .tex file that is automatically generated by a script in a programming language of my choice thay expands the IfStrEqCase command with all variables (eg. a,b,c) with its values(1,2,3) and an other hopfully and other IfStrEqCase with their units... (I know sweave and knitr, but working with invalid latex code is no option with my editor) –  YAK Mar 11 at 14:55

2 Answers 2

up vote 5 down vote accepted

As the manual says, commands from xstring are not fully expandable and may not be nested nor used e.g. in \edef. Several of the xstring commands thus have a final optional argument which is a macro where the result may be stored. This in to the situation for \IfStrEqCase, so you need to provide something like this in the code for each case. For example:

Sample output

\documentclass{article}
\usepackage{xstring}
\usepackage{siunitx}

\newcommand{\bla}[2]{%
\IfStrEqCase{#1}{{a}{\xdef#2{1}}%
    {b}{\xdef#2{2}}%
    {c}{\xdef#2{3}}}%
    [\xdef#2{0}]%
}
\newcommand{\blubb}[1]{1}

\begin{document}
|\num{\blubb{a}}|

|\bla{a}{\outp}\outp|

|\bla{b}{\outp}\num{\outp}|    
\end{document}

In this way you can define a command

\newcommand{\blanum}[1]{\bla{#1}{\outp}\num{\outp}}

that you can use directly as \blanum{b}.

share|improve this answer
    
Works like a charm, ty! I would appreciate if extended your answer for a shortcut à la \newcommand{\bla}[1]{\blahelper{#1}{\outp}\num{\outp}} to make clear it is almost as easy to use as if \IfStrEqCase was fully expandable (whatever that means). –  YAK Mar 11 at 14:41
1  
OK, example definition added. –  Andrew Swann Mar 11 at 15:01

Here is a version using stringstrings. While the \convertchar macro cannot be nested inside of a \num argument, its result (\thestring) is expandable, and can thus be solved in a two-step, as I do in the macro \Inum (indirect \num).

EDITED to take not just letters, but words, as arguments.

\documentclass{article}
\usepackage{stringstrings}
\usepackage{siunitx}

\newcommand\Inum[1]{\bla[q]{#1}\num{\thestring}}

\newcommand{\bla}[2][v]{%
    \convertword[q]{#2}{ax}{1}%
    \convertword[q]{\thestring}{by}{2}%
    \convertword[#1]{\thestring}{c}{3}%
}
\newcommand{\blubb}[1]{1}

\begin{document}
|\num{\blubb{a}}|
|\bla{ax}|
|\Inum{by}|  
\end{document}
share|improve this answer
    
Ok. But it only works for single chars (I admit, I did not state this requirement in the question). And what is that q as first argument of bla needed for? Anyway good answer explaining this \thestring trick. –  YAK Mar 11 at 15:29
1  
@YAK Fixed for your revised case, merely by changing \convertchar into \convertword. The [q] option is for "quiet", so that intermediate results (stored in \thestring) are not printed out. I made the default [v] verbose, so that \thestring is printed out at the end of \bla, unless invoked with a [q] (or a [e], see package documentation for details). –  Steven B. Segletes Mar 11 at 17:29
    
thank you for the fix and the explanation, works like a charm. –  YAK Mar 11 at 21:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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