请考虑以下示例:
\documentclass{article}
\usepackage{amsmath}
\usepackage[locale = DE]{siunitx}
\newcommand*\something[3]{
\SIlist[
list-separator = #1,
list-final-separator = #1,
list-units = brackets
]{#2}{#3}
}
\begin{document}
\begin{align*}
l
&= \SI{38.0}{\cm} + 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \something{+}{38; 52.4; 32.6}{\cm}\\
&= \SI{123.0}{\cm}.
\end{align*}
\end{document}
\something
当只有或时,该命令工作正常,+
但当同时-
使用加号和减号时我可以创建类似的命令吗?
答案1
这可能就是你想要的:
\documentclass{article}
\usepackage{amsmath}
\usepackage[locale = DE]{siunitx}
\ExplSyntaxOn
\NewDocumentCommand\SIexpr{ m m }
{
\svend_siexpr:nn { #1 } { #2 }
}
\cs_new_protected:Npn \svend_siexpr:nn #1 #2
{
\seq_set_split:Nnn \l_svend_siexpr_input_seq { ; } { #1 }
\seq_pop_left:NN \l_svend_siexpr_input_seq \l_svend_siexpr_first_tl
\seq_clear:N \l_svend_siexpr_output_seq
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { \l_svend_siexpr_first_tl > 0 }
{ \num { \l_svend_siexpr_first_tl } }
{ - \num { \tl_tail:V \l_svend_siexpr_first_tl } }
}
\seq_map_inline:Nn \l_svend_siexpr_input_seq
{
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { ##1 > 0 }
{ + \num { ##1 } }
{ - \num { \tl_tail:n { ##1 } } }
}
}
\SI[parse-numbers=false]
{
\sisetup{parse-numbers}
( \seq_use:Nn \l_svend_siexpr_output_seq { } )
}
{ #2 }
}
\ExplSyntaxOff
\begin{document}
\begin{align*}
l
&= \SI{38.0}{\cm} + 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{38.0; 52.4; 32.6}{\cm}\\
&= \SI{123.0}{\cm}.\\
l
&= \SI{38.0}{\cm} - 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{38.0; -52.4; 32.6}{\cm}\\
&= \SI{18.2}{\cm}.\\
l
&= \SI{-38.0}{\cm} + 2 \cdot \SI{26.2}{\cm} + \SI{32.6}{\cm}\\
&= \SIexpr{-38.0; 52.4; 32.6}{\cm}\\
&= \SI{47.0}{\cm}.
\end{align*}
\end{document}
的参数\SIexpr
被分成几个部分。
将第一个组件拆下来单独处理。
检查每个成分看它是正数还是负数:如果是负数,我们添加
-\num{<absolute value>}
else+\num{<absolute value>}
。+
但是,不会通过对第一个组件进行特殊检查来添加前导。
要使第一个强制参数中的分隔符可通过\SIexpr
可选参数选择,请将主代码更改为
\ExplSyntaxOn
\NewDocumentCommand\SIexpr{ O{;} m m }
{
\svend_siexpr:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Npn \svend_siexpr:nnn #1 #2 #3
{
\seq_set_split:Nnn \l_svend_siexpr_input_seq { #1 } { #2 }
\seq_pop_left:NN \l_svend_siexpr_input_seq \l_svend_siexpr_first_tl
\seq_clear:N \l_svend_siexpr_output_seq
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { \l_svend_siexpr_first_tl > 0 }
{ \num { \l_svend_siexpr_first_tl } }
{ - \num { \tl_tail:V \l_svend_siexpr_first_tl } }
}
\seq_map_inline:Nn \l_svend_siexpr_input_seq
{
\seq_put_right:Nx \l_svend_siexpr_output_seq
{
\fp_compare:nTF { ##1 > 0 }
{ + \num { ##1 } }
{ - \num { \tl_tail:n { ##1 } } }
}
}
\SI[parse-numbers=false]
{
\sisetup{parse-numbers}
( \seq_use:Nn \l_svend_siexpr_output_seq { } )
}
{ #3 }
}
\ExplSyntaxOff
现在你可以做
\SIexpr{38.0; 52.4; 32.6}{\cm}
或者
\SIexpr[,]{38.0, 52.4, 32.6}{\cm}
甚至
\SIexpr[?]{38.0 ? 52.4 ? 32.6}{\cm}
如果你喜欢默认使用逗号而不是分号,那么你应该
\NewDocumentCommand\SIexpr{ O{,} m m }
默认分隔符不能是冒号,但您可以使用可选参数选择冒号。