Дополнительное место из-за \patchcmd

Дополнительное место из-за \patchcmd

Похоже, что \patchcmdfrom etoolboxдобавляет три нежелательных пробела, как показано ниже:

\documentclass{minimal}
\usepackage{etoolbox}
\begin{document}
\tracingall%                            3 spaces in log file
\def\test{1}]\patchcmd\test{1}{2}{}{}[% 3 spaces between brackets in output
\end{document}

Как я могу это исправить?

решение1

Два пробела возникают из-за вызовов \scantokens, третий — из-за незащищенного конца строки в коде.

\documentclass{minimal}
\usepackage{etoolbox}

\makeatletter
% Add \ifhmode\unskip\fi
\protected\def\etb@ifscanable#1{%
  \begingroup
  \edef\etb@resrvda{%
    \def\noexpand\etb@resrvda####1\detokenize{macro}:####2->####3&{%
      ####1\def\string\etb@resrvda####2{####3}}%
    \edef\noexpand\etb@resrvda{\noexpand\etb@resrvda\meaning#1&}}%
  \etb@resrvda
  \makeatletter
  \scantokens\expandafter{\etb@resrvda}%
  %%% ADDITION
  \ifhmode\unskip\fi
  %%% END ADDITION
  \expandafter\endgroup\ifx#1\etb@resrvda
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\def\etb@patchcmd@scantoks#1{%
  \edef\etb@resrvda{\endgroup
    \unexpanded{\makeatletter\scantokens}{#1}%
    \catcode\number`\@=\the\catcode`\@\relax}%
  \etb@resrvda
  %%% ADDITION
  \ifhmode\unskip\fi
  %%% END ADDITION
}
% Fix a missing `%'
\protected\long\def\etb@ifpattern#1#2{%
  \begingroup
  \edef\etb@resrvda{%
    \def\noexpand\etb@resrvda####1\detokenize{#2}####2&{%
      \endgroup\noexpand\noexpand\noexpand\ifblank{####2}}%
    \edef\noexpand\etb@resrvda{\noexpand\etb@resrvda
      \expandafter\strip@prefix\meaning#1\detokenize{#2}&}%
    \noexpand\etb@resrvda}% <---------- MISSING IN etoolbox.sty
  \etb@resrvda\@secondoftwo\@firstoftwo}

\makeatother


\begin{document}
\def\test{1}]\patchcmd\test{1}{2}{}{}[% brackets for checking

][% for check
\end{document}

введите описание изображения здесь

Однако лучшей стратегией будет никогда не использовать его \patchcmdв горизонтальном режиме.

Соответствующая команда \xpatchcmdот regexpatchэтой проблемы свободна.


Другой патч мог бы добавить \@emptyв конец двух `\scantokens:

\protected\def\etb@ifscanable#1{%
  \begingroup
  \edef\etb@resrvda{%
    \def\noexpand\etb@resrvda####1\detokenize{macro}:####2->####3&{%
      ####1\def\string\etb@resrvda####2{####3}}%
    \edef\noexpand\etb@resrvda{\noexpand\etb@resrvda\meaning#1&}}%
  \etb@resrvda
  \makeatletter
  \scantokens\expandafter{\etb@resrvda\@empty}% <---- ADDED
  \expandafter\endgroup\ifx#1\etb@resrvda
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi}
\def\etb@patchcmd@scantoks#1{%
  \edef\etb@resrvda{\endgroup
    \unexpanded{\makeatletter\scantokens}{#1\noexpand\@empty}% <---- ADDED
    \catcode\number`\@=\the\catcode`\@\relax}%
  \etb@resrvda}

Во втором случае \noexpand\@emptyнеобходимо, поскольку мы находимся внутри \edef. Однако это требует большего количества тестов, чем я склонен делать.

Мне бы хотелось объединить эти две команды с \patchcmdсамим собой, но они сопротивляются этому.

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