事实我的系统上 pdfTeX 编译的 LaTeX 文档的默认字体的文件名是
cmr10
。 (我怎么知道的?\fontname\font
请参阅这里。事实文件中定义的字体
cmr10
在代码点 3 处有一个希腊大写字母 lambda 的字形,在代码点 31 处有一个表示空集的数学符号的字形。(我怎么知道的?\fonttable{cmr10}
请参阅这里。
考虑以下 (La)TeX 手稿,灵感来自这个答案。
\documentclass{article}
\begin{document}
\def\foo{1}
\chardef\foo=3\foo
\end{document}
使用 pdfTeX 版本 3.14159265-2.6-1.40.18(TeX Live 2017)编译手稿会生成一个 pdf 文件,其正文由一个字母组成:希腊大写字母 lambda。
这与我的预期相反,我认为 pdf 的主体由空集的数学符号组成。
我的期望基于什么?基于 Donald Knuth 的TeXbook,第 20 次修订印刷(Addison-Wesley 1991),其中第 215 页列出了全部可扩展令牌的情况不是扩大。
如果您仔细查看列表,您会注意到,在 的情况下\chardef
,宏扩展仅在读取要定义的控制序列的阶段受到抑制。(相比之下,\def
在吸收参数文本和替换文本时,扩展也受到抑制。)
回到我开始的手稿,从 Knuth 的不可展开列表中可以推断出,\foo
该行中第二次出现的控制序列
\chardef\foo=3\foo
是展开。请注意,在进行此展开时,\chardef
定义仍在处理中,因此控制序列\foo
仍必须定义为具有替换文本的宏1
。因此,此行重新定义\foo
为\char31
。
有趣的是,以下类似的手稿产生了预期的结果(即空集符号)。
\documentclass{article}
\begin{document}
\def\foo{1}
\chardef\bar=3\foo\bar
\end{document}
答案1
关键是暂时变成\chardef\<name>
。我们可以通过 看到这一点:\<name>
\relax
\tracingall
\def\foo{1}
\tracingall
\chardef\bar=3\foo\bar
产量
{\chardef}
{changing \bar=macro:->\mathaccent "7016\relax }
{into \bar=\relax}
\foo ->1
{changing \bar=\relax}
{into \bar=\char"1F}
{\char"1F}
而
\def\foo{1}
\tracingall
\chardef\foo=3\foo
我们得到
{\chardef}
{changing \foo=macro:->1}
{into \foo=\relax}
{changing \foo=\relax}
{into \foo=\char"3}
{\char"3}
所以我们得到你观察到的结果,不是因为\chardef
未能扩展材料,而是因为材料的性质在检查时。
Knuth 说:
\TeX\ takes precautions so that constructions like `|\chardef\cs=10\cs|' and
`|\font\cs=name\cs|' won't expand the second |\cs| until
the assignments are done.
(第 24 章“垂直模式摘要”,第 278 页)。