如何定义一个宏来创建一个新的宏并将名称作为其参数传递?

如何定义一个宏来创建一个新的宏并将名称作为其参数传递?

我想定义一个\create接受单个强制参数的宏,从该参数创建并命名另一个新的宏。

以下代码片段可能更清楚地说明了我想要实现的目标。但以下代码无法编译,因为它是错误的。:-)

\documentclass{article}

\newcommand\create[1]{%
\newcommand\#1{My name is #1}}

\begin{document}
\create{test}
\test
\end{document}

如何定义一个宏来创建一个新的宏并将名称作为其参数传递?

答案1

使用\csname #1\endcsname前必须先扩展其\newcommand用途\expandafter

\newcommand\create[1]{%
\expandafter\newcommand\csname #1\endcsname{My name is #1}}
% usage: \create{foobar}

如果您想将宏作为控制序列传递,即,\foobar那么foobar您需要将其转换为字符串并删除反斜杠:

\makeatletter
\newcommand\create[1]{%
\expandafter\newcommand\csname\expandafter\@gobble\string#1\endcsname{My name is #1}}
\makeatother
% usage: \create{\foobar}

还有\@namedef定义为的宏\expandafter\def\csname #1\endcsname,因此您可以这样使用它:

\newcommand\create[1]{\@namedef{My name is #1}}

etoolbox包还提供了一个基本相同但功能强大的宏,称为\csdef。对于两者,您都可以提供参数文本,例如在名称参数后直接提供参数:(\csdef{name}#1#2{some code with two arguments #1 and #2}必须#在另一个宏中将其加倍)。

答案2

\documentclass{article}

\newcommand\create[1]{%                                                         
\expandafter\def\csname #1\endcsname{My name is #1}}

\begin{document}
\create{test}
\test
\end{document}

答案3

如果您要做很​​多这类的事情,您可以使用一些etoolbox魔法从逗号分隔的列表中一次性创建一堆宏:

\usepackage{etoolbox}
\newcommand\create[1]{%
\expandafter\newcommand\csname #1\endcsname{My name is #1}}
\newcommand\createlist{%
\let\do\create
\docsvlist
}

的参数\createlist应该是一个像这样的列表:\createlist{foo,Foo,magic,jabberwocky}它将创建\foo,\Foo,\magic,\jabberwocky

答案4

如果要将宏名作为宏名传递:

\documentclass{article}

\newcommand{\create}[1]% #1 = macro name
{\bgroup
  \def\foo{Hello World!}% local definition
  \global\let#1=\foo
\egroup}

\begin{document}
\create{\mymacro}%
\mymacro
\end{document}

相关内容