This is the third, and concluding, article in a series which takes a look at \(\mathrm \TeX\) boxes and glue. The first post Boxes and Glue: A Brief, but Visual, Introduction Using LuaTeX introduced the concepts of boxes and glue and was followed by Pandora’s \hbox: Using LuaTeX to Lift the Lid of TeX Boxes which presented a \(\text{Lua}\mathrm\TeX\)-based Overleaf project to explore the deeper structures of \(\mathrm \TeX\) boxes through the use node graphs. In this final piece we take a “deep dive” into the mechanics of how \(\mathrm \TeX\) calculates glue values in an `\hbox`

: a process referred to as *setting the glue*. We make extensive use of node graphs (introduced in the Pandora’s \hbox: Using LuaTeX to Lift the Lid of TeX Boxes in this series) and show how to use and interpret some of the data they provide: `glue_set`

, `glue_sign`

and `glue_order`

.

We provide a fully worked example of glue calculations for an `\hbox`

and cover a lot of detail; however, there may be additional circumstances and considerations that we don’t have space to address here and the interested reader is referred to page 77 of \(\text{The } \mathrm \TeX \text{book}\).

Suppose we have an `\hbox`

such as this:

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

Here is what this box looks like—for clarity, shown enlarged and with a border:

The question is: what is the final value, in \(\mathrm \TeX\) points, of the space (glue) between the following items:

- A and B
- B and C
- C and D
- D and the end of the box

i.e., we want to calculate the values of \(\mathrm{g}_{1}, \mathrm{g}_{2}, \mathrm{g}_{3} \text{ and } \mathrm{g}_{4}:\)

Here is a node graph representing the above box. Of particular interest are three values contained in the “metadata” section:

`glue_set`

`glue_sign`

`glue_order`

It is important to note that a particular set of values for `glue_set`

, `glue_sign`

and `glue_order`

only affect glues within the top-level box: they do not affect glues within *nested* boxes: each nested box (hlist or vlist object) has its own values for these three parameters. Here is an example of an `\hbox`

nested within an outer `\hbox`

. In this example, you can clearly see the different values of `glue_set`

—of course, the nested box can also have different values for `glue_sign`

and `glue_order`

.

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

\(\mathrm \TeX\) provides a number of primitive glue-related commands, including:

- horizontal glue:
`\hskip`

,`\hfil`

,`\hfill`

,`\hfilneg`

,`\hss`

; - vertical glue:
`\vskip`

,`\vfil`

,`\vfill`

,`\vfilneg`

,`\vss`

;

together with `\mskip`

for inserting glue in math expressions.

An item of glue is defined by a set of three values:

**natural width**: how much space it occupies if you don’t stretch or shrink it;**stretch component**: by how much the glue can stretch;**shrink component**: by how much the glue can shrink.

What we are going to consider is the use of glue inside an `\hbox{...}`

and the calculations \(\mathrm \TeX\) uses to determine how much space the glue will eventually occupy. The command we’ll be using to create some *horizontal* glue is `\hskip`

, which takes the form:

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

For *vertical* glue you would use

.**\vskip** *<natural width>* **plus** *<amount to stretch>* **minus** *<amount to shrink>*

For example, some typical horizontal glue would be expressed as `\hskip 3pt plus 2pt minus 1pt`

. You can use other physical units too:

`\hskip 3mm plus 2mm minus 1mm`

`\hskip 3in plus 2in minus 1in`

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

For the shrink or stretch component of the glue \(\mathrm \TeX\) introduces another type of unit: so-called “infinities”: \(\text{fil}\), \(\text{fill}\) and \(\text{filll}\). These three “levels of infinity” are such that when listed in a sequence, each one is “more infinite” than the previous:

\(\text{fil} < \text{fill} < \text{filll}\)

Perhaps “infinities” is a slightly confusing name for these units—it might be helpful to also think of them as different levels of *priority*, because, ultimately, they help to determine which glues actually take part in the process of stretching or shrinking. By having glue with an “infinite” stretch or shrink component, \(\mathrm \TeX\) lets you create glue that can stretch or shrink by any desired amount. Note that for finite glues, \(\mathrm \TeX\) will restrict the amount by which such glues can shrink. An example of “infinite” glue is

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

Note, we can’t write, say, `\hskip 1fil`

because \(\mathrm \TeX\) will report an error with the message `Illegal unit of measure (pt inserted)`

. At this point, these “levels of infinity” may sound very strange but, for now, just accept it at face value and we’ll soon see how \(\mathrm \TeX\) uses these infinities when performing glue calculations.

Internally, when \(\mathrm \TeX\) performs its glue calculations it considers that each level of infinity is a “glue order” ranging from 0–3 where the 0th order is for glue with physical dimensions such as bp, pt, mm and so forth. However, with \(\text{Lua}\mathrm\TeX\) there is a slight deviation because it actually has an extra type (order) of infinity not present in many other \(\mathrm \TeX\) engines: \(\text{fi}\) (see explanation below). If you read \(\text{The } \mathrm \TeX\text{book}\) you will not see any mention of the \(\text{fi}\) infinity—simply because it is not implemented in Knuth’s original \(\mathrm \TeX\) software. Consequently, we have a slight “disconnect” between \(\text{Lua}\mathrm\TeX\text{'s}\) order of infinities and those you might see in books on \(\mathrm \TeX\). \(\text{Lua}\mathrm\TeX\) uses infinities whose order ranges from 0–4 but other (common) \(\mathrm \TeX\) engines range from 0–3. Here is a table showing the glue order assigned to each type of glue unit.

Physical units (pt, mm, in) | fi | fil | fill | filll | |

\(\text{Lua}\mathrm\TeX\) | 0 | 1 | 2 | 3 | 4 |

Other engines | 0 | N/A | 1 | 2 | 3 |

\(\text{Lua}\mathrm\TeX\) is derived from a number of projects and code libraries, including one called Omega. \(\text{Lua}\mathrm\TeX\) incorporated certain aspects of Omega’s code and that includes a new type of infinite glue called \(\text{fi}\). From the Omega manual:

“A new infinity level \(\text{fi}\) has been added. It is smaller than \(\text{fil}\) but bigger than any finite quantity. Its original intention was for inter-letter stretching: either filling-in-the-black, as is done for calligraphic scripts such as Arabic; or for emphasis, as in Russian; all this without having to rewrite existing macro packages. There is therefore a new keyword, \(\text{fi}\), and two new primitives,

`\hfi`

and`\vfi`

.”

Following Knuth’s model, let’s define two quantities:

- the desired width of a box: \(\mathrm{W}_{\mathrm{D}}\)—how big do we want it to be;
- the natural width a box: \(\mathrm{W}_{\mathrm{N}}\)—the total space occupied by its constituent elements before any glues are stretched or shrunk.

The natural width of a box is the total width of all components in that box: characters, kerns, nested boxes and any glue. For glue inside the box its natural width ignores any stretch or shrink of the glue: i.e., its size before any stretching or shrinking takes place.

Once again, here is the box we are examining:

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

Clearly, we want the box to be 100pt wide, hence \(\mathrm{W}_{\mathrm{D}}=100\mathrm{pt}\) but what about its natural width, \(\mathrm{W}_{\mathrm{N}} \)? To calculate the natural width it is clear that we need the widths of the four characters (A, B, C and D) plus the natural widths of the four glues.

\( \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*)\\ } \)

Where \( \text{width}\) is just a notation to denote the natural width of an item. We can obtain the natural widths of the four characters (A, B, C and D) from our node graph:

From the above node graph we can see that:

\( \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}\\ } \)

Now, all we need are the natural widths of our glues which are easily obtained by ignoring the stretch and shrink components:

\( \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}\\ }\)

Hence:

\( \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}\\ } \)

We now have two key pieces of information:

\( \eqalign{ \mathrm{W}_{\mathrm{D}} & = 100\text{pt}\\ \mathrm{W}_{\mathrm{N}} & = 33.4445\text{pt}\\ } \)

Clearly, \( \mathrm{W}_{\mathrm{D}} > \mathrm{W}_{\mathrm{N}}\) and the difference is \( (100-33.4445)\text{pt}=66.5555\text{pt}\); this excess space has to be filled by stretching the glues—but which ones and by how much?

Following Knuth’s methodology (page 77 of \(\text{The } \mathrm \TeX \text{book}\)), but allowing for the additional infinity type (\(\text{fi}\)) provided by \(\text{Lua}\mathrm \TeX\), the next step is to write down the box’s *total* stretch in the form:

\( \text{total stretch} = y_{0}+ y_{1}\text{fi} +y_{2}\text{fil} +y_{3}\text{fill} +y_{4}\text{filll} \)

Firstly, if we write down the \(\text{total glue}\):

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

we can then see that the \(\text{total stretch}\) is:

\( \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}\\ } \)

Comparing this to \(\text{total stretch} = y_{0}+ y_{1}\text{fi} +y_{2}\text{fil} +y_{3}\text{fill} +y_{4}\text{filll}\space\)we can see that:

\( \eqalign{ y_0 &=3\text{pt}\\ y_1 &=0\\ y_2 &=2\\ y_3&=5\\ y_4&=0\\ } \)

\(\mathrm\TeX\) next “asks itself”: looking at the \(\text{total stretch}\), what is the highest level of infinity with a non-zero value? On inspection of our box’s \(\text{total stretch}\) it is clear that the “most infinite” non-zero stretch component is \(\text{fill}\) and we have \(y_3=5\) units of that: it is glues with a \(\text{fill}\) stretch component that provide all the stretching. The subscript 3 of \(y_3\) tells us the `glue_order`

of the glue that will be used—in this case for stretching. Now, if we look at the “metadata” section within our node diagram for this `\hbox`

we can now make sense of two more “metadata values” (we’ll address `glue_set`

in the next section)

`glue_sign`

: tells you whether the glue is set to its natural length, stretched or shrunk:- 0=set to natural width
- 1=stretch
- 2=shrink
`glue_order`

tells you which “infinity” is involved; for \(\text{Lua}\mathrm \TeX\) a value of 3 tells you that glues with a \(\text{fill}\) component will participate in glue calculations—in our case they will stretch.

In our example, `glue_sign`

has the value of `1`

, meaning that participating glues are to be stretched.

Any glue that does not have a stretch component defined in units of \(\text{fill}\) will be **set to its natural length**: i.e., it will not (in our case) stretch at all.

`glue_set`

To summarize where we are and what we know:

- desired width of box: \(\mathrm{W}_{\mathrm{D}} = 100\text{pt}\);
- natural width of box: \(\mathrm{W}_{\mathrm{N}} = 33.4445\text{pt}\);
- glue will have to stretch but only glues with a \(\text{fill}\) stretch component will do that stretching;
- we have a total of \((2+3)=5\) units of \(\text{fill}\) available.

The next question is: by how much will those glues actually stretch? Enter the *glue set ratio*—referred to as `glue_set`

in our node graph. What \(\mathrm \TeX\) does is to work out how much space must be filled and then distributes that amount of space among the appropriate glues in proportion to the size of their stretch component. If you look back at our actual `\hbox`

you can see exactly which glues have stretch components containing units of \(\text{fill}\):

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

The \(\textit{glue set ratio }(\text{or } \verb*glue_set*)\) is calculated as follows:

\( \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})\\ } \)

And now the final step in the \(\mathrm\TeX\) algorithm is applied:

- for each item of glue whose stretch component matches the desired
`glue_order`

(3 in our case) the length of that glue will become: - all other glues are set to their natural length—i.e., they do not stretch at all.

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

Looking at the glues in our box:

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

we can go through them to calculate their final values:

**Between A and B**:`\hskip 4pt plus3pt minus 2pt`

. The stretch component is`3pt`

, which is order`0`

. The required`glue_order`

is`3`

: the stretch component is ignored and this glue assumes its natural width of`4pt`

.**Between B and C**:`\hskip 0pt plus 2fil`

. The stretch component is`2fil`

, which is order`2`

. The required`glue_order`

is`3`

: the stretch component is ignored and this glue assumes its natural width of`0pt`

.**Between C and D**:`\hskip 0pt plus 2fill`

. The stretch component is`2fill`

, which is order`3`

and matches the required`glue_order`

of`3`

. This glue will be stretched to:
\(
\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}\\
}
\)
**Between D and the end of the box**:`\hskip 0pt plus 3fill`

. The stretch component is`3fill`

, which is order`3`

and matches the required`glue_order`

of`3`

. This glue will be stretched to:
\(
\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}\\
}
\)

The process of calculating the actual space occupied by glue is called *setting the glue* so we can now check if we have filled the box to the desired width, \((\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} }\)

We now know the widths of all glues and can prepare a graphic which answers the question posed at the start of this article: here are the glue widths between the characters in our `\hbox`

:

- Creating a document in Overleaf
- Uploading a project
- Copying a project
- Creating a project from a template
- Using the Overleaf project menu
- Including images in Overleaf
- Exporting your work from Overleaf
- Working offline in Overleaf
- Using Track Changes in Overleaf
- Using bibliographies in Overleaf
- Sharing your work with others
- Using the History feature
- Debugging Compilation timeout errors
- How-to guides

- Creating your first LaTeX document
- Choosing a LaTeX Compiler
- Paragraphs and new lines
- Bold, italics and underlining
- Lists
- Errors

- Mathematical expressions
- Subscripts and superscripts
- Brackets and Parentheses
- Matrices
- Fractions and Binomials
- Aligning Equations
- Operators
- Spacing in math mode
- Integrals, sums and limits
- Display style in math mode
- List of Greek letters and math symbols
- Mathematical fonts

- Inserting Images
- Tables
- Positioning Images and Tables
- Lists of Tables and Figures
- Drawing Diagrams Directly in LaTeX
- TikZ package

- Bibliography management with bibtex
- Bibliography management with natbib
- Bibliography management with biblatex
- Bibtex bibliography styles
- Natbib bibliography styles
- Natbib citation styles
- Biblatex bibliography styles
- Biblatex citation styles

- Multilingual typesetting on Overleaf using polyglossia and fontspec
- Multilingual typesetting on Overleaf using babel and fontspec
- International language support
- Quotations and quotation marks
- Arabic
- Chinese
- French
- German
- Greek
- Italian
- Japanese
- Korean
- Portuguese
- Russian
- Spanish

- Sections and chapters
- Table of contents
- Cross referencing sections and equations
- Indices
- Glossaries
- Nomenclatures
- Management in a large project
- Multi-file LaTeX projects
- Hyperlinks

- Lengths in LaTeX
- Headers and footers
- Page numbering
- Paragraph formatting
- Line breaks and blank spaces
- Text alignment
- Page size and margins
- Single sided and double sided documents
- Multiple columns
- Counters
- Code listing
- Code Highlighting with minted
- Using colours in LaTeX
- Footnotes
- Margin notes

- Theorems and proofs
- Chemistry formulae
- Feynman diagrams
- Molecular orbital diagrams
- Chess notation
- Knitting patterns
- CircuiTikz package
- Pgfplots package
- Typing exams in LaTeX
- Knitr
- Attribute Value Matrices

- Understanding packages and class files
- List of packages and class files
- Writing your own package
- Writing your own class
- Tips