# Extra space due to \patchcmd

It seems that \patchcmd from etoolbox adds three unwanted spaces, as shown below:

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

How can I fix this?

-
Issue a number of \unskips: \def\test{1}]\patchcmd\test{1}{2}{}{}\unskip\unskip\unskip[ – Werner Dec 30 '13 at 0:09

Two spaces come from calls of \scantokens, the third from an unprotected end-of-line in the code.

\documentclass{minimal}
\usepackage{etoolbox}

\makeatletter
\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}%
\ifhmode\unskip\fi
\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
\ifhmode\unskip\fi
}
% 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}

However, the best strategy is never using \patchcmd in horizontal mode.

The corresponding command \xpatchcmd from regexpatch is free from this problem.

A different patch could be adding \@empty at the end of the two \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
\expandafter\endgroup\ifx#1\etb@resrvda
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\def\etb@patchcmd@scantoks#1{%
\edef\etb@resrvda{\endgroup
\catcode\number\@=\the\catcode\@\relax}%