add tag
निरंजन
I am working on a code similar to the following. I want to turn the conditional `foo` to true value **only when A is replaced by X.**

```
\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\footext}{+m}{%
\begingroup
\newif\iffoo
\def\tmpstr{#1}
\StrSubstitute{\tmpstr}{A}{X\global\footrue}[\tmpstr]%
\tmpstr
\endgroup
}%

\begin{document}
\footext{A}
\end{document}
```

The above MWE produces `Incomplete iffalse` error. I wonder why I am getting this error. How to get this working with the correct functionality of the conditional?
Top Answer
Phelype Oleinik
As I said in the comment, but was to lazy to write a proper answer :P:

The problem is `\StrSubstitute` does (by default) a full expansion of its arguments (something equivalent to `\edef\x{\footrue}`), but `\footrue` breaks in an `\edef`.  There's an explanation in the `xstring` documentation, section [3.1 Expansion of arguments](http://mirrors.ctan.org/macros/generic/xstring/xstring-en.pdf#23).  In short, it has three expansion modes: `\fullexpandarg`, `\expandarg` and `\noexpandarg` (if you're familiar with `expl3`, those are `x`, `o`, and `n`-types, respectively).

You have two options:

1. Do `\expandarg` before the `\StrSubstitute`, so the arguments are expanded only once (but then if you have `\def\tmpstrA{A}\def\tmpstrB{B}` then `\StrSubstitute{\tmpstrA\tmpstrB}{B}{X}` the `B` won't be seen, for examle);  
Since you're inside a group you don't need to bother restoring the expansion behaviour manually, otherwise you could use
   ```
   \saveexpandmode
     \expandarg
     \StrSubstitute ...
   \restoreexpandmode
   ```


2. Make `\footrue` (and `\foofalse`) `\protected` so they don't expand in the `\edef` (optionally include `\global` in the definition, if the conditionals are to be always changed globally):  
   ```  
   \protected\def\footrue{\global\let\iffoo\iftrue}
   \protected\def\foofalse{\global\let\iffoo\iffalse}
   ```
   
Without knowing what `\footext` is supposed to do it's hard to say, but it seems it should take “text” (in general) as argument, in which case it is usually a bad idea to `\edef` it, so I'd use option 1 or maybe both:
```
\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}
\newif\iffoo
\protected\def\footrue{\global\let\iffoo\iftrue}
\protected\def\foofalse{\global\let\iffoo\iffalse}
%
\NewDocumentCommand{\footext}{+m}{%
\begingroup
  \def\tmpstr{#1}
  \expandarg
  \StrSubstitute{\tmpstr}{A}{X\footrue}[\tmpstr]%
  \tmpstr
\endgroup
}%

\begin{document}
\footext{A}
\end{document}
```

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.