siunitx 缩写在词汇表条目中不起作用

siunitx 缩写在词汇表条目中不起作用

这里,siunitx如果在词汇表条目键中使用缩写,则会引发错误,但是,如果给出的单位没有缩写,则不会出现错误。

\documentclass{article}

\usepackage{lipsum}
\usepackage{booktabs}
\usepackage{calc,siunitx}
\sisetup{load-configurations = abbreviations}
\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}

答案1

似乎缩写命令\si(见 Ulrike 的回答)无法在序言中处理。这可以通过以下代码来证明:\si\J

\documentclass{article}

\usepackage{siunitx}

\settowidth{\dimen0}{[\si{\J\per\kg\per\K}]}

\begin{document}
\end{document}

这会导致错误:

! Undefined control sequence.
<argument> \J 
              \per \kg \per \K 

移至\settowidth文档环境即可消除错误。

这意味着无法在 MWE 的前导码中计算单位宽度,但在环境中\makenoidxglossaries不允许(并且不建议使用)。相反,您可以使用提供的命令:\newglossaryentrydocument\makeglossaries\glsFindWidestUsedAnyNameSymbolglossaries-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仅检查已标记为已使用的条目(通过 之类的命令\gls),因此需要在词汇表之前使用(前提是它位于文档末尾)。如果您改用\glsaddall,请使用\glsFindWidestAnyNameSymbol可以放在文档开头的:

\begin{document}
\glsFindWidestAnyNameSymbol{\glsunitwidth}
\settowidth{\dimen0}{\glsgetwidestname}
\ifdim\dimen0>\glsnamewidth
 \glsnamewidth=\dimen0
\fi

\lipsum[1]
\glsaddall

\printnoidxglossaries

\end{document}

答案2

缩写的定义仅在文档开始时加载。因此,您应将词汇表定义移到后面\begin{document},不在词汇表定义中使用缩写,或者更早地加载缩写:

\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}

您可以对 siunitx 提出功能请求,希望它添加直接加载它们的选项。

答案3

我发现了一个类似的问题这里。@tomriddle 建议了一种与条目中已提供的答案相比相当简单的解决方案\unexpanded{}。我不知道这是否会在后续引起一些问题,但该解决方案在我的文档中效果很好。

以下是一个例子:

\newacronym{MC}{\unexpanded{\si{\micro}C}}{Mikrocontroller}

相关内容