如何在 siunitx 中打印带有“quantity-product”的 \unit?

如何在 siunitx 中打印带有“quantity-product”的 \unit?

siunitx允许我们打印数字、单位和数量,后者理解为数字和单位的组合。为此,我们分别有\num\unit\qty

使用\qty{<number>}{<unit>}不同于仅仅并列\num{<number>}\unit{<unit>},因为它\qty会根据选项考虑数字和单位之间的适当间距quantity-product。到目前为止,一切顺利。

但是,我希望能够将数字与单位分开,并且仍能从中获取间距quantity-product。用例是一个表格,我想在其中使用一S列,将表格序言中的单位传递给列中的所有数字。

现在,我知道这里的大多数人都会告诉我,我不应该在每个数字上添加单位,而应该只在表格的标题中给出一次。我同意这通常是最佳做法。但我遇到过这种情况,标题已经很拥挤,数字和单位很短,所以我认为如果我这样做,我的表格会看起来更好。因此,无论表格格式的最佳实践和品味如何,我都在寻找针对这种情况的技术解决方案。

以下 MWE 总结了这一情况:

\documentclass{article}

\usepackage{siunitx}
\usepackage{array}

\begin{document}

\begin{tabular}{
  S[table-format = 4.0, group-digits = false]
  S[table-format = 1.1{\unit{\percent}}]<{{\unit{\percent}}}
  }
  \hline
  & \multicolumn{1}{c}{$\frac{\text{imports}}{\text{apparent consumption}}$} \\
  \hline
  1924 & 3,7 \\
  1925 & 3,4 \\
  1926 & 3,6 \\
  1927 & 4,0 \\
  1928 & 3,8 \\
  1929 & 4,0 \\
  1930 & 4,5 \\
  1935 & 4,7 \\
  1936 & 4,4 \\
  1937 & 3,3 \\
  \hline
\end{tabular}

\end{document}

当然,上面的例子缺少第二列中数字和单位之间的空格。所以我想找一个\qtyunit宏来代替\unit它。

我尝试了几种替代方案,但我对它们都不太有信心或满意。第一个是:

\NewDocumentCommand\qtyunit{m}{\qty[print-unity-mantissa=false]{1}{#1}}

这看起来不错,而且能完成工作。但我不确定我是否应该依靠传递1数字来print-unity-mantissa=false实际打印quantity-product。这似乎是一个副作用,可能会发生变化(有人可能会认为它不应该被打印),而且效果没有记录。

siunitx确实允许向传递一个空数字参数\qty,但这种情况会被特殊处理,并被quantity-product跳过)。

于是我就去siunitx.sty做饭了(基于 的定义\unit):

\ExplSyntaxOn
\NewDocumentCommand \qtyunit { O { } > { \TrimSpaces } m }
  {
    \mode_leave_vertical:
    \group_begin:
      \siunitx_unit_options_apply:n {#2}
      \keys_set:nn { siunitx } {#1}
      % print quantity-product spacing, from ‘\siunitx_quantity_print’
      \tl_use:N \l__siunitx_quantity_product_tl
      \bool_if:NTF \l__siunitx_quantity_break_bool
        { \penalty \binoppenalty }
        { \nobreak }
      % now print the unit proper
      \siunitx_unit_format:nN {#2} \l__siunitx_tmp_tl
      \siunitx_print_unit:V \l__siunitx_tmp_tl
    \group_end:
  }
\ExplSyntaxOff

但是,尽管它可以起作用,但我却感觉这样做有点过度了。

因此,问题是,我是否遗漏了某些siunitx可以更直接、更可靠地获得这一点的方法?如果没有,是否有人看到比上述两种方法更好的替代方案?

编辑:我想到了第三种选择:

\NewDocumentCommand\qtyunit{m}{\qty[parse-numbers=false]{\relax}{#1}}

看起来很有希望,但仍然感觉有点作弊。

答案1

在 v3 中,有许多代码级接口用于子模块之间的通信,但这些接口并不直接作为文档命令公开。在这里,您真正需要的是\siunitx_quantity_print:nn,它打印预格式化的数量,并接受缺失的数字部分。(例如,在打印复杂数量时需要这样做。)

我们首先需要格式化该单元,然后将其传递给打印程序。

\documentclass{article}

\usepackage{siunitx}
\usepackage{array}
\ExplSyntaxOn
\NewDocumentCommand \qtyunit { m }
  {
    \siunitx_unit_format:nN {#1} \l_tmpa_tl
    \siunitx_quantity_print:nV { } \l_tmpa_tl
  }
\ExplSyntaxOff


\begin{document}

\begin{tabular}{
  S[table-format = 4]
  S[table-format = 1.1{\qtyunit{\percent}}]<{{\qtyunit{\percent}}}
  }
  \hline
  & \multicolumn{1}{c}{$\frac{\text{imports}}{\text{apparent consumption}}$} \\
  \hline
  1924 & 3,7 \\
  1925 & 3,4 \\
  1926 & 3,6 \\
  1927 & 4,0 \\
  1928 & 3,8 \\
  1929 & 4,0 \\
  1930 & 4,5 \\
  1935 & 4,7 \\
  1936 & 4,4 \\
  1937 & 3,3 \\
  \hline
\end{tabular}

\end{document}

答案2

在下面的示例中,使用以下方法收集第二列中每个单元格的内容collcell\mynum包,然后作为其参数传递给(如\mynum{<cell contents>})。

也就是说,第二列的规范

S[table-format = 1.1{\unit{\percent}}]<{{\unit{\percent}}}
% is replace with
>{\collectcell\mynum}c<{\endcollectcell}
\documentclass{article}

\usepackage{siunitx}
\usepackage{array}
\usepackage{collcell}

\newcommand\mynum[1]{%
  \qty{#1}{\percent}%
}

\begin{document}


\begin{tabular}{
  S[table-format = 4.0, group-digits = false]
  >{\collectcell\mynum}c<{\endcollectcell}
  }
  \hline
  & \multicolumn{1}{c}{$\frac{\text{imports}}{\text{apparent consumption}}$} \\
  \hline
  1924 & 3,7 \\
  1925 & 3,4 \\
  1926 & 3,6 \\
  1927 & 4,0 \\
  1928 & 3,8 \\
  1929 & 4,0 \\
  1930 & 4,5 \\
  1935 & 4,7 \\
  1936 & 4,4 \\
  1937 & 3,3 \\
  \hline
\end{tabular}

\end{document}

在此处输入图片描述

请参阅和collcell的包手册中的更多示例。collcellsiunitx

相关内容