这是对问题的后续回答在 ConTeXt 中 \def 和 \define 相同吗?
mkiv ConTeXt(TeX Live 2013 版本)中的这段代码:
\define\smallfontsize{8.1pt}
\starttext
foo \switchtobodyfont[\smallfontsize] bar
\stoptext
给出以下输出,包括一个错误:
...
fonts > bodyfont '\smallfontsize ' is defined (can better be done global)
fonts > bodyfont '9.72pt' is defined (can better be done global)
fonts > bodyfont '6.48pt' is defined (can better be done global)
! LuaTeX error [string "\directlua "]:1: invalid escape sequence near '\s'.
system > tex > error on line 3 in file C:/Users/Huttar/Documents/work/tex/test-define.tex: LuaTeX error ...
1 \define\smallfontsize{8.1pt}
2 \starttext
3 >> foo \switchtobodyfont[\smallfontsize] bar
4 \stoptext
5
\ctxcommand #1^^@-\directlua {commands.#1}
\font_helpers_low_level_define ..._designsize " )}
\edef \somefontspec {at \n...
\font_helpers_trigger_define ..._identifier_class
\csname \v_font_identifier...
\applyfontclassstrategies ...\fontface \endcsname
\else \expandafter \font_h...
\font_helpers_synchronize_font ...classstrategies
\fi \setfalse \c_font_auto...
\rm f-\ifmmode \mathrm \else \normalrm
\fi
...
l.3 foo \switchtobodyfont[\smallfontsize]
bar
但是如果我们\define
将开头的 改为\def
,错误就会消失。答案是https://tex.stackexchange.com/a/55778/6973虽然有用,但似乎只描述了宏参数方面的差异。在这种情况下,没有参数,为什么使用 定义\switchtobodyfont[\smallfontsize]
时会失败?我们希望更好地理解这一点,以便将来避免以不安全的方式使用。\smallfontsize
\define
\define
次要问题是这样的(授人以渔!)...当面对上述错误消息时,我们不知所措,不知道问题是什么。诊断似乎没有以我们能理解的方式指出问题所在。(它给了我们正确的行号,但实际行号\switchtobodyfont[\smallfontsize]
被埋在几个宏调用的深处,还有许多其他代码。)我们之所以能找到解决方案,是因为一位同事做了很多反复试验,注释掉代码以找到有问题的行,而且我们很久以前就遇到过类似的问题。输出中是否有我们可以学习解释的东西,以便推断问题的原因和解决方案?(或者可以改进诊断消息以更好地提供原因线索吗?)
答案1
原\def
语创建可扩展的宏,或者至少是将在\edef
或内扩展的宏\csname
。另一方面,\define
使用\protected\def
创建受保护的宏。这些不在 内部展开\csname
,因此不适合用于需要以这种方式展开内容的任何事物。因此,您不能将其用于\define
可能需要在\cnsame
构造内部展开的任何事物。(注意:ConTeXt 调用\protected
原语\unexpanded
,而我坚持使用原语名称。)
值得注意的是,这种行为是故意的:“用户命令”通常最好受到“保护”,因为有些地方缺乏扩展是完全正确的做法。