如何在“xparse”中创建特殊分隔的命令

如何在“xparse”中创建特殊分隔的命令

使用\def我可以定义如下命令:

\def\aecmd#1 located at (#2);{---definition---}

我可以用xparse如下方式重新创建它:

\NewDocumentCommand\aecmd{ u{~located~at~(}u{);}}{----definition---}

但是,我遇到过一种情况,我希望能够编写带有(几乎是最后一个)可选参数的命令。用 来做这件事会很麻烦\def

我想要一个可以表达为

\aecmd{Manditory content}[optional content] located at (location);

或者

\aecmd{Manditory content} located at (location);

本质上,我想要的是r,但不是取单个标记,因为分隔符可以取整个字符串。我们称之为假设参数说明符 b

然后我想要的命令可以按照以下步骤定义:

\NewDocumentCommand{ mob{~located~at~(}{);}{ ---something--- }

我知道我可以写类似下面的内容:

\NewDocumentCommand\aecmd{ mou{~located~at~(}u{);}{---definition---}

此外,我想我可以测试第三个参数中是否传递了某些内容,如果有的话,则引发错误。
但这似乎很笨拙。我觉得不对劲。

关于如何更好地做到这一点有什么建议吗?

答案1

xparse?呸!

如果可选参数没有括号,则编辑以捕获语法错误。

\documentclass{article}
\usepackage{parskip}

\newcommand\aecmd[1]{\def\mandatory{#1}\aecmdaux}
\def\aecmdaux#1 located at (#2);{\def\location{#2}\aecmdauxA{#1}}
\newcommand\aecmdauxA[1]{\setbox0=\hbox{%
  \if[#1[\gdef\next{\aecmdauxB#1}\else \gdef\next{syntax error}\fi}%
  \next%
}
\newcommand\aecmdauxB[1][]{%
  Optional: #1\\ Mandatory: \mandatory\\ location: \location}

\begin{document}
\aecmd{Colonel Mustard} located at (the library);

\aecmd{Colonel Mustard}[with a wrench] located at (the library);

\aecmd{Colonel Mustard} on 4th street located at (the library);
\end{document}

在此处输入图片描述

如果不喜欢“语法错误”的输出,那么在 的定义中\aecmdauxA,“语法错误”这个词可以用 替换\aecmdauxB,效果将是忽略语法中的杂散词,同时仍然产生强制性和位置参数。

答案2

使用xparse,但我发现这样的语法是一个非常糟糕的主意,尽管 TiZ 使用它。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\aecmd}{mou{located~at~(}u{);}}
 {
  \tl_if_blank:nF { #3 } { \ERROR }
  \noindent
  #1~(mandatory)\\
  \IfValueT{#2}{#2~(optional)\\}
  #4~(final)
 }
\ExplSyntaxOff

\begin{document}

\aecmd{Mandatory content}[optional content] located at (location);

\aecmd{Mandatory content} located at (location);

\aecmd{Colonel Mustard} on 4th street located at (the library);

\end{document}

在此处输入图片描述

请注意,第三次调用会引发错误。

相关内容