{{i}} Документація модуля[перегляд] [редагувати] [історія] [очистити кеш]

Загальний опис ред.

Модуль описує функцію reformatNumber, яка допомагає краще оформити число (передане першим параметром), зокрема (перелік неостаточний і може змінюватися):

  • замінює роздільник між цілою й дробовою частиною на правильний («,»);
  • відокремлює кожні три цифри цілої частини правильним чином (нерозривним пробілом);
  • замінює мінус на правильний («−»);
  • правильно оформлює слова «тис.», «млн» тощо (крапка після «тис.», але не після інших слів; нерозривний пробіл перед словом).

Приклади:

  • «{{#invoke:ReformatNumber|reformatNumber|123}}» дає «123» [1]
  • «{{#invoke:ReformatNumber|reformatNumber|123.00}}» дає «123,00» [2]
  • «{{#invoke:ReformatNumber|reformatNumber|1234567}}» дає «1 234 567» [3]
  • «{{#invoke:ReformatNumber|reformatNumber|-123}}» дає «−123» [4]
  • «{{#invoke:ReformatNumber|reformatNumber|5 тис}}» дає «5 тис.» [5]
  • «{{#invoke:ReformatNumber|reformatNumber|5млн.}}» дає «5 млн» [6]

.

Додаткові можливості ред.

Необов'язковий параметр preUnit дозволяє задати одиницю вимірювання, яка пишеться до числа, але після мінуса (якщо він присутній). В українській мові зазвичай одиниці так не пишуть (хоча триває дискусія, як краще: «₴123» чи «123 ₴»), але про всяк випадок така можливість передбачена. Можливостей задавати одиниці вимірювання які пишеться після числа (як звичайно) або до-числа-й-до-мінуса не передбачено, оскільки такі одиниці вимірювання можна легко написати просто зовні (до чи після) виклику функції. Приклади:

  • «₴{{#invoke:ReformatNumber|reformatNumber|-123}}» дає «₴−123»;
  • «{{#invoke:ReformatNumber|reformatNumber|-123}} ₴» дає «−123 ₴»;
  • «{{#invoke:ReformatNumber|reformatNumber|-123|preUnit=₴}}» дає «−₴123».

Повний перелік параметрів ред.

Повний перелік параметрів
Назва параметра Номер параметра Обов'язковий? Тлумачення
number 1 Так Число, яке потрібно відформатувати
preUnit 2 Ні Одиниця вимірювання, яка писатиметься до числа, але після мінуса (якщо він присутній)
WHITESPACE_PATTERNS = {' ', ' ', '\194\160'}

MINUS = '−'
THOUSAND_SEPARATOR = ' '
FRACTIONAL_SEPARATOR = ','
FACTORS = {' тис.', ' млн', ' млрд', ' трлн'}

function reformatNumber(numberStr, preUnit)
	-- Перевірити вхідні параметри:
	numberStr = tostring(numberStr)
	preUnit = tostring(preUnit or '')

	-- Прибрати зайве сміття з вхідного рядка:
	local strSimplified = numberStr
	for _, pattern in ipairs(WHITESPACE_PATTERNS) do strSimplified = string.gsub(strSimplified, pattern, '') end
	
	-- Підфункція, що «зчитує» початок зі strSimplified:
	function read(pattern)
		local result = string.match(strSimplified, '^' .. pattern)
		if result then strSimplified = string.sub(strSimplified, 1 + string.len(result)) end
		return result
	end
	
	local isNegative = read('[-]') or read(MINUS)
	local intDigits = read('[0-9]+') or '0'
	read('[,.]')
	local fracDigits = read('[0-9]*')
	local factor = read('тис[.]?') and 1 or read('млн[.]?') and 2 or read('млрд[.]?') and 3 or read('трлн[.]?') and 4
	assert(strSimplified == '', 'Не вдалося розпарсити число "' .. numberStr .. '"')

	return (isNegative and MINUS or '') ..
			preUnit ..
			string.gsub(string.reverse(string.gsub(string.reverse(intDigits), '...', '%0' .. string.reverse(THOUSAND_SEPARATOR))), '^' .. THOUSAND_SEPARATOR, '') ..
			(fracDigits ~= '' and FRACTIONAL_SEPARATOR .. fracDigits or '') ..
			(factor and FACTORS[factor] or '')
end

-- Тести:
-- assert(reformatNumber('123', '$') == '$123')
-- assert(reformatNumber('123.00') == '123,00')
-- assert(reformatNumber('1234567') == '1 234 567')
-- assert(reformatNumber('-123') == '−123')
-- assert(reformatNumber('-123', '$') == '−$123')
-- assert(reformatNumber('5 тис') == '5 тис.')
-- assert(reformatNumber('5млн.') == '5 млн')

return {
	reformatNumber = function(frame)
		return reformatNumber(
			frame.args.number or frame.args[1],
			frame.args.preUnit or frame.args[2]
		)
	end
}