4

In LaTeX there are commands that process arguments but do not produce visible output.
For example, the command \label, or, if you use the package color or xcolor, the command \color.

When the closing curly brace of the argument is tokenized, TeX's reading apparatus switches to state M (middle of line), thus a space that in the .tex-source-code comes after the closing curly brace is tokenized as an explicit space token.

If in the source code you have a space before the corresponding command, which becomes a space-token, and you also have a space after the closing curly brace of the argument of the command, you would get two explicit space tokens, whereof in horizontal mode each results in horizontal space if no linebreak occurs.

Often one does not like this.

Therefore these macros have mechanisms like the \@bsphack..\@esphack-mechanism: When the macro is called, the value of the register \lastskip and the value of the parameter \spacefactor is stored. Lastly, the space factor is restored and if the stored value of \lastskip indicates that a space has been set before calling the macro, subsequent space-tokens are ignored, using \ignorespaces.

This can lead to unexpected output if you define commands that output visible text but use commands in their definition that do not.

Suppose I intend to write a command that reads an argument and sets it in blue color.

I could write this:

\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}#1}}%
\newcommand\ingroup[1]{{#1}}%
\begin{document}
\Huge
\par\noindent(\ingroup{ Text })
\par\noindent(\blue{ Text })
\par\noindent(\textcolor{blue}{ Text })
\end{document}

enter image description here

But the output contains a subtlety:

With the command \ingroup the leading space in the argument was not ignored.

With the command \green the leading space in the argument was ignored. The same with \textcolor.

What is the best way to ensure that

  • leading explicit space tokens in arguments are not ignored and that
  • hyphenation is turned on even in case there are no leading spaces?

2 Answers 2

4

If I understand the question correctly you can simply use \relax to stop \igorespaces. Hyphenation is OK as shown here

enter image description here

\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}\relax#1}}%
\newcommand\ingroup[1]{{#1}}%

\begin{document}
\Huge
\par\noindent X\dotfill X
\par\noindent(\ingroup{ Text })
\par\noindent(\blue{ Text })
\par\noindent(\blue{ TextTextTextTextTextTextTextText })
\par\noindent(\textcolor{blue}{ Text })
\end{document}
2
  • With \par\noindent(\blue{TextTextTextTextTextTextTextText}) you don't get hyphenation. I realized that I didn't phrase the question clearly. I rephrased: "What is the best way to ensure that leading explicit space tokens in arguments are not ignored and that hyphenation is turned on even in case there are no leading spaces?" Commented Jul 31, 2022 at 19:07
  • hspace{0pt} as usual would allow hyphenation use instead of relax Commented Jul 31, 2022 at 19:21
1

Edit 1:

Stop \ignorespaces and enable hyphenation by a horizontal skip of width 0pt. Prepend \relax to ensure the following space token, if present, is turned into horizontal glue.

\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}\ifhmode\hskip0pt\relax\fi#1}}%
\newcommand\ingroup[1]{{\ifhmode\hskip0pt\relax\fi#1}}%
\newcommand\textandlabel[1]{{\label{#1}\ifhmode\hskip0pt\relax\fi#1}}%
% Let's cheat with the hyphenation of 
%  Hippopotomonstrosesquippedaliopho–bia :
%\hyphenation{Hip-popo-tomon-stros-esquippedalio-pho-bia}
\hyphenation{Hip-pop-o-to-mon-stros-es-quip-pe-da-li-o-pho-bia}
\begin{document}
\Huge
\par\noindent(\ingroup{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\ingroup{Hippopotomonstrosesquippedaliophobia})
\par\noindent(\blue{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\blue{Hippopotomonstrosesquippedaliophobia})
\par\noindent(\textandlabel{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\textandlabel{Hippopotomonstrosesquippedaliophobia})
\bigskip
\hrule height 1ex
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .