> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ru/podrobnye-stati/24-how-tex-calculates-glue-settings-in-an-hbox.md).

# Как TeX вычисляет параметры glue в \\\hbox

Это третья и заключительная статья в серии, которая рассматривает $$\mathrm \TeX$$ боксы и клей. Первая запись [Боксы и клей: краткое, но наглядное введение с использованием LuaTeX](/latex/ru/podrobnye-stati/11-boxes-and-glue-a-brief-but-visual-introduction-using-luatex.md) ввела понятия боксов и клея, за которой последовала [Pandora’s \hbox: использование LuaTeX, чтобы приподнять крышку боксов TeX](/latex/ru/podrobnye-stati/36-pandora-s-hbox-using-luatex-to-lift-the-lid-of-tex-boxes.md) в которой был представлен [$$\text{Lua}\mathrm\TeX$$-основанный проект Overleaf](https://www.overleaf.com/latex/examples/exploring-the-structure-of-tex-boxes-with-luatex/pwdrypmtdbgs) для исследования более глубоких структур $$\mathrm \TeX$$ боксов с помощью графов узлов. В этой заключительной части мы делаем «глубокое погружение» в механику того, как $$\mathrm \TeX$$ вычисляет значения клея в `\hbox`: процесс, называемый *установкой клея*. Мы широко используем графы узлов (введённые в [Pandora’s \hbox: использование LuaTeX, чтобы приподнять крышку боксов TeX](/latex/ru/podrobnye-stati/36-pandora-s-hbox-using-luatex-to-lift-the-lid-of-tex-boxes.md) в этой серии) и показываем, как использовать и интерпретировать некоторые данные, которые они предоставляют: `glue_set`, `glue_sign` и `glue_order`.

Мы приводим полностью разобранный пример вычислений клея для `\hbox` и рассматриваем множество подробностей; однако могут быть дополнительные обстоятельства и соображения, которые мы не можем здесь рассмотреть, и заинтересованному читателю рекомендуется обратиться к странице 77 $$\text{The } \mathrm \TeX \text{book}$$.

## Задача

Предположим, у нас есть `\hbox` такой:

```latex
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt%
B\hskip 0pt plus 2fil%
C\hskip 0pt plus 2fill%
D\hskip 0pt plus 3fill%
}
```

Вот как выглядит этот бокс — для наглядности он показан увеличенным и с рамкой:

![бокс](/files/578501cc5191e3906246f6b607b2e01862d87981)

Вопрос в том: каково конечное значение, в $$\mathrm \TeX$$ пунктах, пространства (клея) между следующими элементами:

* A и B
* B и C
* C и D
* D и концом бокса

то есть нам нужно вычислить значения $$\mathrm{g}*{1}, \mathrm{g}*{2}, \mathrm{g}*{3} \text{ and } \mathrm{g}*{4}:$$

![склейка](/files/1038c18a89a59abd3f88b04f14d4fa17dec80588)

Вот граф узлов, представляющий указанный выше бокс. Особый интерес представляют три значения, содержащиеся в разделе «метаданные»:

* `glue_set`
* `glue_sign`
* `glue_order`

![граф узлов](/files/8b058f3f3a4da6a3e209ede02a1b73fd203c4537)

Важно отметить, что определённый набор значений для `glue_set`, `glue_sign` и `glue_order` влияет только на клей внутри бокса верхнего уровня: он не влияет на клей внутри *вложенных* боксов: у каждого вложенного бокса (объекта hlist или vlist) есть свои значения этих трёх параметров. Вот пример `\hbox` вложенного внутри внешнего `\hbox`. В этом примере вы отчётливо видите разные значения `glue_set`—разумеется, вложенный бокс также может иметь другие значения для `glue_sign` и `glue_order`.

```latex
\hbox to 75pt{\hfill ABC\hbox to15pt{\hfill D}}
```

![граф узлов](/files/aea4686f620561f5faa0b9264f112d6aa30af7ae)

## Типы клея, бесконечности и порядки: краткое изложение

$$\mathrm \TeX$$ предоставляет ряд примитивных команд, связанных с клеем, включая:

* горизонтальный клей: `\hskip`, `\hfil`, `\hfill`, `\hfilneg`, `\hss`;
* вертикальный клей:`\vskip`, `\vfil`, `\vfill`, `\vfilneg`, `\vss`;

вместе с `\mskip` для вставки клея в математические выражения.

Элемент клея определяется набором из трёх значений:

* **естественная ширина**: сколько места он занимает, если его не растягивать и не сжимать;
* **компонент растяжения**: насколько клей может растягиваться;
* **компонент сжатия**: насколько клей может сжиматься.

Мы рассмотрим использование клея внутри `\hbox{...}` и вычисления $$\mathrm \TeX$$ которые использует, чтобы определить, сколько места в итоге займёт клей. Команда, которую мы будем использовать для создания некоторого *горизонтального* клея — это `\hskip`, которая имеет вид:

`**\\hskip** *<natural width>* **plus** *<amount to stretch>* **minus** *<amount to shrink>*`

Для *вертикального* клея, который вы бы использовали `**\\vskip** *<natural width>* **plus** *<amount to stretch>* **minus** *<amount to shrink>*`.

Например, некоторый типичный горизонтальный клей записывается как `\hskip 3pt plus 2pt minus 1pt`. Можно использовать и другие физические единицы:

* `\hskip 3mm plus 2mm minus 1mm`
* `\hskip 3in plus 2in minus 1in`
* `\hskip 1in plus 3cm minus 20mm`

## $$\mathrm \TeX$$ клей и единицы «бесконечности»

Для компонента сжатия или растяжения клея $$\mathrm \TeX$$ вводит ещё один тип единиц: так называемые «бесконечности»: $$\text{fil}$$, $$\text{fill}$$ и $$\text{filll}$$. Эти три «уровня бесконечности» устроены так, что при перечислении в последовательности каждый следующий «более бесконечен», чем предыдущий:

$$\text{fil} < \text{fill} < \text{filll}$$

Возможно, слово «бесконечности» — немного запутанное название для этих единиц; полезно также воспринимать их как разные уровни *приоритета*, потому что в конечном счёте они помогают определить, какие именно клеи реально участвуют в процессе растяжения или сжатия. Наличие клея с «бесконечным» компонентом растяжения или сжатия $$\mathrm \TeX$$ позволяет создавать клей, который может растягиваться или сжиматься на любое нужное значение. Заметьте, что для конечного клея, $$\mathrm \TeX$$ ограничит величину, на которую такой клей может сжиматься. Пример «бесконечного» клея:

`\hskip 3pt plus 2fil minus 1fill`

Заметим, мы не можем написать, например, `\hskip 1fil` потому что $$\mathrm \TeX$$ выдаст ошибку с сообщением `Недопустимая единица измерения (вставлено pt)`. На этом этапе эти «уровни бесконечности» могут звучать очень странно, но пока просто примите это как есть, и скоро мы увидим, как $$\mathrm \TeX$$ использует эти бесконечности при вычислениях клея.

### Уровни бесконечности («порядок клея»)

Внутренне, когда $$\mathrm \TeX$$ выполняет вычисления клея, он рассматривает каждый уровень бесконечности как «порядок клея» в диапазоне от 0 до 3, где 0-й порядок относится к клею с физическими единицами, такими как bp, pt, mm и так далее. Однако в $$\text{Lua}\mathrm\TeX$$ есть небольшое отличие, потому что на самом деле у него есть дополнительный тип (порядок) бесконечности, отсутствующий во многих других $$\mathrm \TeX$$ движках: $$\text{fi}$$ (см. объяснение ниже). Если вы прочтёте $$\text{The } \mathrm \TeX\text{book}$$ вы не увидите упоминания о $$\text{fi}$$ бесконечности — просто потому, что она не реализована в оригинальном $$\mathrm \TeX$$ ПО Кнута. Следовательно, у нас есть небольшое несоответствие между $$\text{Lua}\mathrm\TeX\text{'s}$$ порядком бесконечностей и тем, что вы можете увидеть в книгах по $$\mathrm \TeX$$. $$\text{Lua}\mathrm\TeX$$ использует бесконечности, чей порядок варьируется от 0 до 4, но другие (обычные) $$\mathrm \TeX$$ движки — от 0 до 3. Вот таблица, показывающая порядок клея, присвоенный каждому типу единицы клея.

|                           |                                 |     |     |      |       |
| ------------------------- | ------------------------------- | --- | --- | ---- | ----- |
|                           | Физические единицы (pt, mm, in) | fi  | fil | fill | filll |
| $$\text{Lua}\mathrm\TeX$$ | 0                               | 1   | 2   | 3    | 4     |
| Другие движки             | 0                               | Н/Д | 1   | 2    | 3     |

### Примечания к $$\text{Lua}\mathrm\TeX$$: Зачем нужна дополнительная бесконечность?

$$\text{Lua}\mathrm\TeX$$ основан на ряде проектов и библиотек кода, включая одну под названием [Omega](https://en.wikipedia.org/wiki/Omega_\(TeX\)). $$\text{Lua}\mathrm\TeX$$ включил некоторые аспекты кода Omega, и это включает новый тип бесконечного клея под названием $$\text{fi}$$. Из руководства Omega:

> «Новый уровень бесконечности $$\text{fi}$$ был добавлен. Он меньше, чем $$\text{fil}$$ но больше, чем любая конечная величина. Его первоначальное назначение — межбуквенное растяжение: либо для заполнения чёрного, как это делается в каллиграфических письменностях, таких как арабская; либо для выделения, как в русском; и всё это без необходимости переписывать существующие макропакеты. Поэтому введено новое ключевое слово, $$\text{fi}$$, а также два новых примитива, `\hfi` и `\vfi`».

## Вернёмся к нашей задаче

Следуя модели Кнута, определим две величины:

* желаемая ширина бокса: $$\mathrm{W}\_{\mathrm{D}}$$—каким большим мы хотим его сделать;
* естественная ширина бокса: $$\mathrm{W}\_{\mathrm{N}}$$—общее пространство, занимаемое его составными элементами до того, как какой-либо клей растянется или сожмётся.

### Естественная ширина бокса

—это общая ширина всех компонентов в этом боксе: символов, кернов, вложенных боксов и любого клея. Для клея внутри бокса его естественная ширина не учитывает растяжение или сжатие клея: то есть его размер до того, как начнётся растяжение или сжатие.

Ещё раз: вот бокс, который мы рассматриваем:

```latex
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt%
B\hskip 0pt plus 2fil%
C\hskip 0pt plus 2fill%
D\hskip 0pt plus 3fill%
}
```

Очевидно, мы хотим, чтобы ширина бокса была 100pt, следовательно $$\mathrm{W}*{\mathrm{D}}=100\mathrm{pt}$$ но что насчёт его естественной ширины, $$\mathrm{W}*{\mathrm{N}}$$? Чтобы вычислить естественную ширину, очевидно, нам нужны ширины четырёх символов (A, B, C и D), а также естественные ширины четырёх клеев.

$$\eqalign{\mathrm{W}\_{\mathrm{N}} &= &\text{width(A)} + \text{width(B)} + \text{width(C)} + \text{width(D)} \ & &+ \text{width}(\verb\*\hskip 4pt plus3pt minus 2pt\*)\ & &+\text{width}(\verb\*\hskip 0pt plus 2fil\*)\ & &+\text{width}(\verb\*\hskip 0pt plus 2fill)*\ & &+\text{width}(\verb*\hskip 0pt plus 3fill\*)\ }$$

Где $$\text{width}$$ —это просто обозначение естественной ширины элемента. Мы можем получить естественные ширины четырёх символов (A, B, C и D) из нашего графа узлов:

![граф узлов](/files/fca447a6e0951861efe7464379a091623c3a11ce)

Из приведённого выше графа узлов видно, что:

$$\eqalign{ \text{width(A)} &= 7.50002\text{pt}\ \text{width(B)} &= 7.08336\text{pt}\ \text{width(C)} &= 7.22223\text{pt}\ \text{width(D)} &= 7.6389\text{pt}\ }$$

Теперь всё, что нам нужно, — это естественные ширины нашего клея, которые легко получить, проигнорировав компоненты растяжения и сжатия:

$$\eqalign{ &\text{width}(\verb\*\hskip 4pt plus3pt minus 2pt\*) & = 4\text{pt}\ &\text{width}(\verb\*\hskip 0pt plus 2fil\*) &=0\text{pt}\ &\text{width}(\verb\*\hskip 0pt plus 2fill)*&=0\text{pt}\ &\text{width}(\verb*\hskip 0pt plus 3fill\*)&=0\text{pt}\ }$$

Следовательно:

$$\eqalign{ \mathrm{W}\_{\mathrm{N}} & = \text{widths of characters} + \text{width of all glues}\ &= 7.50002\text{pt}+ 7.08336\text{pt} + 7.22223\text{pt} + 7.6389\text{pt} + 4\text{pt}\space \text{(from }\verb\*\hskip\*\text{)}\ &=33.4445\text{pt}\ }$$

Теперь у нас есть две ключевые величины:

$$\eqalign{ \mathrm{W}*{\mathrm{D}} & = 100\text{pt}\ \mathrm{W}*{\mathrm{N}} & = 33.4445\text{pt}\ }$$

Очевидно, $$\mathrm{W}*{\mathrm{D}} > \mathrm{W}*{\mathrm{N}}$$ а разница составляет $$(100-33.4445)\text{pt}=66.5555\text{pt}$$; это лишнее пространство нужно заполнить, растянув клей — но какой именно и насколько?

### У кого наибольшее растяжение?

Следуя методике Кнута (стр. 77 $$\text{The } \mathrm \TeX \text{book}$$), но с учётом дополнительного типа бесконечности ($$\text{fi}$$) , предоставляемого $$\text{Lua}\mathrm \TeX$$, следующим шагом является запись *общего* растяжения в виде:

$$\text{total stretch} = y\_{0}+ y\_{1}\text{fi} +y\_{2}\text{fil} +y\_{3}\text{fill} +y\_{4}\text{filll}$$

Во-первых, если мы запишем $$\text{total glue}$$:

$$\text{total glue } = (\verb*4pt plus3pt minus 2pt*) + (\verb*0pt plus 2fil*) + (\verb*0pt plus 2fill*) + (\verb*0pt plus 3fill*)$$

мы затем увидим, что $$\text{total stretch}$$ таков:

$$\eqalign{ \text{total stretch} & = 3\text{pt}+ 0\text{fi} + (2\text{fil}) + (2\text{fill} + 3\text{fill}) + 0\text{filll}\ &=3\text{pt}+ 0\text{fi} + 2\text{fil} + 5\text{fill} + 0\text{filll}\ }$$

Сравнивая это с $$\text{total stretch} = y\_{0}+ y\_{1}\text{fi} +y\_{2}\text{fil} +y\_{3}\text{fill} +y\_{4}\text{filll}\space$$мы видим, что:

$$\eqalign{ y\_0 &=3\text{pt}\ y\_1 &=0\ y\_2 &=2\ y\_3&=5\ y\_4&=0\ }$$

$$\mathrm\TeX$$ следующий «задаёт себе вопрос»: глядя на $$\text{total stretch}$$, какой наивысший уровень бесконечности имеет ненулевое значение? При рассмотрении метаданных нашего бокса $$\text{total stretch}$$ ясно, что «наиболее бесконечный» ненулевой компонент растяжения — это $$\text{fill}$$ и у нас есть $$y\_3=5$$ единиц этого: это клеи с $$\text{fill}$$ компонентом растяжения, которые обеспечивают всё растяжение. Нижний индекс 3 у $$y\_3$$ говорит нам о `glue_order` уровне клея, который будет использован — в данном случае для растяжения. Теперь, если мы посмотрим на раздел «метаданные» в `\hbox` мы теперь можем понять ещё два «значения метаданных» (мы разберём `glue_set` в следующем разделе)

![метаданные](/files/247098736b618020501f657e726ffddee3163bc2)

* `glue_sign`: показывает, установлен ли клей в свою естественную длину, растянут или сжат:
* 0 = установлено на естественную ширину
* 1 = растяжение
* 2 = сжатие

В нашем примере `glue_sign` имеет значение `1`, что означает, что участвующий клей должен быть растянут.

* `glue_order` указывает, какая «бесконечность» задействована; для $$\text{Lua}\mathrm \TeX$$ значение 3 говорит вам, что клей с $$\text{fill}$$ компонентом будет участвовать в вычислениях клея — в нашем случае он будет растягиваться.

Любой клей, для которого компонент растяжения не определён в единицах $$\text{fill}$$ будет **установлен в свою естественную длину**: то есть он вообще не будет (в нашем случае) растягиваться.

### Насколько растягивать или сжимать: вычисление glue\_set

Подытожим, где мы находимся и что знаем:

1. желаемая ширина бокса: $$\mathrm{W}\_{\mathrm{D}} = 100\text{pt}$$;
2. естественная ширина бокса: $$\mathrm{W}\_{\mathrm{N}} = 33.4445\text{pt}$$;
3. клей придётся растянуть, но только клей с $$\text{fill}$$ с компонентом растяжения будет выполнять это растяжение;
4. у нас в общей сложности есть $$(2+3)=5$$ единиц $$\text{fill}$$ доступных.

Следующий вопрос: насколько именно растянется этот клей? Здесь вступает в дело *коэффициент растяжения клея*—обозначаемый как `glue_set` в нашем графе узлов. Что $$\mathrm \TeX$$ делает — он определяет, сколько пространства нужно заполнить, а затем распределяет это пространство между соответствующими клеями пропорционально величине их компонента растяжения. Если вы посмотрите обратно на наш настоящий `\hbox` вы можете точно увидеть, какие клеи имеют компоненты растяжения, содержащие единицы $$\text{fill}$$:

```latex
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt%
B\hskip 0pt plus 2fil%
C\hskip 0pt plus 2fill%
D\hskip 0pt plus 3fill%
}
```

Это $$\textit{glue set ratio }(\text{or } \verb*glue\_set*)$$ вычисляется следующим образом:

$$\eqalign{ \text{glue set ratio}\space (\verb*glue\_set*) = & {\text{amount to stretch}}\over{\text{value of highest infinity}}\ =& {\mathrm{W}*{\mathrm{D}}-\mathrm{W}*{\mathrm{N}}}\over{y\_3}\ =& {(100-33.4445)}\over{5}\ =& {66.5555}\over{5}\ =& 13.3111\space (\text{to 4 decimal places})\ }$$

И теперь заключительный шаг в $$\mathrm\TeX$$ алгоритме применяется:

1. для каждого элемента клея, чьё значение компонента растяжения соответствует требуемому `glue_order` (3 в нашем случае) длина этого клея станет:

$$\text{stretched value} = \text{natural length} + (\verb*glue\_set* \times \text{value of stretch component})$$

3. все остальные клеи устанавливаются в свою естественную длину — то есть они вообще не растягиваются.

Рассматривая клей в нашем боксе:

```latex
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt%
B\hskip 0pt plus 2fil%
C\hskip 0pt plus 2fill%
D\hskip 0pt plus 3fill%
}
```

мы можем пройтись по ним и вычислить их конечные значения:

1. **Между A и B**: `\hskip 4pt plus3pt minus 2pt`. Компонент растяжения составляет `3pt`, что соответствует порядку `0`. Требуемая `glue_order` равно `3`: компонент растяжения игнорируется, и этот клей принимает свою естественную ширину `4pt`.
2. **Между B и C**: `\hskip 0pt plus 2fil`. Компонент растяжения составляет `2fil`, что соответствует порядку `2`. Требуемая `glue_order` равно `3`: компонент растяжения игнорируется, и этот клей принимает свою естественную ширину `0pt`.
3. **Между C и D**: `\hskip 0pt plus 2fill`. Компонент растяжения составляет `2fill`, что соответствует порядку `3` и соответствует требуемому `glue_order` для `3`. Этот клей будет растянут до: $$\eqalign{ \text{stretched value}\space = & \text{natural width} + (\verb*glue\_set* \times \text{value of stretch component})\ = & 0\text{pt} + 13.3111 \times 2 \ = & 26.6222\text{pt}\ }$$5. **Между D и концом бокса**: `\hskip 0pt plus 3fill`. Компонент растяжения составляет `3fill`, что соответствует порядку `3` и соответствует требуемому `glue_order` для `3`. Этот клей будет растянут до: $$\eqalign{ \text{stretched value}\space = &\text{natural width} + (\verb*glue\_set* \times \text{value of stretch component})\ =& 0\text{pt} + 13.3111 \times 3 \ = &39.9333\text{pt}\ }$$

## И наконец: проверка общей ширины

Процесс вычисления фактического пространства, занимаемого клеем, называется *установкой клея* так что теперь мы можем проверить, заполнили ли мы бокс до желаемой ширины, $$(\mathrm{W}\_{\mathrm{D}} = \text{100pt})$$:

$$\eqalign{ \mathrm{W}\_{\mathrm{D}} & = \text{width of all characters} + \text{width of all }\textbf{set}\text{ glue values}\ & = \text{A:7.50002pt} + \text{B:7.08336pt} + \text{C:7.22223pt} + \text{D:7.6389pt}\ & + \text{4pt} + \text{0pt} + \text{26.6222pt} + \text{39.9333pt}\ & = \text{100.00pt} }$$

Теперь мы знаем ширины всего клея и можем подготовить графику, которая отвечает на вопрос, поставленный в начале этой статьи: вот ширины клея между символами в нашем `\hbox`:

![склейка](/files/ff1fd09567eb8ce03e39dda26cdeff7b3b1ce725)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/ru/podrobnye-stati/24-how-tex-calculates-glue-settings-in-an-hbox.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
