是否可以为包中的所有宏设置一个通用前缀?例如:
\def\prefix{mypackage}
\newcommand{{\prefix}macroone}{ ... } % does not work, of course
\newcommand{{\prefix}macrotwo}{ ... }
然后可以将宏调用为mypackagemacroone
和mypackagemacrotwo
。
答案1
您可以使用它\csname <name> \endcsname
来构建一个\<name>
宏。您需要先将其展开,然后再将其提供给\newcommand
:
\def\prefix{mypackage}
\expandafter\newcommand\csname\prefix macroone\endcsname{ ... }%
还有\@namedef{<name>}<parameter text>{<expansion text>}
一个简单的宏\expandafter\def\csname #1\endcsname
。您可以定义自己的宏,例如,它也会插入前缀:
\def\prefix{mypackage}
\def\@pnamedef#1{\expandafter\def\csname\prefix #1\endcsname}
\@pnamedef{macroone}#1{Hello #1 World}
如果您想\newenvironment
使用它的 does-already-exists 检查和可选参数使用:
\newcommand{\pnewcommand}[1]{%
\@ifstar
{\expandafter\newcommand\expandafter*\csname\prefix #1\endcsname}%
{\expandafter\newcommand\csname\prefix #1\endcsname}%
}%
\pnewcommand{macroone}[2][]{Hello #2 World #1}
请注意,这里的名称仅作为示例,您应该小心定义哪些用户级宏(否@
)。
答案2
\makeatletter
\def\Pnewcommand{\@star@or@long\Pnew@command}
\def\Pnew@command#1{%
\expandafter\@testopt\expandafter{%
\expandafter\@newcommand\csname\prefix#1\endcsname}0}
\makeatother
\def\prefix{my}
\Pnewcommand{macro}[1][!]{\message{Argument is #1}}
\Pnewcommand*{macrotwo}[1]{\message{Argument is #1}}
\mymacro
\mymacro[1]
\mymacrotwo{X}
\mymacrotwo{\par} % invalid
这直接挂接到链接到的命令中\newcommand
,从而省去了 Martin 的答案中的一些扩展和分配,这当然更容易理解。还可以定义一个\Prenewcommand
:
\makeatletter
\def\Prenewcommand{\@star@or@long\Prenew@command}
\def\Prenew@command#1{%
\begingroup \escapechar\m@ne
\xdef\@gtempa{{\expandafter\string\csname\prefix#1\endcsname}}%
\endgroup
\expandafter\@ifundefined\@gtempa
{\@latex@error{\expandafter\noexpand\csname\prefix#1\endcsname undefined}\@ehc}%
\relax
\let\@ifdefinable\@rc@ifdefinable
\Pnew@command{#1}}
\makeatother
这或多或少是对\renewcommand
和的一个直接重写\renew@command
。因为\newenvironment
我们可以说
\newcommand{\Pnewenvironment}[1]{\newenvironment{\prefix#1}}
所以\Pnewenvironment{env}{start}{end}
将定义环境myenv
,如果\prefix
扩展为\my
。