# xstring fails to compare text containing \\

Using xstring in order to compare text containing \\ produces a compilation error. Here is my MWE:

\documentclass{report}
\usepackage{xstring}
\makeatletter
\def\Example#1{\def\@Example{#1}}
\def\printExample{\@Example}
\makeatother
\Example{not \\ void}
\AtBeginDocument{
\begin{titlepage}
\centering
\IfStrEq{}{\printExample}
{void}
{\printExample}
\end{titlepage}
}
\begin{document}

\end{document}


The first error message is:

! Undefined control sequence. \ ->\let \reserved@e \relax \let \reserved@f \relax @ifstar {\let \reserv... l.15 \begin{document}

The \Example command defined here should accept \\. How can I get this working? The solution should take into account that the (La)TeX distribution version used here is the one included in Linux Mint 18.3, i.e. TeX Live 2017/Debian, which cannot be changed.

• What is the expected output. You could try using \noexpandarg, but I am not sure what the code is supposed to do. – Peter Grill May 22 '19 at 9:23
• If you are just testing whether a macro is empty or not, then the void tests from etoolbox might be better, that is what I normally use. But as Peter mentions, it is not quite clear what you are trying to do. – daleif May 22 '19 at 9:52
• It works with xifthen using this test: \ifthenelse{\equal{\printExample}{}}{void}{\printExample} – frougon May 22 '19 at 9:57
• Various tests from etoolbox (\ifdefvoid, \ifstrempty or \ifblank) do not work with TeX Live 2017/Debian (but they work for current TeX Live). Command \ifthenelse from xifthen works well, indeed (even if, from a "logical" perspective, I would expect a command whose argument is directly a string, not a boolean). Can someone explain why \\  breaks \IfStrEq and if there is a way (or not) to use it? – Jérôme Champavère May 22 '19 at 19:52
• I added \centering in environment titlepage because it causes an error (! Incomplete \iffalse; all text was ignored after line …) when \ifthenelse test is used. An other error is raised with center environment (! Use of \@item doesn't match its definition.). In both cases, one needs to use \protect\\  in order to get it working as expected. – Jérôme Champavère May 22 '19 at 20:32

If you need only a test for an empty argument you can use \ifx:

\documentclass{report}
\makeatletter
\def\Example#1{\def\@Example{#1}}
\def\printExample{\@Example}
\makeatother
\Example{}
\AtBeginDocument{%
\begin{titlepage}
\expandafter\ifx\printExample\empty
void\else\printExample\fi
\end{titlepage}
}
\begin{document}

\Example{not \\ void}
\expandafter\ifx\printExample\empty
void\else\printExample\fi

\end{document}

• This might be an option. Is it possible to write a 3-parameter command, e.g. \ifstringempty, from the \expandafter to \fi code, where #1 would be the tested string command (here \printExample), #2 for true (here "void"), and #3 for false (here the second \printExample), in order to simplify the code? I tried \newcommand{\ifstringempty}[3]{\expandafter\ifx#1\empty #2\else#3\fi}, without success. – Jérôme Champavère May 22 '19 at 21:01

I guess you have other macros such as \Example and \printExample.

You can define a macro that does the work getting as input the desired storage bin.

\documentclass{report}

\makeatletter
\newcommand{\void@or@print}[1]{%
\if\relax\detokenize\expandafter{#1}\relax
void%
\else
#1%
\fi
}

\def\printExample{\void@or@print{\@Example}}
\def\Example#1{\def\@Example{#1}}
\Example{} % initialize

\makeatother

\Example{not \\ void}

\AtBeginDocument{
\begin{titlepage}
\centering
\printExample
\end{titlepage}
}

\begin{document}

\end{document}


A more general implementation:

\makeatletter
\newcommand{\print@conditionally}[3]{%
\if\relax\detokenize\expandafter{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{#2}{#3}%
}

\def\printExample{\print@conditionally{\@Example}{void}{\@Example}}
\def\Example#1{\def\@Example{#1}}
\Example{} % initialize

\makeatother

• Yes, there are few other macros as \Example, that should be filled by the template's user (while \printExample's are in some way hidden). But the true/false outputs depend on the macro, i.e., some show a "should-be-filled-message" in the PDF documents if empty, other are optional, and when correctly filled their formattings mostly differ. This is why I need a real if-then-else statement. – Jérôme Champavère May 23 '19 at 10:10
• @JérômeChampavère I added a more general implementation – egreg May 23 '19 at 10:57