![Можно ли перегруппировать каждые 4 цифры в числе с помощью пакета siunitx?](https://rvso.com/image/370310/%D0%9C%D0%BE%D0%B6%D0%BD%D0%BE%20%D0%BB%D0%B8%20%D0%BF%D0%B5%D1%80%D0%B5%D0%B3%D1%80%D1%83%D0%BF%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BA%D0%B0%D0%B6%D0%B4%D1%8B%D0%B5%204%20%D1%86%D0%B8%D1%84%D1%80%D1%8B%20%D0%B2%20%D1%87%D0%B8%D1%81%D0%BB%D0%B5%20%D1%81%20%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E%20%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%B0%20siunitx%3F.png)
Текущая опция группировки цифр по умолчанию в пакете siunitx
дает мне большое число, разделенное запятыми или пробелами каждые 3 цифры, например:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{siunitx}
\begin{document}
\num[group-separator={,}]{123456789}
\end{document}
даст мне 123 456 789. Можно ли изменить его так, чтобы я получил 1 2345 6789?
Я не могу найти ответ в siunitx
документации или где-либо еще в Интернете. Я также рад узнать, есть ли альтернативный пакет, который обрабатывает форматирование чисел и набор текста автоматически, как siunitx
, но позволяет эту перегруппировку. Спасибо заранее!
решение1
В настоящее время в siunitx
. Это можно сделать с помощью другого кода:
\documentclass{article}
\usepackage{xparse,siunitx}
\ExplSyntaxOn
\NewDocumentCommand{\groupfour}{O{,}m}
{
\mikew_groupfour:nn { #1 } { #2 }
}
\tl_new:N \l_mikew_groupfour_separator_tl
\tl_new:N \l_mikew_groupfour_number_tl
\cs_new_protected:Nn \mikew_groupfour:nn
{
\tl_set:Nn \l_mikew_groupfour_separator_tl { {#1} }
\tl_set:Nx \l_mikew_groupfour_number_tl { #2 }
\tl_replace_all:Nnn \l_mikew_groupfour_number_tl { ~ } { }
\tl_reverse:N \l_mikew_groupfour_number_tl
\regex_replace_all:nnN
{ [0-9]{4} } % search
{ \0 \c{l_mikew_groupfour_separator_tl} } % replace
\l_mikew_groupfour_number_tl % token list
\tl_reverse:N \l_mikew_groupfour_number_tl
\regex_replace_once:nnN
{ \A \c{l_mikew_groupfour_separator_tl} }
{ }
\l_mikew_groupfour_number_tl
\tl_use:N \l_mikew_groupfour_number_tl
}
\ExplSyntaxOff
\begin{document}
\groupfour{ 123456789 }
\groupfour[\,]{1 2345 6789}
$\groupfour{12345678}$ % test for math mode
\end{document}
Это меняет порядок ввода на противоположный после удаления пробелов; затем после каждой группы из четырех цифр вставляется разделитель (в символической форме); строка снова переворачивается, и ведущий разделитель удаляется.
Вы можете изменить разделитель, вызвав \groupfour[<separator>]{<number>}
.
Расширенная версия для работы также с десятичными числами. В десятичной части группы из четырех цифр разделены тонкими пробелами. Не составит труда изменить это в соответствии с потребностями.
\documentclass{article}
\usepackage{xparse,siunitx}
\ExplSyntaxOn
\NewDocumentCommand{\groupfour}{O{,}m}
{
\mikew_groupfour:nn { #1 } { #2 }
}
\tl_new:N \l_mikew_groupfour_separator_tl
\tl_new:N \l_mikew_groupfour_number_tl
\seq_new:N \l_mikew_groupfour_parts_seq
\cs_new_protected:Nn \mikew_groupfour:nn
{
\tl_set:Nn \l_mikew_groupfour_separator_tl { {#1} }
\regex_split:nnN { \. } { #2 } \l_mikew_groupfour_parts_seq
\tl_set:Nx
\l_mikew_groupfour_number_tl
{ \seq_item:Nn \l_mikew_groupfour_parts_seq { 1 } }
\tl_replace_all:Nnn \l_mikew_groupfour_number_tl { ~ } { }
\tl_reverse:N \l_mikew_groupfour_number_tl
\__mikew_groupfour_replace:
\tl_reverse:N \l_mikew_groupfour_number_tl
\tl_use:N \l_mikew_groupfour_number_tl
\int_compare:nT { \seq_count:N \l_mikew_groupfour_parts_seq > 1 }
{
\tl_set:Nn \l_mikew_groupfour_separator_tl { {\,} }
. % print the decimal point
\tl_set:Nx
\l_mikew_groupfour_number_tl
{ \seq_item:Nn \l_mikew_groupfour_parts_seq { 2 } }
\__mikew_groupfour_replace:
\tl_use:N \l_mikew_groupfour_number_tl
}
}
\cs_new_protected:Nn \__mikew_groupfour_replace:
{
\regex_replace_all:nnN
{ [0-9]{4} } % search
{ \0 \c{l_mikew_groupfour_separator_tl} } % replace
\l_mikew_groupfour_number_tl % token list
\regex_replace_once:nnN
{ \c{l_mikew_groupfour_separator_tl} \Z }
{ }
\l_mikew_groupfour_number_tl
}
\ExplSyntaxOff
\begin{document}
X\groupfour{ 123456789 }X
X\groupfour[\,]{1 2345 6789}X
X$\groupfour{12345678}$X
X\groupfour{1234567890.12345678}X
\end{document}
решение2
Для разнообразия вот решение на основе LuaLaTeX. Оно очень похоже на то, что приведено вэтот ответ. Решение определяет пользовательский макрос с именем \groupfour
, который вызывает функцию Lua, выполняющую фактическую работу. Если число (аргумент \groupfour
) содержит десятичную часть, запятые в десятичную часть не вставляются.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{siunitx}
\usepackage{luacode}
\begin{luacode}
function groupfour ( s )
z = ""
-- Check if number contains a decimal part. If so, don't
-- insert commas in the decimal part.
n = string.find ( s, "%." )
if n then
-- Set aside decimal part of number in string "z"
z = string.sub ( s , n )
s = string.sub ( s , 1 , n-1 )
end
t = ""
while string.len ( s ) > 4 do
t = "{,}" .. string.sub ( s, -4 ) .. t
s = string.sub ( s , 1, -5 )
end
tex.sprint ( s .. t .. z )
end
\end{luacode}
\newcommand\groupfour[1]{\directlua{groupfour(\luastring{#1})}}
\begin{document}
\num[group-separator={,}]{123456789}
\groupfour{123456789}
\end{document}