How TeX Calculates Glue Settings in an \hbox
This is the third, and concluding, article in a series which takes a look at \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
The challenge
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
- 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
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}}
Glue types, infinities and orders: A summary
- 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 \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
glue and units of “infinity”
For the shrink or stretch component of the glue
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,
\hskip 3pt plus 2fil minus 1fill
Note, we can’t write, say, \hskip 1fil
because 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
Levels of infinity (“glue order”)
Internally, when
Physical units (pt, mm, in) | fi | fil | fill | filll | |
0 | 1 | 2 | 3 | 4 | |
Other engines | 0 | N/A | 1 | 2 | 3 |
Notes On : Why have an extra infinity?
“A new infinity level
has been added. It is smaller than 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, , and two new primitives, \hfi
and\vfi
.”
Back to our challenge
Following Knuth’s model, let’s define two quantities:
- the desired width of a box:
—how big do we want it to be; - the natural width a box:
—the total space occupied by its constituent elements before any glues are stretched or shrunk.
The natural width of a box
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
Where
From the above node graph we can see that:
Now, all we need are the natural widths of our glues which are easily obtained by ignoring the stretch and shrink components:
Hence:
We now have two key pieces of information:
Clearly,
Who has the most stretch?
Following Knuth’s methodology (page 77 of
Firstly, if we write down the
we can then see that the
Comparing this to
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 a value of 3 tells you that glues with a 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
How much to stretch or shrink: calculating glue_set
To summarize where we are and what we know:
- desired width of box:
; - natural width of box:
; - glue will have to stretch but only glues with a
stretch component will do that stretching; - we have a total of
units of 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 \hbox
you can see exactly which glues have stretch components containing units of
\hbox to100pt{%
A\hskip4pt plus3pt minus 2pt%
B\hskip 0pt plus 2fil%
C\hskip 0pt plus 2fill%
D\hskip 0pt plus 3fill%
}
The
And now the final step in the
- 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.
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 is3pt
, which is order0
. The requiredglue_order
is3
: the stretch component is ignored and this glue assumes its natural width of4pt
. - Between B and C:
\hskip 0pt plus 2fil
. The stretch component is2fil
, which is order2
. The requiredglue_order
is3
: the stretch component is ignored and this glue assumes its natural width of0pt
. - Between C and D:
\hskip 0pt plus 2fill
. The stretch component is2fill
, which is order3
and matches the requiredglue_order
of3
. This glue will be stretched to: - Between D and the end of the box:
\hskip 0pt plus 3fill
. The stretch component is3fill
, which is order3
and matches the requiredglue_order
of3
. This glue will be stretched to:
And finally: Checking the total width
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,
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
:
Overleaf guides
- 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
- Guide to Overleaf’s premium features
LaTeX Basics
- Creating your first LaTeX document
- Choosing a LaTeX Compiler
- Paragraphs and new lines
- Bold, italics and underlining
- Lists
- Errors
Mathematics
- 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
- Using the Symbol Palette in Overleaf
Figures and tables
- Inserting Images
- Tables
- Positioning Images and Tables
- Lists of Tables and Figures
- Drawing Diagrams Directly in LaTeX
- TikZ package
References and Citations
- 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
Languages
- 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
Document structure
- Sections and chapters
- Table of contents
- Cross referencing sections, equations and floats
- Indices
- Glossaries
- Nomenclatures
- Management in a large project
- Multi-file LaTeX projects
- Hyperlinks
Formatting
- 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
Fonts
Presentations
Commands
Field specific
- Theorems and proofs
- Chemistry formulae
- Feynman diagrams
- Molecular orbital diagrams
- Chess notation
- Knitting patterns
- CircuiTikz package
- Pgfplots package
- Typesetting exams in LaTeX
- Knitr
- Attribute Value Matrices
Class files
- Understanding packages and class files
- List of packages and class files
- Writing your own package
- Writing your own class