使用\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
,但我发现这样的语法是一个非常糟糕的主意,尽管 Ti钾Z 使用它。
\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}
请注意,第三次调用会引发错误。