Modul:Wikidata: Perbedaan antara revisi
Konten dihapus Konten ditambahkan
k by request (https://id.wikipedia.org/w/index.php?title=Pembicaraan_Modul%3AWikidata&type=revision&diff=16187304&oldid=15607696) |
Hidayatsrf (bicara | kontrib) -- version 20200415 from master @cawiki |
||
Baris 1:
-- version
local p = {}
--
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 BCE", -- how to format negative numbers for precisions 0 to 5
["afternow"] = "$1 CE", -- how to format positive numbers for precisions 0 to 5
["bc"] = "$1 BCE", -- 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
Baris 30 ⟶ 28:
[8] = "$1s", -- precision: decade
-- the following use the format of #time parser function
[9]
[10] = "F Y", -- precision: month
[11] = "F j, Y", -- precision: day
},
["years-old"] = {
["singular"] = "", -- year old, as in {{PLURAL:$1|singular|plural}}
["plural"] = "", -- years old
["paucal"] = "", -- for languages with 3 plural forms as in {{PLURAL:$1|singular|paucal|plural}}
},
["cite"] = { -- Cite web parameters
["url"]
["title"]
["website"]
["access-date"]
["archive-url"]
["archive-date"]
["author"]
["publisher"]
["quote"]
["language"]
["date"]
["pages"]
},
-- 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)
["addfallback"] = {} -- additional fallback language codes
}
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 =
}
p.Untranslated = false
-- 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
Baris 90 ⟶ 89:
end
local function loadI18n(lang)
local
if lang ~= wiki.langcode then i18n_title = "/i18n/" .. lang end
local exist, res = pcall(require, wiki.module_title .. i18n_title)
if exist and next(res) ~= nil then
tableMerge(i18n, res.i18n)
Baris 98 ⟶ 99:
end
-- Table of language codes: requested or default and its fallbacks
local function findLang(langcode)
if
local
local pframe = cframe:getParent()
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 var == '')
end
-- Set local case to a label
local function case(localcase, label, ...)
if not isSet(label) then return label end
if localcase == "smallcaps" then
return '<span style="font-variant: small-caps;">' .. label .. '</span>'
elseif cases[localcase] then
return cases[localcase](label, ...)
end
return label
end
Baris 132 ⟶ 149:
local function getLabelByLangs(id, languages)
local label
local lang
for _, l in ipairs(languages) do
if l == wiki.langcode then
label, l = mw.wikibase.getLabelWithLang(id)
else
label = mw.wikibase.getLabelByLang(id, l)
end
if label then
lang = l
break
end
end
Baris 174 ⟶ 191:
end
-- get safely a serialized snak
local function
local ret = statement
for i, v in ipairs(snaks) do
ret = ret[v]
end
return ret
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
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/Special:EntityPage/" .. label_id .. "?uselang=" .. uselang .. "]]"
p.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
end
-- Add
local function addEditIcon(
local ret = ''
if i18n.addpencil and parameters.editicon and parameters.id and parameters.property then
ret = ' <span data-bridge-edit-flow="overwrite">'
.. "[[File:Arbcom ru editing.svg|10px|baseline|"
.. mw.message.new('Editlink'):inLanguage(parameters.lang[1]):plain()
.. "|link=https://www.wikidata.org/wiki/" .. parameters.id .. "?uselang=" .. parameters.lang[1] .. "#" .. parameters.property .. "]]"
.. "</span>"
end
return
end
-- add edit icon to the last element of a table
local function addEditIconTable(thetable, parameters)
if #thetable == 0 or not i18n.addpencil 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
Baris 238 ⟶ 296:
end
braces = mw.ustring.gsub(braces, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1") -- escape magic characters
braces_expanded =
text = mw.ustring.gsub(text, "{{" .. braces .. "}}", braces_expanded)
end
Baris 245 ⟶ 303:
end
-- Resolve Wikidata redirects, pending phab:T157868
local function resolveEntityId(id)
if not id or not mw.wikibase.isValidEntityId(id) then return id end
-- if no label in local language nor its fallbacks, maybe it is a redirect
-- not using mw.title.new(id).isRedirect as it is expensive
if mw.wikibase.getLabel(id) == nil then
local entity = mw.wikibase.getEntity(id) -- expensive function
if not entity then return nil end
if id ~= entity.id then
-- Qid redirected to be fixed
-- see [[Special:WhatLinksHere/Template:Track/wikidata/redirect]]
require(wiki.module_title .. '/debug').track('redirect')
require(wiki.module_title .. '/debug').track('redirect/' .. id)
else
-- no redirect and no label, fix it to avoid expensive functions
require(wiki.module_title .. '/debug').track('label')
require(wiki.module_title .. '/debug').track('label/' .. id)
end
return entity.id
end
return id
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 value string
local function printDatavalueString(data, parameters)
if mw.ustring.find((parameters.formatting
return expandBraces(mw.ustring.gsub(parameters.formatting, '$1', {['$1'] = data}), parameters.formatting)
elseif parameters.case then
return case(
end
return data
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 printDatavalueString(data, parameters)
end
-- format data type commonsMedia
local function printDatatypeMedia(data, parameters)
local icon
if not string.find((parameters.formatting or ''), '$1', 1, true) then
icon = "no-icon"
end
return printDatavalueString(data, parameters), icon
end
-- format data value globecoordinate
local function printDatavalueCoordinate(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})
local myglobe = 'earth'
if isSet(data.globe
local globenum = mw.text.split(data.globe, 'entity/')[2] -- http://www.wikidata.org/wiki/Q2
myglobe = globes
end
ret = mw.ustring.gsub(ret, '$globe', myglobe)
end
return expandBraces(ret,
elseif
return
elseif
return
elseif
return data.dimension, "no-icon"
else --default formatting='globe'
if isSet(data.globe) ==
return 'earth', "no-icon"
else
local globenum = mw.text.split(data.globe, 'entity/')[2]
return globes
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 = findClaims(id, 'P5061')
if claims 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 parameters.formatting == "unitcode" then
-- get unit symbol
local unit_symbol = unitSymbol(id, parameters.lang)
if isSet(unit_symbol) then
suffix = unit_symbol
end
end
if suffix == '' then -- formatting=unit, or formatting=unitcode not found
-- get unit name
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)
else
suffix = (unit_label or id) .. addLabelIcon(id, lang, parameters.lang[1], parameters.editicon)
end
end
if suffix ~= '' then
suffix = ' ' .. suffix
end
return suffix
end
local function roundPrecision(in_num, out_num)
-- rounds out_num with significant figures of in_num (default precision)
-- 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 value quantity
local function printDatavalueQuantity(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 parameters.convert then
-- example "unit": "http://www.wikidata.org/entity/Q174728"
local unit_id = data.unit
if
suffix = getUnit(amount, unit_id, parameters)
local convert_to
if exist 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
end
if
-- 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 = mw.wikibase.getAllStatements(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 = roundPrecision(amount, 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
end
end
local lang_obj = mw.language.new(parameters.lang[1])
local sortkey = string.format("%019d", tonumber(amount) * 1000)
if parameters.case then
amount = case(parameters.case, amount, parameters.lang[1])
else
amount = lang_obj:formatNum(tonumber(amount))
end
if conv_amount then
local conv_sortkey = string.format("%019d", tonumber(conv_amount) * 1000)
conv_amount = lang_obj:formatNum(tonumber(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
end
Baris 339 ⟶ 567:
end
-- format data value time
local function printDatavalueTime(data, parameters)
-- Dates and times are stored in ISO 8601 format
local timestamp = data.time
local
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
elseif precision > 8 then
-- calendar model
local calendar_model = {["Q12138"] = "gregorian", ["Q1985727"] = "gregorian", ["Q11184"] = "julian", ["Q1985786"] = "julian"}
Baris 362 ⟶ 589:
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") -- supress 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 =
if
ret = mw.ustring.gsub(i18n.datetime.beforenow, "$1", relative)
else
Baris 386 ⟶ 634:
ret = mw.ustring.gsub(ret, ret_number, mw.language.new(parameters.lang[1]):formatNum(tonumber(ret_number)))
end
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 =
ret = postFormat(ret)
elseif
return
elseif precision == 9 or parameters.formatting == 'Y' then -- precision is
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
ret = postFormat(ret) .. calendar_add
end
return ret,
end
-- format data value entity
local function printDatavalueEntity(data, parameters)
local
if parameters.formatting == 'raw' then
if data['entity-type'] == 'item' then
entity_id = resolveEntityId(entity_id)
end
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'
labelcase = feminineForm(
end
if parameters.case ~= 'gender' then
labelcase = case(
end
local ret1, ret2
if parameter == 'label' then
ret1 =
ret2 = labelcase or
elseif parameter == 'sitelink' then
ret1 = (sitelink or '
ret2 = sitelink or
elseif mw.ustring.find((parameter or ''), '$1', 1, true) then -- formatting = a pattern
ret1 = mw.ustring.gsub(parameter, '$1', labelcase or
ret1 = expandBraces(ret1, parameter)
ret2 = labelcase or
else
if parameter == "ucfirst" or parameter == "ucinternallink" then
if labelcase
labelcase end
-- only first of a list, reset formatting for next ones
if parameter == "ucinterlanllink" then
Baris 464 ⟶ 708:
ret2 = labelcase
else
ret1 = '[[
ret2 = labelcase or
end
end
return ret1 ..
end
-- format data value monolingualtext
local function printDatavalueMonolingualText(data, parameters)
-- data fields: language [string], text [string]
Baris 482 ⟶ 727:
local result = data["text"]
if data["language"] ~= wiki.langcode then
result = mw.ustring.gsub(
end
if mw.ustring.find((parameters.formatting or ''), '$', 1, true) then
Baris 493 ⟶ 738:
local function printError(key)
end
Baris 512 ⟶ 757:
end
function findClaims(
if not property or not
if not mw.ustring.match(property, "^P%d+$") then
Baris 520 ⟶ 765:
if not property then return end
end
local claims = mw.wikibase.getAllStatements(entityId, property)
claims = nil
end
return claims
end
Baris 529 ⟶ 777:
if snak.datatype == 'math' then
return printDatatypeMath(snak.datavalue.value)
elseif snak.datatype == 'musical-notation' then
return printDatatypeMusical(snak.datavalue.value, parameters.formatting)
elseif snak.datatype == "url" then
return
elseif snak.datatype == "commonsMedia" then
return printDatatypeMedia(snak.datavalue.value, parameters)
elseif snak.datavalue.type == "string" then
return printDatavalueString(snak.datavalue.value, parameters)
Baris 545 ⟶ 797:
end
elseif snak.snaktype == 'novalue' then
if parameters.formatting == 'raw' 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
Baris 564 ⟶ 818:
-- iterate over monolingualtext qualifiers to get local language
for idx in pairs(qualifier) do
if getSnak(qualifier[idx]
return qualifier[idx]
end
Baris 583 ⟶ 837:
function getValueOfClaim(claim, qualifierId, parameters)
local snak, error = getQualifierSnak(claim, qualifierId, parameters)
if not snak then
return nil, nil, error
Baris 612 ⟶ 864:
if parent_claims[1] ~= nil then
value, sortkey, _ = getValueOfClaim(parent_claims[1], nil, parameters)
-- raw parent value needed
valueraw, _, _ =
end
end
Baris 620 ⟶ 872:
local function getReferences(claim)
local
["P143"] = true, -- imported from
["P3452"] = true, -- inferred from
["P887"] = true, -- based on heuristic
["P4656"] = true -- Wikimedia import URL
}
local result = ""
Baris 645 ⟶ 883:
local refparts
local refs = {}
local validref = true
-- 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
Baris 658 ⟶ 903:
-- get title of general template for citing web references
local template = mw.wikibase.getSitelink(
template = mw.text.split(template, ":")[2]
--
if refs[
local citeParams = {}
citeParams[i18n['cite']['url']] = refs[
citeParams[i18n['cite']['title']] = refs[
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
citeParams[i18n['cite']['
refparts = mw.getCurrentFrame():expandTemplate{title=template, args=citeParams}
else
-- raw ouput
local italics = "''"
for k, v in orderedpairs(refs or {}, claim.references[ref]["snaks-order"]) do
if k and v then
refparts = refparts ..
refparts = refparts .. italics .. v .. italics .. "."
italics = ""
end
end
Baris 690 ⟶ 937:
end
return result
end
-- Set whitelist or blacklist values
local function setWhiteOrBlackList(type_list, num_qual, args)
local listed = false
local list = {}
if isSet(args[type_list .. i]
listed = true
list[tostring(i)] = {}
Baris 719 ⟶ 950:
for _, v in ipairs(values) do
list[tostring(i)][v] = true
list[tostring(i)][resolveEntityId(v)] = true
end
end
end
return list, listed
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
local args = frame.args or frame
local pargs = frame.args and frame:getParent().args
local id = args.item or args.from or (unnamed and mw.text.trim(args[1] or '') or nil)
if not isSet(id) and pargs 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
-- Main function claim ---------------------------------------------
--
function p.claim(frame)
p.Untranslated = false
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()).claim(frame)
end
local args = frame.args or frame -- via invoke or require
--If a value is already set, use it
if isSet(args.value)
if args.value return
else
return args.value
end
end
-- arguments
local id =
if id == nil
local property = string.upper(args.property or "")
local qualifierId = {}
qualifierId[1] = isSet(args
local i = 2
while isSet(args["qualifier" .. i]) do
qualifierId[i] = string.upper(args["qualifier" .. i])
i = i + 1
end
local
local convert = args.convert; if convert == "" then convert = nil end
local case = args.case
local list = args
local sorting_col = args.tablesort
local sorting_up = (args.sorting or "") ~= "-1"
local separator = isSet(args.separator) and args.separator
local conjunction = isSet(args.conjunction)
local rowformat = args.rowformat
local references = args
local showerrors = args
local default = args
if default then showerrors = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no" or formatting == "raw")
local parameters = {["
["
["separator"] = separator, ["conjunction"] = conjunction, ["qseparator"] = separator, ["qconjunction"] = conjunction}
parameters.lang = findLang(args.lang)
-- defaults for table
Baris 828 ⟶ 1.066:
blacklist, blacklisted = setWhiteOrBlackList("blacklist", #qualifierId, args)
end
-- fetch property
local claims
for p in string.gmatch(property, 'P%d+') do
claims = findClaims(id, p)
if claims and claims[1] then
parameters.property = p
break
end
end
if not claims or not claims[1] then
if showerrors then return printError("property-not-found") else return default end
Baris 842 ⟶ 1.081:
-- set feminine case if gender is requested
local itemgender = args["itemgender"]
local
if itemgender then
if string.match(itemgender, "^P%d+$") then
local snak_id = getSnak(mw.wikibase.getBestStatements(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
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
if feminineGender(idgender or id) then
end
end
Baris 875 ⟶ 1.118:
local comparator = function(a, b)
local rankmap = { deprecated = 2, normal = 1, preferred = 0 }
local ranka = rankmap[claims[a].rank or "normal"] ..
local rankb = rankmap[claims[b].rank or "normal"] ..
return ranka < rankb
end
table.sort(sortindices, comparator)
local result, result2
local error
if parameters.list or parameters.formatting == "table" then
Baris 900 ⟶ 1.143:
for idx in pairs(claims) do
local claim = claims[sortindices[idx]]
local reference = {}
if not whitelisted then rowlist[idx] = true end
if firstrank ~= '' and firstrank ~= claim.rank then
Baris 906 ⟶ 1.149:
end
if parameters.formatting == "table" then
local params =
value, sortkey, error = getValueOfClaim(claim, nil, params)
if value then
values[#values + 1] = {}
Baris 930 ⟶ 1.165:
for i, qual in ipairs(qualifierId) do
local j = tostring(i)
params = tableParameters(args, parameters, j)
local valueq, sortkeyq, valueraw
if qual == property then -- hack for getting the property with another formatting, i.e. colformat1=raw
valueq, sortkeyq, _ =
else
for q in mw.text.gsplit(qual, '%s*OR%s*') do
if string.find(q, ".+/.+") then
valueq, sortkeyq, valueraw =
elseif string.find(q, "^/.+") then
local claim2 = findClaims(
if claim2 then
valueq, sortkeyq, _ =
end
else
valueq, sortkeyq, _ =
end
if valueq then break end
Baris 971 ⟶ 1.197:
end
else
value, sortkey, error =
values[#values + 1] = {}
sortkeys[#sortkeys + 1] = {}
Baris 978 ⟶ 1.204:
if not value and showerrors then value = error end
if value then
if references and claim.references then reference = claim.references end
refs[#refs]["col0"] = reference
values[#values]["col0"] = value
sortkeys[#sortkeys]["col0"] = sortkey or value
Baris 1.011 ⟶ 1.237:
local valuerow = values[sortindices[idx]]
local reference = getReferences({["references"] = refs[sortindices[idx]]["col0"]})
value = valuerow["col0"]
if parameters.formatting == "table" then
Baris 1.017 ⟶ 1.243:
value = nil
else
value = mw.ustring.gsub(rowformatting, "$0", value)
value = mw.ustring.gsub(value, "$R0", reference) -- add reference
for i, _ in ipairs(qualifierId) do
local valueq = valuerow["col" .. i]
Baris 1.026 ⟶ 1.252:
-- 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
value = mw.ustring.gsub(value, "$" .. i .. "(%D)", valueq .. "%1")
end
Baris 1.036 ⟶ 1.263:
value = expandBraces(value, rowformatting)
end
elseif value then
value = expandBraces(value, parameters.formatting)
value = value .. reference
end
if isSet(value) then
result[#result + 1] = value
if not parameters.list then
break
end
end
end
-- in a table, add edit icon on last element
if parameters.formatting == 'table' and parameters.editicon then
result = addEditIconTable(result, parameters)
end
result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat
Baris 1.048 ⟶ 1.282:
-- return first element
local claim = claims[sortindices[1]]
result,
if result and references then result = result .. getReferences(claim) end
end
if isSet(result) then
-- add edit icon
if parameters.formatting == 'table' then
return result -- added previously on last element
elseif result2 and result2 == 'no-icon' then
return result
elseif i18n.addpencil then
return result .. addEditIcon(parameters)
else
return result
end
else
if showerrors then return error else return default end
end
Baris 1.062 ⟶ 1.307:
-- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string
p.getTAValue = function(frame)
end
end
--
local function uc_first(word)
Baris 1.100 ⟶ 1.332:
end
local function getPropertyValue(id, property, parameter, langs, editicon, case)
local snaks = mw.wikibase.getBestStatements(id, property)
local mysnak
Baris 1.109 ⟶ 1.341:
end
local
local result = '-' -- default for 'no value'
if mysnak.datavalue then
result, _ = getSnakValue(mysnak, {formatting=parameter, lang=langs, editicon=editicon, case=case})
end
return
end
local function
for index, value in ipairs(tab) do
if value == val then
return true
end
end
return false
end
local function getParentObjects(id,
formatting,
languages,
propertySupString,
propertyLabel,
propertyLink,
labelShow,
editicon,
upto,
upto_linkId,
last_only,
grammatical_case,
include_self)
if (upto_linkId == nil) then upto_linkId = "" end
local upto_link_ids = mw.text.split(upto_linkId, '[/%s]+')
local propertySups = mw.text.split(propertySupString, '[/%s]+')
local lastlabel = uc_first(upto or '')
Baris 1.146 ⟶ 1.388:
end
end
local label_self
_, label_self = getPropertyValue(id, propertyLabel, "label", languages)
local result = {}
local label, link, linktext
for iter = 1, maxloop do
local label, link
for _, propertySup in pairs(propertySups) do
_id, _link = getPropertyValue(id, propertySup, formatting, languages, editicon, grammatical_case)
if _id and _link then id = _id link = _link break end
end
if not id or not link then break end
if propertyLink then
_, linktext = getPropertyValue(id, propertyLink, "label", languages)
if linktext then
link = mw.ustring.gsub(link, "%[%[(.*)%|.+%]%]", "[[%1|" .. linktext .. "]]")
end
_, label = getPropertyValue(id, propertyLabel, "label", languages, editicon, "infoboxlabel")
if labelShow == nil or labelFilter[label] then
result[#result + 1] = {label, link}
if label then
labelFilter[label] = nil -- only first label found
end
end
if not tonumber(upto) and label == lastlabel then
break
end
if contains(upto_link_ids, id) then
break
end
end
if last_only then
result = {result[#result]}
end
if include_self then table.insert(result, 1, {label_self, mw.title.getCurrentTitle().text}) end
return result
end
local function parentObjectsToString(result,
rowformat,
cascade,
sorting)
local ret = {}
Baris 1.183 ⟶ 1.450:
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 prefix = ""
for i = 1, #ret do
ret[i] = prefix .. "• " .. ret[i]
prefix = prefix .. " "
end
end
return ret
end
-- Returns pairs of instance label and property value fetching a recursive tree
function p.getParentValues(frame)
if not required and frame.args and frame:getParent().args.sandbox then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getParentValues(frame)
end
local args = frame.args or frame -- via invoke or require
local id = getEntityId(frame)
if id == nil then return end
local languages = findLang(args.lang)
local propertySup = args.property; if not isSet(propertySup) then propertySup = "P131" end --administrative entity
local propertyLabel = args.label; if not isSet(propertyLabel) then propertyLabel = "P31" end --instance
local propertyLink = args.valuetext; if propertyLink == "" then propertyLink = nil end --internallink
local upto = args.upto; if upto == "" then upto = nil end
local last_only = (args.last_only == "true" or args.last_only == "yes")
local labelShow = args.labelshow; if labelShow == "" then labelShow = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no")
local include_self = (args.include_self == "true" or args.include_self == "yes")
local case = args.case; if case == "" then case = nil end
if isSet(args.uptolabelid) then
upto = mw.wikibase.getLabel(args.uptolabelid)
end
if isSet(args.showlabelid) then
local showLabelList = {}
for substring in mw.text.gsplit(args.showlabelid, '[/%s]+') do
table.insert(showLabelList, mw.wikibase.getLabel(substring))
end
if #showLabelList > 0 then
labelShow = table.concat(showLabelList,"/")
end
end
local result = getParentObjects(id,
args.formatting,
languages,
propertySup,
propertyLabel,
propertyLink,
labelShow,
editicon,
upto,
args.uptolinkid,
last_only,
case,
include_self)
if #result == 0 then return end
local rowformat = args.rowformat; if not isSet(rowformat) then rowformat = "$0 = $1" 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)
if not required and frame.args and frame:getParent().args.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 = "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(findClaims(items_table[1], args.parent), {1, "mainsnak", "datatype"})
if parent_claim == 'monolingualtext' then
largs.formatting = nil
largs.list = 'lang'
else
end
largs.property = args.parent
largs.qualifier = nil
for i, v in ipairs(items_table) do
local link_label = p.
if isSet(link_label
link_table[i] = mw.ustring.gsub(link_table[i] or '', "%[%[(.*)%|.+%]%]", "[[%1|" .. link_label .. "]]")
end
end
args.editicon = not (args.editicon == "false" or args.editicon == "no")
args.id = getEntityId(frame)
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 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 id = getEntityId(frame)
local lang = mw.language.new('en')
local function getBestValue(id, prop)
local
return snak_value
end
Baris 1.304 ⟶ 1.651:
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 = "< 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, yo_sg, yo_pl, yo_pau
if langs[1] == wiki.langcode then
yo_sg = i18n["years-old"].singular
yo_pl = i18n["years-old"].plural
yo_pau = i18n["years-old"].paucal
end
if not isSet(yo_pl) then
yo_pl = getLabelByLangs('Q24564698', langs)
yo_sg = yo_pl
end
if not isSet(yo_pau) then
yo_pau = yo_pl
end
yo = mw.language.new(langs[1]):plural(old_max, {yo_sg, yo_pau, 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
end
-- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked.
function p.getLabel(frame)
p.Untranslated = false
if not required and frame.args and frame:getParent().args.sandbox then
return require(wiki.module_title .. "/" .. mw.message.new('Sandboxlink-subpage-name'):inLanguage(wiki.langcode):plain()).getLabel(frame)
end
local args = frame.args or frame -- via invoke or require
local id =
if id ==
local editicon = not (args.editicon == "false" or args.editicon == "no") and mw.wikibase.isValidEntityId(id)
local
local label, lang
if args.label then
Baris 1.325 ⟶ 1.707:
else
local languages = findLang(args.lang)
-- exceptions or labels fixed
local exist, labels = pcall(require, wiki.module_title .. "/labels" .. (languages[1] == wiki.langcode and '' or '/' .. languages[1]))
if exist and next(labels.infoboxLabelsFromId) ~= nil then
end
if label == nil then
if
label, lang = getLabelByLangs(new_id, languages)
if args.itemgender and feminineGender(args.itemgender) then
label = feminineForm(new_id, lang) or label
end
label = mw.language.new(lang):ucfirst(mw.text.nowiki(label)) -- sanitize
end
label_icon = addLabelIcon(new_id or id, lang, languages[1], editicon)
end
end
end
local linked = args.linked
if isSet(linked
local article = mw.wikibase.getSitelink(id) or ("d:" .. id)
return "[[" .. article .. "|" .. (label or id) .. "]]" ..
else
return (label or id) ..
end
end
-- Utilities -----------------------------
-- See also module ../debug.
-- Copied from Module:Wikibase
function p.getSiteLink(frame)
local id = getEntityId(frame, 1)
if id == nil then
return
end
return mw.wikibase.getSitelink(id, mw.text.trim(frame.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 id = getEntityId(frame)
if id == nil then
end
local args = frame.args
local prop = mw.text.trim(args[1])
local num = mw.wikibase.getBestStatements(id, prop)
return #num
end
-- Returns true if property datavalue is found excluding novalue/somevalue
function p.validProperty(frame)
local property = mw.text.trim(frame.args[1])
local item = getEntityId(frame)
if item == nil then return end
local properties = mw.wikibase.getBestStatements(item, property)
if
return properties[1].mainsnak.datavalue and true or nil
end
|