TeX 将内联数学公式用\mathon
和包围起来\mathoff
,看起来像节点。例如,在 上运行 TeX$ $\showlists\bye
会得到
### horizontal mode entered at line 0
\hbox(0.0+0.0)x20.0
\mathon
\mathoff
spacefactor 1000
### vertical mode entered at line 0
prevdepth ignored
这些在哪里定义或记录?字符串mathon
和mathoff
源文件中都没有出现tex.web
的 TeX。
答案1
在tex.web
, 你会找到
3826: @ @<Display math node |p|@>=
3827: begin print_esc("math");
3828: if subtype(p)=before then print("on")
3829: else print("off");
3830: if width(p)<>0 then
3831: begin print(", surrounded "); print_scaled(width(p));
3832: end;
3833: end
使其成为“程序”的一部分Display math node
。\mathon
并且\mathoff
是打印的构造\math
,然后是条件on
或off
基于subtype
数学节点的“。
答案2
\mathon
我们对和了解多少\mathoff
? 它们由 来显示\showbox
,\showlists
在其他情况下,框或排版列表的内容会写入终端或日志文件。 如段落“12. 显示框”中所述,所有这些都是通过程序 实现的,该程序显示节点列表(TeX 用于存储排版材料的数据结构)。 忽略一些重要的错误检查,该程序仅使用列表中每个节点show_node_list
调用的代码片段。 该代码片段是@<Display node |p|@>;
p
@ @<Display node |p|@>=
if is_char_node(p) then print_font_and_char(p)
else case type(p) of
hlist_node,vlist_node,unset_node: @<Display box |p|@>;
rule_node: @<Display rule |p|@>;
ins_node: @<Display insertion |p|@>;
whatsit_node: @<Display the whatsit node |p|@>;
glue_node: @<Display glue |p|@>;
kern_node: @<Display kern |p|@>;
math_node: @<Display math node |p|@>;
ligature_node: @<Display ligature |p|@>;
penalty_node: @<Display penalty |p|@>;
disc_node: @<Display discretionary |p|@>;
mark_node: @<Display mark |p|@>;
adjust_node: @<Display adjustment |p|@>;
@t\4@>@<Cases of |show_node_list| that arise in mlists only@>@;
othercases print("Unknown node type!")
endcases
根据节点类型将显示内容分发到其他各个代码段。名称\mathon
和\mathoff
提示我们应该查看案例math_node
。那么让我们开始吧。
@ @<Display math node |p|@>=
begin print_esc("math");
if subtype(p)=before then print("on")
else print("off");
if width(p)<>0 then
begin print(", surrounded "); print_scaled(width(p));
end;
end
正如 Werner 在评论中所说,我们看到 TeX 打印\math
数学节点,然后根据节点的子类型打印on
或。然后它还提供了有关的一些详细信息。off
\mathsurround
我们现在知道要寻找什么了:子类型为before
或after
(事实证明)的数学节点在哪里创建?我们找到了函数new_math
@p function new_math(@!w:scaled;@!s:small_number):pointer;
var p:pointer; {the new node}
begin p:=get_node(small_node_size); type(p):=math_node;
subtype(p):=s; width(p):=w; new_math:=p;
end;
它在当前列表中插入一个具有类型math_node
和子类型的节点s
,并发现在“完成文本中的数学运算”时它被使用了两次:
@<Finish math in text@>=
begin tail_append(new_math(math_surround,before));
cur_mlist:=p; cur_style:=text_style; mlist_penalties:=(mode>0); mlist_to_hlist;
link(tail):=link(temp_head);
while link(tail)<>null do tail:=link(tail);
tail_append(new_math(math_surround,after));
space_factor:=1000; unsave;
end
before
这是最终插入具有子类型和的数学节点的代码after
,它们最终显示为\mathon
和\mathoff
(并且具有等于的值的宽度\mathsurround
)。