3

In the following MWE (it's minimal, so not the original problem). As you can check there is one space on both sides of \mycommand. While I'm making the macro "dummy" for a specific use: can I remove one of the spaces if there would be two left?

\documentclass{article}

\DeclareRobustCommand\mycommand[1]{%
   \textbf{#1}%
}

\makeatletter
\newcommand\nobf[1]{%
    {\def\mycommand##1{}#1}}
\makeatother

\begin{document}

\def\abc{X \mycommand{Y} Z \mycommand{!}}

\abc

\nobf{\abc}

X Z

\abc

\end{document}

There is a doubled space between the first X Z pair:

enter image description here

1

2 Answers 2

3

The reason for the spaces stem from your spurious ones in your macro definition: A line break without % acts like a space. For more on this discussion, see What is the use of percent signs (%) at the end of lines?.

A far shorter definition of \nobf would be

\newcommand\nobf[1]{{\renewcommand{\mycommand}[1]{\leavevmode\unskip\ignorespaces}#1}}

Note that there's no line break, so the macro doesn't introduce any spurious spaces in the output. Also, redefining \mycommand is done inside a group, so there's no need to save and restore the macro. The redefinition removes any skip before it (via \unskip) as well as ignoring any following (via \ignorespaces).

enter image description here

\documentclass{article}

\DeclareRobustCommand\mycommand[1]{\textbf{#1}}

\makeatletter
\newcommand\nobf[1]{{\renewcommand{\mycommand}[1]{\leavevmode\unskip\ignorespaces}#1}}
\makeatother

\begin{document}

\def\abc{X \mycommand{Y} Z \mycommand{!}}

\abc

\nobf{\abc}

X Z

\abc

\end{document}
7
  • The output is absolutely not the same... I don't want Y-s an !-s in my output when I use \nobf. Sorry if the function name was misleading (they were unfortunate random characters I typed).
    – masu
    Commented Dec 2, 2013 at 2:17
  • And even if I have a ton of %-s there are still two spaces between X and Z (there should be no Y there).
    – masu
    Commented Dec 2, 2013 at 2:20
  • @masu: Then you should add \unskip to your macro (either at the start, or the end, or both). It wasn't clear from your original question.
    – Werner
    Commented Dec 2, 2013 at 2:26
  • My code had clearly different output. :) Doesn't matter... I'll try \unskip.
    – masu
    Commented Dec 2, 2013 at 2:27
  • @masu: I've updated my answer. If you're not after any spaces when using \nobf, then \mycommand should probably be \unskip\ignorespaces (or perhaps one or the other). Let me know.
    – Werner
    Commented Dec 2, 2013 at 2:30
6

In latex internal code, any command that can be used in a paragraph, but provides no visible text, uses two internal commands: \@bsphack and @esphack. The first one tries to detect if a space preceded it and passes that information to the second. If the space was there \@esphack issues \ignorespaces. Thus:

\documentclass{article}
\DeclareRobustCommand\mycommand[1]{%
   \textbf{#1}}
\makeatletter
\newcommand\nobf[1]{% Use the "space hack"
    {\def\mycommand##1{\@bsphack\@esphack}#1}}
\makeatother
\begin{document}
\def\abc{X \mycommand{Y} Z}
\abc

\nobf{\abc}

\def\abc{X\mycommand{Y} Z}
\abc

\nobf{\abc}

\def\abc{X \mycommand{Y}Z}
\abc

\nobf{\abc}
\end{document}

output

Actually, in this resricted application, no internal commands are needed. In place of \def\mycommand##1{\@bsphack\@esphack}
one can use
\def\mycommand##1{\ifdim\lastskip>0pt \ignorespaces\fi}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .