在带有可选参数的宏中使用带有可选参数的宏

在带有可选参数的宏中使用带有可选参数的宏

我正在尝试定义一个具有可选参数的宏,该宏可以将带有可选参数的宏作为参数。下面是一个最简单的示例,可以更清楚地解释该问题:

\documentclass{article}

\newcommand*{\inn}[1][a]{#1}
\newcommand*{\out}[1][\inn]{\underline{#1}}
% \newcommand*{\out}[1][\inn]{\underline{#1}} % this also doesn't work (1)
% \newcommand*{\out}[1][\inn]{{#1}} % this also doesn't work (2)

\begin{document}
  $\out[\inn[b]]$
%  $\out[{\inn[b]}]$ % this works (3)
\end{document}

我收到错误! Argument of \\inn has an extra }。如所示,我可以根据具体情况修复该问题,但不能一般性地修复(使用宏的正确定义)。

\underline我一开始以为这是由脆弱性引起的问题。但是使用\ensuremath\protected并没有找到解决方案。

我怎样才能修复宏,让它们按照我的要求执行而不会出现错误?

答案1

LaTeX2e 获取可选参数的方法是使用 TeX 分隔宏,即寻找一个开口,[然后使用以以下形式定义的宏

\def\foo[#1]{...

这将始终抓取第一个,]而不是进行括号匹配。当然可以匹配括号。使用xparse因为它是内置的

\documentclass{article}
\usepackage{xparse}
\NewDocumentCommand\inn{O{a}}{#1}
\NewDocumentCommand\out{O{\inn}}{\underline{#1}}

\begin{document}
  $\out[\inn[b]]$
\end{document}

请注意,使用 定义的命令xparse使用与 不同的语法进行声明\newcommand。这里,可选参数是 type O,默认值作为 的参数给出O

答案2

如果您愿意接受xparse,则可以\NewDocumentCommand嵌套可选参数而无需附加参数。{}

的语法\NewDocumentCommand与 不同,\newcommand对于初学者来说有点令人困惑,但我最近改用了它,不会再怀念它了。我推荐xparse和 它的宏,只要不需要扩展(除了功能\DeclareExpandableDocumentCommand

\documentclass{article}

\usepackage{xparse}
\newcommand*{\inn}[1][a]{#1}
\newcommand*{\out}[1][{\inn}]{\underline{#1}}
% \newcommand*{\out}[1][\inn]{\underline{#1}} % this also doesn't work
% \newcommand*{\out}[1][\inn]{{#1}} % this also doesn't work

\NewDocumentCommand{\Inn}{O{a}}{%
#1%
}

\NewDocumentCommand{\Out}{O{\Inn}}{%
\underline{#1}%
}


\begin{document}
\out[{\inn[b]}] % original version
  \Out[\Inn[b]] % Double []
  \Out[\Inn]
\end{document}

相关内容