我如何编写一个命令来定义另一个可以选择以 \global 作为前缀的宏?

我如何编写一个命令来定义另一个可以选择以 \global 作为前缀的宏?

在各种情况下,我定义一个宏,例如

\makeatletter
\newcommand\aedosomething{\ae@do@something}
\def\ae@do@something#1#2#3{%%
   %% do something with arguments #2 and #3
   \def#1{<result of doing something>}}
\makeatother

这是一个更完整的例子(尽管毫无意义)

\makeatletter
\newcommand\aesavesumas{\ae@save@sum@as}
\def\ae@save@sum@as#1#2#3{%%
    \pgfmathparse{#2+#3}%%
    \edef#1{\pgfmathresult}}
\makeatother

在这个特定例子中,我知道有一个非常好的宏

\pgfmathsetmacro

它能够计算和存储信息。但我的问题不是关于如何处理额外参数的细节。我想知道的是,如果我写类似

\global\aesavesumas\mysum{2}{3}

如何让宏\aesavesumas知道它应该使定义成为全局的,这样,如果\aesavesumas\mysum{2}{3}在特定范围内调用,则保存该定义以供以后在该范围之外使用。

答案1

前缀\global只能位于赋值之前。但是,TeX 会扩展后面的标记\global以找到赋值。例如,\booltrue中的宏etoolbox

\newrobustcmd*{\booltrue}[1]{%
  \ifcsundef{if#1}
    {\etb@noglobal\etb@err@nobool{#1}}
    {\csname#1true\endcsname}}

如果有的话\global\booltrue{foo},后一个宏将被展开,留下

\global\ifcsundef{iffoo}{...}{...}

并被\ifcsundef扩展;如果\iffoo被定义,TeX 会发现

\global\footrue

需要进一步扩展才能到达最后一步

\global\let\iffoo\iftrue

这就是 TeX 正在寻找的赋值。如果\iffoo未定义,TeX 将把\global\etb@noglobal它变成\global\let\relax\relax,并且它是一个不执行任何操作的赋值(除了可能污染保存堆栈,但这并不重要,因为会发出错误消息)。

问题在于,我们无法获知最后的分配是否为全球性的,也无法获知此次扩张是否因独自\global寻找配偶分配而引发。

你的任务\edef#1来得太晚了。而且\pgfmathparse以 开头\begingroup,所以你注定要失败。

如果你使用后缀而不是前缀,那就没有问题了。你可以很容易地设置,以便\global在调用时添加

\aesavesumas*\mysum{2}{3}

而不是当*缺少时。

相关内容