Get Started with Glossaries.jl
Ronny Bergmann 2025-12-26
This tutorial provides a short introduction to using the package Glossaries.jl for managing either a small own glossary or a glossary for a certain package.
Introduction
A Glossary is, according to Wikipedia, a list of Terms in some domain knowledge. The goal of this package is to easily define such glossaries but also to format or print certain terms or lists of terms.
As a guiding example, consider the usual set of variables that appear in signatures of a package. In a documentation we would hence often repeat variable names, their types, maybe their default values, or their short description in a list of arguments or keywords.
As a remedy one can define a glossary of common variables, but also terms, short definitions or remarks, that can then be reused.
Starting a new Glossary
To start a new glossary, you first need to create a Glossary object. This can be done by simply calling the constructor:
using Glossaries
g = Glossaries.Glossary()An Empty GlossaryWhen working with just one Glossary, one can also use @Glossary, which creates a current_glossary in the current module. Each Term within a Glossary consists of a list of properties. There are either Strings or functions returning strings to allow for a certain amount of parametrization. Terms within a Glossary are stored at a certain symbol.
For our example, consider we have a recurring variable named duck of type AbstractDuck.
We enter this for example as
Glossaries.define!(g, :duck, :name, "duck")
Glossaries.define!(g, :duck, :type, "AbstractDuck")
Glossaries.define!(g, :duck, :description, "A yellow duck")
Glossaries.define!(g, :duck, :default, "`[`YellowDuck`](@ref)`()")Glossary with 1 terms:
* :duck Term “duck”
- :default `[`YellowDuck`](@ref)`()
- :type AbstractDuck
- :name duck
- :description A yellow duckNote that since the type and the default are considered to be typeset in code, we have to start the default with ending a code block before adding the @ref markdown link.
Again, you can also use @define!(:duck, ...) to add entries to the glossary of the current module.
We can also create a Term manually and add it to g afterwards. Since the name is a usual property, providing a string, sets the :name property.
t = Glossaries.Term("habitat")
t[:type] = "AbstractHabitat"
t[:description] = (var="duck") -> "A habitat of a `$var`"
t[:default] = "Lake()""Lake()"As already mentioned, entries can also be functions. Here the description can be used to also specify that the habitat variable might refer to another arguments habitat than that of the duck.
and we can add the term to the glossary either also by using g[:habitat] = t or with
Glossaries.define!(g, :habitat, t)Glossary with 2 terms:
* :habitat Term “habitat”
- :default Lake()
- :type AbstractHabitat
- :name habitat
- :description A habitat of a `duck`
* :duck Term “duck”
- :default `[`YellowDuck`](@ref)`()
- :type AbstractDuck
- :name duck
- :description A yellow duckUsing a Glossary
If we now have a function to check whether a certain duck fits into a habitat, e.g. fits(duck, habitat), we can use a TermFormatter to generate its argument list.
_arg = Glossaries.Argument()
_arg(g, [:duck, :habitat]) |> print- `duck::AbstractDuck`: A yellow duck
- `habitat::AbstractHabitat`: A habitat of a `duck`Again, using @Argument allows to omit the first parameter, since that formatter would use the glossary of the current module.
Similarly if we want to generate that for a function something(; kwargs...) where both are keyword arguments. We get using Keyword
_kw = Glossaries.Keyword()
_kw(g, [:duck, :habitat]) |> print- `duck::AbstractDuck = `[`YellowDuck`](@ref)`()`: A yellow duck
- `habitat::AbstractHabitat = Lake()`: A habitat of a `duck`note that in this format, the default is printed as well. Still, in both cases the information throughout multiple documentation strings is not only consistent, but if we had a typo, there is a single place to fix this, namely where we define the glossary terms.