以下 MWE 无法编译(不幸的是)。目标是创建一个动态创建的宏,例如,\Newton
带有可选参数。
如果\Newton
被调用,$F=ma$
将会被渲染。如果\Newton[$F=GMm/r^2$]
被调用,那么$F=GMm/r^2$
而不是$F=ma$
将会被渲染。
如何实现这一点?
平均能量损失
\documentclass{book}
\usepackage{etoolbox}
\newcommand\CreateMacro[2]{%
\expandafter\newrobustcmd\csname#1\endcsname[1][]{%
% if ##1 is given
% then use ##1
% else use #2
}%
}
\begin{document}
\CreateMacro{Newton}{$F=ma$}
\Newton should produce $F=ma$.
\Newton[$F=GMm/r^2$] replaces $F=ma$.
\end{document}
答案1
非常简单:
\newcommand{\CreateMacro}[2]{%
% #1 is the macro name, #2 the default expansion
\expandafter\newcommand\csname #1\endcsname[1][#2]{##1}%
}
让我们看看为什么:\CreateMacro{Newton}{$F=ma$}
会
\expandafter\newcommand\csname Newton\endcsname[1][$F=ma$]{#1}
和电话
\Newton
\Newton[$F=GMm/r^2$]
将产生预期的输出。
答案2
这是一个etoolbox
和一个xparse
版本,该xparse
版本对于空的可选参数更加安全。
版本etoolbox
使用\ifblank{...}{true}{false}
来检查可选参数。但是,还有一个替代方案(但不短)\notblank
。
\documentclass{book}
\usepackage{etoolbox}
\usepackage{xparse}
\newcommand\CreateMacro[2]{%
\expandafter\newrobustcmd\csname#1\endcsname[1][]{%
\ifblank{##1}{%
#2%
}{%
##1%
}%
}%
}
\NewDocumentCommand{\CreateOtherMacro}{mm}{%
\expandafter\NewDocumentCommand\csname #1\endcsname{o}{%
\IfValueTF{##1}{%
##1%
}{%
#2%
}%
}%
}
\begin{document}
\CreateMacro{Newton}{$F=ma$}%
\CreateOtherMacro{Einstein}{$E=mc^2$}%
\Newton\ should produce $F=ma$.
\Newton[$F=GMm/r^2$] replaces $F=ma$.
\Einstein\ should produce $E=mc^2$.
\Einstein[$8\pi G$] will show something different
\end{document}