在许多情况下,我需要创建自己的命令,而且很多时候我还需要它们有一个可选参数。这没什么问题。
但是,我需要将其中一个命令放在某个部分的标题内,这样就不会生成 .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}