我有一个像这样的命令
\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}