I am writing on a thesis with a symbols glossary with some custom-defined fields and a custom-defined glossary style. The document also has an abbreviations glossary but it does not use any custom fields nor custom style.
This has been working great for several months of draft revisions, along with all the default glossary commands (\gls, \glsname, etc.).
Recently I redefined the custom fields from field-aliases to \glsaddkey in order to be able to print them in the document, and stumbled on some very curious behaviour which seems to center around siunitx, glossaries-extra (possibly also bib2gls) and latexmk. Read on for the gory details. I would be grateful for help in understanding what could be going on.
Here's (the relevant parts of) my preamble including the definition of my custom glossary fields as well as my glossary style:
\RequirePackage{luatex85}
\PassOptionsToPackage{final}{graphicx}
\PassOptionsToPackage{final}{hyperref}
% https://git.solarchemist.se/config/texmf-latex/src/branch/master/UUThesisTemplate.cls
\documentclass[draft,openright,titles]{LuaUUThesis}
\usepackage{siunitx}
\sisetup{uncertainty-mode=compact,reset-text-family=false,text-family-to-math=true}
\usepackage{hyperref}
\usepackage[record=nameref,abbreviations,symbols,nomain]{glossaries-extra}
\glsaddkey{value}{\glsentryvalue}{\Glsentryvalue}{\glsvalue}{\Glsvalue}{\GLSvalue}
\glsaddkey{unit}{}{\glsentryunit}{\Glsentryunit}{\glsunit}{\Glsunit}{\GLSunit}
\glsaddkey{exact}{}{\glsentryexact}{\Glsentryexact}{\glsexact}{\Glsexact}{\GLSexact}
% \glssetnoexpandfield{value} % had no effect
% \glssetnoexpandfield{unit} % had no effect
% \glsnoexpandfields % had no effect, same error
\GlsXtrLoadResources[src={assets/glossaries/acronyms},sort={en-GB},selection=all]
\GlsXtrLoadResources[src={assets/glossaries/symbols},sort={en-GB},selection=all]
\setlength{\glsdescwidth}{.90\textwidth}
% define custom style=supermod that includes value/unit
% the code below is based on glossaries-extra v1.50 source code
\newglossarystyle{supermod}{%
\renewenvironment{theglossary}{%
\tablehead{}\tabletail{}%
\begin{supertabular}{@{}lp{\glsdescwidth}}%
}{%
\end{supertabular}%
}%
\renewcommand{\glossaryheader}{}%
\renewcommand{\glsgroupheading}[1]{}%
\renewcommand{\glssubgroupheading}[4]{}%
\renewcommand{\glossentry}[2]{%
\glsentryitem{##1}\glstarget{##1}{\glossentryname{##1}} &
\ifglshasfield{value}{##1}{%
% if field "exact" is set, use $\equiv$ sign instead of equals sign
\ifglshasfield{exact}{##1}{%
\ifthenelse{\glsentryexact{##1} = 1}{$\equiv$}{$=$}%
}{$=$}%
\ifglshasfield{unit}{##1}{%
$\thinspace$\qty{\glsentryvalue{##1}}{\glsentryunit{##1}}\newline%
}{%
$\thinspace$\num{\glsentryvalue{##1}}\newline%
}%
}{%
\ifglshasfield{unit}{##1}{%
$/\unit{\glsentryunit{##1}}$\newline%
}{}%
}%
\glossentrydesc{##1}%
\glspostdescription%
\space ##2%
\tabularnewline[0pt]
}%
% I am not using sub-entries, so this could be removed?
\renewcommand{\subglossentry}[3]{%
&
\glssubentryitem{##2}%
\glstarget{##2}{\strut}\glossentrydesc{##2}\glspostdescription
\space ##3\tabularnewline
}%
\ifglsnogroupskip
\renewcommand{\glsgroupskip}{}%
\else
\renewcommand*{\glsgroupskip}{& \tabularnewline}%
\fi
}
And here's a few representative entries from the symbols.bib glossary (I use bib2gls):
@Symbol{electron_mass,
Name = {{}\ensuremath{m_\mathrm{e}}},
Sort = {electron mass},
Description = {mass of a stationary electron},
Text = {electron mass},
Exact = {},
Value = {9.1093837015 \pm 0.0000000028e-31},
Unit = {\kg},
First = {electron mass, \ensuremath{m_\mathrm{e}}}
}
@Symbol{elementary_charge,
Name = {{}\ensuremath{q_\mathrm{e}}},
Sort = {elementary charge},
Description = {elementary charge, the negative charge carried by a single electron},
Text = {elementary charge},
Exact = {1},
Value = {1.602176634e-19},
Unit = {\coulomb},
First = {elementary charge, \ensuremath{q_\mathrm{e}}}
}
@Symbol{frequency,
Name = {{}\ensuremath{\nu}},
Sort = {frequency},
Description = {frequency of electromagnetic radiation (the inverse of wavelength)},
Text = {frequency},
Exact = {},
Value = {},
Unit = {\Hz},
First = {frequency, \ensuremath{\nu}}
}
As you can see, the value field is a number using scientific notation and sometimes +- error. It is not surrounded by siunitx \num{}, which has worked fine (I add \num{...} later, when printing).
Likewise the unit field does not surround the siunitx unit macros with \unit{}.
You may notice that my custom glossary style takes advantage of this way of defining value and unit and contains \qty{\glsentryvalue{##1}}{\glsentryunit{##1}} (or only \num{...} or only \unit{...}, as the case may be) which has typographic advantages compared to manually setting the value-unit inter-space.
What I want to impress is that this approach has worked fine for several months, including many fresh recompilations (where all auxiliary files were wiped).
Like mentioned above, the whole thing started falling apart when I attempt to siunitx-print the value/unit using the \glsentryvalue{...} or \glsentryunit{...} commands made available by their respective \glsaddkey definitions.
Giving the \glsentryvalue command by itself works without problem (typesets the value as text, e.g., "1.602176634e-19", which is not pretty but always works).
The unit field would likewise work except it contains "naked" siunitx unit macros, and will thus fail, but that is for an easily understandable reason.
So naturally, I would like to put those \glsentry*{...} commands inside siunitx macros.
And this is where (re)compilations start to behave differently depending on whether auxiliary files exist or not.
\begin{document}
\glsentryvalue{elementary_charge} % always works
% with the 3 following rows commented out, compilation from "clean slate" works
\num{\glsentryvalue{elementary_charge}} % works only if aux files are present
\unit{\glsentryunit{elementary_charge}} % ditto
\qty{\glsentryvalue{electron_mass}}{\glsentryunit{electron_mass}} % ditto
\end{document}
I guess I should explain my build procedure.
It is a pretty straight-forward latexmk build, just latexmk -pdf -bibtex thesis with the following pretty vanilla .latexmkrc file (to handle makeglossaries and bib2gls):
$pdflatex = 'lualatex -file-line-error %O %S';
$pdf_mode = 1;
$postscript_mode = $dvi_mode = 0;
add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');
add_cus_dep('slo', 'sls', 0, 'run_makeglossaries');
sub run_makeglossaries {
system( "makeglossaries '$_[0]'" );
}
push @generated_exts, 'glstex', 'glg';
add_cus_dep('aux', 'glstex', 0, 'run_bib2gls');
sub run_bib2gls {
if ( $silent ) {
my $ret = system "bib2gls --silent --group '$_[0]'";
} else {
my $ret = system "bib2gls --group '$_[0]'";
};
my ($base, $path) = fileparse( $_[0] );
if ($path && -e "$base.glstex") {
rename "$base.glstex", "$path$base.glstex";
}
local *LOG;
$LOG = "$_[0].glg";
if (!$ret && -e $LOG) {
open LOG, "<$LOG";
while (<LOG>) {
if (/^Reading (.*\.bib)\s$/) {
rdb_ensure_file( $rule, $1 );
}
}
close LOG;
}
return $ret;
}
As a matter of prudence, every now and then (like a few times a week) I usually delete all the LaTeX auxiliary files before recompiling. This makes the subsequent compilation take marginally longer time, but so far I have never experienced that a compilation from a "clean slate" fails when the same sources compiled successfully before wiping the auxiliary files.
And yet, that's exactly what appears to be happening when adding \num{\glsentryvalue{elementary_charge}} to the document.
Step-by-step procedure that should reproduce this weird behaviour:
- At this point the LaTeX source contains no
\num{\glsentryvalue{...}}nor\unit{\glsentryunit{...}}commands, and the working directory is clean (no aux files). We compile withlatexmk ...as per above. Compilation succeeds, as expected. - Now add
\num{\glsentryvalue{...}}(orunitorqty) to the source, and recompile withlatexmk ...as per above. Compilation succeeds and the siunitx values/units/quantities are correctly typeset. So what's the problem? - Well, now wipe all the aux files. Recompile, and watch it choke on the first occurrence of
\num{\glsentryvalue{...}}during the firstlualatexrun with:Package siunitx Error: Invalid number ''
If I comment out the offending line and recompile it succeeds, and then I uncomment the same line and recompile again and it will succeed (provided I don't wipe the aux files in between). What is up with that?
Note that this works whether or not any of \glssetnoexpandfield{value}, \glssetnoexpandfield{unit} or \glsnoexpandfields were declared. Perhaps they are no longer necessary - the latest TeX.SE posts recommending them are from several years ago.
I tried to identify which aux file this behaviour depends on, but could not determine any specific one. These are all the generated aux files for my project: *.aux, *.bcf, *.fls, *-1.glstex, *.glstex, *.lof, *.lol, *.los, *.out, *.bbl, *.blg, *.fdb_latexmk, *.glg, *.lob, *.log, *.lor, *.lot, *.run.xml, *.toc.
I went so far as to delete them one at a time then recompiling, but found that recompilation succeeded in all cases.
So it seems the absence of any one aux file does not trigger this behaviour, but the absence of all them does? I'm no LaTeX developer, but that is weird, right?
So, I can't figure out if this is a siunitx or glossaries-extra or latexmk issue. Your comments or questions are much appreciated.
I have tried to eliminate other possible factors by doing some testing, and can confirm that
it's not caused by using siunitx v2 or v3 (same behaviour for \usepackage{siunitx} as \usepackage{siunitx}[=v2]); TeXLive 2022 or 2023 made no difference; surrounding the unit field in the glossary by \unexpanded{...} had no effect; \glssetnoexpandfield{unit} and \glssetnoexpandfield{value} had no effect; \glsnoexpandfields made no difference; disabling draft mode in documentclass had no effect.
TeXLive 2023 with glossaries-extra 1.50, siunitx 3.2.2, and bib2gls 3.2, latexmk 4.79
on Ubuntu 22.04.
Related links:
- delay load of glossary to
\AtBeginDocument, 2022 - Dickimaw gallery example: units, 2021
- setting width dynamically from siunitx unit macros, 2017
- how to use siunitx command in glossary entry?, 2016
- custom unit glossary field with siunitx, 2014
- redefining glossary display color, 2013
- makeglossaries and latexmk, 2012
- why LaTeX produces auxiliary files, 2011
- should you (and how to) delete auxiliary files, 2011
articleorbook. We'd always like to help, but not when we have to do a lot of digging and clean up first. – daleif Mar 23 '23 at 09:03