Gallery: glossaries performance

Documents that use the glossaries package can take a long time to build. This page compares the performance of the various methods that can be used with just the base glossaries package and with the extension package glossaries-extra.

If you’re wondering what kind of document would require over 1,000 entries, the bib2gls user manual has over 4,500 entries. The user manual for glossaries-extra v1.49 has over 2,600 entries. Each command and option described in those documents is a glossary entry. If you click on a command it will take you to the relevant place in the document where that command is defined (a “standalone” definition), but you can also look up the command’s summary and syntax in the list in the back matter for a quick reminder or look up the location list in the index (glossaries). Similarly for the options.

The tests described here were compiled with glossaries.sty v4.49, glossaries-extra.sty v1.48 and bib2gls v3.0 (pending at the time of writing). Some of the examples may not work with earlier versions.

The test files were generated using Perl scripts. The first, mkentries, writes n instances of \newglossaryentry{entryidx}{name={word,description={sample idx}}} to STDOUT, where idx is an integer (0 to n−1) and word is a randomly generated word.

#!/usr/bin/perl -w

use strict;
use warnings;
use Data::Random::WordList;
use List::Util qw/shuffle/;

if ($#ARGV != 0) { die "Syntax:$0 <number>\n";
}

my $count =$ARGV[0];

my $wl = new Data::Random::WordList( wordlist => '/usr/share/dict/words'); my @rand_words = shuffle($wl->get_words($count));$wl->close();

for (my $idx = 0;$idx < $count;$idx++)
{
my $word =$rand_words[$idx];$word=~s/([\\\&#%_\{\}\$])/\\$1/g;

$word=~s/\^/\\textasciicircum /g;$word=~s/\^/\\textasciitilde /g;

print "\\newglossaryentry{entry$idx}{name={$word},description={sample $idx}}\n"; } 1; The test file entries-1000.tex was generated using: mkentries 1000 > entries-1000.tex The first five lines are: \newglossaryentry{entry0}{name={silverback},description={sample 0}} \newglossaryentry{entry1}{name={urbaneness},description={sample 1}} \newglossaryentry{entry2}{name={twice-taken},description={sample 2}} \newglossaryentry{entry3}{name={exoskeletal},description={sample 3}} \newglossaryentry{entry4}{name={Dorsy},description={sample 4}} There are three entries that start with a hyphen (which can be found with grep 'name={-' entries-1000.tex): \newglossaryentry{entry447}{name={-hippus},description={sample 447}} \newglossaryentry{entry606}{name={-el},description={sample 606}} \newglossaryentry{entry730}{name={-fuge},description={sample 730}} The file only contains ASCII characters. This was converted to .bib format for the bib2gls tests using: convertgls2bib entries-1000.tex entries-1000.bib The file entries-1000.bib starts with: % Encoding: UTF-8 @entry{entry0, name = {silverback}, description = {sample 0} } @entry{entry1, name = {urbaneness}, description = {sample 1} } @entry{entry2, name = {twice-taken}, description = {sample 2} } @entry{entry3, name = {exoskeletal}, description = {sample 3} } @entry{entry4, name = {Dorsy}, description = {sample 4} } The encoding line identifies the file as UTF-8, although it only contains ASCII characters. (This isn’t a problem as ASCII is a subset of Unicode.) There’s a similar Perl script, mkabbreviations, to create random abbreviations: #!/usr/bin/perl -w use strict; use warnings; use Data::Random::WordList; use List::Util qw/shuffle/; if ($#ARGV != 0)
{
die "Syntax: $0 <number>\n"; } my$count = $ARGV[0]; my$wl = new Data::Random::WordList( wordlist => '/usr/share/dict/words');

my @rand_words = shuffle($wl->get_words(3*$count));

$wl->close(); my$wordidx = 0;

for (my $idx = 0;$idx < $count;$idx++)
{
my $word1 =$rand_words[$wordidx++]; my$word2 = $rand_words[$wordidx++];
my $word3 =$rand_words[$wordidx++]; my$word = "$word1$word2 $word3"; my$abbreviation = uc(substr $word1, 0, 1).uc(substr$word2, 0, 1).uc(substr $word3, 0, 1);$word=~s/([\\\&#%_\{\}\$])/\\$1/g;
$abbreviation=~s/([\\\&#%_\{\}\$])/\\$1/g;$word=~s/\^/\\textasciicircum /g;
$abbreviation=~s/\^/\\textasciicircum /g;$word=~s/\^/\\textasciitilde /g;
$abbreviation=~s/\^/\\textasciitilde /g; print "\\newacronym{abbrv$idx}{$abbreviation}{$word}\n";
}

1;

The file acronyms-1000.tex was created using:

./mkabbreviations 1000 > acronyms-1000.tex

The file starts:

\newacronym{abbrv0}{CMO}{Cuyab mercurialism oversaturates}
\newacronym{abbrv1}{BAJ}{bemoaningly aburban jackassism}
\newacronym{abbrv2}{RHS}{rend horsts stormward}
\newacronym{abbrv3}{IFS}{intercommon foliocellosis scription}
\newacronym{abbrv4}{OCP}{otter Celanese powderize}

The file abbreviations-1000.tex is a copy of acronyms-1000.tex with \newacronym replaced with \newabbreviation. The file starts:

\newabbreviation{abbrv0}{CMO}{Cuyab mercurialism oversaturates}
\newabbreviation{abbrv1}{BAJ}{bemoaningly aburban jackassism}
\newabbreviation{abbrv2}{RHS}{rend horsts stormward}
\newabbreviation{abbrv3}{IFS}{intercommon foliocellosis scription}
\newabbreviation{abbrv4}{OCP}{otter Celanese powderize}

The file abbreviations-1000.tex was converted to abbreviations-1000.bib using:

convertgls2bib abbreviations-1000.tex abbreviations-1000.bib

The first few entries are:

% Encoding: UTF-8
@abbreviation{abbrv0,
short = {CMO},
long = {Cuyab mercurialism oversaturates}
}

@abbreviation{abbrv1,
short = {BAJ},
long = {bemoaningly aburban jackassism}
}

@abbreviation{abbrv2,
short = {RHS},
long = {rend horsts stormward}
}

@abbreviation{abbrv3,
short = {IFS},
long = {intercommon foliocellosis scription}
}

@abbreviation{abbrv4,
short = {OCP},
long = {otter Celanese powderize}
}

To test UTF-8 support, entries-1000.tex was copied and the first few entries were changed to words starting with UTF-8 characters. This file was saved as entries-utf8-1000.tex. The first few lines are:

\newglossaryentry{entry0}{name={Øresund},description={sample 0}}
\newglossaryentry{entry1}{name={Þríhyrningsvatn},description={sample 1}}
\newglossaryentry{entry2}{name={Ängelholm},description={sample 2}}
\newglossaryentry{entry3}{name={ætherial},description={sample 3}}
\newglossaryentry{entry4}{name={œsophagus},description={sample 4}}
\newglossaryentry{entry5}{name={Łobez},description={sample 5}}
\newglossaryentry{entry6}{name={Ćmielów},description={sample 6}}
\newglossaryentry{entry7}{name={Żelechów},description={sample 7}}
\newglossaryentry{entry8}{name={Ångström},description={sample 8}}

The remaining lines are unchanged. This file was converted to entries-utf8-1000.bib using:

convertgls2bib entries-utf8-1000.tex entries-utf8-1000.bib

For the symbol examples, the file greek.tex contains Greek symbols defined (indirectly) with \newglossaryentry. The first few lines provide some commands definitions:

\providecommand{\Beta}{B}
\providecommand{\Digamma}{F}
\providecommand{\Eta}{H}
\providecommand{\omicron}{o}
\providecommand{\Omicron}{O}
\providecommand{\Kappa}{K}
\providecommand{\mtx}[1]{\mathbf{#1}}

This provides math-greek commands missing from the LaTeX kernel (\Beta, \Omicron, etc) and also a semantic command to format symbols representing matrices (\mtx). You may prefer different definitions for these commands, such as

\providecommand{\Kappa}{\mathrm{K}}
\providecommand{\mtx}[1]{\pmb{#1}}

Such minor font modifications are irrelevant to the tests performed here (as long as the changes are within these custom commands and aren’t added to the name field). The glossaries-extra-bib2gls package (provided with glossaries-extra v1.27+ and automatically loaded by the record option) provides the missing math-greek commands using \providecommand, so those definitions can be used instead if that package has been loaded.

There’s also a convenient command \newsymbol{label}{symbol}{description}{topic} used to define each symbol.

\providecommand{\newsymbol}[4]{%
\newglossaryentry{#1}{name={#2},description={#3},user1={#4}}%
}

For example:

\newsymbol{alpha}{\ensuremath{\alpha}}{angular acceleration}{physics}

\newsymbol{beta}{\ensuremath{\beta}}{thermodynamic beta}{statistical mechanics}

\newsymbol{Beta}{\ensuremath{\Beta(x,y)}}{Euler beta function}{functions}

The \sortart command, defined as

\providecommand{\sortart}[2]{#1 #2}

is used in descriptions that start with an article (‘the’, ‘a’, ‘an’). For example:

\newsymbol{lambda}{\ensuremath{\lambda}}{\sortart{an}{eigenvalue}}{linear algebra}

The equivalent bib2gls file can be obtained using:

convertgls2bib greek.tex greek.bib

This creates the file greek.bib containing @entry definitions (convertgls2bib is able to parse the provided definition of \newsymbol). This just needs to have the custom commands added in @preamble, but I made some extra modifications for convenience: the user1 field was converted to a custom topic field using a global search and replace (s/user1/topic), and all instances of @entry were replaced with @symbol (s/@entry/@symbol).

After these edits, the file greek.bib starts with:

% Encoding: UTF-8

@preamble{"\providecommand{\Beta}{B}
\providecommand{\Digamma}{F}
\providecommand{\Eta}{H}
\providecommand{\omicron}{o}
\providecommand{\Omicron}{O}
\providecommand{\mtx}[1]{\mathbf{#1}}
\providecommand{\sortart}[2]{#1 #2}"}

@symbol{alpha,
topic = {physics},
name = {\ensuremath{\alpha}},
description = {angular acceleration}
}

@symbol{beta,
topic = {statistical mechanics},
name = {\ensuremath{\beta}},
description = {thermodynamic beta}
}

@symbol{Beta,
topic = {functions},
name = {\ensuremath{\Beta(x,y)}},
description = {Euler beta function}
}

The custom topic field will be ignored by bib2gls unless defined or aliased. The math-greek commands may be omitted from @preamble when the document is compiled with glossaries-extra v1.27+ as they’re provided by glossaries-extra-bib2gls. Since \providecommand is used, these definitions will be ignored if the example documents here are built with glossaries-extra v1.27+.

The cross-reference examples use the file xrentries.tex which was created by a slightly modified Perl script (mkxrentries) adapted from mkentries:

#!/usr/bin/perl -w

use strict;
use warnings;
use Data::Random::WordList;
use List::Util qw/shuffle/;

if ($#ARGV != 0) { die "Syntax:$0 <number>\n";
}

my $count =$ARGV[0];

my $wl = new Data::Random::WordList( wordlist => '/usr/share/dict/words'); my @rand_words = shuffle($wl->get_words($count));$wl->close();

for (my $idx = 0;$idx < $count;$idx++)
{
my $word =$rand_words[$idx];$word=~s/([\\\&#%_\{\}\$])/\\$1/g;

$word=~s/\^/\\textasciicircum /g;$word=~s/\^/\\textasciitilde /g;

my $desc = "sample$idx";

if ($idx%4 == 3) { my$rand_idx = int(rand($idx));$desc .= " ref \\gls{xrentry$rand_idx}"; } print "\\newglossaryentry{xrentry$idx}{name={$word},description={$desc}}\n";
}

1;
This adds a cross-reference in the description field every fourth entry. The file xrentries.tex was then created with:
mkxrentries 6000 > xrentries.tex
Note that I haven’t used the see field, as this would automatically trigger indexing and is therefore inappropriate for large files that contain entries that may not be required (unless you are using bib2gls, which has a different way of dealing with the cross-reference fields).

The bib2gls cross-reference examples require the corresponding file xrentries.bib which was created with:

convertgls2bib xrentries.tex xrentries.bib

Each document (that can be fully compiled) has an associated bash script (called builddoc1 etc) to perform the complete build so that the process can be timed using the GNU time command. For example, the script builddoc1a contains:

#!/usr/bin/bash

pdflatex -jobname test-doc1a test-doc1
makeglossaries-lite test-doc1a
pdflatex -jobname test-doc1a test-doc1

(The documents that can’t compile without error aren’t timed.) For simplicity, the build processes listed in each test below omits -jobname and the hash bang line.

The bash script that times all the test documents is simply:

#!/usr/bin/bash

function build
{
filename=$1 /usr/bin/time -f "$filename:\t%e\t%E" --append --output=$logfile$filename  || exit $? } logfile='runtest.log' rm -f$logfile
touch $logfile bib2gls --version || exit$?
xindy --version || exit $? rm -f test-*.{pdf,aux,log,ist,xdy,gls,glo,glg,acr,acn,alg,gls-abr,glo-abr,glg-abr,glstex} for file in builddoc*; do [ -e "$file" ] || continue

The complete document code is:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc51a
makeglossaries test-doc51a
pdflatex test-doc51a

The total build time was 0:01.24 (PDF). The list of symbols is now ordered as follows:

𝛼 angular acceleration. 1
𝜛 angular frequency. 1
𝜔 angular velocity. 1
𝜋 Archimedes’ constant. 1

𝛰 big O notation. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1

𝜒 chromatic number. 1
𝚺 covariance matrix. 1
𝜅 curvature. 1

𝜌 density. 1
𝚲 diagonal matrix of eigenvalues. 1
Ϝ digamma function. 1

𝜆 an eigenvalue. 1
𝛣(x, y) Euler beta function. 1

𝜗(x) first Chebyshev function. 1
𝜐 frequency. 1

𝛤(n) gamma function. 1
𝜙 the golden ratio. 1

𝜄 inclusion map. 1

𝛫 Kappa number. 1
𝜈 kinematic viscosity. 1
𝛿 Kronecker delta. 1

𝛥 Laplace operator. 1
𝛾 Lorentz factor. 1

𝜇(n) Möbius function. 1
𝛷 magnetic flux. 1

𝛺 the omega constant. 1
𝛱 osmotic pressure. 1

𝜓(m)(z) polygamma function. 1

𝜂 refractive index. 1
𝜁(s) Riemann zeta function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1

𝜊 small o notation. 1
𝜖 small positive quantity. 1
𝜎 standard deviation. 1
𝜃i the ith statistical model parameter. 1

𝛽 thermodynamic beta. 1
𝛳 Theta decay. 1
𝜏 torque. 1

𝛶 upsilon meson. 1

𝜃⃗ the vector of statistic model parameters. 1

𝛹 water potential. 1

Note the odd ordering of ‘Möbius function’ and ‘magnetic flux’. Both sort values start with the same letter (ignoring case), so the order is based on the next letter, but one of the terms has an extended Latin character as the second letter, which makeindex interprets as two characters (obtained from the two octets of the UTF-8 character). Instead of comparing ‘ö’ with ‘a’, makeindex is comparing the non-letter 0xC3 (the first octet of ö) with the letter ‘a’.

6.4 makeglossaries (makeindex): symbols (sort by topic)

The topic argument hasn’t been needed so far. This example modifies Test 6.3 so that the sort value is formed from topic, description:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#4, #3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc51b
makeglossaries test-doc51b
pdflatex test-doc51b

The total build time was 0:01.24 (PDF). The list of symbols is now ordered as follows:

𝛰 big O notation. 1
𝜊 small o notation. 1

𝛱 osmotic pressure. 1

𝛳 Theta decay. 1
𝜛 angular frequency. 1
Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝛿 Kronecker delta. 1
𝜇(n) Möbius function. 1
𝜓(m)(z) polygamma function. 1
𝜁(s) Riemann zeta function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1

𝜋 Archimedes’ constant. 1
𝜅 curvature. 1
𝜒 chromatic number. 1

𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1

𝜏 torque. 1

𝛥 Laplace operator. 1

𝛼 angular acceleration. 1
𝜔 angular velocity. 1
𝜐 frequency. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛷 magnetic flux. 1
𝛶 upsilon meson. 1
𝛹 water potential. 1

𝜌 density. 1
𝜙 the golden ratio. 1
𝛫 Kappa number. 1
𝛺 the omega constant. 1
𝜂 refractive index. 1
𝜖 small positive quantity. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1

𝜄 inclusion map. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1
𝚺 covariance matrix. 1
𝜎 standard deviation. 1

The default group skip creates odd blocks. The topics ‘finance’, ‘functions’ and ‘fluid dynamics’ all belong to the ‘F’ letter group, so they are clumped together. Similarly ’geometry’ and ‘graph theory’ belong to the ‘G’ letter group, and ‘set theory’, ‘statistical mechanics’ and ‘statistics’ belong to the ‘S’ letter group.

The UTF-8 character no longer causes a problem as the sort values for ‘Möbius function’ and ‘magnetic flux’ are now ‘functions, Möbius function’ and ‘physics, magnetic flux’.

6.5 makeglossaries (makeindex): symbols (topic hierarchy)

This example modifies Test 6.4 to improve the grouping. This takes advantage of the fact that all the topics in the example don’t contain any non-expandable or fragile commands. This means that the topic argument may be used as a label. The \newsymbol command now creates an entry for the topic and defines the symbol entry as a child entry:

\newcommand{\newsymbol}[4]{%
\provideglossaryentry{#4}{name={#4},description={\nopostdesc}}%
\newglossaryentry{#1}{parent={#4},sort={#3},name={#2},description={#3}}%
}

The use of \provideglossaryentry means that each topic entry is only defined once. If it has already been defined, \provideglossaryentry does nothing. The sub-entries are sorted by description (as in Test 6.3)

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\provideglossaryentry{#4}{name={#4},description={\nopostdesc}}%
\newglossaryentry{#1}{parent={#4},sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc51c
makeglossaries test-doc51c
pdflatex test-doc51c

The total build time was 0:01.28 (PDF). The list of symbols is now ordered as follows:

asymptotic notation
𝛰 big O notation. 1
𝜊 small o notation. 1

biology

𝛱 osmotic pressure. 1

finance

𝛳 Theta decay. 1
fluid dynamics
𝜛 angular frequency. 1
functions
Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝛿 Kronecker delta. 1
𝜇(n) Möbius function. 1
𝜓(m)(z) polygamma function. 1
𝜁(s) Riemann zeta function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1

geometry

𝜋 Archimedes’ constant. 1
𝜅 curvature. 1
graph theory
𝜒 chromatic number. 1

linear algebra

𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1

mechanics

𝜏 torque. 1

operators

𝛥 Laplace operator. 1

physics

𝛼 angular acceleration. 1
𝜔 angular velocity. 1
𝜐 frequency. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛷 magnetic flux. 1
𝛶 upsilon meson. 1
𝛹 water potential. 1

quantities

𝜌 density. 1
𝜙 the golden ratio. 1
𝛫 Kappa number. 1
𝛺 the omega constant. 1
𝜂 refractive index. 1
𝜖 small positive quantity. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1

set theory

𝜄 inclusion map. 1
statistical mechanics
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1
statistics
𝚺 covariance matrix. 1
𝜎 standard deviation. 1

Again, the default group skip option creates an odd effect, although it’s less jarring now that the topics are visible in the list.

6.6 makeglossaries (makeindex): symbols (order of definition)

This example is like Test 6.1 but lists symbols according to the order of definition:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sort=def,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc51d
makeglossaries test-doc51d
pdflatex test-doc51d

The total build time was 0:01.24 (PDF). The resulting list of symbols is in the following order:

𝛼 angular acceleration. 1
𝛽 thermodynamic beta. 1
𝛣(x, y) Euler beta function. 1
𝛤(n) gamma function. 1
𝛾 Lorentz factor. 1
𝛥 Laplace operator. 1
𝛿 Kronecker delta. 1
𝜖 small positive quantity. 1
Ϝ digamma function. 1
𝜁(s) Riemann zeta function. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝜂 refractive index. 1
𝛳 Theta decay. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1
𝜗(x) first Chebyshev function. 1
𝜄 inclusion map. 1
𝛫 Kappa number. 1
𝜅 curvature. 1
𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1
𝜇(n) Möbius function. 1
𝜈 kinematic viscosity. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1
𝛰 big O notation. 1
𝜊 small o notation. 1
𝛱 osmotic pressure. 1
𝜋 Archimedes’ constant. 1
𝜛 angular frequency. 1
𝜌 density. 1
𝚺 covariance matrix. 1
𝜎 standard deviation. 1
𝜏 torque. 1
𝛶 upsilon meson. 1
𝜐 frequency. 1
𝛷 magnetic flux. 1
𝜙 the golden ratio. 1
𝜒 chromatic number. 1
𝛹 water potential. 1
𝜓(m) (z) polygamma function. 1
𝛺 the omega constant. 1
𝜔 angular velocity. 1

This ordering is quite reasonable, but only because I happened to define the symbols in a reasonable order.

6.7 makeglossaries (makeindex): symbols (order of use)

This example is like Test 6.6 but lists symbols according to the order of use:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sort=use,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc51e
makeglossaries test-doc51e
pdflatex test-doc51e

The total build time was 0:01.24 (PDF). The resulting list of symbols is in the following order:

𝜔 angular velocity. 1
𝜐 frequency. 1
Ϝ digamma function. 1
𝛿 Kronecker delta. 1
𝜓(m) (z) polygamma function. 1
𝜃i the ith statistical model parameter. 1
𝛫 Kappa number. 1
𝜏 torque. 1
𝜉(s) Riemann’s xi-function. 1
𝜊 small o notation. 1
𝛶 upsilon meson. 1
𝜛 angular frequency. 1
𝜆 an eigenvalue. 1
𝛣(x, y) Euler beta function. 1
𝜌 density. 1
𝚺 covariance matrix. 1
𝜁(s) Riemann zeta function. 1
𝛼 angular acceleration. 1
𝜅 curvature. 1
𝜒 chromatic number. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1
𝜖 small positive quantity. 1
𝛤(n) gamma function. 1
𝛥 Laplace operator. 1
𝜗(x) first Chebyshev function. 1
𝜇(n) Möbius function. 1
𝛳 Theta decay. 1
𝛹 water potential. 1
𝜄 inclusion map. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛯 Riemann’s original xi-function. 1
𝛱 osmotic pressure. 1
𝛺 the omega constant. 1
𝛷 magnetic flux. 1
𝜋 Archimedes’ constant. 1
𝚲 diagonal matrix of eigenvalues. 1
𝜙 the golden ratio. 1
𝜎 standard deviation. 1
𝜂 refractive index. 1
𝛰 big O notation. 1
𝜃⃗ the vector of statistic model parameters. 1

6.8 makeglossaries (xindy): symbols (sort by name)

This example is like Test 6.1 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process should be:

pdflatex test-doc52
makeglossaries test-doc52
pdflatex test-doc52

However, xindy fails in this case. The actual xindy call (executed by makeglossaries) is:

xindy -L english -I xindy -M "test-doc52" -t "test-doc52.glg" -o "test-doc52.gls" "test-doc52.glo"

This fails with a fairly cryptic error message:

ERROR: CHAR: index 0 should be less than the length of the string

This is one of the messages that makeglossaries checks for when xindy fails, and it reports the problem:

Sort key required for entries only containing command names.

The makeglossaries script then tries to parse the .glo file to determine which sort values are problematic:

Attempting to determine which entries have problem sort keys.
Parsing 'test-doc52.glo'

In this case 32 problematic entries where found, which is almost all of the entries defined in greek.tex. These are then listed. For brevity, only the first two are reproduced below:

31 problematic entries found:

Label: 'gamma'. Sort value : '\\ensuremath {\\gamma }'
(Try adding sort={gamma} to the definition.)
Label: 'beta'. Sort value : '\\ensuremath {\\beta }'
(Try adding sort={beta} to the definition.)

This diagnostic function isn’t available with makeglossaries-lite and is the one of the reasons why makeglossaries is the recommended script.

The problem stems from the fact that xindy strips LaTeX commands and braces from the sort value so, for example, \emph{duck} becomes simply duck. This is usually quite useful, but it becomes a problem when the sort value only contains commands, as with \ensuremath{\alpha}. Once the markup is stripped, the sort value becomes empty, which is what triggers the error. The solution is suggested by makeglossaries: add a suitable sort value, which is done in Test 6.9 below.

6.9 makeglossaries (xindy): symbols (sort by label)

This example is like Test 6.2 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#1},name={#2},description={#3}}%
}

\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc53
makeglossaries test-doc53
pdflatex test-doc53

The total build time was 0:01.57 (PDF). This produces the same order as Test 6.2.

6.10 makeglossaries (xindy): symbols (sort by description)

This example is like Test 6.3 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc54
makeglossaries test-doc54
pdflatex test-doc54

The total build time was 0:01.56 (PDF). This produces a similar order as Test 6.3, but not identical:

𝛼 angular acceleration. 1
𝜛 angular frequency. 1
𝜔 angular velocity. 1
𝜋 Archimedes’ constant. 1

𝛰 big O notation. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1

𝜒 chromatic number. 1
𝚺 covariance matrix. 1
𝜅 curvature. 1

𝜌 density. 1
𝚲 diagonal matrix of eigenvalues. 1
Ϝ digamma function. 1

𝜆 an eigenvalue. 1
𝛣(x, y) Euler beta function. 1

𝜗(x) first Chebyshev function. 1
𝜐 frequency. 1

𝛤(n) gamma function. 1
𝜙 the golden ratio. 1

𝜄 inclusion map. 1

𝛫 Kappa number. 1
𝜈 kinematic viscosity. 1
𝛿 Kronecker delta. 1

𝛥 Laplace operator. 1
𝛾 Lorentz factor. 1

𝛷 magnetic flux. 1

𝜇(n) Möbius function. 1
𝛺 the omega constant. 1
𝛱 osmotic pressure. 1

𝜓(m)(z) polygamma function. 1

𝜂 refractive index. 1
𝜁(s) Riemann zeta function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1

𝜊 small o notation. 1
𝜖 small positive quantity. 1
𝜎 standard deviation. 1
𝜃i the ith statistical model parameter. 1

𝛽 thermodynamic beta. 1
𝛳 Theta decay. 1
𝜏 torque. 1

𝛶 upsilon meson. 1

𝜃⃗ the vector of statistic model parameters. 1

𝛹 water potential. 1

The difference is in the ordering of ‘magnetic flux’ and ‘Möbius function’. In this case, xindy has produced a more sensible order than makeindex.

6.11 makeglossaries (xindy): symbols (sort by topic)

This example is like Test 6.4 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#4, #3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc55
makeglossaries test-doc55
pdflatex test-doc55

The total build time was 0:01.58 (PDF). The order is the same as for Test 6.4.

6.12 makeglossaries (xindy): symbols (topic hierarchy)

This example is like Test 6.5 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,sanitizesort=false,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\provideglossaryentry{#4}{name={#4},description={\nopostdesc}}%
\newglossaryentry{#1}{parent={#4},sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc56
makeglossaries test-doc56
pdflatex test-doc56

The total build time was 0:01.62 (PDF). The order is the same as for Test 6.5.

6.13 makeglossaries (xindy): symbols (order of definition)

This example is like Test 6.6 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,sort=def,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc57
makeglossaries test-doc57
pdflatex test-doc57

The total build time was 0:01.57 (PDF). The order is the same as for Test 6.6.

6.14 makeglossaries (xindy): symbols (order of use)

This example is like Test 6.7 but it uses xindy:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[xindy,sort=use,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makeglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printglossary
\end{document}

The document build process is:

pdflatex test-doc58
makeglossaries test-doc58
pdflatex test-doc58

The total build time was 0:01.56 (PDF). The order is the same as for Test 6.7.

6.15 \makenoidxglossaries: symbols (sort by name)

This example is like Test 6.1 but it uses TeX to sort and collate. Note the need for the sanitizesort package option. This is usually on by default but \makeidxnoglossaries changes the default to sanitizesort=false (unless explicitly overridden). This allows certain commands (such as \" and \c) to be stripped or (for example, \ae and \oe) replaced. While this worked for documents like Test 2.14, it doesn’t work when the name key contains other commands. Without the sanitizesort option, the document in this example would generate the error:
! Improper alphabetic constant.
<to be read again>
\protect

By sanitizing the sort value, \ensuremath{\alpha} is interpreted as the sequence of 19 characters \ e n s u r e m a t h { \ a l p h a }, and so on, as makeindex does in Test 6.1.

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sanitizesort,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc59
pdflatex test-doc59

The total build time was 0:03.60 (PDF). The order is the same as for Test 6.1.

6.16 \makenoidxglossaries: symbols (sort by label)

This example is like Test 6.2 but it uses TeX to sort and collate. There’s no need for the sanitizesort option in this case as the labels don’t contain any commands.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries

\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#1},name={#2},description={#3}}%
}

\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc60
pdflatex test-doc60

The total build time was 0:01.49 (PDF). The resulting order is almost the same except that lower case comes before upper case within each letter group:

𝛼 angular acceleration. 1

𝛽 thermodynamic beta. 1
𝛣(x, y) Euler beta function. 1

𝜒 chromatic number. 1

𝛿 Kronecker delta. 1
𝛥 Laplace operator. 1
Ϝ digamma function. 1

𝜖 small positive quantity. 1
𝜂 refractive index. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1

𝛾 Lorentz factor. 1
𝛤(n) gamma function. 1

𝜄 inclusion map. 1

𝜅 curvature. 1
𝛫 Kappa number. 1

𝜆 an eigenvalue. 1
𝚲 diagonal matrix of eigenvalues. 1

𝜇(n) Möbius function. 1

𝜈 kinematic viscosity. 1

𝜔 angular velocity. 1
𝛺 the omega constant. 1
𝜊 small o notation. 1
𝛰 big O notation. 1

𝜙 the golden ratio. 1
𝛷 magnetic flux. 1
𝜋 Archimedes’ constant. 1
𝛱 osmotic pressure. 1
𝜓(m)(z) polygamma function. 1
𝛹 water potential. 1

𝜌 density. 1

𝜎 standard deviation. 1
𝚺 covariance matrix. 1

𝜏 torque. 1
𝜃⃗ the vector of statistic model parameters. 1
𝛳 Theta decay. 1
𝜃i the ith statistical model parameter. 1

𝜐 frequency. 1
𝛶 upsilon meson. 1

𝜛 angular frequency. 1
𝜗(x) first Chebyshev function. 1

𝜉(s) Riemann’s xi-function. 1
𝛯 Riemann’s original xi-function. 1

𝜁(s) Riemann zeta function. 1

6.17 \makenoidxglossaries: symbols (sort by description)

This example is like Test 6.3 but it uses TeX to sort an collate. In this case there’s no need for the sanitizesort=false option as it’s automatically implemented by \makenoidxglossaries.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc61
pdflatex test-doc61

The total build time was 0:01.53 (PDF). The resulting order is almost the same as in Test 6.3 but there are some differences.

𝛼 angular acceleration. 1
𝜛 angular frequency. 1
𝜔 angular velocity. 1
𝜋 Archimedes’ constant. 1

𝛰 big O notation. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1

𝜒 chromatic number. 1
𝚺 covariance matrix. 1
𝜅 curvature. 1

𝜌 density. 1
𝚲 diagonal matrix of eigenvalues. 1
Ϝ digamma function. 1

𝜆 an eigenvalue. 1
𝛣(x, y) Euler beta function. 1

𝜗(x) first Chebyshev function. 1
𝜐 frequency. 1

𝛤(n) gamma function. 1
𝜙 the golden ratio. 1

𝜄 inclusion map. 1

𝛫 Kappa number. 1
𝜈 kinematic viscosity. 1
𝛿 Kronecker delta. 1

𝛥 Laplace operator. 1
𝛾 Lorentz factor. 1

𝛷 magnetic flux. 1
𝜇(n) Möbius function. 1

𝛺 the omega constant. 1
𝛱 osmotic pressure. 1

𝜓(m)(z) polygamma function. 1

𝜂 refractive index. 1
𝛯 Riemann’s original xi-function. 1
𝜁(s) Riemann zeta function. 1
𝜉(s) Riemann’s xi-function. 1

𝜖 small positive quantity. 1
𝜊 small o notation. 1
𝜎 standard deviation. 1
𝜃i the ith statistical model parameter. 1

𝛽 thermodynamic beta. 1
𝛳 Theta decay. 1
𝜏 torque. 1

𝛶 upsilon meson. 1

𝜃⃗ the vector of statistic model parameters. 1

𝛹 water potential. 1

The first difference is in the ordering of ‘magnetic flux’ and ‘Möbius function’. This method strips accents so ‘Möbius function’ ends up as ‘Mobius function’ in the sort value. There are two other differences: in the ordering of ‘Riemann’s original x-function’, ‘Riemann zeta function’ and ‘Riemann’s xi-function’ and in the ordering of ‘small positive quantity’ and ‘small o notation’. A better order is obtained using:

\printnoidxglossary[sort=letter]

which suggests something faulty in the default word order sort with \printnoidxglossary.

6.18 \makenoidxglossaries: symbols (sort by topic)

This example is like Test 6.4 but it uses TeX to sort an collate. As with the previous example, there’s no need for the sanitizesort=false option as it’s automatically implemented by \makenoidxglossaries.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\newglossaryentry{#1}{sort={#4, #3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc62
pdflatex test-doc62

The total build time was 0:01.64 (PDF). The list of symbols is now ordered as follows:

𝛰 big O notation. 1
𝜊 small o notation. 1

𝛱 osmotic pressure. 1

𝛳 Theta decay. 1
𝜛 angular frequency. 1
𝛯 Riemann’s original xi-function. 1
𝜇(n) Möbius function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝜁(s) Riemann zeta function. 1
𝛣(x, y) Euler beta function. 1
𝜉(s) Riemann’s xi-function. 1
𝜓(m)(z) polygamma function. 1
𝛿 Kronecker delta. 1
Ϝ digamma function. 1

𝜋 Archimedes’ constant. 1
𝜅 curvature. 1
𝜒 chromatic number. 1

𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1

𝜏 torque. 1

𝛥 Laplace operator. 1

𝛷 magnetic flux. 1
𝛾 Lorentz factor. 1
𝜈 kinematic viscosity. 1
𝛹 water potential. 1
𝛼 angular acceleration. 1
𝛶 upsilon meson. 1
𝜐 frequency. 1
𝜔 angular velocity. 1

𝜃⃗ the vector of statistic model parameters. 1
𝜂 refractive index. 1
𝜙 the golden ratio. 1
𝛺 the omega constant. 1
𝜖 small positive quantity. 1
𝜌 density. 1
𝛫 Kappa number. 1
𝜃i the ith statistical model parameter. 1

𝜄 inclusion map. 1
𝛽 thermodynamic beta. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝜎 standard deviation. 1
𝚺 covariance matrix. 1

As with the previous example, the faulty word comparator used by default with \printnoidxglossary. A better order is again obtained using:

\printnoidxglossary[sort=letter]

6.19 \makenoidxglossaries: symbols (topic hierarchy)

This example is like Test 6.5 but it uses TeX to sort an collate:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries

\newcommand{\sortart}[2]{#2}
\newcommand{\newsymbol}[4]{%
\provideglossaryentry{#4}{name={#4},description={\nopostdesc}}%
\newglossaryentry{#1}{parent={#4},sort={#3},name={#2},description={#3}}%
}

\loadglsentries{greek}
\renewcommand{\sortart}[2]{#1 #2}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc63
pdflatex test-doc63

The total build time was 0:02.26 (PDF). The list of symbols is now ordered as follows:

asymptotic notation
𝛰 big O notation. 1
𝜊 small o notation. 1

biology

𝛱 osmotic pressure. 1

finance

𝛳 Theta decay. 1
fluid dynamics
𝜛 angular frequency. 1
functions
Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝛿 Kronecker delta. 1
𝜇(n) Möbius function. 1
𝜓(m)(z) polygamma function. 1
𝛯 Riemann’s original xi-function. 1
𝜁(s) Riemann zeta function. 1
𝜉(s) Riemann’s xi-function. 1

geometry

𝜋 Archimedes’ constant. 1
𝜅 curvature. 1
graph theory
𝜒 chromatic number. 1

linear algebra

𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1

mechanics

𝜏 torque. 1

operators

𝛥 Laplace operator. 1

physics

𝛼 angular acceleration. 1
𝜔 angular velocity. 1
𝜐 frequency. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛷 magnetic flux. 1
𝛶 upsilon meson. 1
𝛹 water potential. 1

quantities

𝜌 density. 1
𝜙 the golden ratio. 1
𝛫 Kappa number. 1
𝛺 the omega constant. 1
𝜂 refractive index. 1
𝜖 small positive quantity. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1

set theory

𝜄 inclusion map. 1
statistical mechanics
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1
statistics
𝚺 covariance matrix. 1 𝜎 standard deviation. 1

Again the word ordering is inappropriate with the Riemann functions.

6.20 \makenoidxglossaries: symbols (order of definition)

This example is like Test 6.6 but it uses TeX to sort an collate, although there isn’t any actual sorting in this case as the order is obtained from an internal list.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sort=def,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc64
pdflatex test-doc64

The total build time was 0:01.13 (PDF). The ordering is the same as for Test 6.6.

6.21 \makenoidxglossaries: symbols (order of use)

This example is like Test 6.7 but it uses TeX to sort an collate, but again no actual sorting is performed.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[sort=use,nolist,nolong,nosuper,style=tree]{glossaries}

\pagestyle{empty}

\makenoidxglossaries
\loadglsentries{greek}

\begin{document}

\input{symbol-refs}

\printnoidxglossary
\end{document}

The document build process is:

pdflatex test-doc65
pdflatex test-doc65

The total build time was 0:01.14 (PDF). The ordering is the same as for Test 6.7.

6.22 bib2gls: symbols (sort by name, sort=en-GB)

Each bib2gls entry type has a designated field to use if the sort field is omitted (which is typically the case and is recommended practice with bib2gls).

The general @entry type of definition falls back on the name field, which is consistent with the behaviour of \newglossaryentry, but @symbol falls back on the label, which is consistent with the behaviour of \glsxtrnewsymbol.

So, to sort @symbol entries by name, you need to either use symbol-sort-fallback=name to change the fallback or switch the field used for sorting with sort-field=name, which will sort all entries by the name field regardless of whether they have been defined using @symbol or @entry or any other entry type. The first approach is best if you have a mixture of entry types (such as @symbol and @abbreviation), as different types may require different fallback values (for example, you may want abbreviations to fall back on the long field).

Since I used glossaries-extra v1.27 to build the bib2gls examples here, the missing Greek commands (\Beta etc) are provided by glossaries-extra-bib2gls so the definitions in @preamble are ignored. This means that these characters appear slightly differently in this document to the earlier examples as the definitions now use \mathrm for the upper case letters.

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src={greek},symbol-sort-fallback=name]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc66
bib2gls test-doc66
pdflatex test-doc66

The total build time was 0:02.05 (PDF). The resulting list of symbols is in the following order:

Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝛤(n) gamma function. 1
𝛥 Laplace operator. 1
𝛨(t) Boltzmann’s 𝛨-Theorem. 1
𝛫 Kappa number. 1
𝚲 diagonal matrix of eigenvalues. 1
𝛯 Riemann’s original xi-function. 1
𝛰 big O notation. 1
𝛱 osmotic pressure. 1
𝛳 Theta decay. 1
𝚺 covariance matrix. 1
𝛶 upsilon meson. 1
𝛷 magnetic flux. 1
𝛹 water potential. 1
𝛺 the omega constant. 1
𝛼 angular acceleration. 1
𝛽 thermodynamic beta. 1
𝛾 Lorentz factor. 1
𝛿 Kronecker delta. 1
𝜁(s) Riemann zeta function. 1
𝜂 refractive index. 1
𝜃⃗ the vector of statistic model parameters. 1
𝜃i the ith statistical model parameter. 1
𝜄 inclusion map. 1
𝜅 curvature. 1
𝜆 an eigenvalue. 1
𝜇(n) Möbius function. 1
𝜈 kinematic viscosity. 1
𝜉(s) Riemann’s xi-function. 1
𝜊 small o notation. 1
𝜋 Archimedes’ constant. 1
𝜌 density. 1
𝜎 standard deviation. 1
𝜏 torque. 1
𝜐 frequency. 1
𝜒 chromatic number. 1
𝜓(m)(z) polygamma function. 1
𝜔 angular velocity. 1
𝜖 small positive quantity. 1
𝜗(x) first Chebyshev function. 1
𝜙 the golden ratio. 1
𝜛 angular frequency. 1

Remember that if the sort resource option (supplied in \GlsXtrLoadResources) is missing, then bib2gls will use a rule-based locale sort. Since the document doesn’t have any language setting, bib2gls uses the default locale for the Java Virtual Machine (which is usually the operating system’s default locale), so for me this is equivalent to using:

\GlsXtrLoadResources[sort={en-GB},src={greek},symbol-sort-fallback=name]

A clue to how bib2gls sorts can be found in the glstex file that it creates. Each entry definition includes the sort field as determined by bib2gls. This field has no use in the document, as it’s only used by bib2gls, but it’s provided for informational purposes.

For example, the symbol with the label zeta had name={\ensuremath{\zeta(s)}} in the greek.bib file. The sort value obtained from this is shown in the glstex file:

sort={𝜁|s|}

The bib2gls transcript (.glg) file contains another clue:

texparserlib: {}\ensuremath{\zeta(s)} -> 𝜁(s)

bib2gls uses the TeX Parser Library to interpret LaTeX commands. Lines starting with texparserlib: in the transcript file indicate the result of a conversion performed by the interpreter. In this case, it shows that bib2gls has determined through the TeX Parser Library that the closest Unicode match for \ensuremath{\zeta(s)} is 𝜁(s).

The parentheses are replaced with the pipe (vertical bar) symbol as a result of the default word-order action used by the locale or rule-based sort methods (such as sort=en-GB).

The TeX Parser Library recognises most of the LaTeX kernel commands that can be represented as Unicode characters (such as \zeta). It also recognises the missing Math-Greek commands so, for example, \ensuremath{\Beta} is converted to the Mathematical Italic Capital Beta 𝛣 (0x1D6E3), not the Basic Latin B. Since \Beta is already defined from bib2gls’s point of view, the definition of \Beta provided in the @preamble has no effect on bib2gls (since it’s defined with \providecommand), but the @preamble definition is written to the glstex file to ensure that LaTeX recognises \Beta when the document is compiled.

Since the en-GB rule doesn’t include Greek or Math-Greek characters, they are sorted according to their Unicode values. So digamma Ϝ (0x03DC) is listed first, followed by the Mathematical Italic Capital Greek letters, followed by the Mathematical Italic small Greek letters. Font information is stripped so, although bib2gls can detect the definition of \mtx from @preamble, the font change introduced by \mathbf is ignored. However, combining accents aren’t ignored, as seen with the theta entry:

texparserlib: {}\ensuremath{\vec{\theta}} -> 𝜃⃗

The result consists of two Unicode characters: 0x1D703 (Mathematic Italic Small Theta) and 0x20D7 (Combining Right Arrow Above). In this case, the sort rule ignores the combining diacritic.

Note that if I had simply used the Latin B, H, O and o explicitly in the name, instead of providing the missing commands (\Beta, \Eta, \Omicron and \omicron), those entries would be listed first, since they are recognised as valid letter groups by the rule.

One final observation, the name field has had an empty brace inserted at the front, which is the reason for the transcript messages:

Inserting empty group in front of \ensuremath to protect it from mfirstuc.

This is done to protect the field against any first letter upper-casing that might be performed by a glossary style or the use of commands like \Gls. These lines are just messages not warnings and can be ignored or you can switch off this action with --no-mfirstuc-math-protection. The presence of this empty group doesn’t affect the sorting when the TeX parser is used.

6.23 bib2gls: symbols (sort by name, sort=custom)

This is like Test 6.22 but it uses a custom rule, which is set with sort=custom and sort-rule=rule. For convenience, I’ve used one of the common rule commands provided with glossaries-extra.sty v1.27. If you have an older version the rule would need to be written explicitly in terms of \string\u hex or \glshex hex.
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[sort={custom},
sort-rule={\glsxtrspacerules
;\glsxtrcombiningdiacriticrules
,\glsxtrhyphenrules
<\glsxtrgeneralpuncrules
<\glsxtrdigitrules
<\glsxtrGeneralLatinIrules
<\glsxtrMathItalicGreekIrules},
src={greek},symbol-sort-fallback=name]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

Be careful if you use a group style, such as treegroup, as the group title is obtained from the Unicode character at the start of the sort value. Your document will need support for these characters.

The document build process is:

pdflatex test-doc67
bib2gls test-doc67
pdflatex test-doc67

The total build time was 0:02.09 (PDF).

The rule here is:

• ignore spaces, combining diacritics and hyphens (\glsxtrspacerules ; \glsxtrcombiningdiacriticrules , \glsxtrhyphenrules)
• punctuation characters come first (<\glsxtrgeneralpuncrules)
• digits 0,…,9 from the Basic Latin set come next (<\glsxtrdigitrules)
• letters Aa,…,Zz from the Basic Latin set come next (<\glsxtrGeneralLatinIrules)
• Math-Greek 𝛢𝛼,…,𝛺𝜔 (with digamma between epsilon and zeta) come next (<\glsxtrMathItalicGreekIrules)
• anything else comes last ordered by character code.

If you prefer to have digamma before or after all the other Greek letters you can use <\glsxtrUpDigamma <\glsxtrMathItalicGreekIIrules or <\glsxtrMathItalicGreekIIrules <\glsxtrUpDigamma instead of <\glsxtrMathItalicGreekIrules.

The resulting list of symbols is in the following order:

𝛼 angular acceleration. 1
𝛽 thermodynamic beta. 1
𝛣(x, y) Euler beta function. 1
𝛾 Lorentz factor. 1
𝛤(n) gamma function. 1
𝛥 Laplace operator. 1
𝛿 Kronecker delta. 1
𝜖 small positive quantity. 1
Ϝ digamma function. 1
𝜁(s) Riemann zeta function. 1
𝜂 refractive index. 1
𝛨(t) Boltzmann’s 𝛨-Theorem. 1
𝛳 Theta decay. 1
𝜃⃗ the vector of statistic model parameters. 1
𝜗(x) first Chebyshev function. 1
𝜃i the ith statistical model parameter. 1
𝜄 inclusion map. 1
𝛫 Kappa number. 1
𝜅 curvature. 1
𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1
𝜇(n) Möbius function. 1
𝜈 kinematic viscosity. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1
𝛰 big 𝛰 notation. 1
𝜊 small o notation. 1
𝛱 osmotic pressure. 1
𝜋 Archimedes’ constant. 1
𝜛 angular frequency. 1
𝜌 density. 1
𝚺 covariance matrix. 1
𝜎 standard deviation. 1
𝜏 torque. 1
𝛶 upsilon meson. 1
𝜐 frequency. 1
𝛷 magnetic flux. 1
𝜙 the golden ratio. 1
𝜒 chromatic number. 1
𝛹 water potential. 1
𝜓(m)(z) polygamma function. 1
𝛺 the omega constant. 1
𝜔 angular velocity. 1

Note that the variants have been gathered appropriately, so the variant theta (𝜗) is with the regular upper and lower case theta (𝛳 and 𝜃). Similarly, the variant pi (𝜛) is with the regular upper and lower case pi (𝛱 and 𝜋). In each case, the different versions of the letter are considered identical from the rule’s point of view. So 𝛳, 𝜃 and 𝜗 are treated as the same character.

• The Theta entry (\ensuremath{\Theta}) has a sort value consisting of a single letter (𝛳), so that comes first in the theta letter group.
• The rule ignores combining diacritics so although the theta entry (\ensuremath{\vec{\theta}}) ends up with a sort value consisting of two Unicode characters, only the first is relevant, so 𝜃⃗ comes next.
• The vartheta entry (\ensuremath{\vartheta(x)}) ends up with the sort value 𝜗|x| (because the default word ordering is on). So 𝜗(x) comes next since the rule has | before letters. (If the word ordering is switched off with the option break-at=none then the sort value would be 𝜗(x), which in this particular case wouldn’t make a difference as 𝜗 is still followed by a punctuation character.)
• The thetai entry (\ensuremath{\theta_i}) ends up with the sort value 𝜃i so it comes fourth in the theta group, since Latin letters come after punctuation characters.

The TeX parser treats ^ (or \sp) and _ (or \sb) slightly differently to \textsuperscript and \textsubscript. In text-mode, if the subscript or superscript can be completely represented in Unicode, then the Unicode characters are used. For example, \textsuperscript{(42)} will be converted to ⁽⁴²⁾ (0x207D, 0x2074, 0x00B2, 0x207E) whereas \textsuperscript{(4,2)} will be converted to <sup>(4,2)</sup> (and the markup is then stripped by bib2gls).

In math-mode (if MathJax output is off, which it always is with bib2gls), then the <sup> and <sub> tags will always be used. The resulting string returned by the TeX parser always has the markup stripped, so \ensuremath{\theta_i} is translated to 𝜃<sup>i</sup> and ends up as just 𝜃i. If any of the entries contain code that could end up as subscript or superscript characters, then these would need to be incorporated into the rule.

6.24 bib2gls: symbols (sort by label)

This is like Test 6.2 but it uses bib2gls. Since the default fallback for the sort field is the label for @symbol entries, this example is quite simple:
\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src={greek}]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc68
bib2gls test-doc68
pdflatex test-doc68

The total build time was 0:02.07 (PDF). This has the same ordering as for Test 6.2, but in this case there are no group separators since the --group switch wasn’t used.

6.25 bib2gls: symbols (sort by description)

This is like Test 6.3 but it uses bib2gls. In this case, instead of changing symbol-sort-fallback the field used for sorting is set with sort-field. The definition of \sortart is provided for use in the document, but it would be better to supply an alternative definition just for bib2gls’s use that omits the first argument.

There are a number of different ways to achieve this. The examples in the bib2gls manual have separate .bib files for different command definitions. So there’s a file nointerpret-preamble.bib that provides commands for use in the document that should be ignored by bib2gls and there’s a file interpret-preamble.bib that provides commands for use by bib2gls that shouldn’t be defined in the document.

In order to adopt this approach, the @preamble code would need to be moved out of greek.bib and into a new file nointerpret-preamble.bib (which contains nothing else). Another file, interpret-preamble.bib just needs the line:

@preamble{"\providecommand{\sortart}[2]{#2}"}

The other definitions aren’t required. The Greek commands like \Beta are already defined in the TeX parser. The custom command \mtx simply applies a font change, so it’s not needed by bib2gls. Unknown commands are ignored, so \mtx{\Lambda} will be treated as \Lambda, which is the end result in Test 6.22 and Test 6.23. (Besides, this example is sorting by description and none of the descriptions contain \mtx.)

The document would then have two instances of \GlsXtrLoadResources. The first ensures that the definitions required by the document are provided:

\GlsXtrLoadResources[src=nointerpret-preamble,
interpret-preamble=false]

The interpret-preamble=false prevents bib2gls from parsing the definitions. The second instance provides the definition needed by bib2gls:

\GlsXtrLoadResources[src={interpret-preamble,greek},
sort-field=description]

Since the command is defined using \providecommand it won’t override the previous definition. You can instruct bib2gls to omit the command definitions from the glstex file if you want using write-preamble=false, but in this case it’s not essential.

Since the above method would require editing greek.bib, I decided to use a different approach here. In this case, I still have a file called interpret-preamble.bib which just contains:

@preamble{"\providecommand{\sortart}[2]{#2}"}

This needs to be loaded before greek.bib to ensure that bib2gls picks up the definition, but the definition shouldn’t be written to the glstex file:

\GlsXtrLoadResources[src=interpret-preamble,
write-preamble=false]

The next resource set can load greek.bib. Since \sortart is now a recognised command, bib2gls will ignore the second definition (since it’s defined with \providecommand). Since none of the other commands are needed by bib2gls, it’s simplest to instruct bib2gls to skip the preamble-parsing step. (It will still write the preamble commands to the glstex file.)

The complete document is:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src=interpret-preamble,
write-preamble=false]

\GlsXtrLoadResources[src={greek},
interpret-preamble=false,
sort-field=description
]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc69
bib2gls --group test-doc69
pdflatex test-doc69

The total build time was 0:02.08 (PDF).

Note that in this case I’ve used the --group switch, which divides the list into (unheaded) letter groups. For headed letter groups, the style needs to be changed (for example, style=treegroup).

The ordering is slightly different from Test 6.3, Test 6.10 and Test 6.17:

𝛼 angular acceleration. 1
𝜛 angular frequency. 1
𝜔 angular velocity. 1
𝜋 Archimedes’ constant. 1

𝛰 big O notation. 1
𝛨(t) Boltzmann’s 𝛨-theorem. 1

𝜒 chromatic number. 1
𝚺 covariance matrix. 1
𝜅 curvature. 1

𝜌 density. 1
𝚲 diagonal matrix of eigenvalues. 1
Ϝ digamma function. 1

𝜆 an eigenvalue. 1
𝛣(x, y) Euler beta function. 1

𝜗(x) first Chebyshev function. 1
𝜐 frequency. 1

𝛤(n) gamma function. 1
𝜙 the golden ratio. 1

𝜄 inclusion map. 1

𝛫 Kappa number. 1
𝜈 kinematic viscosity. 1
𝛿 Kronecker delta. 1

𝛥 Laplace operator. 1
𝛾 Lorentz factor. 1

𝛷 magnetic flux. 1
𝜇(n) Möbius function. 1

𝛺 the omega constant. 1
𝛱 osmotic pressure. 1

𝜓(m)(z) polygamma function. 1

𝜂 refractive index. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1
𝜁(s) Riemann zeta function. 1

𝜊 small o notation. 1
𝜖 small positive quantity. 1
𝜎 standard deviation. 1
𝜃i the ith statistical model parameter. 1

𝛽 thermodynamic beta. 1
𝛳 Theta decay. 1
𝜏 torque. 1

𝛶 upsilon meson. 1

𝜃⃗ the vector of statistic model parameters. 1

𝛹 water potential. 1

The difference between this and the xindy version (Test 6.10) is in the ordering of the Riemann functions. The default break-at=word setting replaces word boundaries with | so the sort values (which can be found in the file test-doc69-1.glstex) are:

sort={Riemann's|original|xi-function|}
sort={Riemann's|xi-function|}
sort={Riemann|zeta|function|}

The en-GB rule orders the pipe character (|) after the apostrophe character (') so Riemann| comes after Riemann'. The ordering can be altered by changing the break marker to a character that comes before apostrophe in the rule. For example:

\GlsXtrLoadResources[src={greek},
interpret-preamble=false,
break-marker={_},
sort-field=description
]

(Alternatively, you could provide a custom rule but it’s usually simpler to just change the marker.)

6.26 bib2gls: symbols (sort by topic)

So far the topic field has been ignored by bib2gls. This example aliases it to the group field. Note that this field may only contain content that can form a label. That is, it can’t contain any special characters or unexpandable commands. Fortunately, the topic field only contains ASCII letters and spaces, so it’s acceptable content. (If it did contain any problematic content, you can just add labelify=group to strip any non-label content.)

The sorting is performed according to the topic (group) followed by the description. This is done with sort-field=group (to sort by the group field) combined with sort-suffix=description, which appends the description to the sort field.

The document just requires a minor modification to Test 6.25:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=treegroup]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src=interpret-preamble,
write-preamble=false]

\GlsXtrLoadResources[src={greek},
interpret-preamble=false,
field-aliases={topic=group},
sort-field=group,
sort-suffix=description
]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc70
bib2gls --group test-doc70
pdflatex test-doc70

The total build time was 0:02.10 (PDF). The order is:

asymptotic notation

𝛰 big O notation. 1
𝜊 small o notation. 1

biology

𝛱 osmotic pressure. 1

finance

𝛳 Theta decay. 1

fluid dynamics

𝜛 angular frequency. 1

functions

Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝛿 Kronecker delta. 1
𝜇(n) Möbius function. 1
𝜓(m)(z) polygamma function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1
𝜁(s) Riemann zeta function. 1

geometry

𝜋 Archimedes’ constant. 1
𝜅 curvature. 1

graph theory

𝜒 chromatic number. 1

linear algebra

𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1

mechanics

𝜏 torque. 1

operators

𝛥 Laplace operator. 1

physics

𝛼 angular acceleration. 1
𝜔 angular velocity. 1
𝜐 frequency. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛷 magnetic flux. 1
𝛶 upsilon meson. 1
𝛹 water potential. 1

quantities

𝜌 density. 1
𝜙 the golden ratio. 1
𝛫 Kappa number. 1
𝛺 the omega constant. 1
𝜂 refractive index. 1
𝜖 small positive quantity. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1

set theory

𝜄 inclusion map. 1

statistical mechanics

𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1

statistics

𝚺 covariance matrix. 1
𝜎 standard deviation. 1

Note that this creates custom groups, so it doesn’t have the odd clumping effect from topics starting with the same letter. Remember that the group value is a label. The title can be changed using \glsxtrsetgrouptitle{label}{title}. For example:

\glsxtrsetgrouptitle{fluid dynamics}{Fluid Dynamics}

6.27 bib2gls: symbols (topic hierarchy)

One weakness of bib2gls is that you can’t programmatically define entries, so it’s not possible to do something like:

\newcommand{\newsymbol}[4]{%
\provideglossaryentry{#4}{name={#4},description={\nopostdesc}}%
\newglossaryentry{#1}{parent={#4},sort={#3},name={#2},description={#3}}%
}

Although it’s possible to create a second entry using dual entry formats, such as @dualabbreviationentry, more complicated multi-definitions like the above aren’t supported. However, it’s still possible to provide a bib2gls version of Test 6.5 by providing an extra .bib file. This is less convenient as it means that the parent entries need defining, but this method doesn’t require any modifications to the greek.bib file. The file topics.bib was created using

grep topic greek.bib | sed -r 's/  topic = \{(.*)\},/@index{\1}/' | sort | uniq > topics.bib

Spaces aren’t permitted in label names in the .bib format, so topics with a compound title needed editing:

@index{asymptotic-notation,
name={asymptotic notation}
}

@index{fluid-dynamics,
name={fluid dynamics}
}
@index{graph-theory,
name={graph theory}
}
@index{linear-algebra,
name={linear algebra}
}
@index{set-theory,
name={set theory}
}
@index{statistical-mechanics,
name={statistical mechanics}
}

I also added the encoding comment at the start of the file (although in this case it’s not strictly necessary as the file only contains ASCII characters). You can download the final topics.bib.

The aim here is to alias the topic fields in greek.bib to the parent field, but the space in the compound names needs to be replaced with a hyphen in order to match the labels in topics.bib. As from version 1.2 of bib2gls, you can use the resource option labelify to convert the contents of a field into a string suitable for use as a label. This will first try to interpret the value if certain special characters are detected in it (not applicable in this example), and will then apply any substitutions indicated by labelify-replace and finally remove any content that can’t be included in a label (such as special characters). If fontspec isn’t detected in the document’s .log file, then non-ASCII characters will additionally be decomposed and non-ASCII content stripped.

This means that to convert

topic = {fluid dynamics}

into

parent = {fluid-dynamics}

I need the resource options:

field-aliases={topic=parent},
labelify={parent},
labelify-replace={{ }{-}}

The complete document is:

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src=interpret-preamble,
write-preamble=false]

\GlsXtrLoadResources[src={topics,greek},
interpret-preamble=false,
field-aliases={topic=parent},
labelify={parent},
labelify-replace={{ }{-}},
symbol-sort-fallback=description
]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build is:

pdflatex test-doc71
bib2gls test-doc71
pdflatex test-doc71

The total build time was 0:02.11 (PDF).

I haven’t used the --group switch so there are no separations between letter groups (because there aren’t any distinct groups). The entries defined with @index (the top-level topics) are sorted by the name field (which defaults to the label if omitted). The entries defined with @symbol (the symbol sub-entries) fall back on the description field (identified by symbol-sort-fallback).

The order is:

asymptotic notation
𝛰 big O notation. 1
𝜊 small o notation. 1
biology
𝛱 osmotic pressure. 1
finance
𝛳 Theta decay. 1
fluid dynamics
𝜛 angular frequency. 1
functions
Ϝ digamma function. 1
𝛣(x, y) Euler beta function. 1
𝜗(x) first Chebyshev function. 1
𝛤(n) gamma function. 1
𝛿 Kronecker delta. 1
𝜇(n) Möbius function. 1
𝜓(m)(z) polygamma function. 1
𝛯 Riemann’s original xi-function. 1
𝜉(s) Riemann’s xi-function. 1
𝜁(s) Riemann zeta function. 1
geometry
𝜋 Archimedes’ constant. 1
𝜅 curvature. 1
graph theory
𝜒 chromatic number. 1
linear algebra
𝚲 diagonal matrix of eigenvalues. 1
𝜆 an eigenvalue. 1
mechanics
𝜏 torque. 1
operators
𝛥 Laplace operator. 1
physics
𝛼 angular acceleration. 1
𝜔 angular velocity. 1
𝜐 frequency. 1
𝜈 kinematic viscosity. 1
𝛾 Lorentz factor. 1
𝛷 magnetic flux. 1
𝛶 upsilon meson. 1
𝛹 water potential. 1
quantities
𝜌 density. 1
𝜙 the golden ratio. 1
𝛫 Kappa number. 1
𝛺 the omega constant. 1
𝜂 refractive index. 1
𝜖 small positive quantity. 1
𝜃i the ith statistical model parameter. 1
𝜃⃗ the vector of statistic model parameters. 1
set theory
𝜄 inclusion map. 1
statistical mechanics
𝛨(t) Boltzmann’s 𝛨-theorem. 1
𝛽 thermodynamic beta. 1
statistics
𝚺 covariance matrix. 1
𝜎 standard deviation. 1

6.28 bib2gls: symbols (order of definition)

This example orders the symbols according to the order of definition, which is implemented with the sort=none resource option.

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src={greek},sort=none]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc72
bib2gls test-doc72
pdflatex test-doc72

The total build time was 0:02.05 (PDF). The order is the same as for Test 6.6.

6.29 bib2gls: symbols (order of use)

This example orders the symbols according to first use in the document, which is implemented with the sort=use resource option.

\documentclass{article}

\usepackage[a4paper,margin=5mm]{geometry}
\usepackage[record,nostyles,stylemods={tree},style=tree]{glossaries-extra}

\pagestyle{empty}

\GlsXtrLoadResources[src={greek},sort=use]

\begin{document}

\input{symbol-refs}

\printunsrtglossary
\end{document}

The document build process is:

pdflatex test-doc73
bib2gls test-doc73
pdflatex test-doc73

The total build time was 0:02.05 (PDF). The order is the same as for Test 6.7.

7. Alphabetical Order With Cross-References (Subset)

These tests are similar to those in Section 3 (location list included) but the entries are all selected from the file xrentries.tex or, with bib2gls, xrentries.bib. Note that there are some cross-reference trails in these files. For example, xrentry655 references xrentry415, xrentry415 references xrentry15, and xrentry15 references xrentry13.

In the first set of tests, the document references 32 entries in the main matter, but once all cross-referenced entries are added, there are a total of 39 entries in the glossary.

In the second set of tests, the document references 4000 entries in the main matter, but once all cross-referenced entries are added, there are a total of 4207 entries in the glossary.

With bib2gls, the cross-references can be picked up when the bib file is parsed, and those entries will added as dependencies of the entries that have been recorded (indexed) in the document. However, it won’t be possible to obtain the locations associated with those cross-referenced entries until they themselves have been recorded. This means that if you required location lists, you will need a second bib2gls+LaTeX in the document build. If you don’t require location lists, or if you don’t require location lists for the entries that are only referenced within the glossary, then you will only need one bib2gls call.

Location lists can be suppressed with the nonumberlist package option, or you can instruct bib2gls not to bother saving locations with the save-locations=false resource option. To prevent locations within the glossary from being added to the location lists, you can change the default format to glsignore at the start of the glossary. For example:

\GlsXtrSetDefaultNumberFormat{glsignore}
\printunsrtglossaries

With the other indexing options, the cross-references will only be indexed once the description in which they are contained is displayed in the glossary. This means that you will have to repeatedly rebuild the document until all cross-references are present. The test documents use hyperref, which will generate a warning when the document build is incomplete as there will be hyperlinks to undefined targets. For example:

pdfTeX warning (dest): name{glo:xrentry0} has been referenced but does not exist, replaced by a fixed one

The other indexing options will also be problematic if you want to suppress locations that are indexing within the glossary (but retain the locations in the main matter). In this case, using format=glsignore will result in an invisible location and, if there’s more that one location in the list, spurious commas or en-dashes. Switching off indexing in the glossary (using the noindex option, provided by glossaries-extra), won’t work as then the entries that are only referenced in the glossary won’t be indexed and so won’t appear in the glossary.

The results are summarized in Table 6. The fastest method is to use bib2gls with the location suppressed in the glossary. This only requires one bib2gls call. The document build was approximately 4 seconds for 32/6000, and approximately 25 seconds for 4000/6000. Using two bib2gls calls to allow locations from references within the glossary took approximately 7 seconds for 32/6000 and 53 seconds for 4000/6000.

The other methods were significantly slower. For the smaller 32/6000 tests, makeindex and \makenoidxglossaries were comparable (55 seconds for makeindex and 54 seconds for \makenoidxglossaries), and the slowest method was with xindy, which took approximately 65 seconds.

For the larger 4000/6000 tests, makeindex took approximately 53 seconds. The xindy test document required special handling to deal with duplicate sort values. The total build time took approximately 73 seconds. Worst of all, by far, was \makenoidxglossaries, which doesn’t scale well, and took over 12 hours and had to be aborted.

Table 6: Summary (Alphabetical Order, Subset with Cross-References)
Test Build time (minutes:​seconds) PDF
32/6000
7.1 makeglossaries (makeindex) 0:54.51 (PDF)
7.2 makeglossaries (xindy) 1:04.61 (PDF)
7.3 \makenoidxglossaries 0:53.86 (PDF)
7.4 bib2gls 0:06.98 (PDF)
7.5 bib2gls (no glossary locations) 0:03.93 (PDF)
4000/6000
7.6 makeglossaries (makeindex) 0:53.27 (PDF)
7.7 makeglossaries (xindy) 1:12.82 (PDF)
7.8 \makenoidxglossaries aborted at 12h 24m (PDF)
7.9 bib2gls 0:53.17 (PDF)
7.10 bib2gls (no glossary locations) 0:25.11 (PDF)

7.1 makeglossaries (makeindex): cross-references (minimum 32/6000)

This example uses makeindex (via makeglossaries). There is only one list, which is displayed with \printglossaries. For convenience a loop is used to automate the references for testing. This will create 32 references within the main matter, but once the glossary is present, there will be additional references in the back matter.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makeglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printglossaries
\end{document}
The bash script (builddoc74) used to build this document (test-doc74.tex) uses a while loop that tests the transcript file for the undefined hypertarget warning, but there’s a cap on the number of iterations to prevent the build process going on indefinitely in the event that some modification to the document doesn’t accidentally introduce a hyperlink that will never be defined.
#!/usr/bin/bash

N=0;
pdflatex test-doc74
while grep -q "pdfTeX warning (dest): name{glo:" "test-doc74.log" ; do
let N=N+1
if [ $N -ge 20 ] then echo "Exceeded maximum number of iterations" 1>&2 exit 1 fi makeglossaries test-doc74 pdflatex test-doc74 done echo "N:"$N

In this case, a total of four iterations are needed to fully resolve all references. This is equivalent to:

pdflatex test-doc74
makeglossaries test-doc74
pdflatex test-doc74
makeglossaries test-doc74
pdflatex test-doc74
makeglossaries test-doc74
pdflatex test-doc74
makeglossaries test-doc74
pdflatex test-doc74

The total build time was 0:54.51 (PDF).

7.2 makeglossaries (xindy): cross-references (minimum 32/6000)

This example is as Test 7.1 but uses xindy instead of makeindex. The document is almost the same as in the other example, except for the xindy package option.

\usepackage[xindy]{glossaries}

As before, a total of four iterations are needed to fully resolve all references:

pdflatex test-doc75
makeglossaries test-doc75
pdflatex test-doc75
makeglossaries test-doc75
pdflatex test-doc75
makeglossaries test-doc75
pdflatex test-doc75
makeglossaries test-doc75
pdflatex test-doc75

The total build time was 1:04.61 (PDF).

7.3 \makenoidxglossaries: cross-references (minimum 32/6000)

This example is as Test 7.1 but uses \makenoidxglossaries:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makenoidxglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printnoidxglossaries
\end{document}

The document build needed to fully resolve all references:

pdflatex test-doc76
pdflatex test-doc76
pdflatex test-doc76
pdflatex test-doc76
pdflatex test-doc76

The total build time was 0:53.86 (PDF).

7.4 bib2gls: cross-references (minimum 32/6000)

This example is as Test 7.1 but uses bib2gls with the file xrentries.bib.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printunsrtglossaries
\end{document}

This only requires two bib2gls calls:

pdflatex test-doc77
bib2gls -g test-doc77
pdflatex test-doc77
bib2gls -g test-doc77
pdflatex test-doc77
The first instance is sufficient to pick up the cross-reference trails. The second is required to pick up the locations from the references in the glossary.

The total build time was 0:06.98 (PDF).

7.5 bib2gls: cross-references, no glossary locations (minimum 32/6000)

This example is as Test 7.4 but suppresses the locations that occur in the glossary:

\backmatter
\GlsXtrSetDefaultNumberFormat{glsignore}
\printunsrtglossaries

This now only requires one bib2gls call:

pdflatex test-doc77a
bib2gls -g test-doc77a
pdflatex test-doc77a

The total build time was 0:03.93 (PDF).

7.6 makeglossaries (makeindex): cross-references (minimum 4000/6000)

This is similar to Test 7.1, but references 4000 entries within the main matter.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makeglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printglossaries
\end{document}

In this case, a total of three iterations in the bash script are needed to fully resolve all references. This is equivalent to:

pdflatex test-doc74big
makeglossaries test-doc74big
pdflatex test-doc74big
makeglossaries test-doc74big
pdflatex test-doc74big
makeglossaries test-doc74big
pdflatex test-doc74big

The total build time was 0:53.27, compared with 0:54.51 for Test 7.1 (PDF).

7.7 makeglossaries (xindy): cross-references (minimum 4000/6000)

This example is as Test 7.6 but uses xindy instead of makeindex. The document should almost be the same as in the other example, except for the xindy package option.

\usepackage[xindy]{glossaries}

Unfortunately the build script in this case originally exceeded the maximum number of iterations (20) with some entries that were actually referenced in the document not being added to the glossary. There were no warning or error messages. On investigate, it turned out that these entries, by random chance, had duplicate names, which meant they had duplicate sort values and so were merged. (This highlights the need to cap the maximum number of iterations.) Although the xrentries.tex file was randomly generated, these duplicates could indicate homographs in a real document. The solution was to redefine \glsprestandardsort to append the entry’s label to the sort value. This ensures unique sort values (although it could adversely affect the sort order).

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[xindy]{glossaries}

\renewcommand*{\glsprestandardsort}[3]{%
\edef#1{#1.#3}%
\glsdosanitizesort
}

\makeglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printglossaries
\end{document}

As in the previous example, a total of three iterations is required to fully resolve all references:

pdflatex test-doc75big
makeglossaries test-doc75big
pdflatex test-doc75big
makeglossaries test-doc75big
pdflatex test-doc75big
makeglossaries test-doc75big
pdflatex test-doc75big

The total build time was 1:12.82, compared with 1:04.61 for Test 7.2 (PDF).

7.8 \makenoidxglossaries: cross-references (minimum 4000/6000)

This example is as Test 7.6 but uses \makenoidxglossaries instead of makeindex. This document takes hours to compile. The main bulk of this time is spent sorting the entries. This only needs to be done on the final LaTeX run, so a workaround is used to omit sorting for the intermediate steps.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\providecommand{\sortmethod}{def}

\makenoidxglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printnoidxglossary[sort=\sortmethod]
\end{document}

The document build required to fully resolve all references is:

pdflatex test-doc76big
pdflatex test-doc76big
pdflatex test-doc76big
pdflatex "\def\sortmethod{standard}\input test-doc76big"

The total build time was aborted at 12h 24m, compared with 0:53.86 for Test 7.3 and 0:53.27 for Test 7.6 (PDF).

7.9 bib2gls: cross-references (minimum 4000/6000)

This example is as Test 7.6 but uses bib2gls instead of makeindex.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}
\begin{document}
\mainmatter

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printunsrtglossaries
\end{document}

As with Test 7.4, two bib2gls calls are require to ensure the location lists include the locations of the entries that are only referenced within the glossary:

pdflatex test-doc77big
bib2gls -g test-doc77big
pdflatex test-doc77big
bib2gls -g test-doc77big
pdflatex test-doc77big

The total build time was 0:53.17, compared with 0:06.98 for Test 7.4 and 0:53.27 for Test 7.6 (PDF).

7.10 bib2gls: cross-references (minimum 4000/6000)

This example is as Test 7.9 but switches to ignored locations in the backmatter:

\GlsXtrSetDefaultNumberFormat{glsignore}
\printunsrtglossaries
As with Test 7.5, this only requires a single bib2gls call:
pdflatex test-doc77abig
bib2gls -g test-doc77abig
pdflatex test-doc77abig

The total build time was 0:25.11, compared with 0:03.93 for Test 7.5 and 0:53.17 for Test 7.9 (PDF).

8. Alphabetical Order With Last Used (Subset)

These tests are as those in Section 3 (location list included) and in Section 7, but there is additional code at the end of the document that writes information to the aux file for each entry that has been marked as used. This simulates storing information in the aux file for use in the next run. The test command that performs this action is:

\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
which needs to be issued at the end of the document.

This command writes \@entry@used{label} to the aux file for each entry that has been marked as used. That command also needs to be defined. In this case, I’m assuming that a comma-separated list of entry labels is required as well as the total number of labels in that list:

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
Note that these definitions use internal commands so \makeatletter and \makeatother are required. Global definitions are necessary as the aux file is input within a group, which means that local definitions will be lost.

It may be that this sub-list isn’t required, in which case this command could simply set a field. For example, the following alternative definition will set the user1 field to 1:

\newcommand{\@entry@used}[1]{\glsfieldgdef{#1}{useri}{1}}
Here's a command that performs a simple test to determine if this field has been set for an individual entry (whose label is provided in the argument):
\newcommand{\ifentrywasusedlastrun}[1]{\ifglsfieldeq{#1}{useri}{1}}
This command actually has three arguments. The final two are the true and false code that will be picked up by \ifglsfieldeq (which takes five arguments). For example:
\ifentrywasusedlastrun{entry1}{was used}{wasn’t used}

For these tests, it’s simpler to create a list and calculate the total count as it makes it easier to check the result. The list is displayed at the start of the document with \glsseelist (this requires its argument to be expanded, otherwise use \glsxtrseelist with glossaries-extra).

With bib2gls, no entries are defined on the first LaTeX run, so there’s nothing to loop over. This means that in order to pick up the information from the aux file, an extra LaTeX run will be required after bib2gls has created the relevant glstex file. (This is likely to be needed anyway for all methods for substantial documents, to ensure page numbers are correct in the table of contents, location lists are up-to-date in the index etc.)

However, in this case, the list that is being iterated over only contains the entries that have been selected by bib2gls, which may be significantly smaller than the entire set of entries that the other methods are iterating over. Furthermore, when using bib2gls, the required information may already be available without the need to save it in the aux file. For example, if I’m testing the first use flag to determine whether or not an entry was indexed in the previous run (since I’m only using \gls, which both indexes and unsets the first use flag), then that information can already be determined.

The default settings with bib2gls means that only those entries that have been recorded (indexed) and their dependencies will be selected. Which means that all entries defined in the document (within the glstex file) were either recorded or were required by a recorded entry. In the event that there are dependencies that aren’t recorded, a simple test is to check if the location field has been set (which will be the case if either the entry is an unrecorded dependency or if it was only recorded with an ignored format, such as glsignore).

The \testloop is now performed in the preamble:

\newcommand{\testloop}{%
\global\advance\usedlastruncount by 1\relax
\forallglsentries{\thisentry}%
{%
\glsxtrifhasfield{location}{\thisentry}%
{%
\ifdefempty\entriesusedlastrun
{\global\let\entriesusedlastrun\thisentry}%
{\xappto\entriesusedlastrun{,\thisentry}}%
}{}%
}
}

If no list of entries from last run is required, but instead you just want to use the earlier \ifentrywasusedlastrun, then this can be defined as:

\newcommand{\ifentrywasusedlastrun}[1]{\glsxtrifhasfield{location}{#1}}

There are cases where the location field will be set for an entry without any records, and that’s where the entry has one of the cross-reference fields set (see, seealso or alias), in which case the cross-reference is added to the location list by default. If that’s likely to occur then another method is to instruct bib2gls to save the record count. By default, this is the total number of all records associated with the entry, including ignored records. If you want to exclude ignored records, you will need bib2gls v3.0+ and use the record-count-rule switch.

Note that if you have been using commands like \cgls, then you may want to consider switching to the analogous \rgls commands, which are more efficient, if you are storing the record count. (The \cgls commands require additional information to be written to the aux file, which is what using the record count is aiming to avoid.) If you want unit record counting, you’ll need to include the --record-count-unit switch when you invoke bib2gls.

The custom \testloop command could now be defined as:

\newcommand{\testloop}{%
\global\advance\usedlastruncount by 1\relax
\forallglsentries{\thisentry}%
{%
\GlsXtrIfFieldNonZero{recordcount}{\thisentry}%
{%
\ifdefempty\entriesusedlastrun
{\global\let\entriesusedlastrun\thisentry}%
{\xappto\entriesusedlastrun{,\thisentry}}%
}{}%
}
}
However, there’s no need for this command as bib2gls provides a command in the glstex file, which is used to set the recordcount field:
\providecommand*{\bibglssettotalrecordcount}[2]{%
\GlsXtrSetField{#1}{recordcount}{#2}%
}
This command can instead be defined before \GlsXtrLoadResources to set the field and the additional information at the same time:
\newcommand*{\bibglssettotalrecordcount}[2]{%
\GlsXtrSetField{#1}{recordcount}{#2}%
\ifnum#2>0\relax
\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\def\entriesusedlastrun{#1}}%
{\appto\entriesusedlastrun{,#1}}%
\fi
}

In this case, \ifentrywasusedlastrun can be defined as:

\newcommand{\ifentrywasusedlastrun}[1]{\GlsXtrIfFieldNonZero{recordcount}{#1}}

For comparison, Test 8.10 and Test 8.17 use the same test command to write to the aux file as the non-bib2gls examples (which requires an extra LaTeX run), whereas the other bib2gls tests replace that command with a simple check to determine whether or not the location field has been set or hook into the record count assignment, as described above.

These alternative bib2gls methods are subtly different from using \ifglsused to determine whether or not to write information to the aux file. Since these test documents are now noting entries that were indexed (recorded) on the last LaTeX run rather that those that were marked as used by the end of the document for the last LaTeX run. The other difference is the order of entry labels in the list \entriesusedlastrun.

\forallglsentries is actually a nested loop that iterates over all glossaries and, for each glossary, iterates over all entries within that glossary. This means that the list will be in subsets corresponding to each glossary, with the items in each subset in the order in which they were added to the glossary (which occurs when the entry is defined). This means that the list is according to the order of definition per glossary. With bib2gls, the order of definition (from LaTeX’s point of view) is the order obtained from sorting. So with bib2gls, the list is in alphabetical order (within each subset).

Finally, Test 8.13 and Test 8.20 use record counting but switch to ignored locations for the glossary and the bib2gls v3.0+ switch --record-count-rule non-ignored is used. Since ignored locations aren’t included in the record count, entries that only occur in the glossary aren’t included in the list created by the test commands because, even though they were marked as used by the end of the document, their record count is zero. These examples have the simplest document build (LaTeX+bib2gls+LaTeX).

The best method depends on whether or not you are specifically interested in entries that have been marked as used (beware of resets) or if you are only interested in entries that have been indexed/recorded. The number of entries that are referenced within the document also makes a difference.

The results are summarized in Table 7. The comparison column shows the build time for the corresponding test from Section 3 or Section 7. Note that all but two tests list all entries that have been used in the document. Test 8.13 and Test 8.20 only list the subset of entries (32 and 4000, respectively) that were used in the main matter and not the additional entries that were added to resolve cross-references.

As with Section 3 and Section 7, the fastest methods are with bib2gls. The document build was approximately 3 seconds for Test 8.5 and 4 seconds for Test 8.13.

The slowest method for the small tests was xindy with a build time of approximately 8 seconds for Test 8.2 and 78 seconds for Test 8.8.

The large 4000/6000 tests that write information to the aux file cause a delay both in writing the information to the aux file at the end of the document and in reading the aux file at the start of the document. There are 4000 entries referenced in the main matter and 207 cross-referenced entries in the glossary. This means that the aux file has an additional 4207 lines on top of what it had for the analogous tests in Section 7.

The aux file will ordinarily be significantly larger with both bib2gls and \makenoidxglossaries, as that’s where the indexing information is saved. With makeindex and xindy, the information is saved in the associated glossary file. This means that all methods have the same number of write operations, but inputting the aux file will take longer for bib2gls and \makenoidxglossaries. Despite this, bib2gls still has the faster build times, even for Test 8.17 because bib2gls is able to resolve all the cross-reference trails in a single call. The second call is only required to ensure the location lists are correct.

For the large 4000/6000 tests, the information added to the aux file caused the build time for bib2gls to jump from 53 seconds to 3 minutes, for makeindex to jump from 53 seconds to 8.5 minutes, and for xindy to jump from 73 seconds to 9 minutes.

Table 7: Summary (Alphabetical Order With Last Used, Subset Referenced)
Test Build time (minutes:​seconds) Comparison PDF
Counterparts to Section 3 (40/2000)
8.1 makeglossaries (makeindex): 20/1000 (entries and acronyms) 0:06.21 0:05.84 (PDF)
8.2 makeglossaries (xindy): 20/1000 (entries and acronyms) 0:07.93 0:07.65 (PDF)
8.3 \makenoidxglossaries: 20/1000 (entries and acronyms) 0:05.83 0:05.64 (PDF)
8.4 bib2gls: 20/1000 (entries and abbreviations) 0:05.41 0:02.57 (PDF)
8.5 bib2gls: 20/1000 (entries and abbreviations) location check 0:02.71 0:02.57 (PDF)
8.6 bib2gls: 20/1000 (entries and abbreviations) record count 0:02.78 0:02.57 (PDF)
Counterparts to Section 7 (32/6000)
8.7 makeglossaries (makeindex): cross-references 1:06.25 0:54.51 (PDF)
8.8 makeglossaries (xindy): cross-references 1:17.87 1:04.61 (PDF)
8.9 \makenoidxglossaries: cross-references 1:05.77 0:53.86 (PDF)
8.10 bib2gls: cross-references 0:07.17 0:06.98 (PDF)
8.11 bib2gls: cross-references, location field 0:07.22 0:06.98 (PDF)
8.12 bib2gls: cross-references, record count 0:07.23 0:06.98 (PDF)
8.13 bib2gls: cross-references, record count and ignored locations 0:04.04 0:03.93 (PDF)
Counterparts to Section 7 (4000/6000)
8.14 makeglossaries (makeindex): cross-references 8:36.02 0:53.27 (PDF)
8.15 makeglossaries (xindy): cross-references 8:48.99 1:12.82 (PDF)
8.16 \makenoidxglossaries: cross-references aborted at 12h 24m (PDF)
8.17 bib2gls: cross-references 3:19.61 0:53.17 (PDF)
8.18 bib2gls: cross-references, location field 1:31.06 0:53.17 (PDF)
8.19 bib2gls: cross-references, record count 1:35.14 0:53.17 (PDF)
8.20 bib2gls: cross-references, record count and ignored locations 0:47.19 0:25.11 (PDF)

8.1 makeglossaries (makeindex): 20/1000 (entries and acronyms)

This example is as Test 3.1, but with the extra commands to save information in the aux file:

\documentclass{article}

\usepackage[acronym]{glossaries}

\makeglossaries
\loadglsentries{entries-1000}
\loadglsentries{acronyms-1000}

\newcount\entryindex
\newcommand{\test}[2]{%
\entryindex=0\relax
\loop
\gls{#1\number\entryindex}.
\advance\entryindex by 1\relax
\ifnum\entryindex<#2
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\test{entry}{20}
\test{abbrv}{20}

\test{entry}{20}
\test{abbrv}{20}

\newpage
\test{entry}{10}
\test{abbrv}{10}

\newpage
\test{entry}{5}
\test{abbrv}{5}

\newpage
\test{entry}{3}
\test{abbrv}{3}

\newpage
\test{entry}{2}
\test{abbrv}{2}

\newpage
\test{entry}{20}
\test{abbrv}{20}

\printglossaries
\end{document}

The document build is:

pdflatex test-doc78
makeglossaries test-doc78
pdflatex test-doc78

The total build time was 0:06.21, compared with 0:05.84 for Test 3.1 (PDF).

8.2 makeglossaries (xindy): 20/1000 (entries and acronyms)

This example is as Test 8.1, but includes the xindy package option.

The document build is:

pdflatex test-doc79
makeglossaries test-doc79
pdflatex test-doc79

The total build time was 0:07.93, compared with 0:07.65 for Test 3.2 and 0:06.21 for Test 8.1 (PDF).

8.3 \makenoidxglossaries: 20/1000 (entries and acronyms)

This example is as Test 3.3, but with the extra commands to save information in the aux file:

\documentclass{article}

\usepackage[acronym]{glossaries}

\makenoidxglossaries
\loadglsentries{entries-1000}
\loadglsentries{acronyms-1000}

\newcount\entryindex
\newcommand{\test}[2]{%
\entryindex=0\relax
\loop
\gls{#1\number\entryindex}.
\advance\entryindex by 1\relax
\ifnum\entryindex<#2
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\test{entry}{20}
\test{abbrv}{20}

\test{entry}{20}
\test{abbrv}{20}

\newpage
\test{entry}{10}
\test{abbrv}{10}

\newpage
\test{entry}{5}
\test{abbrv}{5}

\newpage
\test{entry}{3}
\test{abbrv}{3}

\newpage
\test{entry}{2}
\test{abbrv}{2}

\newpage
\test{entry}{20}
\test{abbrv}{20}

\printnoidxglossaries
\end{document}

The document build is:

pdflatex test-doc80
pdflatex test-doc80

The total build time was 0:05.83, compared with 0:05.64 for Test 3.3 and 0:06.21 for Test 8.1 (PDF).

8.4 bib2gls: 20/1000 (entries and abbreviations)

This example is as Test 3.4, but with the extra commands to save information in the aux file:

\documentclass{article}

\usepackage[abbreviations,record,postdot]{glossaries-extra}

\GlsXtrLoadResources[src={entries-1000,abbreviations-1000}]

\newcount\entryindex
\newcommand{\test}[2]{%
\entryindex=0\relax
\loop
\gls{#1\number\entryindex}.
\advance\entryindex by 1\relax
\ifnum\entryindex<#2
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\test{entry}{20}
\test{abbrv}{20}

\test{entry}{20}
\test{abbrv}{20}

\newpage
\test{entry}{10}
\test{abbrv}{10}

\newpage
\test{entry}{5}
\test{abbrv}{5}

\newpage
\test{entry}{3}
\test{abbrv}{3}

\newpage
\test{entry}{2}
\test{abbrv}{2}

\newpage
\test{entry}{20}
\test{abbrv}{20}

\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc81
bi2gls --group test-doc81
pdflatex test-doc81
pdflatex test-doc81

Note the extra LaTeX call that’s required in this case.

The resulting document is slightly different to Test 8.3, as the list stored in \entriesusedlastrun is now in alphabetical order (per glossary). Whereas in the previous tests, the list stored in \entriesusedlastrun is in the order of definition (per glossary). They are, in fact, both in order of definition, it’s just that bib2gls writes the LaTeX definition code in the glstex files in the order obtained from sorting (which is how it can be used with \printunsrtglossary).

The total build time was 0:05.41, compared with 0:02.57 for Test 3.4 and 0:06.21 for Test 8.1 (PDF).

8.5 bib2gls: 20/1000 (entries and abbreviations) location check

This example is as Test 8.4, but instead of saving information in the aux file, it simply tests if the location field has been set. Note that in this case \testloop is performed before the start of the document instead of at the end of the document.

\documentclass{article}

\usepackage[abbreviations,record,postdot]{glossaries-extra}

\GlsXtrLoadResources[src={entries-1000,abbreviations-1000}]

\newcount\entryindex
\newcommand{\test}[2]{%
\entryindex=0\relax
\loop
\gls{#1\number\entryindex}.
\advance\entryindex by 1\relax
\ifnum\entryindex<#2
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}
\newcommand{\testloop}{%
\global\advance\usedlastruncount by 1\relax
\forallglsentries{\thisentry}%
{%
\glsxtrifhasfield{location}{\thisentry}%
{%
\ifdefempty\entriesusedlastrun
{\global\let\entriesusedlastrun\thisentry}%
{\xappto\entriesusedlastrun{,\thisentry}}%
}{}%
}
}

\testloop

\begin{document}
\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\test{entry}{20}
\test{abbrv}{20}

\test{entry}{20}
\test{abbrv}{20}

\newpage
\test{entry}{10}
\test{abbrv}{10}

\newpage
\test{entry}{5}
\test{abbrv}{5}

\newpage
\test{entry}{3}
\test{abbrv}{3}

\newpage
\test{entry}{2}
\test{abbrv}{2}

\newpage
\test{entry}{20}
\test{abbrv}{20}

\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc82
bi2gls --group test-doc82
pdflatex test-doc82

The total build time was 0:02.71, compared with 0:02.57 for Test 3.4 and 0:05.41 for Test 8.4 (PDF).

8.6 bib2gls: 20/1000 (entries and abbreviations) record count

This example is as Test 8.5, but uses record counting instead of checking the location field. The document build requires that bib2gls is invoked with the --record-count (or -c) switch. This will save the record count in the recordcount field. The \testloop command is defined in this case.

\documentclass{article}

\usepackage[abbreviations,record,postdot]{glossaries-extra}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\newcommand*{\bibglssettotalrecordcount}[2]{%
\GlsXtrSetField{#1}{recordcount}{#2}%
\ifnum#2>0\relax
\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\def\entriesusedlastrun{#1}}%
{\appto\entriesusedlastrun{,#1}}%
\fi
}

\GlsXtrLoadResources[src={entries-1000,abbreviations-1000}]

\newcount\entryindex
\newcommand{\test}[2]{%
\entryindex=0\relax
\loop
\gls{#1\number\entryindex}.
\advance\entryindex by 1\relax
\ifnum\entryindex<#2
\repeat
}

\begin{document}
\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\test{entry}{20}
\test{abbrv}{20}

\test{entry}{20}
\test{abbrv}{20}

\newpage
\test{entry}{10}
\test{abbrv}{10}

\newpage
\test{entry}{5}
\test{abbrv}{5}

\newpage
\test{entry}{3}
\test{abbrv}{3}

\newpage
\test{entry}{2}
\test{abbrv}{2}

\newpage
\test{entry}{20}
\test{abbrv}{20}

\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc83
bi2gls --group --record-count test-doc83
pdflatex test-doc83

The total build time was 0:02.78, compared with 0:02.57 for Test 3.4 and 0:02.71 for Test 8.5 (PDF).

8.7 makeglossaries (makeindex): cross-references (minimum 32/6000)

This example is like Test 7.1, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makeglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printglossaries
\end{document}

As with Test 7.1, a total of four iterations are needed to fully resolve all references, but one final LaTeX call is required to ensure that the last used information is correct:

pdflatex test-doc84
makeglossaries test-doc84
pdflatex test-doc84
makeglossaries test-doc84
pdflatex test-doc84
makeglossaries test-doc84
pdflatex test-doc84
makeglossaries test-doc84
pdflatex test-doc84

The total build time was 1:06.25, compared with 0:54.51 for Test 7.1 (PDF).

8.8 makeglossaries (xindy): cross-references (minimum 32/6000)

This example is like Test 7.2, but with the extra commands to save information in the aux file. The document is the same as for Test 8.7 but uses the xindy package option.

As before, a total of four iterations are needed to fully resolve all references, and one final LaTeX call is required to ensure that the last used information is correct:

pdflatex test-doc85
makeglossaries test-doc85
pdflatex test-doc85
makeglossaries test-doc85
pdflatex test-doc85
makeglossaries test-doc85
pdflatex test-doc85
makeglossaries test-doc85
pdflatex test-doc85
pdflatex test-doc85

The total build time was 1:17.87, compared with 1:04.61 for Test 7.2 (PDF).

8.9 \makenoidxglossaries: cross-references (minimum 32/6000)

This example is like Test 7.3, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makenoidxglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printnoidxglossaries
\end{document}

As before, a total of four iterations are needed to fully resolve all references, but one final LaTeX call is needed to ensure the last used information is correct:

pdflatex test-doc86
pdflatex test-doc86
pdflatex test-doc86
pdflatex test-doc86
pdflatex test-doc86

The total build time was 1:05.77, compared with 0:53.86 for Test 7.3 (PDF).

8.10 bib2gls: cross-references (minimum 32/6000)

This example is like Test 7.4, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printunsrtglossaries
\end{document}

The document build requires two bib2gls calls to ensure that the location lists are correct. All the dependent entries are found on the first call, but their locations can’t be determined until they are recorded when the glossary is typeset. Since all entries are present following the first bib2gls call, they will all be added to the aux file on the second LaTeX call, so \entriesusedlastrun will be up-to-date by the third LaTeX call.

pdflatex test-doc87
bib2gls -g test-doc87
pdflatex test-doc87
bib2gls -g test-doc87
pdflatex test-doc87

As with Test 8.4, the list of last used entries is in alphabetical order.

The total build time was 0:07.17, compared with 0:06.98 for Test 7.4 (PDF).

8.11 bib2gls: cross-references (minimum 32/6000) location field

This example is like Test 8.10, but the location field is tested instead of saving information in the aux file.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}
\newcommand{\testloop}{%
\global\advance\usedlastruncount by 1\relax
\forallglsentries{\thisentry}%
{%
\glsxtrifhasfield{location}{\thisentry}%
{%
\ifdefempty\entriesusedlastrun
{\global\let\entriesusedlastrun\thisentry}%
{\xappto\entriesusedlastrun{,\thisentry}}%
}{}%
}
}

\testloop

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc88
bib2gls -g test-doc88
pdflatex test-doc88
bib2gls -g test-doc88
pdflatex test-doc88

The total build time was 0:07.22, compared with 0:06.98 for Test 7.4 and 0:07.17 for Test 8.10 (PDF).

8.12 bib2gls: cross-references (minimum 32/6000) record count

This example is like Test 8.11, but record counting is used.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\newcommand*{\bibglssettotalrecordcount}[2]{%
\GlsXtrSetField{#1}{recordcount}{#2}%
\ifnum#2>0\relax
\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\def\entriesusedlastrun{#1}}%
{\appto\entriesusedlastrun{,#1}}%
\fi
}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{50}{600}

\chapter{Second}
\test{600}{5}{700}

\backmatter
\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc89
bi2gls --group --record-count test-doc89
pdflatex test-doc89
bi2gls --group --record-count test-doc89
pdflatex test-doc89

The total build time was 0:07.23, compared with 0:06.98 for Test 7.4 and 0:07.17 for Test 8.10 (PDF).

8.13 bib2gls: cross-references (minimum 32/6000) record count excluding glossary

This example is like Test 8.12, but locations within the glossary are suppressed (Test 7.5)

\GlsXtrSetDefaultNumberFormat{glsignore}
\printunsrtglossaries

This now only requires one bib2gls call. As with the previous example, when --record-count is used, this example will list the 32 entries that are referenced in the main document plus the 7 cross-references that only occur in the document. This is because, by default, the record count includes ignored records.

With bib2gls v3.0+, it’s possible to exclude the ignored records from the count:

pdflatex test-doc90
bib2gls --group --record-count-rule non-ignored test-doc90
pdflatex test-doc90
If you prefer short switches:
pdflatex test-doc90
bib2gls -g -r n test-doc90
pdflatex test-doc90
This will now only list the 32 entries that are referenced in the main document.

The total build time was 0:04.04, compared with 0:06.98 for Test 7.4 and 0:07.17 for Test 8.10 (PDF).

8.14 makeglossaries (makeindex): cross-references (minimum 4000/6000)

This example is like Test 7.6, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\makeglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printglossaries
\end{document}
A similar bash script to that for Test 7.1 was used. In this case, there were three iterations in the loop, but an additional LaTeX call is required to ensure that \entriesusedlastrun is up-to-date. The document build is therefore:
pdflatex test-doc84big
makeglossaries test-doc84big
pdflatex test-doc84big
makeglossaries test-doc84big
pdflatex test-doc84big
makeglossaries test-doc84big
pdflatex test-doc84big
pdflatex test-doc84big

The total build time was 8:36.02, compared with 0:53.27 for Test 7.6 (PDF).

8.15 makeglossaries (xindy): cross-references (minimum 4000/6000)

This example is like Test 7.7, but with the extra commands to save information in the aux file. The document is the same as for Test 8.14 but uses the xindy package option and, as with Test 7.7, it needs to ensure unique sort values:

\usepackage[xindy]{glossaries}

\renewcommand*{\glsprestandardsort}[3]{%
\edef#1{#1.#3}%
\glsdosanitizesort
}

The document build is as for Test 8.14:

pdflatex test-doc85big
makeglossaries test-doc85big
pdflatex test-doc85big
makeglossaries test-doc85big
pdflatex test-doc85big
makeglossaries test-doc85big
pdflatex test-doc85big
pdflatex test-doc85big

The total build time was 8:48.99, compared with 1:12.82 for Test 7.7 (PDF).

8.16 \makenoidxglossaries: cross-references (minimum 4000/6000)

This example is like Test 7.8, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}

\providecommand{\sortmethod}{def}

\makenoidxglossaries
\loadglsentries{xrentries}

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\expandafter\glsseelist\expandafter{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printnoidxglossary[sort=\sortmethod]
\end{document}

The document build required to fully resolve all references and ensure that \entriesusedlastrun is up-to-date:

pdflatex test-doc86big
pdflatex test-doc86big
pdflatex test-doc86big
pdflatex test-doc86big
pdflatex "\def\sortmethod{standard}\input test-doc86big"

Since Test 7.8 was aborted at 12h 24m, there was no point running this test. The impact of saving and retrieving information in the aux file is negligible compared to the length of time taken to sort the entries.

8.17 bib2gls: cross-references (minimum 4000/6000)

This example is like Test 7.9, but with the extra commands to save information in the aux file:

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\makeatletter
\newcommand{\@entry@used}[1]{%
\global\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\gdef\entriesusedlastrun{#1}}%
{\gappto\entriesusedlastrun{,#1}}%
}
\newcommand{\testloop}{\forallglsentries{\thisentry}%
{\ifglsused{\thisentry}{\protected@write\@auxout{}{\string\@entry@used{\thisentry}}}{}}}
\makeatother

\AtEndDocument{\testloop}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printunsrtglossaries
\end{document}

The document build is as for Test 8.10:

pdflatex test-doc87big
bib2gls -g test-doc87big
pdflatex test-doc87big
bib2gls -g test-doc87big
pdflatex test-doc87big

As with Test 8.10, the list of last used entries is in alphabetical order.

The total build time was 3:19.61, compared with 0:53.17 for Test 7.9 (PDF).

8.18 bib2gls: cross-references (minimum 4000/6000) location field

This example is like Test 8.17, but the location field is tested instead of saving information in the aux file.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}
\newcommand{\testloop}{%
\global\advance\usedlastruncount by 1\relax
\forallglsentries{\thisentry}%
{%
\glsxtrifhasfield{location}{\thisentry}%
{%
\ifdefempty\entriesusedlastrun
{\global\let\entriesusedlastrun\thisentry}%
{\xappto\entriesusedlastrun{,\thisentry}}%
}{}%
}
}

\testloop

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc88big
bib2gls -g test-doc88big
pdflatex test-doc88big
bib2gls -g test-doc88big
pdflatex test-doc88big

The total build time was 1:31.06, compared with 0:53.17 for Test 7.9 and 3:19.61 for Test 8.17 (PDF).

8.19 bib2gls: cross-references (minimum 4000/6000) record count

This example is like Test 8.18, but record counting is used.

\documentclass{book}

\usepackage[colorlinks]{hyperref}
\usepackage[record]{glossaries-extra}

\newcount\usedlastruncount
\newcommand{\entriesusedlastrun}{}

\newcommand*{\bibglssettotalrecordcount}[2]{%
\GlsXtrSetField{#1}{recordcount}{#2}%
\ifnum#2>0\relax
\advance\usedlastruncount by 1\relax
\ifdefempty\entriesusedlastrun
{\def\entriesusedlastrun{#1}}%
{\appto\entriesusedlastrun{,#1}}%
\fi
}

\GlsXtrLoadResources[src={xrentries}]

\newcount\entryindex
\newcommand{\test}[3]{%
\entryindex=#1\relax
\loop
\gls{xrentry\number\entryindex}.
\advance\entryindex by #2\relax
\ifnum\entryindex<#3
\repeat
}

\begin{document}
\frontmatter
\pagenumbering{roman}
\chapter{Recap}

\ifdefempty\entriesusedlastrun
{No entries used last run.}
{\number\usedlastruncount\space entries used last run:
\glsxtrseelist{\entriesusedlastrun}.}

\mainmatter
\pagenumbering{arabic}

\chapter{First}
\test{0}{1}{2000}

\chapter{Second}
\test{4000}{1}{6000}

\backmatter
\printunsrtglossaries
\end{document}

The document build is:

pdflatex test-doc89big
bi2gls --group --record-count test-doc89big
pdflatex test-doc89big
bi2gls --group --record-count test-doc89big
pdflatex test-doc89big

The total build time was 1:35.14, compared with 0:53.17 for Test 7.9 and 3:19.61 for Test 8.17 (PDF).

8.20 bib2gls: cross-references (minimum 4000/6000) record count excluding glossary

This example is like Test 8.19, but locations within the glossary are suppressed (Test 7.10)

\GlsXtrSetDefaultNumberFormat{glsignore}
\printunsrtglossaries

The document build is as for Test 8.13:

pdflatex test-doc90big
bib2gls --group --record-count-rule non-ignored test-doc90big
pdflatex test-doc90big

The total build time was 0:47.19, compared with 0:53.17 for Test 7.9 and 3:19.61 for Test 8.17 (PDF).

Summary

1. If you only have ASCII sort values, then makeindex is the fastest method if you want an alphabetical list of all defined entries for simple documents that don’t have complex cross-references. If you can’t work out how to integrate makeindex into your document build, use the automake package option.
2. Cross-reference trails work best with bib2gls. With other methods, the document build complexity can increase significantly.
3. The \makenoidxglossaries method should not be used for alphabetical sorting for a large number of entries. Test 7.3 took approximately 54 seconds to sort 39 entries, Test 1.8 took approximately 11 minutes to sort 100 entries, and Test 7.8, which had 4,207 entries, was aborted at 12h 24m.
4. If you have non-ASCII sort values that consist of words or phrases and you want the terms ordered according to a particular locale’s alphabet, then use xindy or bib2gls.
5. If the sort value consists solely of LaTeX commands, then the best method is bib2gls if bib2gls can convert the commands into the best matching Unicode characters or if another field (such as description) may be used as a more appropriate sort value (see Gallery: Sorting). Otherwise consider ordering by definition or use a helper command, like the example \newsymbol, to make it easier to assign the sort key to the label or description.
6. If you’re sorting by order of use, the best methods are using bib2gls or using TeX (\makenoidxglossaries) but don’t have order of use with hierarchical entries as they are incompatible.
7. If you don’t want to use an external tool, the simplest method is to define your terms in the required order (and only define the terms that are required in the document) and use \printunsrtglossary with glossaries-extra. Note that this won’t create any location lists.
8. If you want to have a large file (or set of files) containing all the terms that you might need in any of your documents, then the best method is to use bib2gls with glossaries-extra. This is more efficient in terms of the document build time.
9. If you have abbreviations then, with just the base glossaries package, use \setacronymstyle (to switch to the newer acronym mechanism) or, with the extension glossaries package, use \newabbreviation (rather than \newacronym).

History

Version 2 (2022-06-18)

This document was updated to add Section 7 and Section 8. All test documents were rebuilt with glossaries.sty v4.49, glossaries-extra.sty v1.48 and bib2gls v3.0.

Version 1 (2019-09-10)

The original document had tests compiled with TeX Live 2017, glossaries.sty v4.35, glossaries-extra.sty v1.27 and bib2gls v1.2. A summary of all build times from the previous version of this document are listed in Table H1.
Table H1: Summary of V1 Results
Test Build time (minutes:​seconds)
1.10:02.31
1.20:02.47
1.30:02.22
1.40:02.22
1.50:03.84
1.60:02.97
1.70:03.66
1.810:41.13
1.90:02.86
1.100:04.46
1.1110:29.05
1.120:03.07
1.130:04.16
1.140:03.51
1.150:05.57
1.160:04.77
1.1710:22.21
1.1810:15.07
1.190:06.76
1.200:05.76
1.210:07.13
1.2210:13.18
1.230:04.63
2.10:02.30
2.20:02.28
2.30:02.28
2.40:02.33
2.5failed
2.60:03.75
2.70:03.85
2.80:03.77
2.90:03.70
2.100:03.82
2.1110:31.03
2.1210:27.78
2.1310:29.45
2.1410:48.98
2.1510:48.40
2.160:03.20
2.170:03.15
2.180:03.30
2.190:03.35
2.200:03.26
3.10:05.30
3.20:07.16
3.30:05.06
3.40:02.30
3.50:05.28
3.60:07.12
3.70:05.11
3.80:02.32
3.90:02.45
4.10:02.27
4.20:03.69
4.30:03.08
4.40:01.53
4.50:02.90
5.10:05.01
5.20:05.65
5.30:04.93
5.40:02.19
6.10:00.73
6.20:00.59
6.30:00.67
6.40:00.58
6.50:00.58
6.60:00.64
6.70:00.64
6.8failed
6.90:00.88
6.100:00.89
6.110:00.94
6.120:00.94
6.130:01.07
6.140:00.91
6.150:01.73
6.160:00.84
6.170:00.87
6.180:00.89
6.190:01.33
6.200:00.48
6.210:00.57
6.220:01.35
6.230:01.33
6.240:01.34
6.250:01.49
6.260:01.33
6.270:01.35
6.280:01.38
6.290:01.21

© 2018 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.