# \xspace in combination with ifmmode

Sometimes I want a special font for the word "true", use it in mathmode as well as outside, and have a correct space afterwords if I am not in mathmode. Using

\newcommand{\tru}{\ifmmode {\text{\upshape \bfseries true}}%
\else {{\upshape \bfseries true}\@\xspace}\fi}%


xspace sometimes does not put a space when it should, eg. in
$s=$ \tru iff. Why? How can I fix it?

-
Did you see: mail-archive.com/ctan-ann@dante.de/msg04870.html -- I didn't test it. I only read the announcement –  Marco Daniel May 29 '12 at 15:49
Looks interesting, Marco. But I'm interested in spaces, not punctuations. –  DaveBall aka user750378 May 29 '12 at 18:31
You are right. I missed this. –  Marco Daniel May 29 '12 at 18:33

\xspace looks ahead to the next token to see if it should add space or not, you have extra brace groups in your definition which will defeat that. The outer brace groups in both your true and false branch are not doing much, {\text{\upshape \bfseries true}} is more or less the same as \text{\upshape \bfseries true}. Try

\newcommand{\tru}{\relax\ifmmode \text{\upshape \bfseries true}%
\else {\upshape \bfseries true}\@\expandafter\xspace\fi}

-
Thanks a lot, David, eliminating the outer brace group did the trick (without the need for \expandafter) (+1). Why did you add \expandafter? It should expand \xspace after what? After \fi? –  DaveBall aka user750378 May 29 '12 at 11:57
The \expandafter makes the \fi expand before \xspace starts. A "trailing \fi token may or may not interfere with xspace's lookahead but either way it will work or not essentially by chance. With the \expandafter there the first token xspace sees will be the first token after \tru without it the first token xspace sees will always be \fi and you rely on the internal scanning of xspace not to trip over that. –  David Carlisle May 29 '12 at 12:01
Note that this command will do the wrong thing if it is used as the first thing in an array cell, as the \ifmmode will be executed (and evaluate false) while looking for \multicolumn so when the array code inserts the \$ to put the cell in math node this command will already be committed to the text mode branch. Put \relax at the start of the command to guard the ifmmode. –  David Carlisle May 29 '12 at 12:04

In this particular case I don't see why doing all that work:

\newcommand{\tru}{\textbf{\textup{true}}\xspace}


will do exactly the same.

On the other hand, \text works both in math mode and in text mode. In text mode it will produce an \mbox which is probably what you want ("true" can't be hyphenated, but longer words could). So

\newcommand{\tru}{\text{\upshape \bfseries true}\xspace}


would be sufficient (and perhaps better, if you don't want the word to be tried for hyphenation). The \@ is not necessary, as after an \mbox the space factor is always 1000. It wouldn't also with the more complicated definition, because the sfcode of e is 1000.

-