# Arguments expansion in IfSubStr

## EDIT: Simplified question

How can I make the following code print "Yes"?

\IfSubStr{\textbf{AAA}}{AAA}{Yes}{No}


## Full question

I'm playing with xstring's IfSubStr, but I don't really understand how expansion works.

Here's a largely simplified MWE demonstrating my problem:

\documentclass{minimal}

\usepackage{xstring}

\newcommand{\correctanswer}{}
\newcommand{\mytext}[1]{
Text :
\noexpandarg
\IfSubStr{#1}{\correctanswer}{
\textbf{\boldmath #1}
}{
#1
}
}
\newcommand{\mymathtext}[1]{\mytext{\ensuremath{#1}}}

\begin{document}
\mytext{Foo} \mytext{Bar\correctanswer} \mymathtext{\frac{1}{2}} \mymathtext{\frac{1}{4}\correctanswer}
\end{document}


The code works as follow: first define a \correctanswer which expands to an empty string, and second emphasize (by typesetting in bold) text that contains this macro.

I'm using xstring's \noexpandarg to prevent \correctanswer from being expanded too early, but that doesn't work when the argument text is already passed to another command, such as \ensuremath : Although Bar is typeset in bold, \frac{1}{4} is not.

How can I get \frac{1}{4} to be typeset in bold?

PS: I don't really understand how expansion works. I've read a number of posts on this site, but I still can't figure out a correct solution to this particular problem. I therefore haven't included the numerous unfruitful attempts that I made, hoping that someone could instead provide me with a clear explanation :)

-
For those wondering why I'm using such a bizarre syntax: I'm trying to build my own mutiple-choice template, and my current code has a \choice command chich takes four arguments, with one (or more) containing \correctanswer, which allows me to use the same document for the test and the correction, by switching between \solutionstrue and \solutionsfalse. –  Clément Dec 31 '11 at 15:03
@BrunoLeFloch: Salut Bruno. In my full example, I do more than making the text bold: there's a checkbox before every answer, which gets checked if \ifsolutions is true and the answer is the correct one. –  Clément Jan 2 '12 at 12:11

## 3 Answers

Just don't use \ensuremath: it adds a level of grouping that makes impossible for \IfSubStr to find \correctanswer; indeed the test

\IfSubStr{1{2}3}{2}{true}{false}


returns "false". So write

\newcommand{\mymathtext}[1]{\mytext{$#1$}}


Please, note that your code adds plenty of spurious spaces:

\newcommand{\mytext}[1]{%
Text :
\noexpandarg
\IfSubStr{#1}{\correctanswer}{%
\textbf{\boldmath #1}%
}{%
#1%
}
}


I would rewrite it as

\newcommand{\mytext}[1]{%
Text : % be sure we want a space
\noexpandarg
\IfSubStr{#1}{\correctanswer}
{\textbf{\boldmath #1}}
{#1}%
}


But probably the best thing is to define a *-variant:

\makeatletter
\newcommand{\mytext}{\@ifstar\mytext@s\mytext@n}
\newcommand{\mytext@s}[1]{\textbf{\boldmath #1}}
\newcommand{\mytext@n}[1]{#1}
\makeatother


\ifnum\value{anscount}<\answernumber
\stepcounter{anscount}\expandafter\answer
\fi}
\NewDocumentCommand{\answers}{O{4}}
{\setcounter{anscount}{1}\chardef\answernumber=#1\relax
\answer}
\newcounter{anscount}

-
Awesome answer. Just let me some time to make sure I fully understand it: I had never heard about *-variants before :) –  Clément Dec 31 '11 at 16:36
Probably the last version is the most flexible one (just don't ever write \answer+*). –  egreg Dec 31 '11 at 16:39
Can you explain how the @n and @s notations work (or point me to a relevant resource)? Thanks! –  Clément Dec 31 '11 at 16:40
Thanks for the explanation! –  Clément Jan 2 '12 at 23:58

I think you can also use xstring. Use the commands exploregroup and noexpandarg.

\documentclass{minimal}

\usepackage{xstring}

\newcommand{\correctanswer}{}
\newcommand{\mytext}[1]{
Text :
\noexpandarg
\exploregroups
\IfSubStr{#1}{\correctanswer}{
\textbf{\boldmath #1}
}{%
#1
}
}
\newcommand{\mymathtext}[1]{\mytext{\ensuremath{#1}}}

\begin{document}
\mytext{Foo} \mytext{Bar\correctanswer} \mymathtext{\frac{1}{2}} \mymathtext{\frac{1}{4}\correctanswer}
\end{document}


-
Awesome, thanks! –  Clément Jan 2 '12 at 12:11

After reading the relevant section in xstring's manual, I realize that using IfSubStr* works perfectly =)

-
It does; but one has to think whether adding a \correctanswer tag inside the argument is really a good solution. I don't think so. –  egreg Jan 2 '12 at 13:49
@egreg: Your solution is indeed very pretty; the only trouble that I have atm is that my real-life document has constructs like \choices{Choice 1}{Choice 2}{Choice 3}{Choice 4}, and the command \choices in turns calls \mytext four times, and \mytext adds a checkbox before every choice, and in solution mode checks the right box. I think that the ideal solution would be to pass to \choices a second argument (a number between 1 and 4), which would specify which answer is correct, but since I didn't know how to do that I thought I'd tag the correct answer with \correctanswer. –  Clément Jan 3 '12 at 0:02