4

I am confused by the behaviour of \xspace in combination with the \todo command. I didn't expect \xspace to leave a space when I cut off all spaces by a comment sign %. Usually this works as expected, cf. counterexample.

However, in my context it doesn't work and I cannot really figure out why.

MWE (edit: added counterexample)

\documentclass{scrbook}
\setlength{\parindent}{0pt}

\usepackage{todonotes}
\usepackage{xspace}
% define mtodo WITH xspace
\newcommand{\mtodo}[1]{\todo[fancyline,noline]{#1}\xspace}
% define mmtodo WITHOUT xspace
\newcommand{\mmtodo}[1]{\todo[fancyline,noline]{#1}}
% counterexample
\newcommand{\mylabel}[1]{\label{#1}\xspace}

\begin{document}
  % with xspace (mtodo)
  \mtodo{Margin Note 1}%
  This is an\mtodo{Margin Note 2} example with xspace.\\
  This is an example with xspace.

  % without xspace (mmtodo)
  \mmtodo{Margin Note 1}%
  This is an\mmtodo{Margin Note 2} example without xspace.\\
  This is an example without xspace.

  % without xspace (mmtodo)
  \mylabel{label1}%
  This is a\mylabel{label1} counterexample.\\
  This is a counterexample.      
\end{document}

output

matheburg
  • 1,279
  • Commands with arguments don't benefit in any way from \xspace. Don't use it. – egreg Jan 17 '15 at 13:38
  • @egreg I cannot 100%ly agree, since the second line shows an effect as I require it. Anyway, which alternative way do you suggest. – matheburg Jan 17 '15 at 13:40

1 Answers1

7

The definition of \todo is at the end of todonotes.sty:

\newcommand{\todo}[2][]{\@bsphack\@todo[#1]{#2}\@esphack\ignorespaces}%

The usage of \@bsphack means you are supposed to have a space before \todo, if you want that a space appears in the output. Adding \xspace does no good.

In any case

\xspace%
X

is the same as \xspace X and a space will be added because a letter follows.

So the answer is:

  1. don't use \xspace for commands with arguments
  2. leave a space before \todo (or macros starting with it) if you want a space appears in the output
  3. use \xspace under no circumstances

You probably got the suggestion of \xspace from Todo note steals space Don't follow it.

egreg
  • 1,121,712
  • Thanks a lot for these advices. I will do as you suggest. Just a note: my counterexample shows that xspace can work as expected in some cases even with arguments... am I wrong? – matheburg Jan 17 '15 at 14:12
  • @matheburg No, it doesn't. In this case it seems to work, just because it kills the \ignorespaces in the definition of \todo. – egreg Jan 17 '15 at 14:13
  • 1
    @egreg can you write a comment/answer to your cited question not to use \xspace? I think that would be a good idea ... – Mensch Jan 17 '15 at 14:18
  • I have e.g. a command \newcommand{\intodo}[1]{\color{red}[#1]\color{black}\xspace}. Why shouldn't I use \xspace in this command? It really does what I want :) – matheburg Jan 17 '15 at 14:20
  • @matheburg No, it does nothing at all. Better said: it could add a space when you don't want it. – egreg Jan 17 '15 at 14:21
  • @matheburg xspace after \foo the space character is dropped so xpsace might possibly be useful to put a space back (but usually isn't) after \foo{} the space character does make a space token so there is nothing xspace can do (and it does nothing useful) – David Carlisle Jan 17 '15 at 16:43
  • @DavidCarlisle: What about \foo{}bar? ...but yeah I basically agree with your argumentation. Sorry for all the confusion! :) – matheburg Jan 17 '15 at 16:51
  • @matheburg blame the author of xspace for the confusion. – David Carlisle Jan 17 '15 at 17:06
  • @egreg Corrected. – Heisenb0rg Jan 25 '17 at 23:05