siunitx abbreviations don't work inside glossaries entries
It seems that the \si
\si
abbreviation commands like \J
(see Ulrike's answer) can't be processed in the preamble. This can be demonstrated with:
\documentclass{article}
\usepackage{siunitx}
\settowidth{\dimen0}{[\si{\J\per\kg\per\K}]}
\begin{document}
\end{document}
This causes the error:
! Undefined control sequence.
<argument> \J
\per \kg \per \K
Moving \settowidth
to the document environment gets rid of the error.
This means that the unit width can't be calculated in the preamble for your MWE, but \makenoidxglossaries
won't permit \newglossaryentry
in the document
environment (and it's not recommended with \makeglossaries
). Instead you can make use of the \glsFindWidestUsedAnyNameSymbol
command provided with glossaries-extra-stylemods
:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{calc,siunitx}
\sisetup{load-configurations = abbreviations}
\usepackage[stylemods]{glossaries-extra}
\makenoidxglossaries
\newlength\glsnamewidth
\newlength\glsunitwidth
\settowidth{\glsnamewidth}{\textbf{sign}}
\settowidth{\glsunitwidth}{\textbf{unit}}
\newglossarystyle{namedescunit}{%
\setlength{\glsdescwidth}{\linewidth-\glsnamewidth-\glsunitwidth-6\tabcolsep}%
\renewenvironment{theglossary}%
{\begin{supertabular}{p{\glsnamewidth}p{\glsunitwidth}p{\glsdescwidth}}}%
{\end{supertabular}}%
\renewcommand*{\glossaryheader}{}%
\renewcommand*{\glsgroupheading}[1]{}%
\renewcommand{\glossentry}[2]{%
\raggedright\glstarget{##1}{\glossentryname{##1}} &
\centering\glossentrysymbol{##1} &
\glossentrydesc{##1}\tabularnewline
}%
\renewcommand{\subglossentry}[3]{\glossentry{##2}{##3}}%
\renewcommand*{\glsgroupskip}{}%
}
\setglossarystyle{namedescunit}
\newglossaryentry{L}{name={L},description={Buchstabe},symbol={---}}
\newglossaryentry{P}{name={Cp},description={specific heat},symbol={[\si{\J\per\kg\per\K}]}}
\begin{document}
\lipsum[1]
\gls{L}, \gls{P}.
\glsFindWidestUsedAnyNameSymbol{\glsunitwidth}
\settowidth{\dimen0}{\glsgetwidestname}
\ifdim\dimen0>\glsnamewidth
\glsnamewidth=\dimen0
\fi
\printnoidxglossaries
\end{document}
\glsFindWidestUsedAnyNameSymbol
only checks entries that have been marked as used (through commands like \gls
) so needs to be used just before the glossary (provided it's at the end of the document). If you use \glsaddall
instead, use \glsFindWidestAnyNameSymbol
which can be placed at the start of the document:
\begin{document}
\glsFindWidestAnyNameSymbol{\glsunitwidth}
\settowidth{\dimen0}{\glsgetwidestname}
\ifdim\dimen0>\glsnamewidth
\glsnamewidth=\dimen0
\fi
\lipsum[1]
\glsaddall
\printnoidxglossaries
\end{document}
The definitions for the abbreviations are loaded only at begin document. So you should either move your glossary definition behind \begin{document}
, not use abbreviations in the glossary definitions or load the abbreviations earlier:
\documentclass{article}
\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{calc,siunitx}
%load abbreviations:
\ExplSyntaxOn
\__siunitx_load_abbreviations:
\ExplSyntaxOff
\usepackage{glossaries}
\makenoidxglossaries
\newlength\glsnamewidth
\newlength\glsunitwidth
\settowidth{\glsnamewidth}{\textbf{sign}}
\settowidth{\glsunitwidth}{\textbf{unit}}
\newglossarystyle{namedescunit}{%
\setlength{\glsdescwidth}{\linewidth-\glsnamewidth-\glsunitwidth-6\tabcolsep}%
\renewenvironment{theglossary}%
{\begin{supertabular}{p{\glsnamewidth}p{\glsunitwidth}p{\glsdescwidth}}}%
{\end{supertabular}}%
\renewcommand*{\glossaryheader}{}%
\renewcommand*{\glsgroupheading}[1]{}%
\renewcommand{\glossentry}[2]{%
\raggedright\glstarget{##1}{\glossentryname{##1}} &
\centering\glossentrysymbol{##1} &
\glossentrydesc{##1}\tabularnewline
}%
\renewcommand{\subglossentry}[3]{\glossentry{##2}{##3}}%
\renewcommand*{\glsgroupskip}{}%
}
\setglossarystyle{namedescunit}
%%%%%%%%% this code block causes the crash %%%%%%%%%%%
\makeatletter
\appto\@newglossaryentryposthook{%
\settowidth{\dimen@}{\glsentryname{\@glo@label}}%
\ifdim\dimen@>\glsnamewidth
\setlength{\glsnamewidth}{\dimen@}%
\fi
\settowidth{\dimen@}{\glsentrysymbol{\@glo@label}}%
\ifdim\dimen@>\glsunitwidth
\setlength{\glsunitwidth}{\dimen@}%
\fi
}%
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\glssetnoexpandfield{symbol}
\newglossaryentry{L}{name={L},description={Buchstabe},symbol={---}}
\newglossaryentry{P}{name={Cp},description={specific heat},symbol={[\si{\J\per\kg\per\K}]}}
\begin{document}
\lipsum[1]
\glsaddall
\printnoidxglossaries
\end{document}
You could make a feature request for siunitx that it adds a option to load them directly.