Detect empty or null output from xstring's StrBetween
\middleinitial
is not expandable, and therefore you cannot properly test whether there is a middle initial in \name
or not. You'll have to store the output (the middle initial) first using the optional argument at the end of \StrBetween{<str>}{<from>}{<to>}[<macro>]
and then you can check for an empty argument:
\documentclass{article}
\usepackage{xstring}
\newcommand{\name}{John Doe}
\makeatletter
\newcommand{\middleinitial}{%
\StrBetween{\name}{ }{.}[\@middleinitial]%
}
\newcommand{\test}{%
\middleinitial% Find middle initial
% https://tex.stackexchange.com/q/53068/5764
\if\relax\detokenize\expandafter{\@middleinitial}\relax
Whoo hoo!% No middle initial
\else
Not whoo hoo.% A middle initial
\fi
}
\makeatother
\begin{document}
\test % Whoo hoo.
\renewcommand{\name}{John F. Doe}%
\test % Not whoo hoo!
\end{document}
Werner already explained, why \middleinitial
isn't expandable due to the usage of xstring
macros.
I present a shorter way in order to test for the emptiness of \middleinitial
by using \ifblank
from etoolbox
package. There are still two \expandafter
statements required, but not a bunch of 5 of them. In addition, I find etoolbox
much more convenient than ifthen
or xifthen
.
\expandafter\ifblank\expandafter{\middleinitial}{true branch}{false branch}
is necessary, because \ifblank
does not expand its first argument, i.e. without \expandafter
the macro 'sees' \middleinitial
, but not what the content which is stored in that macro. It must be expanded first before \ifblank
performs the test.
The \expandafter
primitive looks ahead of \ifblank
, i.e. it ignores \ifblank
first and detects the {
of the first argument. Unfortunately, this is not what is desired (and not expandable anyway), so we must jump over {
again, i.e.
\expandafter\ifblank\expandafter{\middleinitial}{...}{...}
will allow TeX/LaTeX to 'jump' over \ifblank
to the second \expandafter
, that jumps over {
to \middleinitial
and expands that sequence -- after this is done, TeX continues with \ifblank{expanded version of \middleinitial}{...}{...}
and performs the test finally.
\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\newcommand{\name}{John C. Doe}
\newcommand{\othername}{John Doe}
\newcommand{\testinitial}[3]{%
\begingroup
\StrBetween{#1}{ }{.}[\middleinitial]%
\expandafter\ifblank\expandafter{\middleinitial}{#2}{#3}%
\endgroup
}
\begin{document}
\testinitial{\name}{Whoo hoo!}{Not whoo hoo.}
\testinitial{\othername}{Whoo hoo!}{Not whoo hoo.}
\end{document}