6

I just noted a strange behavior, when ending a macro with a \color{<color>} invocation, the net effect of which seems to absorb the subsequent space. I realize the easy thing to do is just structure my macro to use \textcolor rather than \color (for many reasons, including, as I understand, italic correction); however, I was just wondering why and how this behavior arises.

Here I have a macro \flag which in its definition ends with \color{black}. I invoke it as

\flag{<argument>} subsequent text

and the space before "subsequent" gets, strangely, absorbed.

\documentclass{article}  
\usepackage{xcolor}
\newcommand\flag[1]{\color{red}#1\color{black}}
\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}

enter image description here

As you can see, I can avoid the issue by either using \textcolor or even by adding a blank group to the macro definition at the end, such that \flag definition ends in \color{black}{}. Nonetheless, this behavior seems to violate the normal expectation for argument absorption.

UPDATE:

Perhaps the problem has nothing to do with argument absorption, as

This is \color{red}very unusual\color{black} behavior

also exhibits the identical behavior. Thus, egreg's suggestion that \ignorespaces is at play makes more sense.

Thus, to David, who claims it was done with purposeful intent, the question might be, what is the purpose of that \ignorespaces as part of the \color definition?

  • My guess is that some \ignorespaces kicks in. – egreg Feb 9 '17 at 12:26
  • 1
    I did it on purpose – David Carlisle Feb 9 '17 at 12:27
  • @DavidCarlisle Perhaps an answer explaining the purpose of it would be very useful. As I said to egreg, I would never have guessed that \color{black} x would have absorbed the space. – Steven B. Segletes Feb 9 '17 at 12:32
  • 1
    The spec for color commands was to work as far as possible like font changes and \rm absorbs space..... \ignorespaces works at a different level so there are cases where it may do something surprising but consider \color{red}<newline>a line of red text would (or would not, depending on context) indent the line of text by a space.... – David Carlisle Feb 9 '17 at 12:41
5

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

  • Thank you for explaining the rationale and pedigree, which was really the underlying intent of my question. – Steven B. Segletes Feb 9 '17 at 13:12
4
% 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.

  • I feel foolish for not having tried it outside of a macro. But I never would have guessed that \color{black} x would have absorbed the space. – Steven B. Segletes Feb 9 '17 at 12:30
2

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}
  • 1
    Well since David wrote both xspace and color, who am I to argue with success? – Steven B. Segletes Feb 9 '17 at 12:39
  • 3
    @StevenB.Segletes I could argue with using my code to defeat the intention of my code! – David Carlisle Feb 9 '17 at 12:42
  • 5
    A truly Biblical standard. From the book of @DavidCarlisle 6:3-4, 3 “But when you code for the poor, do not let your left hand know what your right hand is doing, 4 so that your coding will be in secret; and your Father who sees what is done in secret will reward you. (apologies to Matthew) – Steven B. Segletes Feb 9 '17 at 12:46
  • 1
    @StevenB.Segletes: this is pure gold! – Paulo Cereda Feb 9 '17 at 12:59
  • @StevenB.Segletes I totally agree with Paulo! – CarLaTeX Feb 9 '17 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.