设置宏名的通用前缀

设置宏名的通用前缀

是否可以为包中的所有宏设置一个通用前缀?例如:

\def\prefix{mypackage}

\newcommand{{\prefix}macroone}{ ... } % does not work, of course
\newcommand{{\prefix}macrotwo}{ ... }

然后可以将宏调用为mypackagemacroonemypackagemacrotwo

答案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

相关内容