Mòdul:Wikidata: diferència entre les revisions

Contingut suprimit Contingut afegit
actualització, noves opcions, més seguretat, preparació per Wikidata Bridge
actualització a la darrera versió
 
Línia 1:
-- version 2020051120210304 from master @cawiki
 
local p = {}
Línia 31:
[10] = "F Y", -- precision: month
[11] = "F j, Y", -- precision: day
["hms"] = {["hours"] = "h", ["minutes"] = "m", ["seconds"] = "s"}, -- duration: xh xm xs
},
Linha 60 ⟶ 62:
},
-- 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
}
Linha 82 ⟶ 86:
-- 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
Linha 97 ⟶ 101:
 
local function loadI18n(lang)
local i18n_titleexist, res = pcall(require, wiki.module_title .. "/i18n")
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)
cases = res.cases
end
if lang ~= wiki.langcode and cases.location == nil then
cases.locationexist, res = requirepcall(require, wiki.module_title .. '"/i18n')/" .cases.location lang)
if exist and next(res) ~= nil then
cases.locationcontext = require(wiki.module_title .. '/i18n').cases.locationcontext
tableMerge(i18n, res.i18n)
tableMerge(cases, res.cases)
end
end
end
Linha 141 ⟶ 146:
-- 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
 
Linha 148 ⟶ 153:
if not isSet(label) then return label end
if type(localcase) == "smallcapsfunction" then
return localcase(label)
elseif localcase == "smallcaps" then
return '<span style="font-variant: small-caps;">' .. label .. '</span>'
elseif cases[localcase] then
Linha 184 ⟶ 191:
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
 
Linha 189 ⟶ 213:
local function feminineGender(id)
local claims = mw.wikibase.getBestStatements(id or mw.wikibase.getEntityIdForCurrentPage(),'P21')
iflocal gender_id = getSnak(claims, {1, "mainsnak", "datavalue"}), == nil then -- no claim"value", novalue or somevalue"id"})
if gender_id == "Q6581072" or gender_id == "Q1052281" or gender_id == "Q43445" then -- female, transgender female, female organism
return false
return true
else
local genderId = claims[1].mainsnak.datavalue.value.id
if genderId == "Q6581072" or genderId == "Q1052281" or genderId == "Q43445" then -- female, transgender female, female organism
return true
end
end
return false
Linha 202 ⟶ 222:
-- Fetch female form of label
local function feminineForm(id, lang)
local feminine_claims = mw.wikibase.getBestStatementsgetStatements(id, 'P2521') -- female form of label
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
Linha 218 ⟶ 238:
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/Special:EntityPage/" .. namespace .. label_id .. "?uselang=" .. uselang .. "]]"
untranslated = true
end
Linha 228 ⟶ 252:
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
 
Linha 233 ⟶ 272:
local function addEditIcon(parameters)
local ret = ''
if i18n.addpencil and parameters.editicon and parameters.id and parameters.property then
local icon_style = parameters.editicon == "right" and ' style="float: right;"' or ''
ret = ' <span data-bridge-edit-flow="single-best-value">'
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('EditlinkWikibase-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
Linha 244 ⟶ 287:
-- add edit icon to the last element of a table
local function addEditIconTable(thetable, parameters)
if #thetable == 0 or not i18nparameters.addpencilediticon == false then
return thetable
end
Linha 290 ⟶ 333:
local subparts = mw.ustring.find(parts[i], "=")
if subparts then
parameters[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
else
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
Linha 334 ⟶ 389:
end
return id
end
 
local function findClaims(entityId, property)
if not property or not entityId then return end
if not mw.ustring.match(property, "^P%d+$") then
-- get property id for the given label
property = mw.wikibase.resolvePropertyId(property)
if not property then return end
end
local claims = mw.wikibase.getAllStatements(entityId, property)
return #claims > 0 and claims or nil
end
 
Linha 367 ⟶ 410:
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
Linha 398 ⟶ 446:
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
Linha 461 ⟶ 512:
if unit_symbol == '' then
-- fetch it
local claims = findClaimsmw.wikibase.getBestStatements(id, 'P5061')
if #claims > 0 then
local langclaims = {}
table.insert(lang, 'mul') -- multilingual as last try
Linha 496 ⟶ 547:
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.editiconlabelicon)
end
end
Linha 505 ⟶ 556:
end
 
local function roundPrecisionroundDefPrecision(in_num, out_numfactor)
-- 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
Linha 537 ⟶ 592:
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
-- example "unit": "http://www.wikidata.org/entity/Q174728"
local unit_id = data.unit
unit_id = mw.ustring.sub(unit_id, mw.ustring.find(unit_id, "Q"), -1)
Linha 546 ⟶ 600:
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 = resolveEntityId(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
Linha 563 ⟶ 619:
conv_amount = math.floor(tonumber(amount_f) + 0.5)
else
local conversions = mw.wikibase.getAllStatementsgetStatements(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 = roundPrecisionroundDefPrecision(amount, amount * tonumber(conv.mainsnak.datavalue.value.amount))
break
end
Linha 585 ⟶ 641:
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 == 'durationhms' or parameters.formatting == 'durationh:m:s' then
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
else
return lang_obj:formatDuration(sec)
end
end
if parameters.case then
amount = case(parameters.case, amount, parameters.lang[1])
elseif parameters.formatting ~= 'raw' then
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
Linha 598 ⟶ 680:
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
Linha 736 ⟶ 820:
ret1 = '[[' .. sitelink .. '|' .. labelcase .. ']]'
ret2 = labelcase
elseif label and string.match(parameter ==or '', 'internallink$') orand parameternot == 'ucinternallink'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.editiconlabelicon), ret2
end
 
Linha 753 ⟶ 837:
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
Linha 775 ⟶ 861:
return printDatatypeString(snak.datavalue.value, parameters)
-- other data value string, tabular-data not implemented
elseif snak.datatype == "commonsMedia" or snak.datatype == "geo-shape" then
return printDatatypeMedia(snak.datavalue.value, parameters)
elseif snak.datatype == "url" then
Linha 798 ⟶ 884:
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
Linha 847 ⟶ 933:
elseif snak[1] then -- a multi qualifier
local result, sortkey = {}, {}
local maxvals = tonumber(parameters.list)
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]
Linha 858 ⟶ 946:
local function getValueOfParentClaim(claim, qualifierId, parameters)
local qids = mw.text.split(qualifierId, '/', true)
local valuerawvalue, parent_claimssortkey, valuevalueraw = {}, sortkey{}, {}
local parent_raw, value_text
if qids[1] == parameters.property then
valuerawparent_raw, _, _ = getValueOfClaim(claim, nil, {["formatting"]="raw", ["lang"]=parameters.lang})
else
valuerawparent_raw, _, _ = getValueOfClaim(claim, qids[1], {["formatting"]="raw", ["lang"]=parameters.lang, ["list"]=true, ["qseparator"]='/', ["qconjunction"]='/'})
end
if string.sub(valuerawparent_raw or '', 1, 1) == "Q" then -- protection for 'no value'
local parent_qids = mw.text.split(parent_raw, '/', true)
parent_claims = mw.wikibase.getBestStatements(valueraw, qids[2])
for idx, p_qid in ipairs(parent_qids) do
if parent_claims[1] ~= nil then
local parent_claims = mw.wikibase.getBestStatements(p_qid, qids[2])
value, sortkey, _ = getValueOfClaim(parent_claims[1], nil, parameters)
if parent_claims[1] then
-- raw parent value needed for while/black lists, lang for avoiding an error on types other than entity
valueraw value[idx], _sortkey[idx], _ = getValueOfClaim(parent_claims[1], nil, {["formatting"]="raw", ["lang"]=parameters.lang})
-- 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
returnif value,[1] sortkey, valuerawthen
value_text = mw.text.listToText(value, parameters.qseparator, parameters.qconjunction)
end
return value_text, sortkey[1], valueraw[1]
end
 
Linha 901 ⟶ 996:
for snakidx = 1, #snakval do
if snakidx > 1 then refparts = refparts .. ", " end
refparts = refparts or '' .. (getSnakValue(snakval[snakidx], {lang=lang}) or '')
end
refs[snakkey] = refparts
refparts = nil
if snakkey == "P248" then -- stated in
ref_name = getSnak(snakval[, {1]., "datavalue.", "value.", "id"})
end
end
Linha 927 ⟶ 1.022:
refs['P236'] = refs['P236'] or refParent(ref_name, 'P236') -- ISSN
refs['P356'] = refs['P356'] or refParent(ref_name, 'P356') -- DOI
ref_name = ref_name .. claim.references[ref].hash
end
Linha 992 ⟶ 1.089:
end
if refparts then result = mw.getCurrentFrame():extensionTag("ref", refparts, {name=ref_name}) end
end
if type(result) == 'string' and result ~= "" and isSet(i18n.categoryref) then
result = result .. "[[" ..i18n.categoryref .. "]]"
end
return result
Linha 997 ⟶ 1.097:
 
-- Set whitelist or blacklist values
local function setWhiteOrBlackList(type_list, num_qual, args)
local lists = {['whitelist']={}, ['blacklist']={}, ['ignorevalue']={}, ['selectvalue']={}}
local listed = false
local list = {}
for i = 0, num_qual do
for k, _ in pairs(lists) do
if isSet(args[type_list .. i]) then
if isSet(args[k .. i]) then
listed = true
list lists[k][tostring(i)] = {}
local pattern = 'Q%d+'
for v in string.gmatch(args[type_list .. i], 'Q%d+') do
if string.sub(args[k .. i], 1, 1) ~= 'Q' then
list[tostring(i)][resolveEntityId(v)] = true
pattern = '[^%p%s]+'
end
for q in string.gmatch(args[k .. i], pattern) do
lists[k][tostring(i)][resolveEntityId(q)] = true
end
end
end
end
return lists['whitelist'], lists['blacklist'], lists['ignorevalue'], lists['selectvalue']
return list, listed
end
 
Linha 1.022 ⟶ 1.126:
end
 
local function getEntityId(frameargs, pargs, unnamed)
local argspargs = frame.argspargs 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
Linha 1.037 ⟶ 1.140:
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
 
Linha 1.042 ⟶ 1.156:
-- on debug console use: =p.claim{item="Q...", property="P...", ...}
function p.claim(frame)
iflocal notargs required and= frame.args andor isSet(frame:getParent().args.sandbox) then-- 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
local args = frame.args or frame -- via invoke or require
--If a value is already set, use it
if isSet(args.value) then
Linha 1.056 ⟶ 1.172:
-- arguments
local idparameters = getEntityId(frame){}
parameters.id = getEntityId(args, pargs)
if id == nil then return end
if parameters.id == nil then return end
local property = string.upper(args.property or "")
parameters.property = string.upper(args.property or "")
local qualifierId = {}
qualifierId[1] = isSetgetArg(args.qualifier) and string.upper(args.qualifier) or nil""))
local i = 2
while isSet(args["qualifier" .. i]) do
Linha 1.066 ⟶ 1.183:
i = i + 1
end
local parameters.formatting = isSetgetArg(args.formatting) and args.formatting or nil
local parameters.convert = isSetgetArg(args.convert) and args.convert or nil
local parameters.case = args.case
local parameters.list = getArg(args.list or, true; if (list, {firstrank== "false" or list == "no"'bestrank'}) then list = false end
parameters.shownovalue = getArg(args.shownovalue, true)
parameters.separator = getArg(args.separator)
parameters.conjunction = getArg(args.conjunction, parameters.separator)
parameters.qseparator = parameters.separator
parameters.qconjunction = parameters.conjunction
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) and args.conjunction or separator
local rowformat = args.rowformat
local references = args.references
Linha 1.079 ⟶ 1.199:
local default = args.default
if default then showerrors = nil end
local editicon = not (args.editicon == "false" or args.editicon == "no" or formatting == "raw")
local parameters = {["id"] = id, ["property"] = property, ["formatting"] = formatting, ["convert"] = convert,
["list"] = list, ["case"] = case, ["editicon"] = editicon,
["separator"] = separator, ["conjunction"] = conjunction, ["qseparator"] = separator, ["qconjunction"] = conjunction}
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.list == false or parameters.list == '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
if showerrors then return printError("property-not-found") else return default end
end
-- defaults for table
local preformat, postformat = "", ""
local whitelisted, blacklisted = false, false
local whitelist, blacklist, ignorevalue, selectvalue = {}, {}, {}, {}
if parameters.formatting == "table" then
parameters.separator = parameters.separator or "<br />"
Linha 1.117 ⟶ 1.251:
-- set whitelist and blacklist values
whitelist, whitelistedblacklist, ignorevalue, selectvalue = setWhiteOrBlackList("whitelist", #qualifierId, args)
local next = next
blacklist, blacklisted = setWhiteOrBlackList("blacklist", #qualifierId, args)
if next(whitelist) ~= nil then whitelisted = true end
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
end
Linha 1.139 ⟶ 1.261:
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
Linha 1.159 ⟶ 1.281:
end
if gender_requested then
if feminineGender(idgender or parameters.id) then
parameters.gender = "feminineform"
end
Linha 1.178 ⟶ 1.300:
table.sort(sortindices, comparator)
local result, result2, result_query
local error
if parameters.list or parameters.formatting == "table" then
Linha 1.193 ⟶ 1.315:
local sortkeys = {}
local refs = {}
local firstrank = parameters.list == "firstrank" and claims[sortindices[1]].rank or ''
local rowlist = {} -- rows to list with whitelist or blacklist
for idx in pairs(claims) do
Linha 1.199 ⟶ 1.320:
local reference = {}
if not whitelisted then rowlist[idx] = true end
if firstrank ~= '' and firstrank ~= claim.rank then
break
end
if parameters.formatting == "table" then
local params = tableParameters(args, parameters, "0")
Linha 1.221 ⟶ 1.339:
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
Linha 1.228 ⟶ 1.346:
valueq, sortkeyq, valueraw = getValueOfParentClaim(claim, q, params)
elseif string.find(q, "^/.+") then
local claim2 = findClaimsgetStatements(parameters.id, string.sub(q, 2), bestrank)
if #claim2 > 0 then
valueq, sortkeyq, _ = getValueOfClaim(claim2[1], nil, params)
end
Linha 1.235 ⟶ 1.353:
valueq, sortkeyq, _ = getValueOfClaim(claim, q, params)
end
if valueq then break end
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
Linha 1.246 ⟶ 1.367:
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
Linha 1.287 ⟶ 1.412:
table.sort(sortindices, comparator)
end
local maxvals = tonumber(parameters.list)
result = {}
for idx in pairs(values) do
Linha 1.298 ⟶ 1.424:
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...
Linha 1.323 ⟶ 1.449:
if isSet(value) then
result[#result + 1] = value
if not parameters.list or (maxvals and maxvals == #result) then
break
end
end
end
-- in a table, add edit icon on last element
if parametersargs.formattingquery == 'tablenum' and parameters.editicon then
result_query = 0
result = addEditIconTable(result, parameters)
for _, v in pairs(rowlist) do
result_query = result_query + (v and 1 or 0)
end
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
result = preformat .. mw.text.listToText(result, parameters.separator, parameters.conjunction) .. postformat
else
-- return first element
Linha 1.338 ⟶ 1.474:
result, result2, error = getValueOfClaim(claim, qualifierId[1], parameters)
if result and references then result = result .. getReferences(claim, parameters.lang) end
if args.query == 'num' then result_query = 1 end
end
if isSet(result) then
if i18n.addpencil and 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)
Linha 1.348 ⟶ 1.485:
if showerrors then result = error else result = default end
end
returnif result,args.query not== 'untranslated' and required and ''not oris_sandbox untranslatedthen
result_query = untranslated
end
 
-- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323)
-- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm
-- uses the newer mw.wikibase calls instead of directly using the snaks
-- 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)
local ent = mw.wikibase.getEntity()
local props = ent:formatPropertyValues('P1323')
local out = {}
local t = {}
for k, v in pairs(props) do
if k == 'value' then
t = mw.text.split( v, ", ")
for k2, v2 in pairs(t) do
out[#out + 1] = "[http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/" .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. "]"
end
end
end
return result, result_query or ''
local ret = table.concat(out, "<br> ")
if #ret == 0 then
ret = "Invalid TA"
end
return ret
end
 
Linha 1.378 ⟶ 1.494:
 
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, editiconlabelicon, case)
local snaks = mw.wikibase.getBestStatements(id, property)
local mysnak = getSnak(snaks, {1, "mainsnak"})
Linha 1.392 ⟶ 1.509:
if mysnak.datavalue then
entity_id = "Q" .. tostring(mysnak.datavalue.value['numeric-id'])
result, _ = getSnakValue(mysnak, {formatting=parameter, lang=langs, editiconlabelicon=editiconlabelicon, case=case})
end
Linha 1.405 ⟶ 1.522:
propertyLabel,
propertyLink,
label_show,
labelShow,
labelicon0,
editicon,
labelicon1,
upto,
upto_number,
upto_linkId,
upto_label,
upto_value,
last_only,
grammatical_case,
include_self)
if upto_linkId == nil then upto_linkId = "" end
local upto_link_ids = {}
for q in mw.text.gsplit(upto_linkId, '[^Q%d]') do
upto_link_ids[q] = true
end
local propertySups = mw.text.split(propertySupString, '[^P%d]')
local lastlabelmaxloop = uc_first(upto or '')10
if upto_number then
local maxloop = tonumber(upto) or ((lastlabel .. upto_linkId) == '' and 10 or 50)
maxloop = tonumber(upto_number)
elseif next(upto_label) or next(upto_value) then
local labelFilter = {}
maxloop = 50
if labelShow then
for _, v in ipairs(mw.text.split(labelShow, "/")) do
labelFilter[uc_first(v)] = true
end
end
local labels_filter = next(label_show)
local label_self
_, label_self = getPropertyValue(id, propertyLabel, label_format, languages)
local result = {}
local id_value = id
for iter = 1, maxloop do
local link, label, linktextlabelwicon, _idlinktext, _linkid_label
for _, propertySup in pairs(propertySups) do
_idlocal _id_value, _link = getPropertyValue(idid_value, propertySup, prop_format, languages, editiconlabelicon1, grammatical_case)
if _id_id_value and _link then idid_value = _id_id_value; link = _link break end
end
if not idid_value or not link then break end
if propertyLink then
_, linktext = getPropertyValue(idid_value, propertyLink, "label", languages)
if linktext then
link = mw.ustring.gsub(link, "%[%[(.*)%|.+%]%]", "[[%1|" .. linktext .. "]]")
Linha 1.451 ⟶ 1.561:
end
_id_label, label = getPropertyValue(idid_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 labelShowlabels_filter == nil or labelFilter(label_show[id_label] or label_show[label]) then
result[#result + 1] = {labellabelwicon, link}
label_show[id_label or 'none'], label_show[label or 'none'] = nil, nil -- only first label found
if label then
labelFilter[label] = nil -- only first label found
end
end
if labelupto_label[id_label] ==or lastlabelupto_label[label] or upto_link_idsupto_value[idid_value] then
break
end
Linha 1.470 ⟶ 1.582:
end
if include_self then table.insert(result, 1, {label_self, mw.title.getCurrentTitle().text}) end
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
Linha 1.487 ⟶ 1.604:
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 prefix = ""
local suffix = ""
for i = 1, #ret do
ret[i] = prefix'<ul style="line-height:100%; margin-' .. "•direction .. ':0.45em; padding-' .. direction .. ':0;"><li>' .. ret[i]
prefixsuffix = prefixsuffix .. "&nbsp;"'</li></ul>'
end
ret[#ret] = ret[#ret] .. suffix
end
Linha 1.501 ⟶ 1.620:
end
 
-- Returns pairs of instanceparent label and property value fetching a recursive tree
function p.getParentValues(frame)
iflocal notargs required and= frame.args andor frame:getParent().args.sandbox then-- 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 argsid = frame.getEntityId(args, or frame -- via invoke or requirepargs)
local id = getEntityId(frame)
if id == nil then return end
local languages = findLang(args.lang)
local propertySup = getArg(args.property; if not isSet(propertySup) then propertySup =, "P131" end) --administrative entity
local propertyLabel = getArg(args.label; if not isSet(propertyLabel) then propertyLabel =, "P31" end) --instance
local propertyLink = getArg(args.valuetext; if propertyLink == "" then propertyLink = nil end --internallink)
local property_format = getArg(args.formatting; if property_format == "" then property_format = nil end)
local label_format = getArg(args.labelformat; if not isSet(label_format) then label_format =, "label" end)
local uptoupto_number = getArg(args.upto; if upto == "" then upto = nil end)
local last_only = getArg(args.last_only, == "true" or args.last_only == "yes"false)
local editicon, labelicon = setIcons(args.editicon, pargs.editicon)
local labelShow = args.labelshow; if labelShow == "" then labelShow = nil end
local editiconinclude_self = not getArg(args.editiconinclude_self, == "false" or args.editicon == "no")
local case = getArg(args.case)
local include_self = (args.include_self == "true" or args.include_self == "yes")
local case = args.case; if case == "" then case = nil end
local upto_label = {}
if isSet(args.uptolabelid) then
upto, for _q =in getLabelByLangsstring.gmatch(args.uptolabelid or '', languages'Q%d+') do
local checked_q = resolveEntityId(q)
if checked_q then
upto_label[checked_q] = true
end
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 = {}
if isSet(args.showlabelid) then
for q in string.gmatch(args.uptovalueid or args.uptolinkid or '', 'Q%d+') do
local showLabelList = {}
local checked_q = resolveEntityId(q)
for substring in mw.text.gsplit(args.showlabelid, '[^Q%d]') do
if checked_q then
table.insert(showLabelList, (getLabelByLangs(substring, languages)))
upto_value[checked_q] = true
end
end
if #showLabelList > 0 then
labelShow = table.concat(showLabelList,"/")
local label_show = {}
for q in string.gmatch(args.showlabelid or '', 'Q%d+') do
local checked_q = resolveEntityId(q)
if checked_q then
label_show[checked_q] = true
end
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
Linha 1.543 ⟶ 1.689:
propertyLabel,
propertyLink,
labelShowlabel_show,
editiconlabelicon0,
uptolabelicon1,
upto_number,
args.uptovalueid or args.uptolinkid,
upto_label,
upto_value,
last_only,
case,
Linha 1.552 ⟶ 1.700:
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
Linha 1.567 ⟶ 1.714:
-- Link with a parent label --------------------
function p.linkWithParentLabel(frame)
iflocal notpargs required and= frame.args and frame:getParent().args.sandbox thenor {}
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
Linha 1.584 ⟶ 1.732:
-- 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
Linha 1.598 ⟶ 1.746:
-- get label of parent property
local parent_claim = getSnak(findClaimsgetStatements(items_table[1], args.parent, true), {1, "mainsnak", "datatype"})
if parent_claim == 'monolingualtext' then
largs.formatting = nil
Linha 1.604 ⟶ 1.752:
else
largs.formatting = "label"
largs.list = "false"
end
largs.property = args.parent
Linha 1.615 ⟶ 1.763:
end
end
args.editicon, _ = not setIcons(args.editicon, == "false" or argspargs.editicon == "no")
args.id = getEntityId(frameargs, pargs)
args.lang = findLang(args.lang)
return mw.text.listToText(link_table) .. addEditIcon(args)
Linha 1.623 ⟶ 1.771:
-- 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 idpargs = getEntityId(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)
local snak_value =return getSnak(mw.wikibase.getBestStatements(id, prop), {1, "mainsnak", "datavalue", "value"})
return snak_value
end
Linha 1.730 ⟶ 1.879:
-- Gets a label in a given language (content language by default) or its fallbacks, optionnally linked.
function p.getLabel(frame)
iflocal notargs required and= frame.args andor frame:getParent().args.sandbox then-- 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 argsid = frame.getEntityId(args, or frame -- via invoke orpargs, require1)
local id = getEntityId(frame, true)
if id == nil then return end
local languages = findLang(args.lang)
local editicon = not (args.editicon == "false" or args.editicon == "no") and mw.wikibase.isValidEntityId(id)
local labelicon = false
if mw.wikibase.isValidEntityId(id) then
_, labelicon = setIcons(args.editicon, pargs.editicon)
end
local label_icon = ''
Linha 1.743 ⟶ 1.897:
label = args.label
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 labels.infoboxLabelsFromId and next(labels.infoboxLabelsFromId) ~= nil then
label = labels.infoboxLabelsFromId[id]
end
Linha 1.753 ⟶ 1.906:
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], editiconlabelicon)
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, not required and '' or untranslatedret2
else
return (label or id) .. label_icon, not required and '' or untranslatedret2
end
end
Linha 1.776 ⟶ 1.933:
-- Copied from Module:Wikibase
function p.getSiteLink(frame)
local idargs = getEntityId(frame,.args 1)or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
if id == nil then
local id = getEntityId(args, pargs, 1)
return
if id == nil then return end
end
return mw.wikibase.getSitelink(id, mw.text.trim(frame.args[2] or ''))
end
 
Linha 1.791 ⟶ 1.948:
-- Number of statements
function p.numStatements(frame)
local idargs = getEntityId(frame).args or frame -- via invoke or require
local pargs = frame.args and frame:getParent().args or {}
if id == nil then
local id = getEntityId(args, pargs)
return 0
if id == nil then return 0 end
local prop = mw.text.trim(args[1] or '')
local num = {}
if not isSet(prop) and frame.args then
args = {}
for k, v in pairs(pargs) do
args[k] = v
end
for k, v in pairs(frame.args) do
args[k] = v
end
args.query = 'num'
_, num = p.claim(args)
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
local args = frame.args
local prop = mw.text.trim(args[1])
local num = mw.wikibase.getBestStatements(id, prop)
return #num
end
Linha 1.803 ⟶ 1.979:
-- Returns true if property datavalue is found excluding novalue/somevalue
function p.validProperty(frame)
local propertyargs = mw.text.trim(frame.args[1]) or frame -- via invoke or require
local itempargs = getEntityId(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