在字幕中使用 siunitx v3 的自定义单位 - \protect 是否不够?

在字幕中使用 siunitx v3 的自定义单位 - \protect 是否不够?

我正在使用我的之前讨论过自定义命令(也在下面提供),siunitx。从版本 3 开始,我不再能够在标题中使用它们,而以前,\protect在它们前面添加总是有效的。

定义(在加载的sty文件中):

% Define "quantity-product", as an alias in versions prior to 3.0; allows its unconditional use
% From: https://tex.stackexchange.com/a/621037/134641
\@ifpackagelater{siunitx}{2021/05/17}  % main release of 3.0.0
    { } {
        \ExplSyntaxOn
            \keys_define:nn { siunitx }
            { quantity-product .meta:n = { number-unit-product = {#1} } }
        \ExplSyntaxOFf
    }
%--------------------------------------------

\DeclareSIUnit[quantity-product = \;]\basepair{bp}

使用示例:

\begin{figure}
    \caption{Pertains to $\SI{500}{\protect\basepair}$ regions and uncalibrated data.}
\end{figure}

答案1

siunitx制作单元宏\protected,这样它们在仅扩展的上下文(如标题)中使用时不会爆炸,因此您可以直接使用\SI{500}{\basepair}而不必担心保护(否则您也必须这样做\protect\SI)。以下是完整的示例:

\documentclass{article}
\usepackage{siunitx}

\ExplSyntaxOn\makeatletter
\@ifpackagelater{siunitx}{2021/05/17}  % main release of 3.0.0
  { }
  {
    \keys_define:nn { siunitx }
      { quantity-product .meta:n = { number-unit-product = {#1} } }
  }
\ExplSyntaxOff\makeatother

\DeclareSIUnit[quantity-product = \;]\basepair{bp}

\begin{document}
\listoffigures
\begin{figure}
  \caption{Pertains to $\SI{500}{\noexpand\basepair}$ regions and uncalibrated data.}
\end{figure}
\end{document}

添加时,\protect您使其中断,因为在 中是\caption,因此它会阻止扩展带有 的以下标记,因此您本质上拥有(如果您尝试这样做,您将得到相同的错误)。然后,当解析单元时(此时每个单元宏都被定义为具有其正确含义),它不会扩展,然后在稍后排版时,会扩展,但随后它会恢复为。\protect\@unexpandable@protect\noexpand\SI{500}{\noexpand\basepair}siunitx\basepair\basepair\ERROR

根据经验法则,添加\protect是例外而不是常态,因此只有当您知道宏会爆炸时才添加它(但随后考虑使其变得强大\MakeRobust)。


请注意,在代码中:

\@ifpackagelater{siunitx}{2021/05/17}  % main release of 3.0.0
    { } {
        \ExplSyntaxOn
            \keys_define:nn { siunitx }
            { quantity-product .meta:n = { number-unit-product = {#1} } }
        \ExplSyntaxOff
    }

\ExplSyntaxOn和什么\ExplSyntaxOff都没做(我很惊讶你在运行它时没有得到“未定义的控制序列 \keys”错误)。在开头有一个解释这个答案,但该代码应该是:

\ExplSyntaxOn
\@ifpackagelater{siunitx}{2021/05/17}  % main release of 3.0.0
  { }
  {
    \keys_define:nn { siunitx }
      { quantity-product .meta:n = { number-unit-product = {#1} } }
  }
\ExplSyntaxOff

在您的情况下\makeatletter没有必要,因为它在.sty文件中(\makeatletter在包和类中默认打开),但请注意,在上面的例子中,我也将它添加到括号外面:在里面它没有任何用处。

相关内容