Где разрешено изменять \hsize?

Где разрешено изменять \hsize?

В главе 23 «Процедуры вывода» есть предупреждение:

Лучше не экспериментировать с \hsize и \vsize, за исключением самого начала задания или после того, как вы извлекли все страницы из памяти TeX.

Но вTeXbookесть несколько примеров, где \hsizeэто изменено:

1) В упражнении с story.tex \hsize задается несколько раз в одном задании tex.

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

Я полагаю, что этот случай является «законным», поскольку \ejectон назван в конце story.tex

Еще несколько примеров:

2) На странице 115 \hsizeустановлено внутри \topinsert.

3) На странице 223 \hsizeустановлено внутри \vbox.

В каких контекстах «законно» вносить изменения \hsizeи почему появляется это предупреждение?TeXbook? Есть ли пример, показывающий, что может пойти не так, если мы изменим что-то \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

Итак, мы видим абзац, состоящий из шести строк, соответствующих шести полям шириной 300 пунктов.

Вторая \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для установки заголовков и нижних колонтитулов. Например, \plainoutputhas \makeheadlinethat does

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

и \lineявляется \hbox to \hsize.

Вот в чем заключается основной смысл предупреждения Кнута: если вы внесете изменения \hsizeв середине страницы, могут возникнуть неожиданные результаты, в зависимости от того, когда сработает процедура вывода.

Изменение \hsizeвнутри \vboxвсегда безопасно, поскольку выполнение конструктора страниц при работе со вторичным вертикальным списком никогда не вызывает процедуру вывода.

Связанный контент