# Multiple Space Hacks Generate More Space

This is a follow-up to a recent post: Creating removable comment command without extra space. I'm trying to do a common thing: make a removable comment command so contributors to a document can leave notes for each other and themselves but so that the notes can be automatically removed before production. The trouble is that it's very easy to generate extra space here.

The solution in the aforementioned post turned out to be this:

\newif\ifnotes
\makeatletter
\newcommand{\note}[1]{\ifnotes{#1}\else\@bsphack\@esphack\fi}
\makeatother


It works pretty well, but it's not perfect. Specifically, extra space is added in the event that two notes occur in a row. For instance, consider:

\notesfalse

Testing \note{X} testing testing.

Testing \note{X}\note{Y} testing testing.

Testing \note{X} \note{Y} testing testing.

\notestrue

Testing \note{X} testing testing.

Testing \note{X}\note{Y} testing testing.

Testing \note{X} \note{Y} testing testing.


The above yields:

As we can see, the \@bsphack\@esphack is properly eliminating some of the redundant space and works quite well if only one note is left. But if two notes appear adjacent to each other, more space is generated in the result.

One approach that I've considered is that the \note command could figure out that it was next to another note and then avoid emitting the extra \@bsphack\@esphack. My attempts to build similar commands in the past have gone quite poorly, though. Has anyone encountered something like this? My searches came up empty.

Thanks!

• please fix the code example so that people can run it to get the image shown, and test answers. Feb 18, 2016 at 19:37
• I assume (without a test file) that \newcommand{\note}[1]{\ifnotes{#1}\else\ignorespaces\fi would do the right thing on these tests. Feb 18, 2016 at 19:40
• @DavidCarlisle -- wouldn't an initial \unskip be a good bit of insurance? Feb 18, 2016 at 20:40
• – Guho
Feb 18, 2016 at 20:43

A problem is that \@esphack does both check and afterwards change the value of the register \lastskip.

Therefore the \@esphack in previous instances of \note affects the way in which \@esphack in consecutive instances of \note works out.

A variant of \@esphack where some "skipping backwards and forwards" takes place might help.

Sincerely

Ulrich

\documentclass{article}

\newif\ifnotes
\makeatletter
\newcommand{\note}[1]{%
\@bsphack
%  \showthe\lastskip
\relax
\ifhmode
\spacefactor\@savsf
\ifdim\@savsk>\z@
\nobreak
\hskip\z@skip
% The previous action will change \lastskip, so:
\hskip-\@savsk
\hskip\@savsk
% now \lastskip is almost \@savsk again.
%      \showthe\lastskip
\ignorespaces
\fi
\fi
%===========================
\ifnotes #1\fi
}
\makeatother

\begin{document}

\notesfalse

Testing\note{X}testing testing.

Testing \note{X}testing testing.

Testing\note{X} testing testing.

Testing \note{X} testing testing.

Testing\note{X}\note{Y}testing testing.

Testing\note{X}\note{Y} testing testing.

Testing\note{X} \note{Y}testing testing.

Testing\note{X} \note{Y} testing testing.

Testing \note{X} \note{Y}testing testing.

Testing \note{X} \note{Y} testing testing.

Testing \note{X}\note{Y} testing testing.

Testing \note{X}\note{Y}testing testing.

\notestrue

Testing\note{X}testing testing.

Testing \note{X}testing testing.

Testing\note{X} testing testing.

Testing \note{X} testing testing.

Testing\note{X}\note{Y}testing testing.

Testing\note{X}\note{Y} testing testing.

Testing\note{X} \note{Y}testing testing.

Testing\note{X} \note{Y} testing testing.

Testing \note{X} \note{Y}testing testing.

Testing \note{X} \note{Y} testing testing.

Testing \note{X}\note{Y} testing testing.

Testing \note{X}\note{Y}testing testing.

\end{document}

• I'll have to study this in much greater detail to understand what it's doing, but it seems to exhibit exactly the behavior I was looking for. Thank you! Mar 1, 2016 at 18:25