Modul:Wikidata/Formatters/quantity

Z Wikiknih

Dokumentaci tohoto modulu lze vytvořit na stránce Nápověda:Modul:Wikidata/Formatters/quantity

-- Tato stránka je pravidelně aktualizována robotem. Jakákoliv modifikace bude při příští aktualizaci přepsána a je třeba ji provádět na Wikipedii. 

require 'Modul:No globals'

local p = {}

local formatNumber, formatUnit

local lib = require 'Modul:Wikidata/lib'
local i18n = mw.loadData('Modul:Wikidata/i18n')

local NO_UNIT_ID = 'Q199'

function p.formatUnit(entityId)
	local Formatters = require 'Modul:Wikidata/Formatters'
	return Formatters.formatRawValue(entityId, 'wikibase-entityid', { label = 'unitsymbol', nolink = true })
end

formatUnit = p.formatUnit

function p.formatNumber(number, options)
	local integer, fractional
	local prefix = ''
	if number < 0 then
		number = -number
		prefix = '−'
	end
	number = tostring(number)
	if mw.ustring.find(number, '%.') then
		local decimals = tonumber(options.round)
		if decimals and decimals >= 0 then
			number = mw.ustring.format('%.' .. mw.ustring.format('%d', decimals) .. 'f', number)
		end
		integer, fractional = mw.ustring.match(number, '^(.+)%.(.+)$')
	end
	if not integer then
		integer = number
	end
	local length = mw.ustring.len(integer)
	local i = length % 3
	if i == 0 then
		i = 3
	end
	local formatted_num = mw.ustring.sub(integer, 1, i)
	while i < length do
		formatted_num = formatted_num .. i18n['thousands separator'] .. mw.ustring.sub(integer, i + 1, i + 3)
		i = i + 3
	end
	if fractional then
		local length = mw.ustring.len(fractional)
		local i = 3
		formatted_num = formatted_num .. i18n['decimal point'] .. mw.ustring.sub(fractional, 1, 3)
		while i < length do
			formatted_num = formatted_num .. i18n['thousands separator'] .. mw.ustring.sub(fractional, i + 1, i + 3)
			i = i + 3
		end
	end
	return prefix .. formatted_num
end

formatNumber = p.formatNumber

local function getUnitAndCoef(unit, options)
	local entityId = lib.getItemIdFromURI(unit) or NO_UNIT_ID
	local coef
	-- having T234809 would be better and less expensive
	if options.unit and entityId ~= options.unit then
		local WD = require 'Modul:Wikidata'
		local props = { 'P2370', 'P2442', 'P1181' }
		for _, prop in ipairs(props) do
			coef = WD.getRawValueFromLua{
				id = entityId,
				property = prop,
				withunit = options.unit,
			}
			if coef then break end
		end
		if not coef then
			for _, prop in ipairs(props) do
				coef = WD.getRawValueFromLua{
					id = options.unit,
					property = prop,
					withunit = entityId,
				}
				if coef then
					coef = 1 / coef
					break
				end
			end
		end
		if coef then
			entityId = options.unit
		end
	end
	if entityId == NO_UNIT_ID then
		entityId = nil
	end
	return entityId, coef or 1
end

function p.setFormatNumber(callback)
	formatNumber = callback
end

function p.setFormatUnit(callback)
	formatUnit = callback
end

function p.getRawValue(value, options)
	local _, coef = getUnitAndCoef(value.unit, options)
	return tonumber(value.amount) * coef
end

p.formatRawValue = p.formatNumber

function p._formatValue(value, options)
	local unit, coef = getUnitAndCoef(value.unit, options)
	local amount = tonumber(value.amount) * coef
	local margin
	local funit
	if lib.IsOptionTrue(options, 'showmargin') then
		if value.upperBound then
			margin = tonumber(value.upperBound) * coef - amount
		end
	end
	amount = formatNumber(amount, options)
	if margin then
		amount = amount .. '±' .. formatNumber(margin, options)
	end
	if tostring(options.showunit) ~= 'false' then
		if unit then
			funit = formatUnit(unit)
			if funit == '°' then
				return amount .. funit
			else
				return amount .. '&nbsp;' .. funit
			end
		end
	end
	return amount
end

function p.formatValue(value, options)
	p.setFormatNumber(p.formatNumber)
	p.setFormatUnit(p.formatUnit)
	return p._formatValue(value, options)
end

return p