在 LaTeX 中定义带有圆括号中可选参数的宏

在 LaTeX 中定义带有圆括号中可选参数的宏

是否可以使用选修的参数用圆括号()而不是方括号括起来,例如:

\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”。

为此,我们可以使用\@ifnextcharLaTeX 内核中的宏。您可以说\@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}

相关内容