Modul:Wikidata/Formatters
Věci přenesené přes šablony z cs:wiki
require "Modul:No globals" local p = {} local lib = require 'Modul:Wikidata/lib' local function formatCoordinateValue(value, typeOfValue, field) local function fastConvertDdToDms(ddValue) local dmsArr = { degrees = 0, minutes = 0, seconds = 0.0 } if ddValue then dmsArr.degrees = math.floor(tonumber(ddValue)) dmsArr.minutes = math.floor((tonumber(ddValue) - dmsArr["degrees"]) * 60) dmsArr.seconds = (tonumber(ddValue) - dmsArr["degrees"] - dmsArr["minutes"]/60) * 3600 end return dmsArr end -- type bude nepovinny - tj. "nil" -- priklad pouze -- je tam asi X chyb (mimo jine N vs S a podobne) local result = "" local latdmsText, londmsText if typeOfValue == 'dms' then local latDms = fastConvertDdToDms(value.latitude) local lonDms = fastConvertDdToDms(value.longitude) latdmsText = mw.ustring.format('N %s° %s\' %s"', latDms["degrees"], latDms["minutes"], latDms["seconds"]) londmsText = mw.ustring.format('E %s° %s\' %s"', lonDms["degrees"], lonDms["minutes"], lonDms["seconds"]) if field then if field == 'latitude' then result = latdmsText elseif field == 'longitude' then result = londmsText end else result = latdmsText .. " " .. londmsText end elseif typeOfValue == 'dd' then latdmsText = tonumber(value.latitude) londmsText = tonumber(value.longitude) if field then if field == 'latitude' then result = latdmsText elseif field == 'longitude' then result = londmsText end else result = latdmsText .. " " .. londmsText end else result = value.latitude .. ' / ' .. value.longitude .. ' (přesnost: ' .. value.precision .. ')' end return result end local function findPattern(property) local entity = mw.wikibase.getEntity(property:upper()) if entity then local Statements = entity:getBestStatements('P1630') for _, statement in pairs(Statements) do if lib.IsSnakValue(statement.mainsnak) then return p.getRawValue(statement.mainsnak) end end end return nil end local function formatQuantity(value, options) local amount = tonumber(value.amount) local margin if lib.IsOptionTrue(options, 'showmargin') then margin = tonumber(value.upperBound) - amount if margin == 0 then margin = nil end end local prefix if amount < 0 then amount = tonumber(mw.ustring.sub(amount, 2)) prefix = '-' end if lib.IsOptionTrue(options, 'formatted') then local function formatNumber(number) local integer, decimal if mw.ustring.find(number, '%.') then integer, decimal = mw.ustring.match(number, '^(.+)%.(.+)$') else 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 .. ' ' .. mw.ustring.sub(integer, i + 1, i + 3) i = i + 3 end if decimal then local length = mw.ustring.len(decimal) local i = 3 formatted_num = formatted_num .. ',' .. mw.ustring.sub(decimal, 1, 3) while i < length do formatted_num = formatted_num .. ' ' .. mw.ustring.sub(decimal, i + 1, i + 3) i = i + 3 end end return formatted_num end amount = formatNumber(amount) if margin then margin = formatNumber(margin) end end if margin then amount = amount .. '±' .. margin end if prefix then amount = prefix .. amount end local unit = value.unit if unit ~= '1' and tostring(options.showunit) ~= 'false' then local unit_id = mw.ustring.match(unit, '(Q%d+)') -- separate handler if unit_id then local module = require 'Modul:Wikidata' local unit = module.formatStatementsFromLua{ id = unit_id, limit = 1, property = 'P558', rank = 'best' } if not unit then local ItemFormatter = require 'Modul:Wikidata/item' unit = ItemFormatter.formatEntityId(unit_id, {}) end amount = amount .. ' ' .. unit end end return amount end local function executeFormatter(formatters, value, options) if formatters.module or formatters.withmodule then if not formatters.module or not formatters.func then return formatError('unknown-value-module') end local formatter = require ('Modul:' .. formatters.module) if not formatter then return formatError('value-module-not-found', formatters.module) end local fun = formatter[formatters.func] if not fun then return formatError('value-function-not-found', formatters.func) end return fun(value, options) else return formatters.func(value, options) end end local function getFormatter(datavalue, aspect, options) local FormattersMap = { globecoordinate = { formatted = { func = function(value, options) if not options.field or options.field == '' then -- return error(lib.formatError('param-not-provided', 'field')) return formatCoordinateValue(value, 'dms') elseif options.field == "latitude" or options.field == "longitude" then return formatCoordinateValue(value, options.typeOfCoordinates, options.field) elseif options.field == "precision" or options.field == "globe" then return value[options.field] else return error(lib.formatError('invalid-field', options.field)) end end } }, monolingualtext = { formatted = { func = function(value) return '<span lang="' .. value.language .. '">' .. value.text .. '</span>' end }, raw = { func = function(value) return value.text end } }, quantity = { formatted = { func = formatQuantity }, raw = { func = function(value) return tonumber(value.amount) end } }, string = { formatted = { func = function(value, options) if options.pattern and options.pattern ~= '' then return lib.formatFromPattern(value, options.pattern) elseif lib.IsOptionTrue(options, 'autoformat') then local pattern = findPattern(options.property) if pattern then return lib.formatFromPattern(value, '[' .. pattern .. ' $1]') end else return value end end, } }, time = { formatted = { func = 'formatDateFromWikidataValue', module = 'Wikidata/datum' }, raw = { func = 'newFromWikidataValue', module = 'Time' } }, ["wikibase-entityid"] = { convert = { func = '', module = 'Wikidata/item' }, formatted = { func = function(value, options) local module = require 'Modul:Wikidata/item' return module.formatEntityId(lib.getEntityIdFromValue(value), options) end }, raw = { func = function(...) return lib.getEntityIdFromValue(...) end } }, } if not FormattersMap[datavalue.type] then return error(lib.formatError('unknown-datavalue-type', datavalue.type)) end if not FormattersMap[datavalue.type][aspect] then if aspect == 'raw' then return datavalue.value else return error() -- TODO end end return executeFormatter(FormattersMap[datavalue.type][aspect], datavalue.value, options) end function p.getRawValue(snak, options) if snak.snaktype == 'value' then return getFormatter(snak.datavalue, 'raw', options) elseif snak.snaktype == 'somevalue' or snak.snaktype == 'novalue' then return snak.snaktype else return error(lib.formatError('unknown-snak-type', snak.snaktype)) end end function p.getFormattedValue(snak, options) if snak.snaktype == 'somevalue' or snak.snaktype == 'novalue' then return snak.snaktype elseif snak.snaktype ~= 'value' then return error(lib.formatError('unknown-snak-type', snak.snaktype)) end if options['value-module'] or options['value-function'] then local formatterMap = { func = options['value-function'], module = options['value-module'], withmodule = true -- force throwing error } return executeFormatter(formatterMap, snak.datavalue.value, options) end return getFormatter(snak.datavalue, 'formatted', options) end return p