如何使命令完全空/不可见/不存在?

如何使命令完全空/不可见/不存在?

我有一个像这样的命令

\newcommand{\todo}[1]{#1}

我有时会用以下方式代替:

\newcommand{\todo}[1]{}

就间距/空白而言,“empty”命令的行为如下:

Test.

\todo{foo} % does not generate (vertical) whitespace => good

Test\todo{foo}. Test. % does not generate (horizontal) whitespace => good

Test\todo{foo}. \todo{foo} Test. % _does_ generate (horizontal) whitespace => bad

有什么方法可以避免这种情况,即(暂时)替换命令,使其完全等效删除所有出现的命令?

(我知道有像 todonotes 或 verbatim 这样的软件包,它们提供类似的功能。但我一直想知道如何手动解决这个问题,却从来不知道如何解决这个问题/搜索什么。至少在命令中使用\xspace\empty不起作用。)

答案1

经典方法是使用\@bsphack和。它们由或\@esphack使用,两者在间距方面都应该是不可见/空的。这些命令会记住,如果有空格\label\index命令。如果是,后面的第二个空格将被 抑制\ignorespaces。命令在 LaTeX 内核中定义:

\def\@bsphack{%
  \relax
  \ifhmode
    \@savsk\lastskip
    \@savsf\spacefactor
  \fi}
\def\@esphack{%
  \relax
  \ifhmode
    \spacefactor\@savsf
    \ifdim\@savsk>\z@
      \ignorespaces
    \fi
  \fi}

应用于\todo

\documentclass{article}

\makeatletter
\newcommand{\todo}[1]{%
  \@bsphack
  \@esphack
}
\makeatother

\begin{document}
Test.

\todo{foo}

Test\todo{foo}. Test.

Test\todo{foo}. \todo{foo} Test.
\end{document}

结果

局限性:\@bsphack如果使用和的宏一个\@esphack接一个地使用,则该方法可能会失败。第二个宏\@bsphack不知道前一个宏的状态。因此\ignorespaces可以抑制它,留下以下空间。

答案2

它实际上并没有生成空格,只是你添加了两个空格,你会看到相同的结果,a {} b前后各有一个空格。但你可以用\ignorespaces忽略以下空格来结束命令。

\newcommand{\todo}[1]{\ignorespaces}

答案3

当水平/垂直列表\toto为空时,您不会在其中放入任何内容。因此,\spacefactor操作是多余的(请参阅已接受的答案)。以下代码足以完成此任务:

\def\hideme{\ifdim\lastskip>0pt \ignorespaces\fi}
\def\todo#1{#1}
% or:
\def\todo#1{\hideme}

相关内容