0

I have the following code in my preamble:

\usepackage{xstring}
\newcommand\myhelpermacro[1]{\IfSubStr{#1}{true}{Text contained the word "cat"}{Text did not contain the word "cat"}}
\newcommand\mymacro[1]{\myhelpermacro{\IfSubStr{#1}{cat}{true}{false}}}

When I later try to use mymacro in the document, like so:

\mymacro{cat}

I get the following error:

Use of \@xs@IfSubStr@@ doesn't match its definition. \mymacro{cat}

Modifying mymacro by using \expandafter, like so:

\newcommand\mymacro[1]{\expandafter\myhelpermacro{\IfSubStr{#1}{cat}{true}{false}}}

doesn't help. However, if I instead manually expand the call to IfSubStr in mymacro, i.e.

\newcommand\mymacro[1]{\myhelpermacro{true}}

the code works.

What is going on here? Why doesn't my code work without manually expanding IfSubStr?


Edit 1: To clarify my expectations of the behavior of the code, I expect that when I use, e.g.,

\mymacro{caterpillar}

this expands to

\myhelpermacro{\IfSubStr{caterpillar}{cat}{true}{false}}

which in turn should expand (since I expect what's inside the brackets to be expanded before what's outside of them, because that's how brackets are supposed to behave, right? :) ) to

\myhelpermacro{true}

which in turn should expand to Text contained the word "cat".

However, when I use, e.g.,

\mymacro{aardvark}

I expect this to expand to

\myhelpermacro{\IfSubStr{aardvark}{cat}{true}{false}}

which in turn should expand to

\myhelpermacro{false}

which in turn should expand to Text did not contain the word "cat".


Edit 2: After reading the xstring documentation (under 3.2 Expansion of macros, optional argument), I tried changing the definition of mymacro, by storing the result of IfSubStr in a temporary variable, to

\newcommand\mymacro[1]{\IfSubStr{#1}{cat}{true}{false}[\result]\myhelpermacro{\‌​result}}

only to get the following error message when I try to use mymacro:

Undefined control sequence. \mymacro{cat}

Suddenly, LaTeX seems to think mymacro isn't defined at all. Why?


Edit 3: So what I'm trying to do is to define two macros:

The first macro (myhelpermacro in this case) that takes a boolean value and inserts a string into the document whose value depends on the value of the boolean.

The second macro (mymacro in this case) takes a string and calls the first macro with the boolean true if the string contains a specific substring, otherwise it calls the first macro with the boolean false.

Since I want to be able to make calls to both macros from the document, both of them need to be defined, and since I want to avoid code duplication, the second macro should call the first macro instead of inserting the string into the document itself.

  • When I look at your code, it seems that mymacro calls myhelpmacro with IfSubStr as part of the argument. But myhelpmacro already has IfSubStr in its definition. So, IfSubStr is called within itself. – user139954 Aug 13 '17 at 15:59
  • 4
    There are several questions dealing with the fact that you cannot nest xstring macros. – egreg Aug 13 '17 at 16:10
  • @egreg Okay; why can't I do that? And how can I solve this in a different but equally powerful way in that case? I want to be able to make calls to mymacro and myhelpermacro. – StrawberryFieldsForever Aug 13 '17 at 16:25
  • 2
    @StrawberryFieldsForever \IfSubstr{AAA}{A}{true}{false} is a set of instructions to print true, not the string true. Some context would help: this seems like an XY question. – egreg Aug 13 '17 at 16:36
  • 1
    @erreka No, that's not the issue: it's that the implementation of \IfSubstr performs assignments, and they cannot be expanded. (This is a general feature of TeX.) – Joseph Wright Aug 14 '17 at 19:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.