[Tex/LaTex] Nesting of test commands (IfStrEq, IfSubStr etc.) of xstring

conditionalsexpansionxstring

The following code does not work:

\documentclass{article}

\usepackage{xstring}

\newcommand\checkempty[1]{
    \IfStrEq{#1}{}{%
        Empty
    }{%
        NonEmpty
    }
}

\begin{document}
    \checkempty{\IfStrEq{justadummyvalue}{justadummyvalue}{somevalue}{}}
\end{document}

[Edit:
What I expect with \checkempty{\IfStrEq{a}{a}{val}{}} is NonEmpty. However, \checkempty{\IfStrEq{a}{b}{val}{}} shall result in Empty.
]

However, I get some errors like

Argument of \@xs@expand@and@assign has an extra }. \firstif{a}{b}{c} (followed by: )    document.tex    /test   line 19 Texlipse Build Error

and finally also this

TeX capacity exceeded, sorry [input stack size=65000]. \firstif{a}{b}{c} (followed by: )    document.tex    /test   line 19 Texlipse Build Error

Basically, I can guess the problem. \IfStrEq cannot be expanded (or however this phenomenon is called exactly) and cannot be nested. Therefore, most commands in xstring provide a syntax like \StrLeft{xstring}{4}[\Result]. The result string is stored in \Result then.

However, test commands do not provide this syntax, and I also guess that it would not be meaningful. However, I still hope that there are some tweaks to get my example working.

Please tell me, if there is a tweak I can put inside of \checkempty.
I need to determine (via any case of if) inside of a command (here \checkempty), if the passed argument (expanded) is empty or not.
[Edit: The outer IfStrEq shall be expanded before!]
If there is no tweak, I cannot use IfStrEq, right?

In past I worked with the xifthen package. It was a complete pain, and I could not manage some expansion problem. With xstring and IfSubStr everything worked fine, except in the case I am showing in my example 🙁

Best Answer

The xstring package offers extra (read: advanced) options to control the expansion of the arguments. This is really not meant for beginners and a good understanding of how arguments are expanded is more than welcome.

In your case the code can be tweaked to compile:

\documentclass{article}

\usepackage{xstring}

\newcommand\checkempty[1]{
    \normalexpandarg
    \exploregroups
    \IfStrEq{#1}{}{%
        Empty
    }{%
        NonEmpty
    }
}

\begin{document}
    \checkempty{\IfStrEq{justadummyvalue}{justadummyvalue}{somevalue}{}}
\end{document}

Notice the two new lines in the declaration of \checkempty. The first, \normalexpandarg ensures that the arguments (the strings to be compared) passed to \IfStrEq are not fully expanded, as they would by default (xstring is set by default to fullexpandarg). However, if your argument contains braces, the invoked xstring command will not look inside that group. Since you want to check whether arguments passed to your command are empty or not, this check should still be done, hence the \exploregroups line. (If you don't want to use this feature, simply leave out that line.) You can revert at any time to the default behavior with \noexploregroups.

These toggles can be used at any place within your code and can be made local by scoping.

Hope that helps. :)

Related Question