![在 LaTeX 中定义带有圆括号中可选参数的宏](https://linux22.com/image/235262/%E5%9C%A8%20LaTeX%20%E4%B8%AD%E5%AE%9A%E4%B9%89%E5%B8%A6%E6%9C%89%E5%9C%86%E6%8B%AC%E5%8F%B7%E4%B8%AD%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F.png)
是否可以使用选修的参数用圆括号()
而不是方括号括起来,例如:
\mymacro(){}{}
或者
\mymacro{}{}
答案1
更传统的解决方案!
要构建带有任何可选参数的命令,就像在许多 LaTeX 命令中看到的那样,您需要两样东西:
(a)带有分隔参数的宏
(b)获取命令后面第一个非空格标记的方法
第一部分使用分隔参数宏相当容易,例如我们可以说
\def\test(#1)#2#3{#1, #2, #3}
然后我们可以这样调用这个宏:
\test(a){b}{c}
导致a,b,c
要将 定义()
为可选参数,我们实际上需要将宏定义为条件,即“是-否”开关。如果 TeX 找到“(”括号,则会调用“yes-code”,如果它只找到正常参数,则会执行“no-code”。
为此,我们可以使用\@ifnextchar
LaTeX 内核中的宏。您可以说\@ifnextchar{char}{yes-code}{no-code}
测试(
。结果将取决于后面的标记。如果此标记与第一个参数相同,则执行“yes-code”,否则执行“no-code”。第一个参数应该是单个标记(例如一个字符)。空格将被忽略。
例如,我们可以重新定义 LaTeX 代码以rule
接受圆括号中的可选参数,而不是传统的方括号。
\def\Rule{\@ifnextchar(\@Rule%
{\@Rule(\z@)}}
完整示例如下:
\documentclass{article}
\begin{document}
\def\Rule{\@ifnextchar(\@Rule%
{\@Rule(\z@)}}
\def\@Rule(#1)#2#3{%
\leavevmode
\hbox{%
\setlength\@tempdima{#1}%
\setlength\@tempdimb{#2}%
\setlength\@tempdimc{#3}%
\advance\@tempdimc\@tempdima
\vrule\@width\@tempdimb\@height\@tempdimc\@depth-\@tempdima}}
A test \Rule(6.5pt){100pt}{1pt}
Another test \Rule{100pt}{1pt}
\end{document}
答案2
一个简单的xparse
基于解决方案:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\mymacro{d()mm}{%
\IfNoValueTF{#1}
{}% Case where #1 is not given
{}% Case where #1 is given
}
或者#1
当不存在时您想要一个空的:
\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\mymacro{D(){}mm}{%
% Code here
}
(这用作d
/D
表示一个可选参数,分隔。
答案3
\documentclass{article}
\makeatletter
\def\mymacro{\@ifnextchar(\mymacro@i\mymacro@ii}
\def\mymacro@i(#1)#2#3{%
#1:#2:#3}% the definition
\def\mymacro@ii#1#2{%
#1:#2}% the definition
\makeatother
\begin{document}
\mymacro(foo){bar}{baz} -- \mymacro{BAR}{BAZ}
\end{document}