How does LaTeX typeset headers and footers?
Introduction
If you are looking for a how-to guide on changing headers and footers please visit our help page because this article focuses on explaining low-level mechanisms used by TeX engines, and LaTeX, to produce headers and footers.
- Note (update): This article explores the core LaTeX mark mechanism in use prior to June 2022, at which time a new and more versatile implementation of LaTeX’s mark handling was introduced. See Overview of LaTeX’s new mark mechanism for more details. For reasons of backward compatibility, LaTeX continues to support its legacy mark mechanism. Article material discussing the behavior of TeX engines is unaffected by these changes to LaTeX.
- Note: the terms “LaTeX”, “TeX” and “TeX engine” are used throughout these discussions so it is helpful to understand their meaning—see the Overleaf article What’s in a Name: A Guide to the Many Flavours of TeX for further information.
To provide useful background/context we start with an overview of some relevant low-level areas of TeX-based typesetting—including temporary (internal) content storage, page-breaking and construction. Discussions have been streamlined/simplified by considering a typeset page which contains a “body” of text plus some headers and footers. Page items such as figures (floats) and footnotes are not addressed because they involve a complex TeX mechanism called insertions, which is far outside the scope of this article.
We’ll start with the basic notion of nodes: the fundamental building blocks used by TeX engines for temporary (internal) content storage.
Some notes on storing content: TeX nodes
As the underlying TeX engine processes your LaTeX code to produce typeset material—such as paragraphs, tables and mathematics—it needs to temporarily store that content within the memory of whichever TeX engine is being used to process your LaTeX code. To store typeset content TeX engines use a sequence of so-called nodes, which you can think of as variably-sized “chunks” of computer (device) memory, linked together to form a list (see this Wikipedia article on linked data structures).
To represent the fundamental elements of TeX-based typesetting—such as characters, glue, boxes, penalties, kerns and marks (to name but a few)—TeX engines use different types of node. Some nodes, such as those for boxes, need to store more data compared to simpler node types such as character nodes; consequently, some nodes are larger than others—requiring more bytes to store them in memory. When reading about TeX you may encounter terms such as character nodes, glue nodes, mark nodes and so forth: you now know these are just names given to chunks of memory allocated to store data representing an element of TeX’s typesetting.
Why we’re here: understanding mark nodes
Of the many node types the one we need to discuss is called a mark node which is created by the \mark
command:
\mark{stuff to store}
The \mark
command does not directly produce any typeset content: its argument stuff to store
is saved to memory for later use and a mark node is created to contain the memory location of stuff to store. As we’ll see, the \mark
command was created specifically to assist with producing headers and footers.
Mark nodes created by \mark
commands are “embedded” into the page content ready for use during the final stages of page composition when the TeX engine is ready to add headers and footers to the typeset page (body). Typically, stuff to store
will contain material such as page numbers and chapter or section titles/numbers—the building blocks of headers and footers.
ε-TeX adds the \marks
command
Version 2 of ε-TeX, an extension to Knuth’s original TeX, was published in 1998 and provides new capabilities together with enhancements to existing features. Today, most of ε-TeX’s enhancements have been incorporated into the mainstream TeX engines: pdfTeX, LuaTeX and XeTeX—see the -etex
command line option of TeX engines which enables use of ε-TeX extensions.
Knuth’s original TeX software provides the \mark command which creates just 1 “class”, or “type” of mark node. Your document could include many \mark commands but they all create mark nodes of the same “type” or “class”—there’s no built-in mechanism to group or classify them. This restriction was removed by an ε-TeX enhancement: the \marks command which is supported by pdfTeX, LuaTeX and XeTeX:
\marks n {stuff to store}
where n
is an integer (0
<= n
< 32768
) that determines the mark node class.
Notes:
- writing
\marks 0
(i.e.,n
=0
) is synonymous with using TeX’s original\mark
command - ε-TeX also introduced mark variables (see later) for each class (
n
) of mark:\firstmarks n
,\topmarks n
and\botmarks n
. Selected classes of mark variables could be used to provide mark data for specific typesetting tasks. - LuaTeX increased the maximum value of
n
to65535
, enabling \(2^{16}\) mark classes
Reasons for TeX’s use of marks
To understand why (and how) TeX engines use the \mark
(or \marks
) command to produce headers and footers we need to appreciate some “quirks” of TeX engine mechanisms for constructing pages—finding page breaks and shipping out completed pages to a PDF file. In reality, those page-construction processes are complex but the core principles/concepts can be simplified to provide sufficient background explanations which aid our understanding of marks.
As a TeX engine completes typesetting individual content items such as paragraphs, tables or mathematics, it calls an internal routine (a function called build_page(...)
) which tries to add those newly typeset items to the page currently being constructed in memory. When that new material is added to the page being built, TeX also checks whether that newly-added content has made the current page become “suitably full”. If the page is full TeX can create a page break—sending that page’s worth of content for final processing (“packaging”) and subsequent output to the PDF file.
One key feature of the final stage of page packaging (composition) is something called an output routine which is, in effect, a user-defined sequence of commands used to package-up the page of content to make it ready for sending to the PDF file. One example activity of “packaging-up” is to add headers and footers, but there are numerous ways to use output routines—for example, see this article in TUGboat. Output routines are a fairly complex area of TeX so we won’t go into detail here: for present purposes just remember that the final stage of page composition involves using some user-defined sequence of commands (collectively called an output routine).
But let’s consider what could happen when TeX completes typesetting a lengthy paragraph of text, breaking it into a sequence of individual typeset lines. TeX will want to add that newly-typeset paragraph—line-by-line—to the page currently being built but, perhaps, only some of those lines can fit on the current page. Note by “page” we are referring to the main text area (page body) which does not include other page elements such as headers and footers which are added later (by the output routine).
After several paragraph lines have been added to the current page, it could become “suitably full” and time for TeX to create a page break. However, we have some “leftover” material because only part of the paragraph made it to the current page: the “excess paragraph content” is saved for later, ready for creation of the next page. The following graphic illustrates this idea: part of the paragraph is on the current page and part is held back for the next page.
This paragraph example demonstrates that a TeX engine will often process (typeset) pieces of content which cannot, in their entirety, fit on the current page—because that content reaches beyond the point at which a page break becomes necessary. Recall that TeX engines find linebreaks by inputting, then typesetting, whole paragraphs and, unlike some applications, do not adopt a line-by-line approach to typesetting paragraphs. In other words, TeX typesets the entire paragraph whether or not it fits on the current page (that’s worked out later). Incidentally, the principle of “typeset-in-full then add to the current page” holds true for other types of TeX content, including tables which are fully read-in from the .tex file and typeset in their entirety prior to any attempt at adding them to the current page.
For our paragraph example, the complete text of that paragraph, including any commands within that text, has been fully processed—meaning that TeX’s typesetting has reached a certain location in your .tex
file. The “current internal state” of the TeX engine, such as the value of variables or stored parameter settings, will reflect the material, including any commands, processed up to the current location—the end of the paragraph.
Although the complete paragraph has been typeset, some of it cannot be accommodated by the current page, resulting in “excess paragraph content” being saved for the next page. Within the LaTeX code (text plus commands) which produced the “excess paragraph content”, the TeX engine could have called any number of commands and macros which changed values and variables stored internally by the TeX engine—i.e., made changes to TeX’s “current state”.
The following diagram illustrates an extremely important TeX “quirk”, one which impacts several aspects of TeX-based typesetting. Looking at the right-hand side of the diagram you see a representation of nodes comprising all the content currently stored in memory: the light grey area contains nodes forming the current page and the dark grey area is typeset content destined for the next page. This scenario reflects our paragraph example: the dark grey area represents the “excess paragraph content”: lines of text held back because they don’t fit on the current page.
Recall that once TeX has a “suitably full” page (body) it passes that content to something called an output routine which is a user-defined sequence of commands. Among other things, the output routine adds headers and footers to the page body, finalising the page in readiness for shipping it out to the PDF file.
Our graphic (above) represents the instance TeX has chosen to make a page break at some particular node, such as \baselineskip
glue between typeset lines, and is ready to begin packaging the current page using the output routine—a sequence of built-in commands and user-defined macros. However, in addition to content comprising the current page (stored in memory) TeX has already processed and stored (in memory) additional material, from your .tex
file. That extra material extends beyond the page break and could have included commands which changed important page-related values or variables, affecting TeX’s “current internal state”— which includes values of internal parameters or data stored by macros.
When TeX starts to package the current page, its “current internal state” is not defined by everything typeset up to the page-break location because TeX has already gone past that point in your file and processed additional material. If you consider the location in your file corresponding to where the page break takes place, and the location TeX has actually reached in your .tex
file, the two corresponding internal states of TeX, including stored data and the value of variables, could be very different. The current state of TeX’s typesetting is usually ahead of where the page break occurs; i.e., TeX's typesetting activities are not synchronised with the process of outputting typeset pages via the output routine.
Hypothetical example: how to get the wrong headers
The following diagram illustrates hypothetical commands \myheader
and \myfooter
used to store the desired text of headers and footers; for example, using basic definitions such as
\newtoks\headertoks% a new token list variable for the header text
\newtoks\footertoks% a new token list variable for the footer text
% Use \global to ensure stored header or footer data is
% accessible everywhere, including commands in the
% output routine
\newcommand{\myheader}[1]{\global\headertoks={#1}}
\newcommand{\myfooter}[1]{\global\footertoks={#1}}
in which \headertoks
and \footertoks
are token lists used to store the text of headers and footers.
In addition, our hypothetical example also has an output routine which obtains the header and footer text from the current values of \myheader
and \myfooter
. As shown in the diagram, within the content destined for the current page, \myheader
and \myfooter
set the appropriate (correct) values. However, it would be possible for \myheader
and/or \myfooter
to be called within a paragraph which straddles a page break. Because TeX has to process the entire paragraph, \myheader
and \myfooter
would be called again to reset the header/footer text saved in “TeX’s internal state”, producing values which are not correct for the current page. When the output routine produces the header and footer they will contain text intended for the next page.
TeX’s asynchronous behaviour: \mark
command to the rescue
TeX’s typesetting (content construction) activities are not synchronised with the final process of outputting a typeset page via commands contained in the output routine. When it is time to output a page, the actual internal state of TeX is ahead of any state it might have had at the location of the page break—where it typeset the final piece of content on the current page being output.
In The TeXbook, Donald Knuth, TeX’s creator, describes this situation as
... TeX’s output routine lags behind its page-construction activities
Because of this unsynchronized relationship, “special facilities” in the form of the marks mechanism, applied through the \mark
(or \marks n
) command, are required to ensure headers and footers contain material relevant to the actual page being output. The \mark
command embeds mark nodes into the page content, storing the memory location of content which can be used for the host page’s header and footer.
The author of the well-known and respected book TeX by Topic describes the \mark
mechanism as
... the main mechanism through which the output routine can obtain information about the contents of the currently broken-off page, in particular its top and bottom.
The \mark
command is a mechanism designed to circumvent the asynchronous nature of TeX’s page-breaking and output routine algorithm.
Pre-output checks: looking for mark nodes
After the TeX engine has determined the location of a page break, it calls an internal routine (called fire_up()
) which does a lot of pre-processing prior to the output routine completing page composition and writing the finished page to the PDF file. An important part of those pre-processing steps is to set the value of three global mark variables: \botmark
, \topmark
and \firstmark
which are used to provide data for constructing headers and footers. Of course, a page can contain multiple mark nodes but these are filtered to produce the three mark variables which act as follows:
\botmark
is the mark in effect at the current page break; i.e., the last mark seen on the current page\topmark
is the value of\botmark
from the previous page\firstmark
is the first mark on the current page—the first mark between\topmark
and\botmark
The following schematic shows the basic principles of pre-processing the typeset page content to determine values for the three global mark variables \botmark
, \topmark
and \firstmark
:
The next section uses some of the explanations provided above to outline how LaTeX typesets headers and footers.
When you write \documentclass{class}
where class
might be article
, book
, report
or letter
, LaTeX loads a file named class.cls
; for example, book.cls
, article.cls
and so forth. Those .cls
files contain LaTeX code to implement class-specific variations of various commands and features expected to be present in, and provided by, all document classes—the behaviours shared by all document classes. Examples might include class-specific page layout margins together with class-specific versions of commands, such as \section
, \subsection
and so forth.
Another important element of .cls
files is class-specific implementation of standard page styles which define the headers and footers of documents produced using a particular class and page style. For example:
book.cls
andarticle.cls
each contain implementations of the page stylesheadings
andmyheadings
letter.cls
contains definitions for page stylesheadings
,empty
,plain
and one calledfirstpage
report.cls
contains definitions for the page stylesheadings
andmyheadings
Implementations of page styles often depend on the twoside
option of \documentclass
—whether the document is single- or double-sided—so that headers and footers are defined appropriately for left-facing (even) pages and right-facing (odd) pages.
Document classes may rely on default definitions of the plain
or empty
page styles provided elsewhere in LaTeX—external to the .cls
file being used.
More on page styles
When you change the style of a page using \pagestyle{somestyle}
or \thispagestyle{somestyle}
LaTeX expects to find an internal command named ps@somestyle
—usually provided by the document class .cls
file or perhaps a package such as fancyhdr
. Incidentally, by “internal command” we mean a command that is part of the LaTeX source code and whose name contains an @
symbol, which ordinarily prevents casual use (due to its category code).
The definition of \ps@somestyle
is responsible for implementing the features/behaviours of that page style, which includes providing definitions of:
- commands used during the final stages of page composition (to add headers and footers, see later in the article):
\@oddhead
\@oddfoot
\@evenhead
\@evenfoot
- commands to insert section-related mark data for use in generating document headers and footers which contain section titles, numbers and similar. For example, the
headings
page style (withinbook.cls
) defines the following mark-producing commands:\chaptermark
\sectionmark
We will further explore mark-generating commands, such as \chaptermark
, but just by way of example: when you write \chapter{chapter title}
the \chaptermark
command is also executed to insert chapter-related mark data for subsequent production of page headers.
This section explores some of the core LaTeX commands/processes used to create headers and footers—drawing on explanations or concepts presented earlier in this article.
The content of LaTeX’s (default) headers and footers is based on a two-tier hierarchy of document sections: a “higher level” section containing multiple “lower level” sections. For the book and article classes this translates to:
book
class: “higher level” sections are produced by\chapter
commands and “lower level” sections via\section
, reflecting chapters containing many sections.article
class (assuming two-sided documents): “higher level” sections are produced using\section
commands and “lower level” ones via\subsection
, reflecting multiple subsections appearing within the same section.
LaTeX applies its “model” of headers and footers through its sectioning commands which “inject” mark nodes (via the \mark
command) to store data relevant to the document section being created. For example, each time you write \section{some section title}
a mark node will be created, containing data which reflects some section title
and the section number.
LaTeX uses a system of marks that contain data of the form {left}{right}
, ultimately generated via \mark
commands
\mark{{left}{right}}
encompassed within layers of macros designed to shield users from the lower-level details—which are explored in subsequent sections of this article.
Exploring the book
class
When the book.cls
file is loaded, one of its final actions is to execute \pagestyle{headings}
which sets the default page style to headings
, so we’ll look at that page style in more detail.
As noted above, the features/properties of the headings
page style, as implemented by the book
class, will be defined by the (internal) command \ps@headings
contained in the file book.cls
. The precise definition of \ps@headings
depends on whether the document is single- or double-sided (default for the book
class).
“Mark commands” and “mark data”
For two-sided documents produced by the book
class, the definition of \ps@headings
creates (defines) two “mark commands”: \chaptermark
and \sectionmark
which produce “mark data”, of the form {left}{right}
, for use in headers and footers. Those mark commands reflect LaTeX’s model of headers and footers—based on the hierarchy of document sections:
- the “higher level” section command (here,
\chapter
) is used to provide “mark data” for left-facing (even-numbered) page headers. When you start a new chapter, by writing\chapter{chapter title}
,\chaptermark
is called to create “mark data” which reflects that new chapter—containing itschapter title
and number. - the “lower level” section command (here,
\section
) is used to provide “mark data” for right-facing (odd-numbered) pages. When you write\section{section title}
the\sectionmark
command will be called to create “mark data” which reflects the new section—containing itssection title
and number. Any mark data provided by the previous\chapter
is unaffected by any subsequent \section commands.
\markboth
and \markright
LaTeX’s section-specific mark commands, such as \chaptermark
and \sectionmark
, utilise two further commands called \markboth
and \markright
that provide the actual mark data for headers and footers. \markboth
and/or \markright
can include commands to style header or footer text, such as making it uppercase.
For documents produced using book
class defaults (double-sided, headings
page style), the mark-generating commands work as follows:
\chaptermark
generates mark data using\markboth
\sectionmark
generates mark data\markright
\markboth
and \markright
are macros which, ultimately, use the primitive (built-in, low-level) \mark
command to actually insert marks generated from within sectioning commands.
\markboth
takes the form
\markboth{left}{right}
: inserts a mark (node) using\mark{{left}{right}}
resulting in a mark node containing a pair of braced values{left}{right}
.
\markright
takes the form
\markright{newright}
: inserts a mark (node) using\mark{{currentleft}{newright}}
; i.e., it changes the current value ofright
tonewright
but the current value ofleft
(i.e.,currentleft
) is unchanged, resulting in a mark node containing a pair of braced values{currentleft}{newright}
.
The behaviour of \markboth
and \markright
support the two-tier section hierarchy, such as a document containing multiple sections within each chapter.
By way of examples for the (two-sided) book
document class (using the headings page style):
\chaptermark
uses\markboth
to set:- a
{left}
field which typesets CHAPTER <number>. <chapter title> in uppercase. - a {right} field which is blank (
{}
)
- a
\sectionmark
uses\markright
to set the{right}
mark field to typeset <section number>. <section title>, also in uppercase.
To understand why \sectionmark
uses \markright
we can observe that each new \section
command should:
- insert a new mark containing data for this
\section
(such as its title and number). - but not affect mark data values for the current
\chapter
in which that particular\section
command appears
For these reasons, the \section
command calls \sectionmark
which uses \markright
to create a \section
-related mark: it updates the {right}
mark-data field but does not affect the current {left}
mark-data field value which was set by the current \chapter
.
Note: the LaTeX source code contains the advisory:
The marking commands work reasonably well for right marks ‘numbered within’ left marks—e.g., the left mark is changed by a \chapter command and the right mark is changed by a \section command. However, it does produce somewhat anomalous results if 2 \markboth’s occur on the same page.
Commands for the output routine
The \ps@headings
command implements definitions of the following commands
\@oddhead
\@oddfoot
\@evenhead
\@evenfoot
which are used by the output routine to add headers and footers during the final stage of page composition. For example, book.cls
sets \@oddfoot
and \@evenfoot
to the value \@empty
, which is defined as \def\@empty{}
, thus \ps@headings
produces empty footers on left- and right-facing pages:
\let\@oddfoot\@empty
\let\@evenfoot\@empty
The headers are defined as:
\def\@evenhead{\thepage\hfil\slshape\leftmark}%
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}%
where
\leftmark
extracts the{left}
value from a{left}{right}
mark pair\rightmark
extracts the{right}
value from a{left}{right}
mark pair- \thepage outputs the current page number
In essence, these implementations of \@evenhead
and \@oddhead
produce the following results:
\@evenhead
: the page number appears on the left of the header and the content of\leftmark
, styled with font command\slshape
, is output at the right of the header—the intervening white space is provided by the very flexible\hfil
glue.\@oddhead
: the content of\rightmark
, styled with font command\slshape
, appears at the left of the header and the current page number is output at the right of the header—again, the intervening white space is provided by\hfil
glue.
However, a key question remains: which {left}{right}
mark pair are used by \leftmark
and \rightmark
: in other words, from where do they obtain their mark-data values?
As noted above but explained below, during the final page-composition stages, any marks contained in the document pages are “filtered” and used to set the value of three global mark variables: \botmark
, \topmark
and \firstmark
. Due to the structure of LaTeX’s marks, each of those 3 mark variables will eventually contain a value of {left}{right}
for some pair of values {left}
and {right}
and it is these which provide the actual {left}{right}
mark pair (fields) for \leftmark
and \rightmark
:
\leftmark
extracts theleft
value from the{left}{right}
mark pair (fields) provided by\botmark
\rightmark
extracts theright
value from the{left}{right}
mark pair provided by\firstmark
Note \markboth
and \markright
can contain commands to style the header and footer text—such as conversion to uppercase.
Examples using lower-level LaTeX commands
The following examples demonstrate making changes to page styles or headers and footers by redefining some of the low-level (internal) LaTeX commands discussed in this article (ones which contain the @ symbol). We are not advocating this method for changing headers and footers, but it is available to those who need it (e.g., package authors). The preferred solution to changing headers and footers is using the fancyhdr
package, which is discussed in an Overleaf help article.
Defining a minimal page style
The following example defines a new, extremely minimal, page style called demostyle
which uses static text to define the headers and footers and does not rely on sectioning commands (\chapter
, \section
etc) to set the header and footer content.
The example starts by changing the category code of the @
character to 11 so that it can be used within macro names. The \ps@demostyle
command implements our minimal page style by redefining the commands used (in the output routine) to produce the headers and footers: \@oddhead
, \@oddfoot
, \@evenhead
and \@evenfoot
. Note the twoside
option in our \documentclass
declaration—which uses the article
class.
\documentclass[twoside]{article}
\catcode`@=11
\newcommand{\ps@demostyle}{%
\renewcommand\@oddfoot{\hfil The odd-page footer\hfil}%
\renewcommand\@evenfoot{\hfil The even-page footer\hfil}%
\renewcommand\@evenhead{\thepage\hfil The even-page header}%
\renewcommand\@oddhead{The odd-page header\hfil\thepage}}
\catcode`@=12
\title{Demonstrating a page style}
\author{Overleaf}
\date{August 2022}
\begin{document}
\pagestyle{demostyle}
\maketitle
\newpage
\section{Introduction}
\newpage
\section{More material}
\end{document}
Changing headers for the book class
The following example changes the headers for the book class by redefining \@oddhead
and \@evenhead
so that left- and right-facing page headers contain the current page number and chapter title. Note how the second \chapter
command uses the optional short-form chapter title [The short title]
which now provides the header text, instead of the long title.
\section
commands have no effect on header content because our header redefinitions use only \leftmark
which obtains details of the current chapter. To access details of the current section we’d need to use \rightmark
in the definition of \@oddhead
and/or \evenhead
.
\documentclass{book}
% NB: category code of '@' temporarily changed to 11
% to enable its use in command names
\catcode `@=11
% Let \@oddfoot and \evenfoot be equivalent to \@empty
% to make them blank (empty)
\let\@oddfoot\empty\let\evenfoot\empty
% Redefine \@oddhead and \@evenhead
\renewcommand{\@oddhead}{\leftmark\hfil\thepage}
\renewcommand{\@evenhead}{\thepage\hfil\leftmark}
\catcode `@=12
% Use a conveniently small page size
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Memoirs of a \TeX{} user}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
This is frontmatter which uses Roman numerals.
\mainmatter
\chapter{Where do I start?}
Chapter 1: A short chapter.
\newpage
\section{In the beginning...}
A section.
\chapter[The short title]{A chapter with a very long title, making it unsuitable for headers}
\newpage
\section{Another section}
With little content.
\newpage
\section{What, another section?}
Also with little content.
\end{document}
Using ε-TeX’s extended marks commands
The book
class uses the following definitions of \@evenhead
and \@oddhead
to produce headers:
\def\@evenhead{\thepage\hfil\slshape\leftmark}
\def\@oddhead{{\slshape\rightmark}\hfil\thepage}
where the commands \leftmark
and \rightmark
are defined as
\def\leftmark{\expandafter\@leftmark\botmark\@empty\@empty}
\def\rightmark{\expandafter\@rightmark\firstmark\@empty\@empty}
Using ε-TeX’s extended commands, and the equivalence between ε-TeX’s mark class 0 and the original TeX commands, we can:
- rewrite
\leftmark
to replace\botmark
with ε-TeX’s\botmarks0
equivalent, and - rewrite
\rightmark
to replace\firstmark
with ε-TeX’s\firstmarks0
equivalent
These redefinitions produce
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
Note the use of \relax
to terminate TeX’s hunt for further digits—you can also replace \relax
with a space to act as the terminator.
The following example produces output which is identical to the original definitions of \leftmark
and \rightmark
.
\documentclass{book}
% Redefine \leftmark and \rightmark to use
% \botmarks0 and \firstmarks0 respectively
% NB: category code of '@' temporarily changed to 11
% to enable its use in command names
\catcode `@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks0\relax\@empty\@empty}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks0\relax\@empty\@empty}
\catcode `@=12
% Use a conveniently small page size
\usepackage[paperheight=16cm,paperwidth=12cm,textwidth=10cm]{geometry}
\title{Memoirs of a \TeX{} user}
\author{Overleaf}
\begin{document}
\frontmatter
\maketitle
This is frontmatter which uses Roman numerals.
\mainmatter
\chapter{Where do I start?}
Chapter 1: A short chapter.
\newpage
\section{In the beginning...}
A section.
\newpage
Another section.
\end{document}
Notes on ε-TeX
As we noted above, ε-TeX introduces the \marks
command:
\marks n {stuff to store}
which extends the original \mark
feature of Knuth’s TeX engine and is available in all three mainstream TeX engines: pdfTeX, LuaTeX and XeTeX.
ε-TeX’s implementation also introduces new global mark variables \firstmarks n
, \botmarks n
and \topmarks n
: one for each class n
. These class-based mark variables are determined using the mechanisms outlined above, and can all be used in the production of headers and footers.
You can use any of the \(2^{15}\) = 32768 mark classes, ranging from 0 to 32767, within redefinitions of \leftmark
or \rightmark
. That assumes you have provided (inserted) suitable mark data for your chosen mark class, n
, via \marks n{{left}{right}}
.
Note that LuaTeX provides \(2^{16}\) = 65536 mark classes, with n
ranging from 0 to 65535.
Example using marks class 10
This example demonstrates using mark class 10 (chosen randomly) to create document headers. The sample document typesets 6 pages which contain the sequence of marks presented in the worked example at the end of this article. A study of that example will show why the TeX engine has selected a particular mark, \(\alpha\), \(\beta\), \(\gamma\) and \(\delta\), for use in each of the headers.
We start by defining a convenience macro, \domark
, which uses \marks 10
to insert mark data that follows the LaTeX {left}{right}
convention:
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
Marks of class 10 are made accessible to LaTeX's header and footer mechanism by redefining \leftmark
and \rightmark
—with a bit of extra info added in:
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (via \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (via \texttt{\string\firstmarks10})}
After inserting a number of (class 10) marks, the TeX engine (here, pdfTeX) obligingly creates global mark variables for class 10—\botmarks10
, \topmarks10
and \firstsmarks10
which \leftmark
and \rightmark
use to produce the headers.
\documentclass{book}
% A short command to use marks with class 10
% and following LaTeX's mark structure {left}{right}
\newcommand{\domark}[2]{\marks 10{{#1}{#2}}}
% Redefine \leftmark and \rightmark to use
% \botmarks10 and \firstmarks10 respectively
\catcode`@=11
\renewcommand{\leftmark}{\expandafter\@leftmark\botmarks10 \@empty\@empty{} (via \texttt{\string\botmarks10})}
\renewcommand{\rightmark}{\expandafter\@rightmark\firstmarks10 \@empty\@empty{} (via \texttt{\string\firstmarks10})}
\catcode`@=12
\title{Demonstrating \(\varepsilon\)-\TeX’s enhanced marks}
\author{Overleaf}
\date{August 2022}
\begin{document}
Page 1: No marks added so all mark variables remain in their initialized state: empty (NULL).
\newpage
Page 2: $\alpha$-mark added to this page via
\verb|\domark{$\alpha$-left}{$\alpha$-right}|\domark{$\alpha$-left}{$\alpha$-right}
\newpage
Page 3: No new marks added to this page.
\newpage
Page 4: $\beta$-mark followed by $\gamma$-mark added to this page via
\verb|\domark{$\beta$-left}{$\beta$-right}|
\verb|\domark{$\gamma$-left}{$\gamma$-right}|.
\domark{$\beta$-left}{$\beta$-right}
\domark{$\gamma$-left}{$\gamma$-right}
\newpage
Page 5: $\delta$-mark added to this page via
\verb|\domark{$\delta$-left}{$\delta$-right}|
\domark{$\delta$-left}{$\delta$-right}
\newpage
Page 6: No marks added to this page.
\end{document}
The following graphic shows the headers produced by this example:
- Note: The header on page 1 is created at a time when all three mark variables for class 10—
\botmarks10
,\topmarks10
and\firstsmarks10
—are empty. The end result is that\rightmark
(for page 1) inserts just the last header fragment:(via \texttt{\string\firstmarks10})
, as shown in the graphic above.
A worked example to show how TeX engines determine values for \botmark
, \topmark
and \firstmark
It feels appropriate to replicate Knuth’s use of double dangerous-bend signs (image courtesy of this website) because the material is somewhat low-level and “peeks under the hood”—although we hope it may be of interest to intrepid readers wishing to understand a few more details.
The following discussion is closely based on the last example on page 258 of The TeXbook. Here, we have edited and re-typeset that example for those without access to The TeXbook:
The table presented in this graphic is reproduced from one provided by Knuth but, like the original, there is no explanation of how it was derived. Here we’ll address that to provide additional details which show how those values of \botmark
, \topmark
and \firstmark
were determined—obtaining these details required exploring the source code of a TeX engine!
The process of setting values for \botmark
, \topmark
and \firstmark
can be summarised in 3 short pseudocode fragments as shown in the following diagram and subsequent explanations:
- Pre-content check
- Content loop
- Post-content check
Note:
- The tests in step 1 “Pre-content check” and step 3 “Post-content check” are performed once per page.
- Step 2 “Content loop” involves TeX scanning through the page content searching for mark nodes, and using them to set the mark-variable values as shown.
Each time TeX finds a suitable page break it sends the content of that page for final processing, performing these (three) mark-processing steps for every page in your document. The processing steps labelled 1, 2 and 3 are referenced in the final diagram within this section.
Note that:
- before the first page has been processed, all three global mark variables
\botmark
,\topmark
and\firstmark
have been initialised to be empty (NULL). - the final values of
\botmark
,\topmark
and\firstmark
determined at the end of the previous page become the (input) values for processing the current page—the one being processed.
The following code fragments are pseudocode derived (summarized) from actual TeX engine source code. The goal is to provide a concise code summary that helps to demonstrate the key principles involved.
Step 1: Pre-content check
Before TeX looks through the actual content of the current page, it checks if the current \botmark
value—i.e., resulting from the previous page—is empty (NULL):
if(\botmark != NULL)
{
\topmark = \botmark;
\firstmark= NULL;
}
In this test, if \botmark
(from the previous page) is not empty:
\topmark
for the current page is set to the previous page’s\botmark
value\firstmark
, for the current page (being processed), is set to empty (NULL): start this page assuming there are no\mark
nodes.
Note that this test is performed once for each page being processed.
Step 2: Content loop
Next, TeX loops over the page content; part of that loop includes looking for \mark
nodes:
if(type(node)==mark_node)
{
if(\firstmark==NULL)
{
\firstmark=node(text);
}
\botmark= node(text);
}
This test is applied to every mark node located within (contained in) the current page. The previous test (Step 1, above) could have set \firstmark
to empty so the very first mark found in the current page becomes the value of \firstmark
and \botmark
. Any subsequent \mark
node detected whilst executing this loop will not change the value of \firstmark
, because it is no longer empty (NULL), but \botmark
is updated—because that is the purpose of \botmark
: to store the last seen \mark
node for this page.
Step 3: Post-content check Once it has looped over the page content TeX applies the following, final, test which is also performed once per page:
if((\topmark != NULL)&&(\firstmark==NULL))
{
\firstmark= \topmark;
}
- If
\topmark
is not empty (NULL) we know, from Step 1, that\botmark
for the previous page was not empty (NULL). - If
\firstmark
is still empty then we haven’t seen any\mark
nodes because the test in Step 2 wasn’t triggered; consequently,\firstmark
is set to the value of\topmark
which is also the value of\botmark
from the previous page.
After sequential application of these three steps for all 6 pages of our example, the values of \botmark
, \topmark
and \firstmark
are derived using transitions shown in the diagram below where:
- light blue rounded rectangles are the final mark variable values for each page
- light grey rounded squares represent interim values that arise during processing
- labelled arrows represent changes in marker variable values according to steps 1, 2 or 3 in the diagram above—or a value has not been changed by any of the steps; labelled “no change”.
The following diagram shows how the three fragments of pseudocode generate the final values of \botmark
, \topmark
and \firstmark
listed in the table contained on page 258 of The TeXbook.
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