Glossaries & nomenclature

Every style guide carries the same line: spell an abbreviation out the first time it appears, and use the short form thereafter. By hand it is close to unkeepable. Move one section and “the first time” moves with it; miss the one place that mattered and a reviewer will find it. LaTeX’s glossaries package, and its successor glossaries-extra, hand that rule to the machine. Define each term or abbreviation once in the preamble, then write \gls{key} in the body: the first use expands itself, and as a by-product only the terms you actually used turn up, sorted, in the glossary at the back. This page follows the whole path — defining entries, \newacronym, running makeglossaries, \printglossary — and clears out the four ways a glossary comes out blank, three of which do not even produce a warning.

Define once, call anywhere: newglossaryentry and gls

Write \newglossaryentry{key}{name=..., description=...} in the preamble and call it with \gls{key} in the body. The first argument, key, is a label you invent; name is what gets printed and description is the explanation that will stand in the glossary. The point worth holding on to is that \gls does two jobs at once — it inserts the name where you wrote it, and it writes a record to an auxiliary file saying that this term belongs in the glossary. Consequently a term you defined but never called with \gls does not appear at all. Listing only the terms you used is the design, not a defect.

The variants differ only in the opening letters of the command. At the start of a sentence use \Gls{key}; for a plural, \glspl{key}; for both, \Glspl{key}. The plural generated automatically is just name plus an “s”, so an irregular form such as matrices has to be spelled out with the plural key. When the form used in running text should differ from the display name, set text; put an associated symbol in the symbol key and call it with \glssymbol{key}; insert the explanation alone with \glsdesc{key}. If a description is long enough to span paragraphs, use \longnewglossaryentry. And calling a key that does not exist stops the run with ! Package glossaries Error: Glossary entry ... has not been defined. — being loud about a typo is a virtue here.

latex
\usepackage{glossaries}
\makeglossaries              % opens the glossary files -- required

\newglossaryentry{set}{%
  name={set},
  description={a collection of distinct objects}%
}
\newglossaryentry{matrix}{%
  name={matrix},
  plural={matrices},      % irregular plural, spelled out
  description={a rectangular array of numbers}%
}

\begin{document}
\Gls{set} theory studies a \gls{set}; linear algebra studies \glspl{matrix}.
\printglossaries
\end{document}
CommandOutputUse
\gls{set}setthe ordinary reference; this is also what records the term
\Gls{set}Setcapitalise the first letter at the start of a sentence
\glspl{matrix}matricesplural; name plus s by default, overridden by the plural key
\Glspl{matrix}Matricesplural with a leading capital
\glsdesc{set}a collection of distinct objectsinsert the description field on its own
\glssymbol{sigma}σcall the symbol stored in the symbol key

Handing abbreviations to the machine: newacronym and first-use expansion

Define it with \newacronym{key}{short}{long} and then just write \gls{key}. short is the abbreviation, say SVM, and long the full form, support vector machine. Write the same \gls{svm} twice and the output reads “support vector machine (SVM)” the first time and “SVM” every time after. This is the point where the machine takes over the rule no author keeps by hand: the first-use flag is tracked per entry and in the order things are processed, so when you move a section the expansion moves with it. Rearrange the manuscript and nothing contradicts itself.

When you want a term spelled out again from some point on — a chapter meant to stand alone, say — use \glsreset{key}, or \glsresetall for every entry at once. To collect the abbreviations into a list of their own, load the package as \usepackage[acronym]{glossaries}: you then have two independent lists, a glossary and a list of acronyms, each with its own set of auxiliary files. And when glossaries-extra is also loaded, \newacronym becomes an alias for \newabbreviation with category=acronym — so if you are starting fresh, writing \newabbreviation directly gives you the full range of abbreviation styles straight away.

latex
\usepackage[acronym]{glossaries}   % a second, separate list
\makeglossaries

\newacronym{svm}{SVM}{support vector machine}

\begin{document}
\gls{svm} is a classifier.   % -> support vector machine (SVM)
Another \gls{svm} follows.   % -> SVM

\glsreset{svm}               % start a chapter that must stand alone
\gls{svm} again in full.     % -> support vector machine (SVM)

\printglossary[type=main,title={Glossary}]
\printglossary[type=\acronymtype,title={Acronyms}]
\end{document}

The build: makeglossaries turns .glo into .gls

LaTeX only records the terms; it neither sorts nor formats them. On the first run \makeglossaries emits an .ist file — the style file holding the sorting rules — and every term reached by \gls accumulates in the .glo. Insert the external program makeglossaries at this point and it shows you its hand: it prints makeindex -s mydoc.ist -t mydoc.glg -o mydoc.gls mydoc.glo. It is the very same makeindex that builds an index. Once the sorted .gls exists, run LaTeX once more to read it in.

terminal
pdflatex mydoc       # writes mydoc.glo (and mydoc.ist)
makeglossaries mydoc # sorts it: no file extension here
pdflatex mydoc       # reads mydoc.gls, prints the glossary

# what makeglossaries actually runs, once per glossary type:
#   makeindex -s mydoc.ist -t mydoc.glg -o mydoc.gls mydoc.glo
#   makeindex -s mydoc.ist -t mydoc.alg -o mydoc.acr mydoc.acn

Two glossaries mean two sets of files. The default glossary runs .glo to .gls with a .glg transcript; add the acronym option and the list of acronyms uses .acn to .acr with .alg, and makeglossaries calls makeindex twice. Knowing how many lists exist and running the tool exactly that many times is precisely why you interpose makeglossaries instead of typing makeindex yourself. The script is written in Perl, so where Perl is missing — a common situation on Windows — call makeglossaries-lite instead: the same job, implemented as makeglossaries-lite.lua and run by texlua.

When the glossary comes out blank: four causes, three of them silent

The commonest cause is forgetting to run makeglossaries, and this failure gives you almost nothing to go on. With no .gls the glossary does not appear at all, heading included — you do not get an empty frame, you get nothing set on the page. No error, no warning, just one line buried in the log reading No file mydoc.gls. It is exactly the trap of forgetting makeindex for an index, and it is well disguised: \gls itself expands correctly from the very first run, so as long as you are only looking at the PDF body, everything appears to be working.

  • makeglossaries was never run. No .gls, so the glossary and its heading are both absent. No warning; the log holds only No file mydoc.gls.
  • \makeglossaries is missing from the preamble. The output file is never opened, so not even a .glo is created and again nothing is printed. No warning.
  • A term was defined but never called with \gls. Unused entries are not recorded, so they are not listed. That is by design — mention a term at least once in the body if you want it in the glossary.
  • The one mistake that is actually reported is the opposite one. With \makeglossaries present but \printglossary forgotten you get Package glossaries Warning: No \printglossary or \printglossaries found. (Remove \makeglossaries if you dont want any glossaries.) This document will not have a glossary.

One more combination fails without a word. If you use hyperref, load glossaries after hyperref — one of the few exceptions to the standard advice that hyperref goes last. The package’s own beginners’ guide says so explicitly, and getting the order wrong produces no warning at all: the links and page numbers inside the glossary simply break, quietly. Order the two like this.

latex
\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}   % after hyperref, not before
\makeglossaries

% put the glossary into the table of contents as well:
% \usepackage[toc]{glossaries}

Printing it: title, type and getting into the contents with printglossary

\printglossaries emits every list you have set up; \printglossary emits one. Which you want depends on whether you need options: to give each list its own title or style, pass them, as in \printglossary[type=main, title={Glossary}]; otherwise the single line \printglossaries is enough. The heading word itself lives in \glossaryname and can be replaced with \renewcommand.

Those headings are unnumbered, so by default they do not reach the table of contents. Loading the package as \usepackage[toc]{glossaries} puts them there automatically, which is more reliable than lining up an \addcontentsline for each glossary. The look itself is switched with \setglossarystyle{...}: list (the default) is built on a description environment, altlist puts the term on a line of its own and indents the explanation beneath it, and the long family sets the whole thing as a table. The longer your descriptions, the more altlist and the long styles repay themselves in readability.

The modern setup: glossaries-extra and bib2gls

The first release of glossaries is dated 16 May 2007; Nicola Talbot published it as the successor to the older glossary package. The same author went on to release glossaries-extra in 2015 and bib2gls in 2017. The combination borrows its idea wholesale from bibliography management: you keep your terms in a .bib file, and bib2gls picks out only the ones actually used in the body, sorts them, and pulls them in — the same role biber plays for cited works. Selection and sorting, which used to belong to makeindex or xindy, are handled by a single program.

The key is the record option. Loading \usepackage[record]{glossaries-extra} switches off indexing through makeindex or xindy and instead writes lines such as \glsxtr@record{set}{}{page}{glsnumberformat}{1} into the .aux. bib2gls reads those and writes just the entries you need back into a .glstex. Because of this design, it is normal for nothing to be defined yet on the first run — which is why glossaries-extra downgrades an undefined entry from an error to a warning. A column of Package glossaries-extra Warning: Glossary entry ... has not been defined on pass one is expected. Plain glossaries halts the run in the same situation, and both choices are coherent with their designs.

terms.bib
@entry{set,
  name = {set},
  description = {a collection of distinct objects}
}

@abbreviation{svm,
  short = {SVM},
  long  = {support vector machine}
}

@symbol{sigma,
  name = {\ensuremath{\sigma}},
  description = {standard deviation}
}
latex
\usepackage[record]{glossaries-extra}
\GlsXtrLoadResources[src={terms}]   % terms.bib, without the extension

\begin{document}
\gls{set} and \gls{svm} are used here.
\printunsrtglossary                 % already sorted by bib2gls
\end{document}

What you write in the document barely changes. Load the .bib with \GlsXtrLoadResources[src={terms}]src is the filename without its extension — and go on using \gls{set}. What differs is the printing command: since bib2gls has already done the sorting, you use \printunsrtglossary (unsrt for unsorted, meaning “emit them as they stand”). In the build you call bib2gls in place of makeglossaries; --group adds letter-group headings, and pdflatex may be replaced by xelatex or lualatex. There is one setup caveat: bib2gls is written in Java and therefore needs a Java runtime, at least Java 8. The TeX Live command is a shell script that launches a .jar, so on a machine without Java you find out the moment you run it.

terminal
pdflatex mydoc
bib2gls --group mydoc   # reads mydoc.aux, writes mydoc.glstex
pdflatex mydoc

A list of symbols and nothing else: nomencl

For a table of symbols at the front of a paper you could use glossaries, but the lightweight nomencl gets there with fewer moving parts. Put \usepackage{nomencl} and \makenomenclature in the preamble, mark each symbol where it first appears with \nomenclature{$g$}{gravitational acceleration}, and write \printnomenclature wherever the list belongs. Symbols are mathematics, so wrap them in $...$. The build borrows makeindex again: \makenomenclature produces a .nlo, the bundled style nomencl.ist sorts it into a .nls, and one more LaTeX run reads that in.

terminal
pdflatex mydoc
makeindex mydoc.nlo -s nomencl.ist -o mydoc.nls
pdflatex mydoc

What the sorting works on is the symbol’s input, character for character. Write $\sigma$ and the sort key is the string $\sigma$, in which the dollar and the backslash come before every letter of the alphabet. Try it and σ lands ahead of g and m. Hence the optional argument, which supplies a sort key of your own: in \nomenclature[g-sigma]{$\sigma$}{...} it is g-sigma that gets sorted while the symbol itself is what prints. While you are there, end the line just before a \nomenclature with %: a stray space around the symbol throws the sorting off.

latex
\usepackage{nomencl}
\makenomenclature
\renewcommand{\nomname}{List of Symbols}
% \usepackage[intoc]{nomencl}  % also list it in the contents

\begin{document}
Let $g$ be gravity.%
\nomenclature{$g$}{gravitational acceleration}%
A mass $m$ feels $F = mg$.%
\nomenclature{$m$}{mass of the object}%
\nomenclature[g-sigma]{$\sigma$}{stress}% sort key, not the symbol

\printnomenclature
\end{document}

The heading defaults to the English “Nomenclature” and is replaced with \renewcommand{\nomname}{...}. To list it in the table of contents, load \usepackage[intoc]{nomencl}. Options can annotate each entry automatically as well: refpage appends “, page n” and refeq appends “, see equation (n)”. And when you want physical constants separated from variables, redefining \nomgroup around the leading character of the sort key you have just met splits the list into sub-groups with headings of their own.

  • For a glossary of terms and abbreviations, use glossaries. First-use expansion, plurals and capitalisation are all taken care of.
  • Starting fresh? Use glossaries-extra with bib2gls. Keep the terms in a .bib and let \printunsrtglossary emit the ones you used — just confirm that Java is available.
  • For a list of mathematical symbols alone, use nomencl. Mark with \nomenclature, run makeindex once, and you are done.
  • All of them need an extra pass. Insert the external program (makeglossaries / bib2gls / makeindex) and run LaTeX again. Forget it and nothing will scold you.