空行或 \par 中断 xparse 或 ifthen 宏

空行或 \par 中断 xparse 或 ifthen 宏

留下空白行分隔符简单宏但%终止它解决了这个问题。发生了什么?我知道应该使用%,但我不能在宏中有任何空白行,否则它会抱怨。空白行本质上会终止宏,而 TeX 会抱怨混合}。使用etoolbox也会产生同样的问题,所以这似乎是 的问题xparse

有没有什么方法可以修复xparse软件包,这样我就不用在我的代码里乱放%s 了?

\documentclass{book}

\usepackage{xparse, ifthen, etoolbox}


\NewDocumentCommand\iftb{m m G{\relax}}{\ifthenelse{\boolean{#1}}{#2}{#3}}

%\NewDocumentCommand\iftb{m m G{\relax}}{\ifbool{#1}{#2}{#3}}
\newboolean{A}\setboolean{A}{true}
\newboolean{B}\setboolean{B}{true}


\begin{document}

\iftb{A}{%
% <- remove all text on this line breaks macro (keep blank line)
    \iftb{B}{%
        asdffdsasdff
        % <- same here
        asdf
    }
}

End
\end{document}

答案1

默认情况下,定义的宏\NewDocumentCommand不接受\par其参数(或空行,相同)。

您可以通过+在可能包含以下内容的参数说明符前面添加来克服此行为\par

\NewDocumentCommand\iftb{m +m +G{\relax}}{\ifthenelse{\boolean{#1}}{#2}{#3}}

或者

\NewDocumentCommand\iftb{m +m +G{\relax}}{\ifbool{#1}{#2}{#3}}

\ifthenelse和所基于的宏\ifbool已经接受\par


为什么在宏参数中不被接受的问题\par来自于这样一个事实,即这是宏的默认行为,正如 Knuth 所想象的那样。

用以下方式定义的宏

\def\macro#1{...}

在其论证中不接受\par。Knuth 认为这可以捕捉到忘记右括号的常见错误,并希望避免这种错误导致读取整个当前文件来寻找右括号。

但是宏定义可以加上前缀\long: 因此

\long\def\macro#1{...}

允许在的参数中有空行\macro

LaTeX\newcommand当然是建立在 之上\def,并且默认以 为前缀\long;而 * 形式\newcommand*则没有。

函数\NewDocumentCommand(也是\DeclareDocumentCommand,但New应该优先选择其变体,因为它提供了对重新定义的检查)采用该\newcommand*方法,但略有不同:每个参数都可以声明为“long”或不声明为“long”(默认情况下不是),而使用和时,\newcommand所有\newcommand*参数都被视为平等。

相关内容