我想定义一个\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}