为宏提供可选(未使用)参数以及 \tikzmark 会引入虚假空间

为宏提供可选(未使用)参数以及 \tikzmark 会引入虚假空间

在我的过度杀伤解决将枚举列表中的条目括在括号中开头有虚假空格一些(并非所有) 的使用\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
}

相关内容