哪里允许改变 \hsize?

哪里允许改变 \hsize?

在第 23 章“输出例程”中有一个警告:

最好不要随意修改 \hsize 和 \vsize,除非是在作业刚开始时,或者从 TeX 内存中弹出所有页面之后。

但在电子书本身就有几个\hsize改变的例子:

1) 在 story.tex 练习中,\hsize 在一个 tex 作业中被设置多次。

\hsize=4in \input story
\hsize=3in \input story
...

我认为,这个案例是“合法的”,因为\eject它在故事的结尾被调用。tex

更多示例:

2)在第115页\hsize内设置\topinsert

3)在第223页\hsize内设置\vbox

在哪些情况下修改是“合法的”\hsize,以及为什么会出现这个警告电子书? 有没有例子可以说明如果我们\hsize在一个“糟糕”的地方改变,会出现什么问题?

答案1

什么是\hsize

原始参数\hsize是 TeX 将段落拆分为行所使用的长度(同时考虑到\leftskip\rightskip以及来自\hangindent和 的段落形状指令) \hangafter

当段落被分割成行时,TeX 会将一组宽度的水平框添加到当前垂直列表中。如果使用和,\hsize宽度将有所不同,并将反映每行的实际宽度。\hangindent\hangafter

\parshape使用时,就像\hsize为每一行指定不同的一样。

考虑一下代码

\input plipsum

\hsize=300pt

\showboxbreadth=1000 \showboxdepth=0 

\lipsum{1}

\showlists

\hsize=200pt

\lipsum{2}

\showlists

\bye

第一个\showlists命令输出

### vertical mode entered at line 0
### current page:
\glue(\topskip) 3.05556
\hbox(6.94444+1.94444)x300.0, glue set - 0.62798 []
\penalty 150
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.38911 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set - 0.17653 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.24695 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.36536 []
\penalty 150
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 227.0554fil []
total height 70.0
 goal height 643.20255
prevdepth 1.94444, prevgraf 6 lines

因此我们看到一个由六行组成的段落,对应六个 300pt 宽的框。

第二\showlists条指令输出

### vertical mode entered at line 0
### current page:
\glue(\topskip) 3.05556
\hbox(6.94444+1.94444)x300.0, glue set - 0.62798 []
\penalty 150
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.38911 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set - 0.17653 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.24695 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 0.36536 []
\penalty 150
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x300.0, glue set 227.0554fil []
\glue(\parskip) 0.0 plus 1.0
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set 0.68265 []
\penalty 250
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set - 0.56822 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set 0.02776 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set 0.76903 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set 1.07141 []
\glue(\baselineskip) 3.11111
\hbox(6.94444+1.94444)x200.0, glue set 0.93843 []
\penalty 100
\glue(\baselineskip) 3.11111
\hbox(6.94444+0.0)x200.0, glue set 0.1729 []
\penalty 100
\glue(\baselineskip) 5.05556
\hbox(6.94444+1.94444)x200.0, glue set 0.93886 []
\penalty 250
\glue(\baselineskip) 5.75002
\hbox(4.30554+0.0)x200.0, glue set 179.41664fil []
total height 178.0 plus 1.0
 goal height 643.20255
prevdepth 0.0, prevgraf 9 lines

前六行就在那里,依次查找\parskip以查看第二段从哪里开始。我们有九行,宽度均为 200pt。

在哪里进行更改是合法的\hsize

任何地方。除非\parshape正在使用,否则 TeX 将使用扫描\hsize时的当前值\par来将段落分成行。

当然,这个设置\hsize会尊重 TeX 分组(如果你不够狡猾,无法进行全局设置)。所以如果我们尝试

{\hsize=1pt \nopar\lipsum{1}}\par

我们得到的结果与之前完全相同,因为\hsize当找到时,对 的更改将被遗忘。请注意,在构建段落时,\par不能有两个不同的值(当然,除非)。\hsize\parshape

是否\hsize影响页面形状?

这不是 TeX 的设计。但是,输出例程可以并且可能会使用标准\hsize来设置页眉和页脚。例如,\plainoutput\makeheadline

\line{\vbox to 8.5pt{}\the\headline}

并且\line\hbox to \hsize

所以,这就是 Knuth 警告的主要含义:如果你\hsize在页面中间进行更改,则可能会出现意外结果,具体取决于输出例程何时开始运行。

\hsize在内部进行更改\vbox始终是安全的,因为在辅助垂直列表中工作时执行页面构建器永远不会调用输出例程。

相关内容