在我的过度杀伤解决将枚举列表中的条目括在括号中开头有虚假空格一些(并非所有) 的使用\SpecialItem
。我将其范围缩小到下面的 MWE,其中宏\SpecialItem
定义有两个可选的第一个参数,第一个默认为\DrawLines
:
\NewDocumentCommand{\SpecialItem}{O{\DrawLines} o}{...code...}
在\SpecialItem
这里定义的宏中,第一个可选参数未被使用(宏\DrawLines
甚至没有定义)。因此,使用:
\SpecialItem ...text...
没问题。但如果我指定第一个可选参数:
\SpecialItem[\DrawLines] ...text...
我得到了在 's 标签后面引入的虚假空间,\item
如第三个列表项中所示:
笔记:
如果
\tikzmark
未使用或未将其定义为{}
,则不存在虚假空间。我不认为此问题与此有关,\tikzmark
因为我已多次使用过此问题,之前并未注意到此问题。移动
\tikzmark
前也\item
不会产生这个虚假的空间。但是,我需要它位于标签之后,因为我想要引用这个的开头\item
,而不是前一个的结尾\item
。在这个答案对
mdframed
和项目之间的奇怪互动,egreg 提到重新定义
\item
可能很危险,而且会产生不可预测的结果虽然在实际使用中我重新定义了
\item
,但在此 MWE\item
并未重新定义,只是通过另一个宏调用。因此,我认为问题与此无关。
代码:
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usepackage{showframe}
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}
%\renewcommand{\tikzmark}[1]{}% Using this does not produce spurious space
\NewDocumentCommand{\SpecialItem}{O{\DrawLines} o}{%
% #1 is not really used in this MWE, but is used in actual application
\IfNoValueTF{#2}{%
\item\tikzmark{MarkStart}%
}{%
\item[#2]\tikzmark{MarkStart}%
}%
}%
\begin{document}
\begin{enumerate}
\item item
\SpecialItem SpecialItem without optional param
\SpecialItem[\DrawLines] SpecialItem with optional param
\item item
\end{enumerate}
\end{document}
答案1
通常的\item
命令不会启动水平模式,因此]
其可选参数结束后的空格将被忽略。
您的宏的问题在于,后面\item
跟着\tikzmark
调用\tikz
,然后启动水平模式。现在,后面的]
空格
\SpecialItem[\DrawLines] SpecialItem with optional param
不再被忽视。
解决方案
添加\ignorespaces
:
\NewDocumentCommand{\SpecialItem}{O{\DrawLines} o}{%
% #1 is not really used in this MWE, but is used in actual application
\IfNoValueTF{#2}{%
\item\tikzmark{MarkStart}%
}{%
\item[#2]\tikzmark{MarkStart}%
}%
\ignorespaces
}