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
的包手册中的更多示例。collcell
siunitx