如果我使用
\newcommand{\foo}[3][\empty]{#1#2#3}
并希望通过以下方式更新这些选项
\newcommand{\renewfoo}[2][\empty]{\renewcommand{\foo}[3][\empty]{???}}
#1
如果我想使用和#2
的\renewfoo
,并且仍想保留的#1
,,的#2
,那么除了“???”之外,我还需要注意什么?#3
\foo
答案1
(La)TeX
允许嵌套(重新)定义宏,即在其他宏内(重新)定义。为了区分(La)TeX
外部宏的(可能)参数和内部参数,#
内部宏的参数说明符等的数量必须加倍,#1
即#2
变为等##1
。##2
如果还有另一层嵌套,则参数说明符#
必须再次加倍,即
第一级:#1
第二级:##1
第三级:####1
第四级########1
等等(超过三个级别就很奇怪了),换句话说:必须使用2^{level-of-nesting-1}
该字符的出现次数。#
我还添加了一个版本,以xparse
解决“奇怪”的\empty
可选参数参数。但是,我不建议重新定义 a) 使用另一个包装器和 b) 包装器也具有可选参数。
\documentclass{article}
\usepackage{xparse}
\newcommand{\foo}[3][\empty]{%
#1#2#3%
}
\newcommand{\renewfoo}[2][]{\renewcommand{\foo}[3][#1]{And now for something completely different: #2 and ##2##3[##1]}}
\NewDocumentCommand{\foobar}{o+m+m}{%
\IfValueT{#1}{#1}%
#2#3%
}
\NewDocumentCommand{\RenewFooBar}{o+m}{%
\IfValueTF{#1}{%
\RenewDocumentCommand{\foobar}{O{#1}+m+m}{%
And now for something completely different with xparse: #2 and ##2##3[##1]%
}%
}{%
\RenewDocumentCommand{\foobar}{+m+m}{%
And now for something completely different with xparse: #2 and ##1##2%
}%
}%
}
\begin{document}
\foo[A]{B}{C}
\renewfoo{\LaTeXe}
\foo[C]{A}{B}
\foobar{E}{F}
\foobar[D]{E}{F}
\RenewFooBar{Mr. Gumby}
\foobar{E}{F}
\RenewFooBar[Brain Surgeon]{Mr. Gumby}
\foobar{E}{F}
\end{document}