> 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/uk/dokladni-statti/24-how-tex-calculates-glue-settings-in-an-hbox.md).

# Як TeX обчислює параметри клею в \hbox

Це третя, і завершальна, стаття в серії, яка розглядає $$\mathrm \TeX$$ бокси та клей. Перша публікація [Блоки та клей: короткий, але наочний вступ із використанням LuaTeX](/latex/uk/dokladni-statti/11-boxes-and-glue-a-brief-but-visual-introduction-using-luatex.md) знайомила з поняттями боксів і клею, а за нею йшла [Pandora’s \hbox: Using LuaTeX to Lift the Lid of TeX Boxes](/latex/uk/dokladni-statti/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: Using LuaTeX to Lift the Lid of TeX Boxes](/latex/uk/dokladni-statti/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/6c0d3516d4f7298d7a6b2f12f40eef4ab00ae839)

Питання таке: яким є кінцеве значення, у $$\mathrm \TeX$$ пунктах, простору (клею) між такими елементами:

* A і B
* B і C
* C і D
* D і кінцем боксу

тобто ми хочемо обчислити значення $$\mathrm{g}*{1}, \mathrm{g}*{2}, \mathrm{g}*{3} \text{ and } \mathrm{g}*{4}:$$

![клей](/files/4200f7181cb282f8768850c16d32f1fe2e3b0aa6)

Ось граф вузлів, що представляє наведений вище бокс. Особливо цікаві три значення, що містяться в розділі «метадані»:

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

![граф вузлів](/files/bcd9525b3dcd9bf6295031d60fe7e835b4524d3b)

Важливо зазначити, що певний набір значень для `glue_set`, `glue_sign` та `glue_order` впливає лише на клеї всередині боксa верхнього рівня: вони не впливають на клеї всередині *вкладених* боксів: кожен вкладений бокс (об’єкт hlist або vlist) має власні значення цих трьох параметрів. Ось приклад `\hbox` вкладеного всередині зовнішнього `\hbox`. У цьому прикладі ви чітко бачите різні значення `glue_set`—звісно, вкладений бокс також може мати різні значення для `glue_sign` та `glue_order`.

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

![граф вузлів](/files/5c4f18213c1363770d99dc82efda4074b2d4d410)

## Типи клею, нескінченності та порядки: короткий огляд

$$\mathrm \TeX$$ надає низку примітивних команд, пов’язаних із клеєм, зокрема:

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

разом із `\mskip` для вставлення клею в математичні вирази.

Елемент клею визначається набором із трьох значень:

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

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

`**\hskip** *<натуральна ширина>* **plus** *<кількість для розтягування>* **minus** *<кількість для стискання>*`

Для *вертикальна* клей, який ви б використали `**\vskip** *<натуральна ширина>* **plus** *<кількість для розтягування>* **minus** *<кількість для стискання>*`.

Наприклад, типовий горизонтальний клей можна записати як `\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$$ поверне помилку з повідомленням `Illegal unit of measure (pt inserted)`. На цьому етапі ці «рівні нескінченності» можуть звучати дуже дивно, але поки що просто прийміть це як є, і незабаром ми побачимо, як $$\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$$ походить із низки проєктів і кодових бібліотек, зокрема з тієї, що називається [Омега](https://en.wikipedia.org/wiki/Omega_\(TeX\)). $$\text{Lua}\mathrm\TeX$$ включав певні аспекти коду Omega, і це охоплює новий тип нескінченного клею під назвою $$\text{fi}$$. Із посібника Omega:

> «Додано новий рівень нескінченності $$\text{fi}$$ . Він менший за $$\text{fil}$$ але більший за будь-яку скінченну величину. Його початкове призначення було для розтягування між літерами: або заповнення чорного, як це робиться в каліграфічних писемностях, таких як арабська; або для виділення, як у російській; і все це без необхідності переписувати наявні макропакети. Тому з’явилося нове ключове слово, $$\text{fi}$$, і дві нові примітивні команди, `\hfi` та `\vfi`Значення кодових позицій Unicode лежать у діапазоні від 0 до максимуму 1 114 111, тож неможливо представити всі значення символів Unicode за допомогою одного 8-бітного байта, який може зберігати лише до 256 різних значень: від 0 до 255. Однак будь-яке ціле значення кодової позиції Unicode можна представити за допомогою

## Повернімося до нашого завдання

Дотримуючись моделі Кнута, визначмо дві величини:

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

### Натуральна ширина боксу

Натуральна ширина боксу — це загальна ширина всіх компонентів у цьому боксі: символів, kern-ів, вкладених боксів і будь-якого клею. Для клею всередині боксу його натуральна ширина не враховує жодного розтягування чи стискання клею: тобто це його розмір до того, як починається будь-яке розтягування або стискання.

Ще раз подивімося на бокс, який ми розглядаємо:

```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/4ade99ba4073e5fd500abb0259256c369c7a12f5)

З наведеного вище графа вузлів ми бачимо, що:

$$\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/6bc4cf8779790f7b143549ba6a9cdfd656e21dfe)

* `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*—який позначається як `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/9a9ab437a31c04d3197f728eabff3dc4e8ba9f11)


---

# 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/uk/dokladni-statti/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.
