Přeskočit na obsah

Modul:Wikidata/Formatters/approx

Tuto stránku mohou editovat jen zavedení uživatelé a správci.
Z Wikipedie, otevřené encyklopedie
require 'Modul:No globals'

local p = {}

local parent = require 'Modul:Wikidata/Formatters/quantity'

local inflection = {
	THOUSANDS = {
		['1'] = 'tisíc',
		['2'] = 'tisíc',
		['3'] = 'tisícům',
		['4'] = 'tisíc',
		['6'] = 'tisících',
		['7'] = 'tisíci',
	},
	MILLIONS = {
		one = {
			['1'] = 'milion',
			['2'] = 'milionu',
			['3'] = 'milionu',
			['4'] = 'milion',
			['6'] = 'milionu',
			['7'] = 'milionem',
		},
		few = {
			['1'] = 'miliony',
			['2'] = 'milionů',
			['3'] = 'milionům',
			['4'] = 'miliony',
			['6'] = 'milionech',
			['7'] = 'miliony',
		},
		many = {
			['1'] = 'milionů',
			['2'] = 'milionů',
			['3'] = 'milionům',
			['4'] = 'milionů',
			['6'] = 'milionech',
			['7'] = 'miliony',
		},
	},
}

p.getRawValue = parent.getRawValue

local function roundTo(value, factor)
	local remainder = value % factor
	if remainder < (factor / 2) then
		return math.floor(value / factor) * factor
	else
		return math.ceil(value / factor) * factor
	end
end

local function willDisplayAsInteger(value, magn, decimals)
	local remainder = value % magn
	local minErr = magn / (2 * (10^decimals))
	if remainder < minErr then
		return (value - remainder) / magn
	elseif remainder >= (magn - minErr) then
		return (value - remainder) / magn + 1
	else
		return false
	end
end

local function doInflection(map, case)
	return map[case or '1']
end

function p.formatNumber(value, options)
	local formatNumber = parent.formatNumber
	if 1e3 < value and value < 1e4 then
		return mw.ustring.format('přibližně %s', formatNumber(roundTo(value, 100), {}))
	elseif 1e4 <= value and value < 999500 then
		return mw.ustring.format('přibližně %s&nbsp;%s',
			formatNumber(value / 1000, { round = 0 }),
			doInflection(inflection.THOUSANDS, options.case))
	elseif 999500 <= value and value < 1e7 then
		local decimals = 2
		local int = willDisplayAsInteger(value, 1e6, decimals)
		if int then
			local cases
			if int > 4 then
				cases = inflection.MILLIONS.many
			elseif int > 1 then
				cases = inflection.MILLIONS.few
			else
				cases = inflection.MILLIONS.one
			end
			return mw.ustring.format('přibližně %s&nbsp;%s',
				formatNumber(int, {}),
				doInflection(cases, options.case))
		else
			return mw.ustring.format('přibližně %s&nbsp;%s',
				formatNumber(value / 1e6, { round = decimals }),
				doInflection(inflection.MILLIONS.one, '2'))
		end
	elseif 1e7 <= value and value < 1e8 then
		local decimals = 1
		local int = willDisplayAsInteger(value, 1e6, decimals)
		if int then
			return mw.ustring.format('přibližně %s&nbsp;%s',
				formatNumber(int, {}),
				doInflection(inflection.MILLIONS.many, options.case))
		else
			return mw.ustring.format('přibližně %s&nbsp;%s',
				formatNumber(value / 1e6, { round = decimals }),
				doInflection(inflection.MILLIONS.one, '2'))
		end
	else
		return formatNumber(value, options)
	end
end

p.formatRawValue = p.formatNumber

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

return p