参数中的空行导致失败

参数中的空行导致失败

由于某些原因,\NewDocumentCommandxparse其他包裹\newcommand必须使用 Latex 空行中断 xparse 或 ifthen 宏

但是下面的示例代码仍然无法编译。为什么?

\documentclass{article}
\usepackage{xparse}
\usepackage[most]{tcolorbox}

    \begin{document}

    \NewDocumentCommand{\mycmd}{+O{}m}{% notice "+O{}"
      \begin{tcbitemize}[#1]
        #2
      \end{tcbitemize}
    }
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \mycmd[
    colback=yellow,

    coltext=red
    ]
    {\tcbitem some text}

    \end{document}

答案1

正如 Andrew 在评论中所说,问题不在于您的\mycmd,而在于 PGF 的密钥解析器中更深层的地方。该问题已在\pgfkeys@addpath宏中报告。

第一个也是最简单的选择是删除空白行。在这种情况下,段落分隔符没有多大意义。如果您希望在按键之间有视觉分隔,您可以随时注释行尾:

\mycmd[
colback=yellow,
% <- here
coltext=red
]

第二种选择可以重新定义\pgfkeys@addpath使其变长。剧透警告:另一个宏可能会在不久后发出抱怨,因为令牌\par将通过键值解析器传递。但假设您设法使所有这些宏都成为\long。那么解析器最终会看到这样的键值对:\par coltext=red。解析器被编码为,它会修剪空格在键周围,但\par不是空格,因此至少你必须重写一些解析器以使其\par也删除标记。

如果我们要删除\par标记,那么我们可以直接采用第三种选择,即尽早删除它们:

\documentclass{article}
\usepackage{xparse}
\usepackage[most]{tcolorbox}

\begin{document}

\ExplSyntaxOn
\tl_new:N \LylTmpaTl
\cs_new:Npn \StripPar #1 #2
  {
    \tl_set:Nn #1 { #2 }
    \tl_remove_all:Nn #1 { \par }
  }
\ExplSyntaxOff

\NewDocumentCommand{\mycmd}{+O{}m}{% notice "+O{}"
  \StripPar\LylTmpaTl{#1}% Removing ALL \par tokens
  % Trick to expand \LylTmpaTl once
  \begingroup\edef\x{\endgroup\noexpand
  \begin{tcbitemize}[\unexpanded\expandafter{\LylTmpaTl}]}\x
    #2
  \end{tcbitemize}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\mycmd[
colback=yellow,

coltext=red
]
{\tcbitem some text}

\end{document}

此方法将删除全部从选项列表中删除 par 令牌。即使您不想删除,但这是您必须付出的代价。如果您恰好想要\par某个密钥值中的令牌,则必须使用它\endgraf

答案2

Ti 的内部宏控制键值分配的 Z/PGF 不允许\partoken,而且一件好事™ 他们没有。

您的输入

colback=yellow,

coltext=red

完全等同于

colback=yellow,\par coltext=red

显然没有\par coltext密钥。为了避免这个问题,宏被明确定义为不久,所以不允许\par他们的论点。

回想一下,TeX 会自动将空白行转换为\par标记在读入输入时

事实上,你将可选参数标记为 long (用+)并不能“删除”错误\par标记,它只是允许在参数吸收时接受它。但随后该参数被传递给应该能够接受它的其他宏:好吧,它们不能接受。

相关内容