Несколько хаков по экономии пространства генерируют больше места

Несколько хаков по экономии пространства генерируют больше места

Это продолжение недавнего поста:Создание команды удаляемого комментария без дополнительного пробела. Я пытаюсь сделать обычную вещь: сделать команду удаляемого комментария, чтобы участники документа могли оставлять заметки друг для друга и для себя, но чтобы заметки можно было автоматически удалять перед выпуском. Проблема в том, что здесь очень легко создать дополнительное пространство.

Решение в вышеупомянутом посте оказалось таким:

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

Это работает довольно хорошо, но не идеально. В частности, добавляется дополнительное пространство в случае, если две ноты идут подряд. Например, рассмотрим:

\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.

Вышеуказанное дает:

выход

Как мы видим, это \@bsphack\@esphackправильно устраняетнекоторыйизбыточного пространства и работает достаточно хорошо, если оставить только одну ноту. Но если две ноты появляются рядом друг с другом, в результате образуется больше пространства.

Один из подходов, который я рассматривал, заключается в том, что \noteкоманда может определить, что она находится рядом с другой нотой, и затем не выдавать лишнюю \@bsphack\@esphack. Однако мои попытки создать подобные команды в прошлом были довольно неудачными. Кто-нибудь сталкивался с чем-то подобным? Мои поиски ни к чему не привели.

Спасибо!

решение1

Проблема в том, что \@esphackвыполняется как проверка, так и последующее изменение значения регистра \lastskip.

Поэтому \@esphackв предыдущих случаях \noteвлияет на то, как \@esphack в последующих случаях \noteсрабатывает .

Вариант, в \@esphackкотором происходит «перескакивание вперед и назад», может помочь.

Искренне

Ульрих

\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}

Связанный контент