读过 texbook 的一些章节后,我知道 tex 会从命令行或文件中读取输入行,然后将其转换为标记。当这些标记进入其胃肠道时,tex 会准备通过将其转换为盒子、胶水和其他东西来消化它们,然后构建一些列表。
对于宏,tex 在哪个阶段保存它的宏定义,tex 在哪个阶段做宏扩展以便进行tex替换?
答案1
这很简单!TeX 总是进行宏扩展,除非它不进行。
在第 215 页的第二个双重危险段落中,我们读到
在下列情况下,扩展会受到抑制:
- 当错误恢复期间删除令牌时(参见第 6 章)。
- 由于忽略条件文本而跳过标记时。
- 当 TeX 读取宏的参数时。
- 当 TeX读取由
\let
、\futurelet
、\def
、\gdef
、\edef
、\xdef
、\chardef
、 、、、、 和定义的控制序列 时。\mathchardef
\countdef
\dimendef
\skipdef
\muskipdef
\toksdef
\read
\font
- 当 TeX读取
\expandafter
、、、、、、、、、、\noexpand
的参数标记时。\string
\meaning
\let
\futurelet
\ifx
\show
\afterassignment
\aftergroup
\def
当 TeX 吸收、\gdef
、\edef
或的参数文本时\xdef
。- 当 TeX 吸收
\def
或\gdef
或的替换文本时;或像 或 这样\read
的标记变量的文本;或或 的 标记列表。 ( 的标记列表将在稍后实际输出到文件时进行扩展。)\everypar
\toks0
\uppercase
\lowercase
\write
\write
- 当 TeX 读取对齐的前导码时,除了原始命令的标记之后
\span
或读取之后的 之外\tabskip
。- 紧接着开始数学模式的标记(例如
$
3)之后,查看是否有另一个 3 类标记跟进。- 紧接着
`
12 个标记之后,开始一个字母常量。
不是很合理,不是吗?在进行定义时,我们希望不扩展任何内容(除了\edef
和\xdef
),第四、第五、第六和第七个项目就是处理这个问题的。同样,如果我们想将标记列表存储在寄存器或 中\write
。
\expandafter
类似地,出于显而易见的原因,\noexpand
、\afterassignment
或后面的标记\aftergroup
不能被扩展;当 TeX 在适当的时候再次检查它时,它将被扩展。
最后一项有一个技术原因:如果您想要引用与\catcode
0、5、9、13、14 或 15 字符相对应的字母常量,则可以在其前面加上反斜杠来“转义”,但这实际上并不构成控制序列。因此,`\^^M
如果您想引用常量 13,则可以这样做,或者这样做\chardef\%=`\%
。
第二点可以用一个重要的注释来补充:尽管 TeX 在跳过条件文本时不会进行扩展,但它做检查标记,以便将条件与其\else
或匹配。任何与原始条件匹配\fi
的标记,或都属于此范畴。\let
\else
\fi
答案2
在文本中TeX 简介命令及其参数用蓝色书写,但如果参数未展开,则用红色书写。此处用蓝色书写的参数在展开后读取。请参阅第 9 页的这段文字,其中开始介绍 TeX 基本构造。