# Expand away empty macros within ifthenelse

I want to test whether a string, when it is finally printed, is empty. The following illustrates my problem,

\documentclass{article}
\usepackage{ifthen}
\newcommand{\isempty}[1]%
{
\ifthenelse{\equal{#1}{}}%
{EMPTY}% if #1 is empty
{FULL, it contains the string '#1'}% if #1 is not empty
}

\newcommand{\Something}{Something}
\newcommand{\Nothing}{}

\begin{document}

First the buffer is \isempty{\Something}.

Second the buffer is \isempty{\Nothing}.

{\em So far so good.} But

Third the buffer is \isempty{{\Nothing}}.

Forth the buffer is \isempty{\bf{\Nothing}}.

It says the string is Full with ''!
\end{document}


The output is

First the buffer is FULL, it contains the string ’Something’.
Second the buffer is EMPTY.
So far so good. But
Third the buffer is FULL, it contains the string ’’.
Forth the buffer is FULL, it contains the string ’’.
It says the string is Full with ”!

-
An empty group makes the argument not empty: the set having as element the empty set is not empty. :) –  egreg Jan 25 '12 at 18:55
@egreg Is there a way round this? –  Tom Jan 25 '12 at 19:03
@Tom what is your definition of a string? –  Bruno Le Floch Jan 25 '12 at 19:33

The test \ifthenelse{\equal{{}}{}} follows correctly the "false" path, because the first argument to \equal is not empty, as it contains an empty group.

You can test if the argument produces no printed text in a different way:

\newcommand{\ifnotext}[1]{%
\sbox0{#1}%
\ifdim\wd0=0pt
{EMPTY}% if #1 is empty
\else
{FULL, it contains the string '#1'}% if #1 is not empty
\fi
}


Tricky input might fool \ifnotext, but in your cases it wouldn't: Now \ifnotext{\Nothing} would print "EMPTY".

-
You can use \ifvoid instead. However I would recommend etoolbox. –  Marco Daniel Jan 25 '12 at 19:11
Perfect, this has solved me no end of trouble. Thank you. –  Tom Jan 25 '12 at 19:17
Actually, egreg's answer catches text that's "empty" because it's nonprinting, like \textbf{}. The etoolbox string-testing macros don't even expand their contents, let alone typeset them. –  Ryan Reich Jan 25 '12 at 19:18
@Marco No, \ifvoid will check if the box register 0 holds no box at all. Here, \sbox0{#1} makes the box register 0 hold an hbox containing whatever #1 typeset, perhaps nothing, hence an empty hbox: not a void box. –  Bruno Le Floch Jan 25 '12 at 19:31
@BrunoLeFloch: Thanks. I didn't recognize this. –  Marco Daniel Jan 25 '12 at 21:01

If you are trying to determine if the width of the text is zero, then @egreg's solution is the way to go. An alternate is to use \IfStrEqCase from the xstring package to check each condition:

## Code:

\documentclass{article}

\usepackage{xstring}
\newcommand{\isempty}[1]{%
\IfStrEqCase{#1}{%
{\empty}{EMPTY 1}% if #1 is empty
{{\empty}}{EMPTY 2}% if #1 is {empty}
{\bf{\empty}}{EMPTY 3}% if #1 is {empty}
}[FULL, it contains the string '#1'] % if #1 is not empty
}

\newcommand{\Something}{Something}
\newcommand{\Nothing}{}

\begin{document}

First the buffer is \isempty{\Something}.

Second the buffer is \isempty{\Nothing}.

Third the buffer is \isempty{{\Nothing}}.

Fourth the buffer is \isempty{\bf{\Nothing}}.

{\em So far so good.} And No Buts
\end{document}

-