Strange argument absorption, using \color

It wasn't there in the first test releases, the change log shows that \ignorespaces was added 1994/04/01 which is a while ago.

Basically the intention of the design of the colour interface was to make it look as far as possible to the end user like font changes, although the internal mechanisms are completely different.

Specifically in this case I think I wanted the outcome for 3 to be as it is, not like 2

\documentclass{article}

\usepackage{color}

\begin{document}

1
{\itshape
one two three
}

2
{\let\ignorespaces\relax\color{red}
one two three
}

3
{\color{red}
one two three
}


\end{document}

enter image description here


% color.sty, line 86:
\DeclareRobustCommand\color{%
  \@ifnextchar[\@undeclaredcolor\@declaredcolor}

% color.sty, line 94:
\def\@declaredcolor#1{%
  \@ifundefined{\string\color @#1}%
    {\c@lor@error{`#1'}}%
    {\expandafter\let\expandafter\current@color
     \csname\string\color @#1\endcsname
     \set@color}%
  \ignorespaces}

Now it should be clear: \ignorespaces makes \color{black}x and \color{black} x completely equivalent. If you add a trailing {} in the definition, \ignorespaces finds { and ends its job.


Am I saying a foolishness suggesting to use xspace?

\documentclass{article}  
\usepackage{xcolor}
\usepackage{xspace}
\newcommand\flag[1]{\color{red}#1\color{black}\xspace}
\begin{document}
This is \flag{very unusual} behavior, using \verb|\color|.

\renewcommand\flag[1]{\color{red}#1\color{black}{}}
This is \flag{very typical} behavior, adding an empty group to \verb|\color|.

\renewcommand\flag[1]{\textcolor{red}{#1}}
This is \flag{very typical} behavior, using \verb|\textcolor|.
\end{document}