3

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:

output

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. – David Carlisle Feb 18 '16 at 19:37
  • 1
    I assume (without a test file) that \newcommand{\note}[1]{\ifnotes{#1}\else\ignorespaces\fi would do the right thing on these tests. – David Carlisle Feb 18 '16 at 19:40
  • @DavidCarlisle -- wouldn't an initial \unskip be a good bit of insurance? – barbara beeton Feb 18 '16 at 20:40
  • 1
    A related answer. – Guho Feb 18 '16 at 20:43
4

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
%=== instead of \@esphack: ===
%  \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! – tvynr Mar 1 '16 at 18:25

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.