Location via proxy:
[ UP ]
[Report a bug]
[Manage cookies]
No cookies
No scripts
No ads
No referrer
Show this form
Jump to content
Main menu
Main menu
move to sidebar
hide
Stiureydys
Ard-ghuillag
Ynnyd y phobble
Cooishyn y laa
Caghlaaghyn s'noa
Duillag gyn tort
Cooney
Ronsee
Ronsee
Appearance
Toyrtyssyn
Create account
Log in
Greienyn persoonagh
Toyrtyssyn
Contribute
Create account
Log in
Pages for logged out editors
learn more
Cur loayrtys da'n IP shoh
Reaghey
Module:Wikidades
Add languages
Module
Resoonaght
English
Lhaih
Edit source
Jeeagh er shennaghys
Kishtey greie
Tools
move to sidebar
hide
Actions
Lhaih
Edit source
Jeeagh er shennaghys
General
Cre ta kiangley rish shoh
Caghlaaghyn conastagh
Laad neese coadan
Duillagyn er lheh
Page information
Get shortened URL
Download QR code
In other projects
Appearance
move to sidebar
hide
Raaue:
Cha nel oo loggit stiagh. Bee dt'enmys IP recortyssit ayns shennaghys reaghee yn duillag shoh.
Anti-spam check. Do
not
fill this in!
-- version 20220818 from master @cawiki local p = {} -- Initialization of variables -------------------- local i18n = { -- internationalisation at [[Module:Wikidata/i18n]] ["errors"] = { ["property-not-found"] = "Property not found.", ["qualifier-not-found"] = "Qualifier not found.", }, ["datetime"] = { -- $1 is a placeholder for the actual number ["beforenow"] = "$1 RC", -- how to format negative numbers for precisions 0 to 5 ["afternow"] = "$1 BNJ", -- how to format positive numbers for precisions 0 to 5 ["bc"] = "$1 RC", -- how print negative years ["ad"] = "$1", -- how print 1st century AD dates [0] = "$1 billion years", -- precision: billion years [1] = "$100 million years", -- precision: hundred million years [2] = "$10 million years", -- precision: ten million years [3] = "$1 million years", -- precision: million years [4] = "$100000 years", -- precision: hundred thousand years; thousand separators added afterwards [5] = "$10000 years", -- precision: ten thousand years; thousand separators added afterwards [6] = "$1 millennium", -- precision: millennium [7] = "$1 century", -- precision: century [8] = "$1s", -- precision: decade -- the following use the format of #time parser function [9] = "Y", -- precision: year, [10] = "F Y", -- precision: month [11] = "j F Y", -- precision: day ["hms"] = {["hours"] = "h", ["minutes"] = "m", ["seconds"] = "s"}, -- duration: xh xm xs }, ["years-old"] = {"", ""}, -- year(s) old, as in {{PLURAL:$1|singular|plural}} -- two values for most languages, up to six values for some languages -- see documentation of PLURAL magic word in your language, examples: -- ["years-old"] = {"singular", "paucal", "plural"} in Russian and other Slavic languages -- ["years-old"] = {"zero", "one", "two", "few 3-10", "many 11-99", "other 100-102"} in Arabic ["cite"] = { -- cite parameters ["title"] = "title", ["author"] = "author", ["date"] = "date", ["pages"] = "pages", ["language"] = "language", -- cite web parameters ["url"] = "url", ["website"] = "website", ["access-date"] = "access-date", ["archive-url"] = "archive-url", ["archive-date"] = "archive-date", ["publisher"] = "publisher", ["quote"] = "quote", -- cite journal parameters ["work"] = "work", ["issue"] = "issue", ["issn"] = "issn", ["doi"] = "doi" }, -- default local wiki settings ["addpencil"] = false, -- adds a pencil icon linked to Wikidata statement, planned to overwrite by Wikidata Bridge ["categorylabels"] = "", -- Category:Pages with Wikidata labels not translated (void for no local category) ["categoryprop"] = "", -- Category:Pages using Wikidata property $1 (void for no local category) ["categoryref"] = "", -- Category:Pages with references from Wikidata (void for no local category) ["addfallback"] = {}, -- additional fallback language codes ["suppressids"] = {}, -- list of Qid values to suppress ["qidlabels"] = true -- show labels as Qid if no fallback translation is available } local cases = {} -- functions for local grammatical cases defined at [[Module:Wikidata/i18n]] local required = ... -- variadic arguments from require function local wiki = { langcode = mw.language.getContentLanguage().code, module_title = required or mw.getCurrentFrame():getTitle() } local untranslated -- used in infobox modules: nil or true local _ -- variable for unused returned values, avoiding globals -- Module local functions -------------------------------------------- -- Credit to http://stackoverflow.com/a/1283608/2644759, cc-by-sa 3.0 local function tableMerge(t1, t2) for k, v in pairs(t2) do if type(v) == "table" then if type(t1[k] or false) == "table" then tableMerge(t1[k] or {}, t2[k] or {}) else t1[k] = v end else t1[k] = v end end return t1 end local function loadI18n(lang) local exist, res = pcall(require, wiki.module_title .. "/i18n") if exist and next(res) ~= nil then tableMerge(i18n, res.i18n) cases = res.cases end if lang ~= wiki.langcode then exist, res = pcall(require, wiki.module_title .. "/i18n/" .. lang) if exist and next(res) ~= nil then tableMerge(i18n, res.i18n) tableMerge(cases, res.cases) end end i18n.suppress = {} for _, id in ipairs(i18n.suppressids) do i18n.suppress[id] = true end end -- Table of language codes: requested or default and its fallbacks local function findLang(langcode) if mw.language.isKnownLanguageTag(langcode or '') == false then local cframe = mw.getCurrentFrame() local pframe = cframe:getParent() langcode = pframe and pframe.args.lang if mw.language.isKnownLanguageTag(langcode or '') == false then if not mw.title.getCurrentTitle().isContentPage then langcode = cframe:preprocess('{{int:lang}}') end if mw.language.isKnownLanguageTag(langcode or '') == false then langcode = wiki.langcode end end end loadI18n(langcode) local languages = mw.language.getFallbacksFor(langcode) table.insert(languages, 1, langcode) if langcode == wiki.langcode then for _, l in ipairs(i18n.addfallback) do table.insert(languages, l) end end return languages end -- Argument is 'set' when it exists (not nil) or when it is not an empty string. local function isSet(var) return not (var == nil or (type(var) == 'string' and mw.text.trim(var) == '')) end -- Set local case to a label local function case(localcase, label, ...) if not isSet(label) then return label end if type(localcase) == "function" then return localcase(label) elseif localcase == "smallcaps" then return '<span style="font-variant: small-caps;">' .. label .. '</span>' elseif cases[localcase] then return cases[localcase](label, ...) end return label end -- get safely a serialized snak local function getSnak(statement, snaks) local ret = statement for i, v in ipairs(snaks) do if not ret then return end ret = ret[v] end return ret end -- mw.wikibase.getLabelWithLang or getLabelByLang with a table of languages local function getLabelByLangs(id, languages) local label local lang for _, l in ipairs(languages) do if l == wiki.langcode then -- using getLabelWithLang when possible instead of getLabelByLang label, l = mw.wikibase.getLabelWithLang(id) else label = mw.wikibase.getLabelByLang(id, l) end if label then lang = l break end end return label, lang end -- getBestStatements if bestrank=true, else getAllStatements with no deprecated local function getStatements(entityId, property, bestrank) local claims = {} if not (entityId and mw.ustring.match(property, "^P%d+$")) then return claims end if bestrank then claims = mw.wikibase.getBestStatements(entityId, property) else local allclaims = mw.wikibase.getAllStatements(entityId, property) for _, c in ipairs(allclaims) do if c.rank ~= "deprecated" then table.insert(claims, c) end end end return claims end -- Is gender femenine? true or false local function feminineGender(id) local claims = mw.wikibase.getBestStatements(id or mw.wikibase.getEntityIdForCurrentPage(),'P21') local gender_id = getSnak(claims, {1, "mainsnak", "datavalue", "value", "id"}) if gender_id == "Q6581072" or gender_id == "Q1052281" or gender_id == "Q43445" then -- female, transgender female, female organism return true end return false end -- Fetch female form of label local function feminineForm(id, lang) local feminine_claims = getStatements(id, 'P2521') for _, feminine_claim in ipairs(feminine_claims) do if getSnak(feminine_claim, {'mainsnak', 'datavalue', 'value', 'language'}) == lang then return feminine_claim.mainsnak.datavalue.value.text end end end -- Add an icon for no label in requested language local function addLabelIcon(label_id, lang, uselang, icon) local ret_lang, ret_icon = '', '' if icon then if lang and lang ~= uselang then ret_lang = " <sup>(" .. lang .. ")</sup>" end if label_id and (lang == nil or lang ~= uselang) then local namespace = '' if string.sub(label_id, 1, 1) == 'P' then namespace = 'Property:' end ret_icon = " [[File:Noun Project label icon 1116097 cc mirror.svg|10px|baseline|" .. mw.message.new('Translate-taction-translate'):inLanguage(uselang):plain() .. "|link=https://www.wikidata.org/wiki/" .. namespace .. label_id .. "?uselang=" .. uselang .. "]]" untranslated = true end if isSet(i18n.categorylabels) and lang ~= uselang and uselang == wiki.langcode then ret_icon = ret_icon .. '[[' .. i18n.categorylabels .. (lang and ']]' or '/Q]]') end end return ret_lang .. ret_icon end -- editicon values: true/false (no=false), right, void defaults to i18n.addpencil -- labelicon only by parameter local function setIcons(arg, parg) local val = arg == nil and parg or arg local edit_icon, label_icon if not isSet(val) then edit_icon, label_icon = i18n.addpencil, true elseif val == false or val == "false" or val == "no" then edit_icon, label_icon = false, false else edit_icon, label_icon = val, true end return edit_icon, label_icon end -- Add an icon for editing a statement with requirements for Wikidata Bridge local function addEditIcon(parameters) local ret = '' if parameters.editicon and parameters.id and parameters.property then local icon_style = parameters.editicon == "right" and ' style="float: right;"' or '' ret = ' <span class="penicon" data-bridge-edit-flow="single-best-value"' .. icon_style .. '>' .. "[[File:Arbcom ru editing.svg|10px|baseline|" .. string.gsub(mw.message.new('Wikibase-client-data-bridge-bailout-suggestion-go-to-repo-button'):inLanguage(parameters.lang[1]):plain(), '{{WBREPONAME}}', 'Wikidata') .. "|link=https://www.wikidata.org/wiki/" .. parameters.id .. "?uselang=" .. parameters.lang[1] .. "#" .. parameters.property .. "]]" .. "</span>" if isSet(i18n.categoryprop) then ret = ret .. "[[" .. string.gsub(i18n.categoryprop, '$1', parameters.property) .. "]]" end end return ret end -- add edit icon to the last element of a table local function addEditIconTable(thetable, parameters) if #thetable == 0 or parameters.editicon == false then return thetable end local last_element = thetable[#thetable] local the_icon = addEditIcon(parameters) -- add it before last html closing tags local tags = '' local rev_element = string.reverse(last_element) for tag in string.gmatch(rev_element, '(>%l+/<)') do if string.match(rev_element, '^' .. tags .. tag) then tags = tags .. tag else break end end local last_tags = string.reverse(tags) local offset = string.find(last_element, last_tags .. '$') if offset then thetable[#thetable] = string.sub(last_element, 1, offset - 1) .. the_icon .. last_tags else thetable[#thetable] = last_element .. the_icon end return thetable end -- Escape Lua captures local function captureEscapes(text) return mw.ustring.gsub(text, "(%%%d)", "%%%1") end -- expandTemplate or callParserFunction local function expandBraces(text, formatting) if text == nil or formatting == nil then return text end -- only expand braces if provided in argument, not included in value as in Q1164668 if mw.ustring.find(formatting, '{{', 1, true) == nil then return text end if type(text) ~= "string" then text = tostring(text) end for braces in mw.ustring.gmatch(text, "{{(.-)}}") do local parts = mw.text.split(braces, "|") local title_part = parts[1] local parameters = {} for i = 2, #parts do local subparts = mw.ustring.find(parts[i], "=") if subparts then local param_name = mw.ustring.sub(parts[i], 1, subparts - 1) local param_value = mw.ustring.sub(parts[i], subparts + 1, -1) -- reconstruct broken links by parts if i < #parts and mw.ustring.find(param_value, "[[", 1, true) and not mw.ustring.find(param_value, "]]", 1, true) then parameters[param_name] = param_value local part_next = i + 1 while parts[part_next] and mw.ustring.find(parts[part_next], "]]", 1, true) do parameters[param_name] = parameters[param_name] .. "|" .. parts[part_next] part_next = part_next + 1 end else parameters[param_name] = param_value end elseif not mw.ustring.find(parts[i], "]]", 1, true) then table.insert(parameters, parts[i]) end end local braces_expanded if mw.ustring.find(title_part, ":") and mw.text.split(title_part, ":")[1] ~= mw.site.namespaces[10].name -- not a prefix Template: then braces_expanded = mw.getCurrentFrame():callParserFunction{name=title_part, args=parameters} else braces_expanded = mw.getCurrentFrame():expandTemplate{title=title_part, args=parameters} end braces = mw.ustring.gsub(braces, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape magic characters braces_expanded = captureEscapes(braces_expanded) text = mw.ustring.gsub(text, "{{" .. braces .. "}}", braces_expanded) end return text end -- format data type math local function printDatatypeMath(data) return mw.getCurrentFrame():callParserFunction('#tag:math', data) end -- format data type musical-notation local function printDatatypeMusical(data, formatting) local attr = {} if formatting == 'sound' then attr.sound = 1 end return mw.getCurrentFrame():extensionTag('score', data, attr) end -- format data type string local function printDatatypeString(data, parameters) if mw.ustring.find((parameters.formatting or ''), '$1', 1, true) then -- formatting = a pattern return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', {['$1'] = data}), parameters.formatting) elseif parameters.case then return case(parameters.case, data, parameters.lang[1], feminineGender(parameters.id)) end local data_number = string.match(data, "^%d+") if data_number then -- sort key by initial number and remaining string local sortkey = string.format("%019d", data_number * 1000) return data, sortkey .. string.sub(data, #data_number + 1) end return data end -- format data type tabular-data local function printDatatypeTabular(data, parameters) local icon if parameters.formatting == 'raw' then icon = "no-icon" data = string.gsub(data, '^Data:', '') -- remove prefix, i.e. see Module:Tabular data end return printDatatypeString(data, parameters), icon end -- format data type url local function printDatatypeUrl(data, parameters) if parameters.formatting == 'weblink' then local label_parts = mw.text.split(string.gsub(data, '/$', ''), '/') local label = string.gsub(label_parts[3], '^www%.', '') if #label_parts > 3 then label = label .. '…' end return '[' .. data .. ' ' .. label .. ']' end return printDatatypeString(data, parameters) end -- format data type external-id local function printDatatypeExternal(data, parameters) if parameters.formatting == 'externalid' then local p_stat = mw.wikibase.getBestStatements(parameters.property, 'P1630') -- formatter URL local p_link_pattern = getSnak(p_stat, {1, "mainsnak", "datavalue", "value"}) if p_link_pattern then local p_link = mw.ustring.gsub(p_link_pattern, '$1', {['$1'] = data}) return '[' .. p_link .. ' ' .. data .. ']' end end return printDatatypeString(data, parameters) end -- format data type commonsMedia and geo-shape local function printDatatypeMedia(data, parameters) local icon if not string.find((parameters.formatting or ''), '$1', 1, true) then icon = "no-icon" if not string.find(data, '^Data:') then data = mw.uri.encode(data, 'PATH') -- encode special characters in filename end end return printDatatypeString(data, parameters), icon end -- format data type globe-coordinate local function printDatatypeCoordinate(data, formatting) local function globes(globe_id) local globes = {['Q3134']='callisto',['Q596']='ceres',['Q15040']='dione',['Q2']='earth',['Q3303']='enceladus', ['Q3143']='europa',['Q17975']='phoebe',['Q3169']='ganymede',['Q3123']='io',['Q17958']='iapetus', ['Q308']='mercury',['Q15034']='mimas',['Q405']='moon',['Q15050']='rhea',['Q15047']='tethys', ['Q111']='mars',['Q2565']='titan',['Q3359']='triton',['Q313']='venus',['Q3030']='vesta'} return globes[globe_id] end local function roundPrecision(num, prec) if prec == nil or prec <= 0 then return num end local sig = 10^math.floor(math.log10(prec)+.5) -- significant figure from sexagesimal precision: 0.00123 -> 0.001 return math.floor(num / sig + 0.5) * sig end local precision = data.precision local latitude = roundPrecision(data.latitude, precision) local longitude = roundPrecision(data.longitude, precision) if formatting and string.find(formatting, '$lat', 1, true) and string.find(formatting, '$lon', 1, true) then local ret = mw.ustring.gsub(formatting, '$l[ao][tn]', {['$lat'] = latitude, ['$lon'] = longitude}) if string.find(formatting, '$globe', 1, true) then local myglobe = 'earth' if isSet(data.globe) then local globenum = mw.text.split(data.globe, 'entity/')[2] -- http://www.wikidata.org/wiki/Q2 myglobe = globes(globenum) or 'earth' end ret = mw.ustring.gsub(ret, '$globe', myglobe) end return expandBraces(ret, formatting) elseif formatting == 'latitude' then return latitude, "no-icon" elseif formatting == 'longitude' then return longitude, "no-icon" elseif formatting == 'dimension' then return data.dimension, "no-icon" else --default formatting='globe' if isSet(data.globe) == false or data.globe == 'http://www.wikidata.org/entity/Q2' then return 'earth', "no-icon" else local globenum = mw.text.split(data.globe, 'entity/')[2] return globes(globenum) or globenum, "no-icon" end end end -- Local functions for data value quantity local function unitSymbol(id, lang) -- get unit symbol or code local unit_symbol = '' if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then unit_symbol = require(wiki.module_title .. "/Units").getUnit(0, '', id, true) end if unit_symbol == '' then -- fetch it local claims = mw.wikibase.getBestStatements(id, 'P5061') if #claims > 0 then local langclaims = {} table.insert(lang, 'mul') -- multilingual as last try for _, snak in ipairs(claims) do local snak_language = getSnak(snak, {"mainsnak", "datavalue", "value", "language"}) if snak_language and not langclaims[snak_language] then -- just the first one by language langclaims[snak_language] = snak.mainsnak.datavalue.value.text end end for _, l in ipairs(lang) do if langclaims[l] then return langclaims[l] end end end end return unit_symbol end local function getUnit(amount, id, parameters) -- get unit symbol or name local suffix = '' if string.sub(parameters.formatting or '', 1, 8) == "unitcode" then -- get unit symbol local unit_symbol = unitSymbol(id, parameters.lang) if isSet(unit_symbol) then if string.sub(parameters.formatting or '', -6) == "linked" then suffix = "[[" .. (mw.wikibase.getSitelink(id) or "d:" .. id) .. "|" .. unit_symbol .. "]]" else suffix = unit_symbol end end end if suffix == '' then -- formatting=unit, or formatting=unitcode not found -- get unit label local unit_label, lang = getLabelByLangs(id, parameters.lang) if lang == wiki.langcode and pcall(require, wiki.module_title .. "/Units") then suffix = require(wiki.module_title .. "/Units").getUnit(amount, unit_label, id, false) if string.sub(parameters.formatting or '', -6) == "linked" then suffix = "[[" .. (mw.wikibase.getSitelink(id) or "d:" .. id) .. "|" .. suffix .. "]]" end else suffix = (unit_label or id) .. addLabelIcon(id, lang, parameters.lang[1], parameters.labelicon) end end if suffix ~= '' then suffix = ' ' .. suffix end return suffix end local function roundDefPrecision(in_num, factor) -- rounds out_num with significant figures of in_num (default precision) local out_num = in_num * factor if factor/60 == math.floor(factor/60) or out_num == 0 then -- sexagesimal integer or avoiding NaN return out_num end -- first, count digits after decimal mark, handling cases like '12.345e6' local exponent, prec local integer, dot, decimals, expstr = in_num:match('^(%d*)(%.?)(%d*)(.*)') local e = expstr:sub(1, 1) if e == 'e' or e == 'E' then exponent = tonumber(expstr:sub(2)) end if dot == '' then prec = -integer:match('0*$'):len() else prec = #decimals end if exponent then -- So '1230' and '1.23e3' both give prec = -1, and '0.00123' and '1.23e-3' give 5. prec = prec - exponent end -- significant figures local in_bracket = 10^-prec -- -1 -> 10, 5 -> 0.00001 local out_bracket = in_bracket * out_num / in_num out_bracket = 10^math.floor(math.log10(out_bracket)+.5) -- 1230 -> 1000, 0.00123 -> 0.001 -- round it (credit to Luc Bloom from http://lua-users.org/wiki/SimpleRound) return math.floor(out_num/out_bracket + (out_num >=0 and 1 or -1) * 0.5) * out_bracket end -- format data type quantity local function printDatatypeQuantity(data, parameters) local amount = data.amount amount = mw.ustring.gsub(amount, "%+", "") local suffix = "" local conv_amount, conv_suffix if string.sub(parameters.formatting or '', 1, 4) == "unit" or string.sub(parameters.formatting or '', 1, 8) == "duration" or parameters.convert then local unit_id = data.unit unit_id = mw.ustring.sub(unit_id, mw.ustring.find(unit_id, "Q"), -1) if string.sub(unit_id, 1, 1) == "Q" then suffix = getUnit(amount, unit_id, parameters) local convert_to if parameters.convert == "default" or parameters.convert == "default2" then local exist, units = pcall(require, wiki.module_title .. "/Units") if exist and units.convert_default and next(units.convert_default) ~= nil then convert_to = units.convert_default[unit_id] end elseif string.sub(parameters.convert or '', 1, 1) == "Q" then convert_to = parameters.convert elseif string.sub(parameters.formatting or '', 1, 8) == "duration" then convert_to = 'Q11574' -- seconds end if convert_to and convert_to ~= unit_id then -- convert units local conv_temp = { -- formulae for temperatures ºC, ºF, ªK: [from] = {[to] = 'formula'} ['Q25267'] = {['Q42289'] = '$1*1.8+32', ['Q11597'] = '$1+273.15'}, ['Q42289'] = {['Q25267'] = '($1-32)/1.8', ['Q11597'] = '($1+459.67)*5/9'}, ['Q11597'] = {['Q25267'] = '$1-273.15', ['Q42289'] = '($1-273.15)*1.8000+32.00'} } if conv_temp[unit_id] and conv_temp[unit_id][convert_to] then local amount_f = mw.getCurrentFrame():callParserFunction('#expr', mw.ustring.gsub(conv_temp[unit_id][convert_to], "$1", amount)) conv_amount = math.floor(tonumber(amount_f) + 0.5) else local conversions = getStatements(unit_id, 'P2442') -- conversion to standard unit table.insert(conversions, mw.wikibase.getBestStatements(unit_id, 'P2370')[1]) -- conversion to SI unit for _, conv in ipairs(conversions) do if conv.mainsnak.snaktype == 'value' then -- no somevalue nor novalue if conv.mainsnak.datavalue.value.unit == "http://www.wikidata.org/entity/" .. convert_to then conv_amount = roundDefPrecision(amount, tonumber(conv.mainsnak.datavalue.value.amount)) break end end end end if conv_amount then conv_suffix = getUnit(conv_amount, convert_to, parameters) end elseif parameters.convert == 'M' and tonumber(amount) > 10^8 then conv_amount = math.floor(amount/10^6 + 0.5) conv_suffix = ' M' .. string.sub(suffix, 2) end if conv_amount and parameters.formatting == 'raw' then amount = conv_amount suffix = "" conv_amount = nil end end end local lang_obj = mw.language.new(parameters.lang[1]) local sortkey = string.format("%019d", tonumber(amount) * 1000) if string.sub(parameters.formatting or '', 1, 8) == "duration" then local sec = tonumber(conv_amount or amount) if parameters.formatting == 'duration' then return lang_obj:formatDuration(sec) elseif parameters.formatting == 'durationm:s' then local mm = math.floor(sec / 60) local ss = sec - (mm * 60) return string.format("%02d:%02d", mm, ss) else -- durationhms or durationh:m:s local intervals = {"hours", "minutes", "seconds"} local sec2table = lang_obj:getDurationIntervals(sec, intervals) sec2table["seconds"] = (sec2table["seconds"] or 0) + tonumber("." .. (tostring(sec):match("%.(%d+)") or "0")) -- add decimals local duration = '' for i, v in ipairs(intervals) do if parameters.formatting == 'durationh:m:s' then if i == 1 and sec2table[v] then duration = duration .. sec2table[v] .. ":" elseif i == 2 then duration = duration .. string.format("%02d", sec2table[v] or 0) .. ":" elseif i == 3 then local sec_str = tostring(lang_obj:formatNum(sec2table[v] or 0)) duration = duration .. (sec2table[v] < 10 and "0" or "") .. sec_str end elseif sec2table[v] then duration = duration .. lang_obj:formatNum(sec2table[v]) .. i18n.datetime.hms[v] .. (i < 3 and " " or "") end end return duration end end if parameters.case then amount = case(parameters.case, amount, parameters.lang[1], feminineGender(parameters.id)) elseif parameters.formatting ~= 'raw' then if parameters.numformat then amount = lang_obj:formatNum(tonumber(string.format(parameters.numformat, amount))) else amount = lang_obj:formatNum(tonumber(amount)) end end if conv_amount then local conv_sortkey = string.format("%019d", conv_amount * 1000) conv_amount = lang_obj:formatNum(conv_amount) if parameters.convert == 'default2' then return conv_amount .. conv_suffix .. ' (' .. amount .. suffix .. ')', conv_sortkey else return conv_amount .. conv_suffix, conv_sortkey end elseif mw.ustring.find((parameters.formatting or ''), '$1', 1, true) then -- formatting with pattern amount = mw.ustring.gsub(parameters.formatting, '$1', {['$1'] = amount}) end return amount .. suffix, sortkey end -- format data type time local function printDatatypeTime(data, parameters) -- Dates and times are stored in ISO 8601 format local timestamp = data.time local post_format local calendar_add = "" local precision = data.precision or 11 if string.sub(timestamp, 1, 1) == '-' then post_format = i18n.datetime["bc"] elseif string.sub(timestamp, 2, 3) == '00' then post_format = i18n.datetime["ad"] elseif precision > 8 then -- calendar model local calendar_model = {["Q12138"] = "gregorian", ["Q1985727"] = "gregorian", ["Q11184"] = "julian", ["Q1985786"] = "julian"} local calendar_id = mw.text.split(data.calendarmodel, 'entity/')[2] if (timestamp < "+1582-10-15T00:00:00Z" and calendar_model[calendar_id] == "gregorian") or (timestamp > "+1582-10-04T00:00:00Z" and calendar_model[calendar_id] == "julian") then calendar_add = " <sup>(" .. mw.message.new('Wikibase-time-calendar-' .. calendar_model[calendar_id]):inLanguage(parameters.lang[1]):plain() .. ")</sup>" end end local function formatTime(form, stamp) local pattern if type(form) == "function" then pattern = form(stamp) else pattern = form end stamp = tostring(stamp) if mw.ustring.find(pattern, "$1") then return mw.ustring.gsub(pattern, "$1", stamp) elseif string.sub(stamp, 1, 1) == '-' then -- formatDate() only supports years from 0 stamp = '+' .. string.sub(stamp, 2) elseif string.sub(stamp, 1, 1) ~= '+' then -- not a valid timestamp, it is a number stamp = string.format("%04d", stamp) end local ret = mw.language.new(parameters.lang[1]):formatDate(pattern, stamp) ret = string.gsub(ret, "^(%[?%[?)0+", "%1") -- suppress leading zeros ret = string.gsub(ret, "( %[?%[?)0+", "%1") return ret end local function postFormat(t) if post_format and mw.ustring.find(post_format, "$1") then return mw.ustring.gsub(post_format, "$1", t) end return t end local intyear = tonumber(string.match(timestamp, "[+-](%d+)")) local ret = "" if precision <= 5 then -- precision is 10000 years or more local factor = 10 ^ ((5 - precision) + 4) local y2 = math.ceil(math.abs(intyear) / factor) local relative = formatTime(i18n.datetime[precision], y2) if post_format == i18n.datetime["bc"] then ret = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative) else ret = mw.ustring.gsub(i18n.datetime.afternow, "$1", relative) end local ret_number = string.match(ret, "%d+") if ret_number ~= nil then ret = mw.ustring.gsub(ret, ret_number, mw.language.new(parameters.lang[1]):formatNum(tonumber(ret_number))) end elseif precision == 6 or precision == 7 then -- millennia or centuries local card = math.floor((intyear - 1) / 10^(9 - precision)) + 1 ret = formatTime(i18n.datetime[precision], card) ret = postFormat(ret) elseif precision == 8 then -- decades local card = math.floor(math.abs(intyear) / 10) * 10 ret = formatTime(i18n.datetime[8], card) ret = postFormat(ret) elseif intyear > 9999 then -- not a valid timestamp return elseif precision == 9 or parameters.formatting == 'Y' then -- precision is year ret = formatTime(i18n.datetime[9], intyear) ret = postFormat(ret) .. calendar_add elseif precision == 10 then -- month ret = formatTime(i18n.datetime[10], timestamp .. " + 1 day") -- formatDate yyyy-mm-00 returns the previous month ret = postFormat(ret) .. calendar_add else -- precision 11, day ret = formatTime(parameters.formatting or i18n.datetime[11], timestamp) ret = postFormat(ret) .. calendar_add end return ret, timestamp end -- format data value wikibase-entityid with data types wikibase-item or wikibase-property local function printDatatypeEntity(data, parameters) local entity_id = data['id'] if parameters.formatting == 'raw' then return entity_id, entity_id end local entity_page = 'Special:EntityPage/' .. entity_id local label, lang = getLabelByLangs(entity_id, parameters.lang) local sitelink = mw.wikibase.getSitelink(entity_id) local parameter = parameters.formatting local labelcase = label or sitelink if parameters.gender == 'feminineform' then labelcase = feminineForm(entity_id, lang) or labelcase end if parameters.case ~= 'gender' then labelcase = case(parameters.case, labelcase, lang, parameters.lang[1], entity_id, parameters.id) end if labelcase == nil and i18n.qidlabels == false then return end local ret1, ret2 if parameter == 'label' then ret1 = labelcase or entity_id ret2 = labelcase or entity_id elseif parameter == 'sitelink' then ret1 = (sitelink or 'd:' .. entity_page) ret2 = sitelink or entity_id elseif mw.ustring.find((parameter or ''), '$1', 1, true) then -- formatting = a pattern ret1 = mw.ustring.gsub(parameter, '$1', labelcase or entity_id) ret1 = expandBraces(ret1, parameter) ret2 = labelcase or entity_id else if parameter == "ucfirst" or parameter == "ucinternallink" then if labelcase and lang then labelcase = mw.language.new(lang):ucfirst(labelcase) end -- only first of a list, reset formatting for next ones if parameter == "ucinterlanllink" then parameters.formatting = 'internallink' else parameters.formatting = nil -- default format end end if sitelink then ret1 = '[[' .. sitelink .. '|' .. labelcase .. ']]' ret2 = labelcase elseif label and string.match(parameter or '', 'internallink$') and not mw.wikibase.getEntityIdForTitle(label) then ret1 = '[[' .. label .. '|' .. labelcase .. ']]' ret2 = labelcase else ret1 = '[[d:' .. entity_page .. '|<span style="color:#5f9cbb;">' .. (labelcase or entity_id) .. '</span>]]' ret2 = labelcase or entity_id end end return ret1 .. addLabelIcon(entity_id, lang, parameters.lang[1], parameters.labelicon), ret2 end -- format data type wikibase-lexeme local function printDatatypeLexeme(data, parameters) local entity_id = data['id'] if parameters.formatting == 'raw' then return entity_id, entity_id end local lemmas = mw.wikibase.getEntity(entity_id):getLemmas() if parameters.list == 'lang' and lemmas[1][2] ~= parameters.lang[1] then return end local ret = '[[d:Special:EntityPage/' .. entity_id .. '|<span style="color:#5f9cbb;">' .. lemmas[1][1] .. '</span>]]' if parameters.list ~= 'lang' or (parameters.list == 'lang' and lemmas[1][2] ~= wiki.langcode) then ret = ret .. " <sup>(" .. lemmas[1][2] .. ")</sup>" end return ret, entity_id end -- format data type monolingualtext local function printDatatypeMonolingual(data, parameters) -- data fields: language [string], text [string] if parameters.list == "lang" and data["language"] ~= parameters.lang[1] then return elseif parameters.list == "notlang" and data["language"] == parameters.lang[1] then return elseif parameters.formatting == "language" or parameters.formatting == "text" then return data[parameters.formatting] end local result = data["text"] if data["language"] ~= wiki.langcode then result = mw.ustring.gsub('<span lang="$1">$2</span>', '$[12]', {["$1"]=data["language"], ["$2"]=data["text"]}) end if mw.ustring.find((parameters.formatting or ''), '$', 1, true) then -- output format defined with $text, $language result = mw.ustring.gsub(parameters.formatting, '$text', result) result = mw.ustring.gsub(result, '$language', data["language"]) end return result end local function getSnakValue(snak, parameters) if snak.snaktype == 'value' then -- see Special:ListDatatypes -- data value string if snak.datatype == "string" then return printDatatypeString(snak.datavalue.value, parameters) elseif snak.datatype == "commonsMedia" or snak.datatype == "geo-shape" then return printDatatypeMedia(snak.datavalue.value, parameters) elseif snak.datatype == "tabular-data" then return printDatatypeTabular(snak.datavalue.value, parameters) elseif snak.datatype == "url" then return printDatatypeUrl(snak.datavalue.value, parameters) elseif snak.datatype == "external-id" then return printDatatypeExternal(snak.datavalue.value, parameters) elseif snak.datatype == 'math' then return printDatatypeMath(snak.datavalue.value) elseif snak.datatype == 'musical-notation' then return printDatatypeMusical(snak.datavalue.value, parameters.formatting) -- data types other than string value elseif snak.datatype == 'wikibase-item' or snak.datatype == 'wikibase-property' then if i18n.suppress[snak.datavalue.value.id] then return end return printDatatypeEntity(snak.datavalue.value, parameters) elseif snak.datatype == 'wikibase-lexeme' then return printDatatypeLexeme(snak.datavalue.value, parameters) elseif snak.datatype == 'monolingualtext' then return printDatatypeMonolingual(snak.datavalue.value, parameters) elseif snak.datatype == "globe-coordinate" then return printDatatypeCoordinate(snak.datavalue.value, parameters.formatting) elseif snak.datatype == "quantity" then return printDatatypeQuantity(snak.datavalue.value, parameters) elseif snak.datatype == "time" then return printDatatypeTime(snak.datavalue.value, parameters) end elseif snak.snaktype == 'novalue' then if parameters.formatting == 'raw' or parameters.shownovalue == false then return end return mw.message.new('Wikibase-snakview-snaktypeselector-novalue'):inLanguage(parameters.lang[1]):plain() elseif snak.snaktype == 'somevalue' then if parameters.formatting == 'raw' then return end return mw.message.new('Wikibase-snakview-snaktypeselector-somevalue'):inLanguage(parameters.lang[1]):plain() end return mw.wikibase.renderSnak(snak) end local function printError(key) return '<span class="error">' .. i18n.errors[key] .. '</span>' end local function getQualifierSnak(claim, qualifierId, parameters) -- a "snak" is Wikidata terminology for a typed key/value pair -- a claim consists of a main snak holding the main information of this claim, -- as well as a list of attribute snaks and a list of references snaks if qualifierId then -- search the attribute snak with the given qualifier as key if claim.qualifiers then local qualifier = claim.qualifiers[qualifierId] if qualifier then if qualifier[1].datatype == "monolingualtext" then -- iterate over monolingualtext qualifiers to get local language for idx in pairs(qualifier) do if getSnak(qualifier[idx], {"datavalue", "value", "language"}) == parameters.lang[1] then return qualifier[idx] end end elseif parameters.list then return qualifier else return qualifier[1] end end end return nil, printError("qualifier-not-found") else -- otherwise return the main snak return claim.mainsnak end end local function getValueOfClaim(claim, qualifierId, parameters) local snak, error = getQualifierSnak(claim, qualifierId, parameters) if not snak then return nil, nil, error elseif snak[1] then -- a multi qualifier local result, sortkey = {}, {} local maxvals = tonumber(parameters.listmax) for idx in pairs(snak) do result[#result + 1], sortkey[#sortkey + 1] = getSnakValue(snak[idx], parameters) if maxvals and maxvals == #result then break end end return mw.text.listToText(result, parameters.qseparator, parameters.qconjunction), sortkey[1] else -- a property or a qualifier return getSnakValue(snak, parameters) end end local function getValueOfParentClaim(claim, qualifierId, parameters) local qids = mw.text.split(qualifierId, '/', true) local value, sortkey, valueraw = {}, {}, {} local parent_raw, value_text if qids[1] == parameters.property then parent_raw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=parameters.lang}) else parent_raw, _, _ = getValueOfClaim(claim, qids[1], {["formatting"]="raw", ["lang"]=parameters.lang, ["list"]=true, ["qseparator"]='/', ["qconjunction"]='/'}) end if string.sub(parent_raw or '', 1, 1) == "Q" then -- protection for 'no value' local parent_qids = mw.text.split(parent_raw, '/', true) for idx, p_qid in ipairs(parent_qids) do local parent_claims = mw.wikibase.getBestStatements(p_qid, qids[2]) if parent_claims[1] then value[idx], sortkey[idx], _ = getValueOfClaim(parent_claims[1], nil, parameters) -- raw parent value needed for while/black lists, lang for avoiding an error on types other than entity valueraw[idx], _, _ = getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang}) end end end if value[1] then value_text = mw.text.listToText(value, parameters.qseparator, parameters.qconjunction) end return value_text, sortkey[1], valueraw[1] end -- see d:Help:Sources local function getReferences(claim, parameters) if not (parameters.references or parameters.onlysourced) then return '', false end local lang = parameters.lang local maxrefs = tonumber(parameters.references) or 1 local notproperref = { ["P143"] = true, -- imported from ["P3452"] = true, -- inferred from ["P887"] = true, -- based on heuristic ["P4656"] = true -- Wikimedia import URL } local result = {} -- traverse through all references for ref in pairs(claim.references or {}) do local refparts local refs = {} local validref = true local ref_id -- traverse through all parts of the current reference for snakkey, snakval in pairs(claim.references[ref].snaks or {}) do for partkey, _ in pairs(claim.references[ref].snaks[snakkey] or {}) do if notproperref[snakkey] then -- not a proper reference validref = false break end end if validref then for snakidx = 1, #snakval do if snakidx > 1 then refparts = refparts .. ", " end if snakval[snakidx].datatype == 'external-id' then refparts = refparts or '' .. (getSnakValue(snakval[snakidx], {formatting='externalid', property=snakval[snakidx].property, lang=lang}) or '') else refparts = refparts or '' .. (getSnakValue(snakval[snakidx], {lang=lang}) or '') end end refs[snakkey] = refparts refparts = nil if snakkey == "P248" then -- stated in ref_id = getSnak(snakval, {1, "datavalue", "value", "id"}) end end end -- fill missing values with parent item if ref_id then local function refParent(qid, pid, formatting) local snak = getSnak(mw.wikibase.getBestStatements(qid, pid), {1, "mainsnak"}) return snak and getSnakValue(snak, {formatting=formatting, lang=lang}) end refs['P50'] = refs['P50'] or refParent(ref_id, 'P50', 'label') -- author refs['P407'] = refs['P407'] or refParent(ref_id, 'P407', 'label') -- language of work refs['P123'] = refs['P123'] or refParent(ref_id, 'P123', 'label') -- publisher refs['P577'] = refs['P577'] or refParent(ref_id, 'P577') -- date refs['P1433'] = refs['P1433'] or refParent(ref_id, 'P1433', 'label') -- published in refs['P304'] = refs['P304'] or refParent(ref_id, 'P304') -- page(s) refs['P433'] = refs['P433'] or refParent(ref_id, 'P433') -- issue refs['P236'] = refs['P236'] or refParent(ref_id, 'P236') -- ISSN refs['P356'] = refs['P356'] or refParent(ref_id, 'P356') -- DOI end -- get title of local templates for citing references local template_web = mw.wikibase.getSitelink('Q5637226') or "" template_web = mw.text.split(template_web, ":")[2] -- split off namespace from front local template_journal = mw.wikibase.getSitelink('Q5624899') or "" template_journal = mw.text.split(template_journal, ":")[2] local citeParams = {} if refs['P854'] and (refs['P1476'] or refs['P248']) and template_web then -- if both "reference URL" and "title" (or "stated in") are present, then use cite web template citeParams[i18n['cite']['url']] = refs['P854'] if refs['P248'] and refs['P1476'] == nil then citeParams[i18n['cite']['title']] = refs['P248']:match("^%[%[.-|(.-)%]%]") else citeParams[i18n['cite']['title']] = refs['P1476'] citeParams[i18n['cite']['website']] = refs['P248'] end citeParams[i18n['cite']['author']] = refs['P50'] citeParams[i18n['cite']['language']] = refs['P407'] citeParams[i18n['cite']['publisher']] = refs['P123'] citeParams[i18n['cite']['date']] = refs['P577'] citeParams[i18n['cite']['pages']] = refs['P304'] citeParams[i18n['cite']['access-date']] = refs['P813'] citeParams[i18n['cite']['archive-url']] = refs['P1065'] citeParams[i18n['cite']['archive-date']] = refs['P2960'] citeParams[i18n['cite']['quote']] = refs['P1683'] refparts = mw.getCurrentFrame():expandTemplate{title=template_web, args=citeParams} elseif refs['P1433'] and (refs['P1476'] or refs['P248']) and template_journal then -- if both "published in" and "title" (or "stated in") are present, then use cite journal template citeParams[i18n['cite']['work']] = refs['P1433'] citeParams[i18n['cite']['title']] = refs['P1476'] or refs['P248'] citeParams[i18n['cite']['author']] = refs['P50'] citeParams[i18n['cite']['date']] = refs['P577'] citeParams[i18n['cite']['issue']] = refs['P433'] citeParams[i18n['cite']['pages']] = refs['P304'] citeParams[i18n['cite']['language']] = refs['P407'] citeParams[i18n['cite']['issn']] = refs['P236'] citeParams[i18n['cite']['doi']] = refs['P356'] refparts = mw.getCurrentFrame():expandTemplate{title=template_journal, args=citeParams} elseif validref then -- raw ouput local snaksorder = claim.references[ref]["snaks-order"] local function indexed(a) for _, b in ipairs(snaksorder) do if b == a then return true end end return false end for k, _ in pairs(refs or {}) do if not indexed(k) then table.insert(snaksorder, k) end end local italics = "''" for _, k in ipairs(snaksorder) do if refs[k] then refparts = refparts and refparts .. " " or "" refparts = refparts .. mw.ustring.gsub(getLabelByLangs(k, lang), "^%l", mw.ustring.upper) .. ": " refparts = refparts .. italics .. refs[k] .. italics .. "." italics = "" end end end if refparts then local ref_name = claim.references[ref].hash result[#result + 1] = mw.getCurrentFrame():extensionTag("ref", refparts, {name=ref_name}) if maxrefs and maxrefs == #result then break end end end if #result > 0 then if parameters.references then if isSet(i18n.categoryref) then result[#result + 1] = "[[" ..i18n.categoryref .. "]]" end return table.concat(result), true else return '', true end end return '', false end -- Set whitelist or blacklist values local function setWhiteOrBlackList(num_qual, args) local lists = {['whitelist']={}, ['blacklist']={}, ['ignorevalue']={}, ['selectvalue']={}} for i = 0, num_qual do for k, _ in pairs(lists) do if isSet(args[k .. i]) then lists[k][tostring(i)] = {} local pattern = 'Q%d+' if string.sub(args[k .. i], 1, 1) ~= 'Q' then pattern = '[^%p%s]+' end for q in string.gmatch(args[k .. i], pattern) do lists[k][tostring(i)][q] = true end end end end return lists['whitelist'], lists['blacklist'], lists['ignorevalue'], lists['selectvalue'] end local function tableParameters(args, parameters, column) local column_params = mw.clone(parameters) column_params.formatting = args["colformat"..column]; if column_params.formatting == "" then column_params.formatting = nil end column_params.convert = args["convert" .. column] if args["case" .. column] then column_params.case = args["case" .. column] end return column_params end local function getEntityId(args, pargs, unnamed) pargs = pargs or {} local id = args.item or args.from or (unnamed and mw.text.trim(args[1] or '') or nil) if not isSet(id) then id = pargs.item or pargs.from or (unnamed and mw.text.trim(pargs[1] or '') or nil) end if isSet(id) then if string.find(id, ":") then -- remove prefix as Property:Pid id = mw.text.split(id, ":")[2] end else id = mw.wikibase.getEntityIdForCurrentPage() end return id end local function getArg(value, default, aliases) if type(value) == 'boolean' then return value elseif value == "false" or value == "no" then return false elseif value == "true" or value == "yes" then return true elseif value and aliases and aliases[value] then return aliases[value] elseif isSet(value) then return value elseif default then return default else return nil end end -- Main function claim --------------------------------------------- -- on debug console use: =p.claim{item="Q...", property="P...", ...} function p.claim(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local is_sandbox = isSet(pargs.sandbox) if not required and is_sandbox then return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).claim(frame) end --If a value is already set, use it if isSet(args.value) then if args.value == 'NONE' then return else return args.value end end -- arguments local parameters = {} parameters.id = getEntityId(args, pargs) if parameters.id == nil then return end parameters.property = string.upper(args.property or "") local qualifierId = {} qualifierId[1] = getArg(string.upper(args.qualifier or args.qualifier1 or "")) local i = 2 while isSet(args["qualifier" .. i]) do qualifierId[i] = string.upper(args["qualifier" .. i]) i = i + 1 end parameters.formatting = getArg(args.formatting) parameters.convert = getArg(args.convert) parameters.numformat = getArg(args.numformat) parameters.case = args.case parameters.list = getArg(args.list, true, {firstrank='bestrank'}) parameters.listmax = args.listmax parameters.listrank = getArg(args.listrank) if type(parameters.list) == "number" then -- backwards compatibility parameters.listmax = parameters.listmax or parameters.list parameters.list = true elseif parameters.list == "bestrank" then parameters.listrank = parameters.listrank or "bestrank" parameters.list = true end parameters.shownovalue = getArg(args.shownovalue, true) parameters.separator = getArg(args.separator) parameters.conjunction = getArg(args.conjunction, parameters.separator) parameters.qseparator = getArg(args.qseparator, parameters.separator) parameters.qconjunction = getArg(args.qconjunction, parameters.conjunction) local sorting_col = args.tablesort local sorting_up = (args.sorting or "") ~= "-1" local rowformat = args.rowformat parameters.references = getArg(args.references, false) parameters.onlysourced = getArg(args.onlysourced, false) local showerrors = args.showerrors local default = args.default if default then showerrors = nil end parameters.lang = findLang(args.lang) if parameters.formatting == "raw" then parameters.editicon, parameters.labelicon = false, false else parameters.editicon, parameters.labelicon = setIcons(args.editicon, pargs.editicon) -- needs loadI18n by findLand end -- fetch property local claims = {} local bestrank = parameters.listrank == 'bestrank' and parameters.list ~= 'lang' for p in string.gmatch(parameters.property, 'P%d+') do claims = getStatements(parameters.id, p, bestrank) if #claims > 0 then parameters.property = p break end end if #claims == 0 then local ret = showerrors and printError("property-not-found") or default return ret, args.query == 'num' and 0 or '' end -- defaults for table local preformat, postformat = "", "" local whitelisted = false local whitelist, blacklist, ignorevalue, selectvalue = {}, {}, {}, {} if parameters.formatting == "table" then parameters.separator = parameters.separator or "<br />" parameters.conjunction = parameters.conjunction or "<br />" parameters.qseparator = getArg(args.qseparator, mw.message.new('Comma-separator'):inLanguage(parameters.lang[1]):plain()) parameters.qconjunction = getArg(args.qconjunction, parameters.qseparator) if not rowformat then rowformat = "$0 ($1" i = 2 while qualifierId[i] do rowformat = rowformat .. ", $" .. i i = i + 1 end rowformat = rowformat .. ")" elseif mw.ustring.find(rowformat, "^[*#]") then parameters.separator = "</li><li>" parameters.conjunction = "</li><li>" if mw.ustring.match(rowformat, "^[*#]") == "*" then preformat = "<ul><li>" postformat = "</li></ul>" else preformat = "<ol><li>" postformat = "</li></ol>" end rowformat = mw.ustring.gsub(rowformat, "^[*#] ?", "") end -- set whitelist and blacklist values whitelist, blacklist, ignorevalue, selectvalue = setWhiteOrBlackList(#qualifierId, args) local next = next if next(whitelist) ~= nil then whitelisted = true end end -- set feminine case if gender is requested local itemgender = args.itemgender local idgender if itemgender then if string.match(itemgender, "^P%d+$") then local snak_id = getSnak(mw.wikibase.getBestStatements(parameters.id, itemgender), {1, "mainsnak", "datavalue", "value", "id"}) if snak_id then idgender = snak_id end elseif string.match(itemgender, "^Q%d+$") then idgender = itemgender end end local gender_requested = false if parameters.case == "gender" or idgender then gender_requested = true elseif parameters.formatting == "table" then for i=0, #qualifierId do if args["case" .. i] and args["case" .. i] == "gender" then gender_requested = true break end end end if gender_requested then if feminineGender(idgender or parameters.id) then parameters.gender = "feminineform" end end -- get initial sort indices local sortindices = {} for idx in pairs(claims) do sortindices[#sortindices + 1] = idx end -- sort by claim rank local comparator = function(a, b) local rankmap = { deprecated = 2, normal = 1, preferred = 0 } local ranka = rankmap[claims[a].rank or "normal"] .. string.format("%08d", a) local rankb = rankmap[claims[b].rank or "normal"] .. string.format("%08d", b) return ranka < rankb end table.sort(sortindices, comparator) local result, result2, result_query local error if parameters.list or parameters.formatting == "table" then -- convert LF to line feed, <br /> may not work on some cases parameters.separator = parameters.separator == "LF" and "\010" or parameters.separator parameters.conjunction = parameters.conjunction == "LF" and "\010" or parameters.conjunction -- i18n separators parameters.separator = parameters.separator or mw.message.new('Comma-separator'):inLanguage(parameters.lang[1]):plain() parameters.conjunction = parameters.conjunction or (mw.message.new('And'):inLanguage(parameters.lang[1]):plain() .. mw.message.new('Word-separator'):inLanguage(parameters.lang[1]):plain()) -- iterate over all elements and return their value (if existing) local value, valueq local sortkey, sortkeyq local values = {} local sortkeys = {} local refs = {} local rowlist = {} -- rows to list with whitelist or blacklist for idx in pairs(claims) do local claim = claims[sortindices[idx]] local reference = {} if not whitelisted then rowlist[idx] = true end if parameters.formatting == "table" then local params = tableParameters(args, parameters, "0") value, sortkey, error = getValueOfClaim(claim, nil, params) if value then values[#values + 1] = {} sortkeys[#sortkeys + 1] = {} refs[#refs + 1] = {} if whitelist["0"] or blacklist["0"] then local valueraw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=params.lang}) if whitelist["0"] and whitelist["0"][valueraw or ""] then rowlist[#values] = true elseif blacklist["0"] and blacklist["0"][valueraw or ""] then rowlist[#values] = false end end for i, qual in ipairs(qualifierId) do local j = tostring(i) params = tableParameters(args, parameters, j) local valueq, sortkeyq, valueraw if qual == parameters.property then -- hack for getting the property with another formatting, i.e. colformat1=raw valueq, sortkeyq, _ = getValueOfClaim(claim, nil, params) else for q in mw.text.gsplit(qual, '%s*OR%s*') do if string.find(q, ".+/.+") then valueq, sortkeyq, valueraw = getValueOfParentClaim(claim, q, params) elseif string.find(q, "^/.+") then local claim2 = getStatements(parameters.id, string.sub(q, 2), bestrank) if #claim2 > 0 then -- only first value of a property as alternative to a qualifier -- multiple values may not be related to a given raw of the table valueq, sortkeyq, _ = getValueOfClaim(claim2[1], nil, params) end else valueq, sortkeyq, _ = getValueOfClaim(claim, q, params) end if valueq then qual = q break end end end values[#values]["col" .. j] = valueq sortkeys[#sortkeys]["col" .. j] = sortkeyq or valueq if whitelist[j] or blacklist[j] or ignorevalue[j] or selectvalue[j] then valueq = valueraw or getValueOfClaim(claim, qual, {["formatting"]="raw", ["lang"]=params.lang}) if whitelist[j] and whitelist[j][valueq or ""] then rowlist[#values] = true elseif blacklist[j] and blacklist[j][valueq or ""] then rowlist[#values] = false elseif ignorevalue[j] and ignorevalue[j][valueq or ""] then values[#values]["col" .. j] = nil elseif selectvalue[j] and not selectvalue[j][valueq or ""] then values[#values]["col" .. j] = nil end end end end else value, sortkey, error = getValueOfClaim(claim, qualifierId[1], parameters) values[#values + 1] = {} sortkeys[#sortkeys + 1] = {} refs[#refs + 1] = {} end if not value and showerrors then value = error end if value then if (parameters.references or parameters.onlysourced) and claim.references then reference = claim.references end refs[#refs]["col0"] = reference values[#values]["col0"] = value sortkeys[#sortkeys]["col0"] = sortkey or value end end -- sort and format results sortindices = {} for idx in pairs(values) do sortindices[#sortindices + 1] = idx end if sorting_col then local sorting_table = mw.text.split(sorting_col, '%D+') local comparator = function(a, b) local valuea, valueb local i = 1 while valuea == valueb and i <= #sorting_table do valuea = sortkeys[a]["col" .. sorting_table[i]] or '' valueb = sortkeys[b]["col" .. sorting_table[i]] or '' i = i + 1 end if sorting_up then return valueb > valuea end return valueb < valuea end table.sort(sortindices, comparator) end local maxvals = tonumber(parameters.listmax) result = {} for idx in pairs(values) do local valuerow = values[sortindices[idx]] local reference, valid_ref = getReferences({["references"] = refs[sortindices[idx]]["col0"]}, parameters) value = valuerow["col0"] if parameters.formatting == "table" then if not rowlist[sortindices[idx]] then value = nil else local rowformatting = rowformat .. "$" -- fake end character added for easy gsub value = mw.ustring.gsub(rowformatting, "$0", {["$0"] = value}) value = mw.ustring.gsub(value, "$R0", reference) -- add reference for i, _ in ipairs(qualifierId) do local valueq = valuerow["col" .. i] if args["rowsubformat" .. i] and isSet(valueq) then -- add fake end character $ -- gsub $i not followed by a number so $1 doesn't match $10, $11... -- remove fake end character valueq = captureEscapes(valueq) valueq = mw.ustring.gsub(args["rowsubformat" .. i] .. "$", "$" .. i .. "(%D)", valueq .. "%1") valueq = string.sub(valueq, 1, -2) rowformatting = mw.ustring.gsub(rowformatting, "$" .. i .. "(%D)", args["rowsubformat" .. i] .. "%1") end valueq = valueq and captureEscapes(valueq) or '' value = mw.ustring.gsub(value, "$" .. i .. "(%D)", valueq .. "%1") end value = string.sub(value, 1, -2) -- remove fake end character value = expandBraces(value, rowformatting) end elseif value then value = expandBraces(value, parameters.formatting) value = value .. reference end if isSet(value) and (not parameters.onlysourced or (parameters.onlysourced and valid_ref)) then result[#result + 1] = value if not parameters.list or (maxvals and maxvals == #result) then break end end end if args.query == 'num' then result_query = #result end if #result > 0 then if parameters.formatting == 'table' then result = addEditIconTable(result, parameters) -- in a table, add edit icon on last element end result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat else result = '' end else -- return first element local claim = claims[sortindices[1]] result, result2, error = getValueOfClaim(claim, qualifierId[1], parameters) if result then local ref, valid_ref = getReferences(claim, parameters) if parameters.onlysourced and valid_ref == false then result = nil else result = result .. ref end end if args.query == 'num' then result_query = result and 1 or 0 end end if isSet(result) then if not (parameters.formatting == 'table' or (result2 and result2 == 'no-icon')) then -- add edit icon, except table added previously and except explicit no-icon internal flag result = result .. addEditIcon(parameters) end else if showerrors then result = error else result = default end end if args.query == 'untranslated' and required and not is_sandbox then result_query = untranslated end return result, result_query or '' end -- Local functions for getParentValues ----------------------- local function uc_first(word) if word == nil then return end return mw.ustring.upper(mw.ustring.sub(word, 1, 1)) .. mw.ustring.sub(word, 2) end local function getPropertyValue(id, property, parameter, langs, labelicon, case) local snaks = mw.wikibase.getBestStatements(id, property) local mysnak = getSnak(snaks, {1, "mainsnak"}) if mysnak == nil then return end local entity_id local result = '-' -- default for 'no value' if mysnak.datavalue then entity_id = "Q" .. tostring(mysnak.datavalue.value['numeric-id']) result, _ = getSnakValue(mysnak, {formatting=parameter, lang=langs, labelicon=labelicon, case=case}) end return entity_id, result end local function getParentObjects(id, prop_format, label_format, languages, propertySupString, propertyLabel, propertyLink, label_show, labelicon0, labelicon1, upto_number, upto_label, upto_value, last_only, grammatical_case, include_self) local propertySups = mw.text.split(propertySupString, '[^P%d]') local maxloop = 10 if upto_number then maxloop = tonumber(upto_number) elseif next(upto_label) or next(upto_value) then maxloop = 50 end local labels_filter = next(label_show) local result = {} local id_value = id for iter = 1, maxloop do local link, label, labelwicon, linktext, id_label for _, propertySup in pairs(propertySups) do local _id_value, _link = getPropertyValue(id_value, propertySup, prop_format, languages, labelicon1, grammatical_case) if _id_value and _link then id_value = _id_value; link = _link break end end if not id_value or not link then break end if propertyLink then _, linktext = getPropertyValue(id_value, propertyLink, "label", languages) if linktext then link = mw.ustring.gsub(link, "%[%[(.*)%|.+%]%]", "[[%1|" .. linktext .. "]]") end end id_label, label = getPropertyValue(id_value, propertyLabel, label_format, languages, false, "infoboxlabel") if labelicon0 then _, labelwicon = getPropertyValue(id_value, propertyLabel, label_format, languages, labelicon0, "infoboxlabel") else labelwicon = label end if labels_filter == nil or (label_show[id_label] or label_show[label]) then result[#result + 1] = {labelwicon, link} label_show[id_label or 'none'], label_show[label or 'none'] = nil, nil -- only first label found end if upto_label[id_label] or upto_label[label] or upto_value[id_value] then break end end if last_only then result = {result[#result]} end if include_self then local label_self, link_self _, label_self = getPropertyValue(id, propertyLabel, label_format, languages, labelicon0, "infoboxlabel") link_self, _ = getLabelByLangs(id, languages) table.insert(result, 1, {label_self, link_self}) end return result end local function parentObjectsToString(result, rowformat, cascade, sorting) local ret = {} local first = 1 local last = #result local iter = 1 if sorting == "-1" then first = #result; last = 1; iter = -1 end for i = first, last, iter do local rowtext = mw.ustring.gsub(rowformat, "$[01]", {["$0"] = result[i][1], ["$1"] = result[i][2]}) ret[#ret + 1] = expandBraces(rowtext, rowformat) end if cascade then local direction = mw.language.new(wiki.langcode):isRTL() and "right" or "left" local suffix = "" for i = 1, #ret do ret[i] = '<ul style="line-height:100%; margin-' .. direction .. ':0.45em; padding-' .. direction .. ':0;"><li>' .. ret[i] suffix = suffix .. '</li></ul>' end ret[#ret] = ret[#ret] .. suffix end return ret end -- Returns pairs of parent label and property value fetching a recursive tree function p.getParentValues(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} if not required and isSet(pargs.sandbox) then return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getParentValues(frame) end local id = getEntityId(args, pargs) if id == nil then return end local languages = findLang(args.lang) local propertySup = getArg(args.property, "P131") --administrative entity local propertyLabel = getArg(args.label, "P31") --instance local propertyLink = getArg(args.valuetext) local property_format = getArg(args.formatting) local label_format = getArg(args.labelformat, "label") local upto_number = getArg(args.upto) local last_only = getArg(args.last_only, false) local editicon, labelicon = setIcons(args.editicon, pargs.editicon) local include_self = getArg(args.include_self, false) local case = getArg(args.case) local upto_label = {} for q in string.gmatch(args.uptolabelid or '', 'Q%d+') do upto_label[q] = true end if type(upto_number) == 'string' then upto_label[uc_first(upto_number)] = true upto_number = nil require(wiki.module_title .. '/debug').track('upto') -- replace upto by uptolabelid end local upto_value = {} for q in string.gmatch(args.uptovalueid or args.uptolinkid or '', 'Q%d+') do upto_value[q] = true end local label_show = {} for q in string.gmatch(args.showlabelid or '', 'Q%d+') do label_show[q] = true end for _, v in ipairs(mw.text.split(args.labelshow or '', "/")) do if v ~= '' then label_show[uc_first(v)] = true require(wiki.module_title .. '/debug').track('labelshow') -- replace labelshow by showlabelid end end local rowformat = args.rowformat; if not isSet(rowformat) then rowformat = "$0 = $1" end local labelicon0, labelicon1 = labelicon, labelicon if string.find(label_format, '{{.*$0.*}}') or (string.find(rowformat, '{{.*$0.*}}') and label_format ~= 'raw') then labelicon0 = false end local result = getParentObjects(id, property_format, label_format, languages, propertySup, propertyLabel, propertyLink, label_show, labelicon0, labelicon1, upto_number, upto_label, upto_value, last_only, case, include_self) if #result == 0 then return end local separator = args.separator; if not isSet(separator) then separator = "<br />" end local sorting = args.sorting; if sorting == "" then sorting = nil end local cascade = (args.cascade == "true" or args.cascade == "yes") local ret = parentObjectsToString(result, rowformat, cascade, sorting) ret = addEditIconTable(ret, {property=propertySup, editicon=editicon, id=id, lang=languages}) return mw.text.listToText(ret, separator, separator) end -- Link with a parent label -------------------- function p.linkWithParentLabel(frame) local pargs = frame.args and frame:getParent().args or {} if not required and isSet(pargs.sandbox) then return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).linkWithParentLabel(frame) end local args = {} if frame.args then for k, v in pairs(frame.args) do -- metatable args[k] = v end else args = frame -- via require end if isSet(args.value) then return args.value end -- get id value of property/qualifier local largs = mw.clone(args) largs.list = tonumber(args.list) and args.list or true largs.formatting = "raw" largs.separator = "/·/" largs.editicon = false local items_list, _ = p.claim(largs) if not isSet(items_list) then return end local items_table = mw.text.split(items_list, "/·/", true) -- get internal link of property/qualifier largs.formatting = "internallink" local link_list, _ = p.claim(largs) local link_table = mw.text.split(link_list, "/·/", true) -- get label of parent property local parent_claim = getSnak(getStatements(items_table[1], args.parent, true), {1, "mainsnak", "datatype"}) if parent_claim == 'monolingualtext' then largs.formatting = nil largs.list = 'lang' else largs.formatting = "label" largs.list = false end largs.property = args.parent largs.qualifier = nil for i, v in ipairs(items_table) do largs.item = v local link_label, _ = p.claim(largs) if isSet(link_label) then link_table[i] = mw.ustring.gsub(link_table[i] or '', "%[%[(.*)%|.+%]%]", "[[%1|" .. link_label .. "]]") end end args.editicon, _ = setIcons(args.editicon, pargs.editicon) args.id = getEntityId(args, pargs) args.lang = findLang(args.lang) return mw.text.listToText(link_table) .. addEditIcon(args) end -- Calculate number of years old ---------------------------- function p.yearsOld(frame) if not required and frame.args and isSet(frame:getParent().args.sandbox) then return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).yearsOld(frame) end local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local id = getEntityId(args, pargs) if id == nil then return end local lang = mw.language.new('en') local function getBestValue(id, prop) return getSnak(mw.wikibase.getBestStatements(id, prop), {1, "mainsnak", "datavalue", "value"}) end local birth = getBestValue(id, 'P569') if type(birth) ~= 'table' or birth.time == nil or birth.precision == nil or birth.precision < 8 then return end local death = getBestValue(id, 'P570') if type(death) ~= 'table' or death.time == nil or death.precision == nil then death = {['time'] = lang:formatDate('c'), ['precision'] = 11} -- current date elseif death.precision < 8 then return end local dates = {} dates[1] = {['min'] = {}, ['max'] = {}, ['precision'] = birth.precision} dates[1].min.year = tonumber(mw.ustring.match(birth.time, "^[+-]?%d+")) dates[1].min.month = tonumber(mw.ustring.match(birth.time, "\-(%d%d)\-")) dates[1].min.day = tonumber(mw.ustring.match(birth.time, "\-(%d%d)T")) dates[1].max = mw.clone(dates[1].min) dates[2] = {['min'] = {}, ['max'] = {}, ['precision'] = death.precision} dates[2].min.year = tonumber(mw.ustring.match(death.time, "^[+-]?%d+")) dates[2].min.month = tonumber(mw.ustring.match(death.time, "\-(%d%d)\-")) dates[2].min.day = tonumber(mw.ustring.match(death.time, "\-(%d%d)T")) dates[2].max = mw.clone(dates[2].min) for i, d in ipairs(dates) do if d.precision == 10 then -- month d.min.day = 1 local timestamp = string.format("%04d", tostring(math.abs(d.max.year))) .. string.format("%02d", tostring(d.max.month)) .. "01" d.max.day = tonumber(lang:formatDate("j", timestamp .. " + 1 month - 1 day")) elseif d.precision < 10 then -- year or decade d.min.day = 1 d.min.month = 1 d.max.day = 31 d.max.month = 12 if d.precision == 8 then -- decade d.max.year = d.max.year + 9 end end end local function age(d1, d2) local years = d2.year - d1.year if d2.month < d1.month or (d2.month == d1.month and d2.day < d1.day) then years = years - 1 end if d2.year > 0 and d1.year < 0 then years = years - 1 -- no year 0 end return years end local old_min = age(dates[1].max, dates[2].min) local old_max = age(dates[1].min, dates[2].max) local old, old_expr if old_min == 0 and old_max == 0 then old = "< 1" old_max = 1 -- expression in singular elseif old_min == old_max then old = old_min else old = old_min .. "/" .. old_max end if args.formatting == 'unit' then local langs = findLang(args.lang) local yo local yo_pl = {} if langs[1] == wiki.langcode then yo_pl = i18n["years-old"] end if not isSet(yo_pl[2]) then local yo_label, _ = getLabelByLangs('Q24564698', langs) yo_pl = {yo_label, yo_label} end yo = mw.language.new(langs[1]):plural(old_max, yo_pl) if mw.ustring.find(yo, '$1', 1, true) then old_expr = mw.ustring.gsub(yo, "$1", old) else old_expr = old .. ' ' .. yo end elseif args.formatting then old_expr = expandBraces(mw.ustring.gsub(args.formatting, '$1', old), args.formatting) else old_expr = old end return old_expr end -- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked. function p.getLabel(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} if not required and isSet(pargs.sandbox) then return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getLabel(frame) end local id = getEntityId(args, pargs, 1) if id == nil then return end local languages = findLang(args.lang) local labelicon = false if mw.wikibase.isValidEntityId(id) then _, labelicon = setIcons(args.editicon, pargs.editicon) end local label_icon = '' local label, lang if args.label then label = args.label else -- exceptions or labels fixed local exist, labels = pcall(require, wiki.module_title .. "/labels" .. (languages[1] == wiki.langcode and '' or '/' .. languages[1])) if exist and labels.infoboxLabelsFromId and next(labels.infoboxLabelsFromId) ~= nil then label = labels.infoboxLabelsFromId[id] end if label == nil then label, lang = getLabelByLangs(id, languages) if label then if isSet(args.itemgender) and feminineGender(args.itemgender) then label = feminineForm(id, lang) or label end label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize if args.case then label = case(args.case, label, lang) end end label_icon = addLabelIcon(id, lang, languages[1], labelicon) end end local linked = args.linked local ret2 = required and untranslated or '' if isSet(linked) and linked ~= "no" then local article = mw.wikibase.getSitelink(id) or ("d:Special:EntityPage/" .. id) return "[[" .. article .. "|" .. (label or id) .. "]]" .. label_icon, ret2 else return (label or id) .. label_icon, ret2 end end -- Utilities ----------------------------- -- See also module ../debug. -- Copied from Module:Wikibase function p.getSiteLink(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local id = getEntityId(args, pargs, 1) if id == nil then return end return mw.wikibase.getSitelink(id, mw.text.trim(args[2] or '')) end -- Helper function for the default language code used function p.lang(frame) local lang = frame and frame.args[1] -- nil via require return findLang(lang)[1] end -- Number of statements function p.numStatements(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local id = getEntityId(args, pargs) if id == nil then return 0 end local prop = mw.text.trim(args[1] or '') local num = {} if not isSet(prop) then local largs = {} for k, v in pairs(pargs) do largs[k] = v end for k, v in pairs(args) do largs[k] = v end largs.query = 'num' _, num = p.claim(largs) return num elseif args[2] then -- qualifier local qual = mw.text.trim(args[2]) local values = p.claim{item=id, property=prop, qualifier=qual, formatting='raw', separator='/·/'} if values then num = mw.text.split(values, '/·/') end else num = mw.wikibase.getBestStatements(id, prop) end return #num end -- Returns true if property datavalue is found excluding novalue/somevalue function p.validProperty(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local item = getEntityId(args, pargs) if item == nil then return end local property = mw.text.trim(args[1]) local prop_data = getSnak(mw.wikibase.getBestStatements(item, property), {1, "mainsnak", "datavalue"}) return prop_data and true or nil end function p.editAtWikidata(frame) local args = frame.args or frame -- via invoke or require local pargs = frame.args and frame:getParent().args or {} local value = isSet(args[1]) if value then return end local param = {} param.id = getEntityId(args, pargs) param.property = args.property param.lang = findLang(args.lang) param.editicon, _ = setIcons(args.editicon) return addEditIcon(param) end function p.formatNum(frame) local num = tonumber(mw.text.trim(frame.args[1])) local lang = findLang(mw.text.trim(frame.args[2])) return mw.language.new(lang[1]):formatNum(num) end return p
Giare-choontey:
By saving changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Doll magh
Cooney reaghee
(t'eh foshley ayns uinnag elley)
Preview page with this template
Clowan ymmydit er y duillag shoh:
Module:Wikidades/doc
(
reagh
)