Knuth 在书的第 286 页中写道:
\noindent
在水平模式下没有效果。
相反,在第283页他写道:
这与 完全相同
\indent
,只是 TeX 以水平模式开始,使用空列表而不是缩进。
下列哪项陈述正确?
答案1
这两种说法都是正确的,但或许都没有说出全部真相。
在 hmode 中,\indent
添加一个宽度的框\parindent
,看起来像一个水平空间,\noindent
添加一个空的 hlist,正如您的第一个引文所说,它没有任何效果。
在 vmode 下,两个命令都会导致开始一个新段落和一个新的 hlist,在 的情况下以缩进框开头\indent
。
答案2
当 TeX 处于垂直模式时,\noindent
启动水平模式。当 TeX 已经处于水平模式时,\noindent
则无效果。没有矛盾。
TeX 程序中的相关部分:
在程序启动(INITEX)期间,§1088 将原语定义为带有额外参数 0 的
\noindent
命令代码:start_par
稍后在主控制循环中(TeX 对到达其“胃”的每个标记做出反应的部分),如果start_par
看到此命令,
如果当前模式是垂直模式,则 TeX
new_graf
调用false
:new_graf
就开始新的段落而言, 这将达到您的预期: 您引用的这句话也是这样的:这与 完全相同
\indent
,只是 TeX 以水平模式开始,使用空列表而不是缩进。否则(水平模式或数学模式),TeX 调用
indent_in_hmode
:indent_in_hmode
如您所见,当cur_chr = 0
(即\noindent
而不是)时, 这完全不执行任何操作\indent
: 您引用的这句话也是这样的:\noindent
在水平模式下没有效果。
编辑:相应的 LuaTeX 代码(C 语言),用于比较:
-
primitive_tex("noindent", start_par_cmd, 0, 0);
-
static void run_start_par_vmode (void) { new_graf((cur_chr > 0)); } static void run_start_par (void) { if (cur_chr != 2) indent_in_hmode(); }
和(省略
new_graf
因为它有点长)void indent_in_hmode(void) { halfword p; if (cur_chr > 0) { /*tex \.{\\indent} */ p = new_null_box(); width(p) = par_indent_par; if (abs(mode) == hmode) space_factor_par = 1000; else p = new_sub_box(p); tail_append(p); } }
和(在
init_main_control
):jump_table[vmode + start_par_cmd] = run_start_par_vmode; jump_table[hmode + start_par_cmd] = run_start_par; jump_table[mmode + start_par_cmd] = run_start_par;
答案3
在第 283 页的顶部,Knuth 描述了当 TeX 处于垂直模式时发生的情况,它发现\noindent
:此命令启动水平模式,不会在水平列表中添加任何内容。
在第 282 页的底部描述了的效果\indent
:它启动水平模式并附加一个与 一样宽的空框\parindent
(宽度也可以是负数)。
这两个描述在第24章“垂直模式总结”中。
\noindent
第 286 页描述了 TeX 处于水平模式时的效果:效果是根本不执行任何操作。这在第 25 章“水平模式摘要”中。
类似地,数学模式中的效果\noindent
描述为:再次什么都没有(第 291 页)。这在第 26 章“数学模式摘要”中。