![有没有更方便的方法用 siunitx 表示 (1,2+3,4) m?](https://linux22.com/image/267399/%E6%9C%89%E6%B2%A1%E6%9C%89%E6%9B%B4%E6%96%B9%E4%BE%BF%E7%9A%84%E6%96%B9%E6%B3%95%E7%94%A8%20siunitx%20%E8%A1%A8%E7%A4%BA%20(1%2C2%2B3%2C4)%20m%EF%BC%9F.png)
背景:
- 我希望 TeX 输入文件中的所有十进制数都用作
.
小数分隔符。 - 如果我的文档被翻译成德语(例如),则可以通过选项
.
进行全局转换。,
locale
- 现在考虑一下如果我想
(1,2+3,4) m
以翻译后的版本而不是(1.2+3,4) m
原始版本输出。 - 使用会产生具有和
$\num{1.2}+\num{3.4}$\si{\m}$
之间不正确间距的输出。)
m
- 使用
$\SI{(1.2+3.4)}{\m}$
会引发错误。 - 使用
$\SI[parse-numbers=false]{(1.2+3.4)}{\m}$
将忽略locale=DE
选项,因此输出将使用.
而不是,
。 - 使用
$\SI[parse-numbers=false]{(1{,}2+3{,}4)}{\m}$
会让我的翻译不高兴。
梅威瑟:
\documentclass[preview,border=12pt,varwidth]{standalone}
\usepackage{amsmath}
\usepackage[locale=DE]{siunitx}
\def\x{1.23}
\def\y{4.56}
\def\X{1{,}23}
\def\Y{4{,}56}
\begin{document}
$\!
\begin{aligned}[t]
L &= \SI{\x}{\m} + \SI{\y}{\m}\\
&= (\num{\x}+\num{\y})\si{\m}
\end{aligned}
$
$\!
\begin{aligned}[t]
L &= \SI{\x}{\m} + \SI{\y}{\m}\\
&= \SI[parse-numbers=false]{(\x+\y)}{\m}
\end{aligned}
$
$\!
\begin{aligned}[t]
L &= \SI{\x}{\m} + \SI{\y}{\m}\\
&= \SI[parse-numbers=false]{(\X+\Y)}{\m}
\end{aligned}
$
\end{document}
问题:
有没有更方便的方式来表示(1,2+3,4) m
翻译版本,而无需使用parse-numbers=false
丑陋xxx{,}yyy
的技巧,同时保持正确的间距?
答案1
该siunitx
包已经可以很好地处理乘积和商,我们可以制作一些辅助宏+
并将-
其作为分割器\num
。
正确答案直接inter-unit-product
取自siunitx
。
第二个示例显示了这种方法的一个缺点:单元符号需要用括号括起来,这样我们自己的解析器就看不到它了。(此外,它还缺少一些括号。)不过,我认为它们没什么用,因为减号可以简单地替换前面的+
。
更好的方法是使用siunitx
'/LaTeX 3 已经存在的设施来解析与乘积和商类似的参数(这可能与它们作为输入文字的用法相矛盾\SI
)。\num
\pm
所有数字周围括号的排版均外包给mathtools
及其\DeclarePairedDelimiter
宏。新siunitx
键any
可用于将可选参数/星号自定义为分隔符(参见示例)。
旧版本的\SIany
宏采用一个可选的*
( \SIany*…
)/一个括号中的可选参数 ( \SIany(\big)
),这些参数被转发到mathtools
分隔符,如下所示修订 7这个答案。
代码
\documentclass{article}
\usepackage{mathtools}
\usepackage[locale=DE]{siunitx}
\makeatletter
% copied from pgfutil-common.tex
\newif\ifqrr@in@
\def\qrr@in@#1#2{%
\def\qrr@in@@##1#1##2##3\qrr@in@@{%
\ifx\qrr@in@##2\qrr@in@false\else\qrr@in@true\fi}%
\qrr@in@@#2#1\qrr@in@\qrr@in@@}
\def\qrr@in#1#2{\qrr@in@{#1}{#2}\ifqrr@in@\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi}
%
% Splitter
\def\parse@stop{\parse@stop}
\def\parse@numbers@split@plus#1+#2\parse@stop{\parse@numbers{#1}+\parse@numbers{#2}}
\def\parse@numbers@split@minus#1-#2\parse@stop{\parse@numbers{#1}-\parse@numbers{#2}}
%
\DeclarePairedDelimiter{\qrr@siunitx@p}{(}{)}
\ExplSyntaxOn
\def\qrr@siunitx@p@star{*}
\keys_define:nn { siunitx }{
any .code:n =
\def\@tempa{#1}
\ifx\qrr@siunitx@p@star\@tempa
\def\qrr@siunitx@p@params{*}
\else
\expandafter\def\expandafter\qrr@siunitx@p@params
\expandafter{\expandafter[\csname#1\endcsname]}
\fi
}
\sisetup{any=}
\newcommand*\SIany[3][]{
\begingroup
\sisetup{#1}
\expandafter\qrr@siunitx@p\qrr@siunitx@p@params{\parse@numbers{#2}}%
\l__siunitx_unit_product_tl
\si{#3}
\endgroup}
\ExplSyntaxOff
% Parser
\def\parse@numbers#1{%
\qrr@in+{#1}
{\parse@numbers@split@plus#1\parse@stop}
{%
\qrr@in-{#1}
{\parse@numbers@split@minus#1\parse@stop}
{\num{#1}}
}%
}
\makeatother
\begin{document}
$ \SIany{1.23 + 4.56 x 7.89 - 0.12 / 3.56}{\m} $
$ \SIany{1.23 + {-}4.56 x 7.89 - 0.12 / 3.56}{\m} $
\sisetup{quotient-mode=fraction}
$ \SIany{1 + 0.12 / 3.56}{\m} = \SIany[any=*]{1 + 0.12 / 3.56}{\m} = \SIany[any=big]{1 + 0.12 / 3.56}{\m} $
\end{document}