纯 TeX 理论,\afterassignment

纯 TeX 理论,\afterassignment

两者之间有什么区别吗?

\newcount\acounter
\def\dosomething{\afterassignment\dosomesecret\acounter=}
\def\dosomesecret{I do something with \the\acounter}

\newcount\acounter
\def\dosomething#1{\acounter=#1%
    I do something with \the\acounter}

是什么?为什么\afterassignment我应该选择其中一个解决方案而不是另一个?

答案1

主要区别在于使用\afterassignment可以保留赋值语法。因此,在您的反例中,后面的任意数量的标记都\dosomething将被扩展,直到扫描到构成 a 的一系列不可扩展标记为止<number>。第二个版本强制使用宏参数语法,其中数字必须作为单个标记或括号组给出。哪种更好取决于您要做什么。

来自乳胶来源的另一个例子

\def\protected@edef{%
   \let\@@protect\protect
   \let\protect\@unexpandable@protect
   \afterassignment\restore@protect
   \edef
}

\protected@edef采用带有分隔参数等的语法,并在之后\edef恢复的含义。因此您可以这样做\protect\edef

\protectected@edef\foo#1#2\@nil{.....#1...#2}

如果不使用的话,这样做会不太方便\afterassignment

另一个可能更好的例子,同样基于 latex 库中的用法,以下是纯 TeX 文件

\def\removetonil#1\xx{}

\def\myset#1{\afterassignment\removetonil
             \dimen0=#1pt\relax\xx
             \immediate\write20{[\the\dimen0]}}

\myset{3}
\myset{3em}    
\myset{3cm}
\myset{\vsize}

\bye

生产

[3.0pt]
[30.00005pt]
[85.35826pt]
[643.20255pt]

这是设置\dimen0为用户指定的长度,其中参数可以省略单位(默认为pt)或给出明确的单位,或者是 TeX 维度寄存器或原语,例如\vsize。通过使用\afterassignment原语赋值可能会或可能不会使用后面的标记,#1 pt\relax如果参数是,则将被使用<number>,但如果它已经是维度,则不会。因为\removetonil在赋值之后立即插入,它可以清除任何未使用的标记。

答案2

\afterassignment宏向用户公开了 TeX 的词法分析例程。正如 David 在他的回答中指出的那样,这可以简化宏参数的处理。您还可以在此基础上构建纯 TeX 中的词法分析器或解析器。

我为普通的 TeX 编写了 geoptk 包,它允许定义以 TeX 基元为参数的宏\hbox\hfill等等。使用此包,您可以定义一个\begindisplay可以调用的宏,例如

\begindisplay file {chapter1} literal offset 20pt

此输入文本被替换为

\display@M{%
    \getoptk@behaviour@display@file{chapter1}%
    \getoptk@behaviour@display@literal
    \getoptk@behaviour@display@dimen{20pt}%
}

这样它\display@M就能完成其工作并在适当的时间触发行为。

所涉及的词法分析程序严重依赖于\afterassignment。包代码足够短,因此您可以在几个小时内“获得它”,我也在 TUGBoat 上写了一篇关于此的文章。

http://www.ctan.org/pkg/getoptk

http://tug.org/TUGboat/tb32-2/

相关内容