有没有更方便的方法用 siunitx 表示 (1,2+3,4) m?

有没有更方便的方法用 siunitx 表示 (1,2+3,4) m?

背景:

  • 我希望 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宏。新siunitxany可用于将可选参数/星号自定义为分隔符(参见示例)。

旧版本的\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}

输出

在此处输入图片描述

相关内容