部分标题中带有可选参数的自定义命令

部分标题中带有可选参数的自定义命令

在许多情况下,我需要创建自己的命令,而且很多时候我还需要它们有一个可选参数。这没什么问题。

但是,我需要将其中一个命令放在某个部分的标题内,这样就不会生成 .pdf。以下是简化的代码:

\documentclass[12pt]{article}

\makeatletter
\newcommand{\foo}{\@ifnextchar[{bracket}{parenthesis}}
\makeatother

\begin{document}

\section{\foo()}
\foo()
\section{\foo[]}
\foo[]

\end{document}

如果\section{\foo()}\section{\foo[]}被删除,那么一切似乎都正常。另外,如果你删除它们,编译,获取你的 .pdf,然后将其中一个添加到代码中,那么你仍然得到 .pdf即使你之前不能,如果你添加第二个,它仍然符合要求。总是有一堆错误。

如果我使它变得更复杂 - 假设我重新定义了一个预先存在的命令 - 那么该命令的旧定义在环境中也无法工作\section

\documentclass[12pt]{article}

\let\doublevowelhyphen\H
\makeatletter
\renewcommand{\H}{\@ifnextchar[{\@foo}{\@ffoo}}
\def\@foo[#1]#2{#2.#1}
\def\@ffoo#1{#1.}
\makeatother

\begin{document}

\section{\doublevowelhyphen{o}}
\doublevowelhyphen{o}
\section{\H{1}}
\H{1}
\section{\H[1]{2}}
\H[1]{2}

\end{document}

在这里我得到了与以前类似的行为。

hyperref最后,如果我使用我需要的包,似乎会出现其他错误。

我怀疑这与符号有关@,我不太明白发生了什么。有人能解释一下为什么会发生这种情况吗?

答案1

这个问题有点难回答,因为尽管问题标题如此,但给出的示例没有可选参数。(请注意,以下[]命令排版为文本,不作为参数分隔符)。但是它确实使用了\@ifnextchar会使其变得脆弱的构造,但是您可以通过将其声明为强大的命令来隐藏它:

\documentclass[12pt]{article}

\makeatletter
\DeclareRobustCommand{\foo}{\@ifnextchar[{bracket}{parenthesis}}
\makeatother

\begin{document}

\section{\foo()}
\foo()
\section{\foo[]}
\foo[]

\end{document}

相反,这个命令有一个可选参数,通过它\newcommand被定义为健壮的,但当然有不同的行为。

\documentclass[12pt]{article}


\newcommand{\foo}[1][bracket]{parenthesis}


\begin{document}

\section{\foo()}
\foo()
\section{\foo[]}
\foo[]

\end{document}

相关内容