Przejdź do zawartości

Moduł:Wikidane/format/quantity

Z Wikipedii, wolnej encyklopedii
 Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]

Dedykowana uniwersalna wtyczka formatująca wartość cechy z wartością ilościową z opcjonalną jednostką.

Wtyczka obsługuje parametr format, w którym można wskazać identyfikator Wikidanych (Qnnnnn) określający jednostkę miary w jakiej ma być zaprezentowany wynik. Jeśli jest pusty to wyświetlana jest aktualna wartość wraz z jednostką.

Zobacz też

[edytuj kod]
local i18n = mw.loadData("Moduł:Wikidane/data").quantityFormats
local units = mw.loadData("Moduł:Wikidane/data").quantityUnits

local function selectRoundCoefficients(value)
	local num = math.abs(value)
	if num > i18n.maximumAmount then
		return false, "", math.floor(num * i18n.maximumVarFactor)
	end

	for i, v in ipairs(i18n) do
		if num > v.amount then
			return v.factor, v.suffix, v.minvar
		end
	end

	return false, "", 0
end

local function formatVar(snak)
	local amount = tonumber(snak.datavalue.value.amount)
	local upperVar = snak.datavalue.value.upperBound and (tonumber(snak.datavalue.value.upperBound) - amount) or 0
	local lowerVar = snak.datavalue.value.lowerBound and (amount - tonumber(snak.datavalue.value.lowerBound)) or 0
	local lang = mw.getContentLanguage()
	if (upperVar == 0) and (lowerVar == 0) then
		return lang:formatNum(amount), amount
	elseif math.abs(upperVar - lowerVar) < ((upperVar + lowerVar) / 1000) then
		local var = math.max(upperVar, lowerVar)
		var = string.format("%f", var)
		if string.match(var, "%.") then
			local _ = false -- no globals
			var, _ = string.gsub(var, "%.", ",")
			var, _ = string.gsub(var, "0+$", "")
			var, _ = string.gsub(var, ",$", "")
		end
		
		return string.format(i18n.variance, lang:formatNum(amount), var), amount
	else
		return string.format(i18n.between, lang:formatNum(tonumber(snak.datavalue.value.lowerBound)), lang:formatNum(tonumber(snak.datavalue.value.upperBound))), tonumber(snak.datavalue.value.upperBound)
	end		
end

local function formatText(snak)
	local amount = tonumber(snak.datavalue.value.amount)
	local upperVar = snak.datavalue.value.upperBound and (tonumber(snak.datavalue.value.upperBound) - amount) or 0
	local lowerVar = snak.datavalue.value.lowerBound and (amount - tonumber(snak.datavalue.value.lowerBound)) or 0

	local div = false
	local suffix = ""
	local var = 0
	if (upperVar ~= 0) or (lowerVar ~= 0) then
		div, suffix, var = selectRoundCoefficients(amount)
	end
	
	local lang = mw.getContentLanguage()
	if (div == 1) or not div then
		if (upperVar == 0) and (lowerVar == 0) then
			return lang:formatNum(amount), amount
		elseif math.max(upperVar, lowerVar) <= var then
			return string.format(i18n.around, lang:formatNum(amount)), amount
		elseif upperVar == lowerVar then
			return string.format(i18n.variance, lang:formatNum(amount), lang:formatNum(upperVar)), amount
		else
			return string.format(i18n.between, lang:formatNum(tonumber(snak.datavalue.value.lowerBound)), lang:formatNum(tonumber(snak.datavalue.value.upperBound))), tonumber(snak.datavalue.value.upperBound)
		end		
	elseif div then
		if math.max(upperVar, lowerVar) <= var then
			local atxt = lang:formatNum(tonumber(string.format("%.2f", amount / div)))..suffix
			return string.format(i18n.around, atxt), amount / div
		elseif upperVar == lowerVar then
			local atxt = lang:formatNum(tonumber(string.format("%.2f", amount / div)))..suffix
			local vtxt = lang:formatNum(tonumber(string.format("%.2f", upperVar / div)))..suffix
			return string.format(i18n.variance, atxt, vtxt), amount / div
		else
			local ltxt = lang:formatNum(tonumber(string.format("%.2f", tonumber(snak.datavalue.value.lowerBound) / div)))..suffix
			local utxt = lang:formatNum(tonumber(string.format("%.2f", tonumber(snak.datavalue.value.upperBound) / div)))..suffix
			return string.format(i18n.between, ltxt, utxt), tonumber(snak.datavalue.value.lowerBound) / div
		end
	end
end

local function formatUnit(unitEntityId, options, value)
	local quantityUnits = units[unitEntityId]
	if type(quantityUnits) == "table" then
		return mw.getContentLanguage():convertPlural(value, quantityUnits)
	end
	
	local symbol = false
	local unitSymbols = mw.wikibase.getBestStatements(unitEntityId, "P5061")
	for _, v in ipairs(unitSymbols) do
		if (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "monolingualtext") and (v.mainsnak.datavalue.value.language == "pl") then
			symbol = v.mainsnak.datavalue.value.text
			break
		end
	end
	
	if not symbol then
		for _, v in ipairs(unitSymbols) do
			if (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "monolingualtext") and (v.mainsnak.datavalue.value.language == "en") then
				symbol = v.mainsnak.datavalue.value.text
				break
			end
		end
	end
	
	if not symbol then
		for _, s in ipairs(mw.wikibase.getBestStatements(unitEntityId, "P487")) do
			if (s.mainsnak.snaktype == "value") and (s.mainsnak.datatype == "string") and (s.mainsnak.datavalue.type == "string") then
				symbol = s.mainsnak.datavalue.value
				break
			end
		end
	end

	if not symbol then
		symbol = mw.wikibase.getLabel(unitEntityId)
	end
	
	local sitelink = options.linkItem and mw.wikibase.getSitelink(unitEntityId)
	if symbol and sitelink then
		return "[["..sitelink.."|"..symbol.."]]"
	elseif symbol then
		return symbol
	else
		return unitEntityId
	end
end

local autoUnitConverter = {
	-- temperatura
	Q42289   = function(value) return "Q25267", (value - 32) * 5/9 end, -- stopień Fahrenheita [°C]
	Q223061  = function(value) return "Q25267", value * 5/4 end, -- skala Réaumura [°C]
	Q488013  = function(value) return "Q25267", (value - 7.5) * 40/21 end, -- skala Rømera [°C]
	Q839449  = function(value) return "Q25267", 100 - value * 2/3 end, -- skala Delisle [°C]
	Q1133606 = function(value) return "Q25267", value * 100/33 end, -- Skala Newtona [°C]
	-- odległość
	Q3710    = function(value) return "Q11573", value * 0.3048006 end, -- stopa angielska [m]
	Q253276  = function(value) return "Q828224", value * 1.609344 end, -- mila [km]
	Q482798  = function(value) return "Q11573", value * 0.9144 end, -- jard [m]
	Q218593  = function(value) return "Q174728", value * 2.54 end, -- cal [cm]
	-- masa
	Q48013   = function(value) return "Q41803", value * 28.34952 end, -- uncja [g]
	Q100995  = function(value) return "Q11570", value * 0.4535923 end, -- funt [kg]
	-- prędkość
	Q748716  = function(value) return "Q182429", value * 0.3048006 end, -- stopy na sekundę [m/s]
	Q22673229= function(value) return "Q21014455", value * 0.3048006 end, -- stopy na minutę [m/min]
	Q6014364 = function(value) return "Q18413919", value * 2.54 end, -- cale na sekundę [cm/s]
	Q211256  = function(value) return "Q180154", value * 1.609344 end, -- mila na godzinę [km/h]
}

local function round(value)
	if not tonumber(value) or (value == 0) then
		return value
	end
	
	local abs = math.abs(value)
	local fix = value >= 0 and 0.5 or -0.5
	if abs >= 1000 then
		return math.floor(value + fix)
	elseif abs >= 100 then
		return math.floor(10*value + fix) / 10
	elseif abs >= 10 then
		return math.floor(100*value + fix) / 100
	elseif abs >= 1 then
		return math.floor(1000*value + fix) / 1000
	elseif abs >= 0.1 then
		return math.floor(10000*value + fix) / 10000
	else
		return value
	end
end

return {

scope = "snak",

options = {
	default = {
		linkItem = false,
	},
},

format = function(snak, options)
	local value, last
	if options.format == "tekst" then
		value, last = formatText(snak)
	else
		value, last = formatVar(snak)
	end

	if snak.datavalue.value.unit == "1" then
		return value
	end
	
	local unitEntityId = string.match(snak.datavalue.value.unit, "^http://www%.wikidata%.org/entity/(Q%d+)$")
	if not unitEntityId then
		mw.log("unrecognized unit: "..snak.datavalue.value.unit)
		return value.." ?"
	end
	
	local unit = formatUnit(unitEntityId, options, last)
	
	local builder = mw.html.create()
	
	local converter = autoUnitConverter[unitEntityId]
	if converter then
		local unitId2, amount2 = converter(snak.datavalue.value.amount)
		local _, upperBound = snak.datavalue.value.upperBound and converter(snak.datavalue.value.upperBound) or nil
		local _, lowerBound = snak.datavalue.value.upperBound and converter(snak.datavalue.value.lowerBound) or nil
		local v2, l2 = formatText( { datavalue = { value = { amount = round(amount2), upperBount = round(upperBound), lowerBound = round(lowerBound) } } } )
		local u2 = formatUnit(unitId2, options, last)
		
		builder:tag("span")
			:addClass("wd-auto-converted")
			:attr("title", value.." "..unit)
			:wikitext(v2, " ", u2)
	else
		builder:wikitext(value, " ", unit or "!")
	end

	return tostring(builder)
end,

}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy