siunitx 宏中的自定义词汇表字段无法通过 latexmk 编译

siunitx 宏中的自定义词汇表字段无法通过 latexmk 编译

我正在用一个符号词汇表撰写论文,其中包含一些自定义字段和自定义词汇表样式。该文档还有一个缩写词汇表,但它不使用任何自定义字段或自定义样式。这在几个月的草稿修订中一直运行良好,以及所有默认词汇表命令(\gls\glsname等)。

最近,我重新定义了自定义字段,从field-aliases到 ,\glsaddkey以便能够在文档中打印它们,并偶然发现了一些非常奇怪的行为,这些行为似乎围绕着siunitxglossaries-extra(也可能是bib2gls)和latexmk。请继续阅读以了解详细信息。如果能帮助我了解可能发生的事情,我将不胜感激。

这是我的序言(的相关部分),包括我的自定义词汇表字段的定义以及我的词汇表样式:

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

以下是词汇表中的几个代表性条目symbols.bib(我使用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}}
}

如您所见,该value字段是一个使用科学计数法的数字,有时会出现 +- 错误。它没有被 siunitx 包围\num{},这可以正常工作(我\num{...}稍后在打印时添加)。同样,该unit字段没有用 包围 siunitx 单元宏\unit{}

您可能会注意到,我的自定义词汇表样式利用了这种定义valueunit包含\qty{\glsentryvalue{##1}}{\glsentryunit{##1}}(或仅\num{...}或仅\unit{...},视情况而定)的方式,与手动设置值单元间距相比,这种方式具有排版优势。我想强调的是,这种方法已经运行了几个月,包括许多新的重新编译(其中所有辅助文件都被清除)。

如上所述,当我尝试使用各自定义提供的\glsentryvalue{...}或命令 siunitx 打印值/单位时,整个事情开始崩溃。给出命令\glsentryunit{...}\glsaddkey\glsentryvalue通过它自己工作正常(将值排版为文本,例如“1.602176634e-19”,虽然不太美观,但始终有效)。单位字段同样可以工作,除非它包含“裸”的siunitx单元宏,因此会失败,但这是一个很容易理解的原因。

因此,我自然会想把这些\glsentry*{...}命令里面siunitx 宏。这就是(重新)编译开始根据辅助文件是否存在而表现不同的地方。

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

我想我应该解释一下我的构建过程。这是一个相当直接的 latexmk 构建,只需latexmk -pdf -bibtex thesis使用以下漂亮的原始.latexmkrc文件(处理makeglossariesbib2gls):

$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;
}

出于谨慎考虑,我通常会时不时地(比如一周几次)删除所有 LaTeX 辅助文件,然后再重新编译。这会使后续编译花费的时间稍微长一些,但到目前为止,我已经绝不经历了从“白纸一张”开始的编撰失败在擦除辅助文件之前,相同的源代码编译成功。然而,这似乎正是正在发生的事情添加时\num{\glsentryvalue{elementary_charge}}到文档中。

重现这种奇怪行为的分步过程:

  • 此时 LaTeX 源不包含\num{\glsentryvalue{...}}任何\unit{\glsentryunit{...}}命令,工作目录是干净的(没有辅助文件)。我们latexmk ...按照上面的方法进行编译。编译成功,正如预期的那样。
  • 现在将\num{\glsentryvalue{...}}(或unitqty)添加到源中,然后按照latexmk ...上述方法重新编译。编译成功并且 siunitx 值/单位/数量排版正确。那么问题是什么?
  • 好了,现在清除所有辅助文件。重新编译,并\num{\glsentryvalue{...}}在第一次lualatex运行时观察它在第一次出现时阻塞:Package siunitx Error: Invalid number ''

如果我注释掉有问题的行并重新编译,它会成功,然后我取消注释同一行并再次重新编译,它会成功(前提是我不清除中间的辅助文件)。这是怎么回事?

请注意,这是有效的是否\glssetnoexpandfield{value}或中的任何一个\glssetnoexpandfield{unit}\glsnoexpandfields被声明了。也许它们不再需要了——推荐它们的最新 TeX.SE 帖子是几年前的。

我试图识别哪个此行为依赖于辅助文件,但无法确定任何特定文件。这些是我的项目生成的所有辅助文件:*.aux, *.bcf, *.fls, *-1.glstex, *.glstex, *.lof, *.lol, *.los, *.out, *.bbl, *.blg, *.fdb_latexmk, *.glg, *.lob, *.log, *.lor, *.lot, *.run.xml, *.toc。我甚至一次删除一个,然后重新编译,但发现在所有情况下重新编译都成功。所以似乎任何一个辅助文件的缺失都不会触发此行为,但所有辅助文件的缺失都会触发此行为?我不是 LaTeX 开发人员,但这很奇怪,对吧?

所以,我不知道这是否是一个希尼奇或者额外词汇表或者latexmk问题。我们非常欢迎您提出意见或问题。

我尝试通过一些测试来排除其他可能的因素,并可以确认这不是由使用 siunitx v2 或 v3 引起的(与 的行为相同\usepackage{siunitx}\usepackage{siunitx}[=v2];TeXLive 2022 或 2023 没有区别;在词汇表中用 包围单位字段\unexpanded{...}没有影响;\glssetnoexpandfield{unit}并且\glssetnoexpandfield{value}没有影响;\glsnoexpandfields没有区别;draft在 documentclass 中禁用模式没有影响。

TeXLive 2023在 Ubuntu 22.04 上搭载glossaries-extra1.50、3.2.2siunitxbib2gls3.2、4.79版本。latexmk

相关链接:

相关内容