Module:PBD: Difference between revisions
Content deleted Content added
PeaceDeadC (talk | contribs) Created page with "-- Original module located at en:Module:PBD, en:Module:PBD/i18n and en:Module:PBD/aliasesP. local p = {} local arg = ... local i18n function loadSubmodules(fr..." |
PeaceDeadC (talk | contribs) No edit summary |
||
Line 1:
local p = {}
local arg = ...
local i18n
local function
local title
if frame then
title = frame:getTitle()
else
title = arg
end
if not i18n then
end
end
Line 61 ⟶ 58:
p.args = {
eid = "eid",
page = "page",
date = "date"
}
local aliasesP = {
coord = "P48",
-----------------------
image = "P470",
author = "P215",
publisher = "P218",
importedFrom = "P36",
statedIn = "P15",
pages = "P219",
language = "P44",
hasPart = "P173",
publicationDate = "P19",
startTime = "P34",
endTime = "P41",
chapter = "P221",
retrieved = "P17",
referenceURL = "P35",
sectionVerseOrParagraph = "P223",
archiveURL = "P208",
title = "P225",
formatterURL = "P167",
quote = "P226",
shortName = "P203",
definingFormula = "P232",
archiveDate = "P227",
inferredFrom = "P71",
typeOfReference = "P228",
column = "P230"
}
Line 99 ⟶ 128:
}
local defaultSeparators = {
["sep"] = {" "},
Line 116 ⟶ 144:
local Config = {}
function Config:new()
local cfg = {}
setmetatable(cfg,
self.__index = self
cfg.separators = {
["sep"] = {copyTable(defaultSeparators["sep"])},
["sep%s"] = {copyTable(defaultSeparators["sep%s"])},
Line 131 ⟶ 157:
["punc"] = {copyTable(defaultSeparators["punc"])}
}
cfg.entity = nil
cfg.entityID = nil
Line 138 ⟶ 164:
cfg.qualifierIDs = {}
cfg.qualifierIDsAndValues = {}
cfg.bestRank = true
cfg.ranks = {true, true, false}
cfg.foundRank = #cfg.ranks
cfg.flagBest = false
cfg.flagRank = false
cfg.periods = {true, true, true}
cfg.flagPeriod = false
cfg.atDate = {parseDate(os.date('!%Y-%m-%d'))}
cfg.mdyDate = false
cfg.singleClaim = false
Line 153 ⟶ 180:
cfg.editable = false
cfg.editAtEnd = false
cfg.inSitelinks = false
cfg.langCode = mw.language.getContentLanguage().code
cfg.langName = mw.language.fetchLanguageName(cfg.langCode, cfg.langCode)
cfg.langObj = mw.language.new(cfg.langCode)
cfg.siteID = mw.wikibase.getGlobalSiteId()
cfg.states = {}
cfg.states.qualifiersCount = 0
cfg.curState = nil
cfg.prefetchedRefs = nil
return cfg
end
local State = {}
function State
local stt = {}
setmetatable(stt,
self.__index = self
stt.conf = cfg
stt.type = type
stt.results = {}
stt.parsedFormat = {}
stt.separator = {}
stt.movSeparator = {}
stt.puncMark = {}
stt.linked = false
stt.rawValue = false
Line 191 ⟶ 221:
stt.unitOnly = false
stt.singleValue = false
return stt
end
local function replaceAlias(id)
if
id =
end
return id
end
local function errorText(code, param)
local text = i18n["errors"][code]
if param then text = mw.ustring.gsub(text, "$1", param) end
Line 209 ⟶ 239:
end
local function throwError(errorMessage, param)
error(errorText(errorMessage, param))
end
local function replaceDecimalMark(num)
return mw.ustring.gsub(num, "[.]", i18n['numeric']['decimal-mark'], 1)
end
local function padZeros(num, numDigits)
local numZeros
local negative = false
if num < 0 then
negative = true
num = num * -1
end
num = tostring(num)
numZeros = numDigits - num:len()
for
num = "0"..num
end
if negative then
num = "-"..num
end
return num
end
local function replaceSpecialChar(chr)
if chr == '_' then
return ' '
else
Line 249 ⟶ 278:
end
local function replaceSpecialChars(str)
local chr
local esc = false
local strOut = ""
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
Line 268 ⟶ 297:
end
end
return strOut
end
local function buildWikilink(target, label)
if not label or target == label then
return "[[" .. target .. "]]"
Line 280 ⟶ 309:
end
function copyTable(tIn)
if not tIn then
return nil
end
local tOut = {}
for i, v in pairs(tIn) do
tOut[i] = v
end
return tOut
end
local function mergeArrays(a1, a2)
for i = 1, #a2 do
a1[#a1 + 1] = a2[i]
end
return a1
end
local function split(str, del)
local out = {}
local i, j = str:find(del)
if i and j then
out[1] = str:sub(1, i - 1)
Line 316 ⟶ 341:
out[1] = str
end
return out
end
local function
local id
if url:match('^http[s]?://') then
id = split(url, "Q")
if id[2] then
return "Q" .. id[2]
end
end
return nil
end
Line 336 ⟶ 361:
function parseDate(dateStr, precision)
precision = precision or "d"
local i, j, index, ptr
local parts = {nil, nil, nil}
if dateStr == nil then
return parts[1], parts[2], parts[3] -- year, month, day
end
i, j = dateStr:find("[T/]")
if i then
dateStr = dateStr:sub(1, i-1)
end
local from = 1
if dateStr:sub(1,1) == "-" then
from = 2
end
index = 1
ptr = 1
i, j = dateStr:find("-", from)
if i then
parts[index] = tonumber(mw.ustring.gsub(dateStr:sub(ptr, i-1), "^\+(.+)$", "%1"), 10)
if parts[index] == -0 then
parts[index] = tonumber("0")
end
if precision == "y" then
return parts[1], parts[2], parts[3]
end
index = index + 1
ptr = i + 1
i, j = dateStr:find("-", ptr)
if i then
-- month
parts[index] = tonumber(dateStr:sub(ptr, i-1), 10)
if precision == "m" then
-- we're done
return parts[1], parts[2], parts[3]
end
index = index + 1
ptr = i + 1
end
end
if dateStr:sub(ptr) ~= "" then
parts[index] = tonumber(dateStr:sub(ptr), 10)
end
return parts[1], parts[2], parts[3]
end
local function datePrecedesDate(aY, aM, aD, bY, bM, bD)
if aY == nil or bY == nil then
return nil
Line 411 ⟶ 431:
bM = bM or 1
bD = bD or 1
if aY < bY then
return true
end
if aY > bY then
return false
end
if aM < bM then
return true
end
if aM > bM then
return false
end
if aD < bD then
return true
end
return false
end
local function getHookName(param, index)
if hookNames[param] then
return hookNames[param][index]
Line 445 ⟶ 465:
end
local function alwaysTrue()
return true
end
local chr, esc, param, root, cur, prev, new
local params = {}
local function newObject(array)
local obj = {}
obj.str = ""
array[#array + 1] = obj
obj.parent = array
return obj
end
local function endParam()
if param > 0 then
Line 521 ⟶ 496:
end
end
root = {} -- array
root.req = {}
cur = newObject(root)
prev = nil
esc = false
param = 0
for i = 1, #str do
chr = str:sub(i,i)
if not esc then
if chr == '\\' then
Line 570 ⟶ 545:
end
end
cur.str = cur.str .. replaceSpecialChar(chr)
end
Line 577 ⟶ 552:
esc = false
end
prev = nil
end
endParam()
if not next(root.req) then
throwError("missing-required-parameter")
end
if root.req[parameters.separator] then
throwError("extra-required-parameter", parameters.separator)
end
return root, params
end
local function sortOnRank(claims)
local rankPos
local ranks = {{}, {}, {}, {}}
local sorted = {}
for
rankPos = rankTable[v.rank] or 4
ranks[rankPos][#ranks[rankPos] + 1] = v
end
sorted = ranks[1]
sorted = mergeArrays(sorted, ranks[2])
sorted = mergeArrays(sorted, ranks[3])
return sorted
end
function Config:getLabel(id, raw, link, short)
local label = nil
local title = nil
local prefix= ""
if not id then
id = mw.wikibase.getEntityIdForCurrentPage()
if not id then
return ""
end
end
id = id:upper()
if raw then
if mw.wikibase.isValidEntityId(id) and mw.wikibase.entityExists(id) then
label = id
if id:sub(1,1) == "P" then
prefix = "Property:"
end
end
prefix = "
title = label
else
if short then
label = p._property{
if label == "" then
label = nil
end
end
-- get label
if not label then
label
end
end
if not label then
label = ""
elseif link then
if not title then
if id:sub(1,1) == "Q" then
title = mw.wikibase.
if not title then
title = id
prefix = "pbd:Special:EntityPage/"
end
elseif id:sub(1,1) == "P" then
title = id
prefix = "
end
end
label = mw.text.nowiki(label)
if title then
label = buildWikilink(prefix .. title, mw.text.nowiki(label))
end
end
return label
end
Line 689 ⟶ 655:
local value = ""
local prefix = ""
local front = "
local back = ""
if self.entityID:sub(1,1) == "P" then
prefix = "Property:"
end
if self.editAtEnd then
front = '<span style="float:'
if self.langObj:isRTL() then
front = front .. 'left'
Line 704 ⟶ 670:
front = front .. 'right'
end
front = front .. '">'
back = '</span>'
end
value = "[[File:OOjs UI icon edit-ltr-progressive.svg|frameless|text-top|10px|alt=" .. i18n['info']['edit-on-
if self.propertyID then
value = value .. "#" .. self.propertyID
Line 716 ⟶ 682:
value = value .. "#sitelinks-pbc"
end
value = value .. "|" .. i18n['info']['edit-on-
return front .. value .. back
end
function Config:concatValues(valuesArray)
local outString = ""
local j, skip
for i = 1, #valuesArray do
-- check if this is a reference
Line 733 ⟶ 697:
j = i - 1
skip = false
while valuesArray[j] and valuesArray[j].refHash do
if valuesArray[i].refHash == valuesArray[j].refHash then
Line 742 ⟶ 705:
j = j - 1
end
if not skip then
outString = outString .. mw.getCurrentFrame():extensionTag("ref", valuesArray[i][1], {name = valuesArray[i].refHash})
end
Line 751 ⟶ 713:
end
end
return outString
end
Line 758 ⟶ 720:
local space = " "
local label = ""
local itemID
if unit == "" or unit == "1" then
return nil
end
if unitOnly then
space = ""
end
itemID =
if itemID then
if itemID == aliasesQ.percentage then
Line 774 ⟶ 737:
else
label = self:getLabel(itemID, raw, link, short)
if label ~= "" then
return space .. label
Line 780 ⟶ 743:
end
end
return ""
end
function
return self.conf:getValue(snak, self.rawValue, self.linked, self.shortName, true, self.unitOnly, false, self.type:sub(1,2))
end
function Config:getValue(snak, raw, link, short, anyLang, unitOnly, noSpecial, type)
if snak.snaktype == 'value' then
local datatype = snak.datavalue.type
local subtype = snak.datatype
local datavalue = snak.datavalue.value
if datatype == 'string' then
if subtype == 'url' and link then
if raw then
return "[" .. datavalue .. "]"
else
Line 801 ⟶ 766:
elseif subtype == 'commonsMedia' then
if link then
return buildWikilink("
elseif not raw then
return "[[File:" .. datavalue .. "]]"
Line 808 ⟶ 773:
end
elseif subtype == 'geo-shape' and link then
return buildWikilink("
elseif subtype == 'math' and not raw then
local attribute = nil
if (type == parameters.property or (type == parameters.qualifier and self.propertyID == aliasesP.hasPart)) and snak.property == aliasesP.definingFormula then
attribute = {qid = self.entityID}
end
return mw.getCurrentFrame():extensionTag("math", datavalue, attribute)
elseif subtype == 'external-id' and link then
local url = p._property{
if url ~= "" then
url = mw.ustring.gsub(url, "$1", datavalue)
Line 824 ⟶ 795:
end
elseif datatype == 'monolingualtext' then
if anyLang or datavalue['language'] == self.langCode then
return datavalue['text']
else
Line 834 ⟶ 803:
local value = ""
local unit
if not unitOnly then
value = mw.ustring.gsub(datavalue['amount'], "^\+(.+)$", "%1")
if raw then
return value
end
value = replaceDecimalMark(value)
value = i18n.addDelimiters(value)
end
unit = self:convertUnit(datavalue['unit'], raw, link, short, unitOnly)
if unit then
value = value .. unit
end
return value
elseif datatype == 'time' then
Line 866 ⟶ 832:
local calendar = ""
local precision = datavalue['precision']
if precision == 11 then
p = "d"
Line 875 ⟶ 841:
yFactor = 10^(9-precision)
end
y, m, d = parseDate(datavalue['time'], p)
if y < 0 then
sign = -1
y = y * sign
end
if precision <= 8 then
yDiv = y / yFactor
if precision >= 6 then
mayAddCalendar = true
if precision <= 7 then
yRound = math.ceil(yDiv)
if not raw then
if precision == 6 then
Line 901 ⟶ 864:
suffix = i18n['datetime']['suffixes']['century']
end
suffix = i18n.getOrdinalSuffix(yRound) .. suffix
else
yRound = (yRound - 1) * yFactor + 1
end
else
yRound = math.floor(yDiv) * yFactor
if not raw then
prefix = i18n['datetime']['prefixes']['decade-period']
Line 918 ⟶ 877:
end
end
if raw and sign < 0 then
yRound = yRound + yFactor - 1
end
else
local yReFactor, yReDiv, yReRound
yRound = math.floor(yDiv + 0.5)
if yRound == 0 then
if precision <= 2 and y ~= 0 then
Line 935 ⟶ 891:
yReDiv = y / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
precision = 3
yFactor = yReFactor
Line 943 ⟶ 898:
end
end
if yRound == 0 then
precision = 5
yFactor = 1
Line 952 ⟶ 906:
end
end
if precision >= 1 and y ~= 0 then
yFull = yRound * yFactor
yReFactor = 1e9
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
precision = 0
yFactor = yReFactor
Line 969 ⟶ 922:
yReDiv = yFull / yReFactor
yReRound = math.floor(yReDiv + 0.5)
if yReDiv == yReRound then
precision = 3
yFactor = yReFactor
Line 978 ⟶ 930:
end
end
if not raw then
if precision == 3 then
Line 1,000 ⟶ 952:
mayAddCalendar = true
end
if mayAddCalendar then
calendarID =
if calendarID and calendarID == aliasesQ.prolepticJulianCalendar then
if not raw then
Line 1,016 ⟶ 968:
end
end
if not raw then
local ce = nil
if sign < 0 then
ce = i18n['datetime']['BCE']
Line 1,025 ⟶ 977:
ce = i18n['datetime']['CE']
end
if ce then
if link then
Line 1,032 ⟶ 984:
suffix = suffix .. " " .. ce
end
value = tostring(yRound)
if m then
dateStr = self.langObj:formatDate("F", "1-"..m.."-1")
if d then
if self.mdyDate then
Line 1,045 ⟶ 997:
end
end
value = dateStr .. " " .. value
end
value = prefix .. value .. suffix .. calendar
else
value = padZeros(yRound * sign, 4)
if m then
value = value .. "-" .. padZeros(m, 2)
if d then
value = value .. "-" .. padZeros(d, 2)
end
end
value = value .. calendar
end
return value
elseif datatype == 'wikibase-entityid' then
local label
local itemID = datavalue['numeric-id']
if subtype == 'wikibase-item' then
itemID = "Q" .. itemID
Line 1,263 ⟶ 1,028:
return '<strong class="error">' .. errorText('unknown-data-type', subtype) .. '</strong>'
end
label = self:getLabel(itemID, raw, link, short)
if label == "" then
label = nil
end
return label
else
Line 1,276 ⟶ 1,041:
elseif snak.snaktype == 'somevalue' and not noSpecial then
if raw then
return " "
else
return i18n['values']['unknown']
Line 1,282 ⟶ 1,047:
elseif snak.snaktype == 'novalue' and not noSpecial then
if raw then
return ""
else
return i18n['values']['none']
Line 1,293 ⟶ 1,058:
function Config:getSingleRawQualifier(claim, qualifierID)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[qualifierID] end
if qualifiers and qualifiers[1] then
return self:getValue(qualifiers[1], true) -- raw = true
Line 1,305 ⟶ 1,070:
function Config:snakEqualsValue(snak, value)
local snakValue = self:getValue(snak, true) -- raw = true
if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper() end
return snakValue == value
end
Line 1,313 ⟶ 1,078:
function Config:setRank(rank)
local rankPos
if rank == p.flags.best then
self.bestRank = true
self.flagBest = true
return
end
if rank:sub(1,9) == p.flags.preferred then
rankPos = 1
Line 1,329 ⟶ 1,094:
return
end
if not self.flagRank then
self.ranks = {false, false, false}
self.bestRank = self.flagBest
self.flagRank = true
end
if rank:sub(-1) == "+" then
for i = rankPos, 1, -1 do
Line 1,352 ⟶ 1,116:
function Config:setPeriod(period)
local periodPos
if period == p.flags.future then
periodPos = 1
Line 1,362 ⟶ 1,126:
return
end
if not self.flagPeriod then
self.periods = {false, false, false}
self.flagPeriod = true
end
self.periods[periodPos] = true
end
Line 1,374 ⟶ 1,137:
function Config:qualifierMatches(claim, id, value)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[id] end
if qualifiers then
for
if self:snakEqualsValue(v, value) then
return true
Line 1,383 ⟶ 1,146:
end
elseif value == "" then
return true
end
return false
end
Line 1,407 ⟶ 1,169:
local endTimeM = nil
local endTimeD = nil
if self.periods[1] and self.periods[2] and self.periods[3] then
-- any time
return true
end
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
if startTime and startTime ~= "" and startTime ~= " " then
startTimeY, startTimeM, startTimeD = parseDate(startTime)
end
endTime = self:getSingleRawQualifier(claim,
if endTime and endTime ~= "" and endTime ~= " " then
endTimeY, endTimeM, endTimeD = parseDate(endTime)
end
if startTimeY ~= nil and endTimeY ~= nil and datePrecedesDate(endTimeY, endTimeM, endTimeD, startTimeY, startTimeM, startTimeD) then
endTimeY = nil
endTimeM = nil
endTimeD = nil
end
if self.periods[1] then
-- future
if startTimeY and datePrecedesDate(
return true
end
end
if self.periods[2] then
-- current
if (startTimeY == nil or not datePrecedesDate(
(endTimeY == nil or datePrecedesDate(
return true
end
end
if self.periods[3] then
-- former
if endTimeY and not datePrecedesDate(
return true
end
end
return false
end
Line 1,467 ⟶ 1,220:
return false
end
if flag == p.flags.linked then
self.curState.linked = true
Line 1,473 ⟶ 1,226:
elseif flag == p.flags.raw then
self.curState.rawValue = true
if self.curState == self.states[parameters.reference] then
self.separators["sep%r"][1] = {" "}
end
return true
elseif flag == p.flags.short then
Line 1,521 ⟶ 1,273:
function Config:processFlagOrCommand(flag)
local param = ""
if not flag then
return false
end
if flag == p.claimCommands.property or flag == p.claimCommands.properties then
param = parameters.property
Line 1,537 ⟶ 1,289:
return self:processFlag(flag)
end
if self.states[param] then
return false
end
self.states[param] = State:new(self, param)
self.states[param].parsedFormat = parseFormat(parameters.general) -- will be overwritten for param=="%p"
self.states[param].separator = self.separators["sep"..param] -- will be nil for param=="%p", which will be set separately
if flag == p.claimCommands.property or flag == p.claimCommands.qualifier or flag == p.claimCommands.reference then
self.states[param].singleValue = true
end
self.curState = self.states[param]
return true
end
Line 1,562 ⟶ 1,311:
function Config:processSeparators(args)
local sep
for i, v in pairs(self.separators) do
if args[i] then
sep = replaceSpecialChars(args[i])
if sep ~= "" then
self.separators[i][1] = {sep}
Line 1,583 ⟶ 1,332:
end
function State:isSourced(claim)
self.conf.prefetchedRefs = self:getReferences(claim)
Line 1,598 ⟶ 1,344:
function State:claimMatches(claim)
local matches, rankPos
self:resetCaches()
if self.conf.propertyValue then
matches = self.conf:snakEqualsValue(claim.mainsnak, self.conf.propertyValue)
Line 1,608 ⟶ 1,352:
matches = true
end
for i, v in pairs(self.conf.qualifierIDsAndValues) do
matches = (matches and self.conf:qualifierMatches(claim, i, v))
end
rankPos = rankTable[claim.rank] or 4
matches = (matches and self.conf:rankMatches(rankPos) and self.conf:timeMatches(claim))
if self.conf.sourcedOnly then
matches = (matches and self:isSourced(claim))
end
return matches, rankPos
end
function State:out()
local result
local valuesArray
local sep = nil
local out = {}
local function walk(formatTable, result)
local valuesArray = {}
for i, v in pairs(formatTable.req) do
if not result[i] or not result[i][1] then
return {}
end
end
for
if v.param then
valuesArray = mergeArrays(valuesArray, result[v.str])
Line 1,649 ⟶ 1,388:
valuesArray[#valuesArray + 1] = {v.str}
end
if v.child then
valuesArray = mergeArrays(valuesArray, walk(v.child, result))
end
end
return valuesArray
end
for i = #self.results, 1, -1 do
result = self.results[i]
if #out > 0 then
sep = self.separator[1]
result[parameters.separator] = {self.movSeparator[1]}
else
sep = nil
result[parameters.separator] = {self.puncMark[1]}
end
valuesArray = walk(self.parsedFormat, result)
if #valuesArray > 0 then
if sep then
valuesArray[#valuesArray + 1] = sep
end
out = mergeArrays(valuesArray, out)
end
end
self.results = {}
return out
end
Line 1,690 ⟶ 1,426:
-- level 1 hook
function State:getProperty(claim)
local value = {self
if #value > 0 then
return {value}
else
return {}
end
end
function State:getQualifiers(claim, param)
local qualifiers
if claim.qualifiers then qualifiers = claim.qualifiers[self.conf.qualifierIDs[param]] end
if qualifiers then
return self.conf.states[param]:iterate(qualifiers, {[parameters.general] = hookNames[parameters.qualifier.."\\d"][2], count = 1}) -- pass qualifier state with level 2 hook
else
return {}
end
end
function State:getQualifier(snak)
local value = {self
if #value > 0 then
return {value}
else
return {}
end
end
function State:getAllQualifiers(claim, param, result, hooks)
local out = {}
local sep = self.conf.separators["sep"..parameters.qualifier][1]
for i = 1, self.conf.states.qualifiersCount do
if not result[parameters.qualifier..i] then
self:callHook(parameters.qualifier..i, hooks, claim, result)
end
if result[parameters.qualifier..i] and result[parameters.qualifier..i][1] then
if #out > 0 and sep then
out[#out + 1] = sep
end
out = mergeArrays(out, result[parameters.qualifier..i])
end
end
return out
end
function State:getReferences(claim)
if self.conf.prefetchedRefs then
return self.conf.prefetchedRefs
end
if claim.references then
return self.conf.states[parameters.reference]:iterate(claim.references, {[parameters.general] = hookNames[parameters.reference][2], count = 1}) -- pass reference state with level 2 hook
else
return {}
end
end
Line 1,778 ⟶ 1,501:
local value = ""
local ref = {}
local version = 1
if statement.snaks then
if statement.snaks[aliasesP.importedFrom] then
end
if statement.snaks[aliasesP.inferredFrom] then
end
if statement.snaks[aliasesP.typeOfReference] then
end
if statement.snaks[aliasesP.image] then
end
if self:getReferenceDetail(statement.snaks, aliasesP.language) == self.conf.langName then
end
for i in pairs(statement.snaks) do
label = ""
if i == aliasesP.author then
params[i] = self:getReferenceDetails(statement.snaks, i, false, self.linked, true) -- link = true/false, anyLang = true
else
params[i] = {self:getReferenceDetail(statement.snaks, i, false, (self.linked or (i ==
end
if #params[i] == 0 then
params[i] = nil
Line 1,824 ⟶ 1,540:
key = "external-id"
label = self.conf:getLabel(i)
if label ~= "" then
label = label .. " "
Line 1,831 ⟶ 1,547:
key = i
end
for j in pairs(citeParams) do
if not citeMismatch[j] then
if i18n['cite'][j][key] then
if i18n['cite'][j][key] ~= "" then
citeParams[j][i18n['cite'][j][key]] = label .. params[i][1]
for k=2, #params[i] do
citeParams[j][i18n['cite'][j][key]..k] = label .. params[i][k]
Line 1,854 ⟶ 1,565:
end
end
citeWeb = split(mw.wikibase.getSitelink(aliasesQ.citeWeb) or "", ":")[2]
citeQ = split(mw.wikibase.getSitelink(aliasesQ.citeQ) or "", ":")[2]
if citeWeb and not citeMismatch['web'] and citeParams['web'][i18n['cite']['web'][aliasesP.referenceURL]] and citeParams['web'][i18n['cite']['web'][aliasesP.title]] then
useCite = citeWeb
useParams = citeParams['web']
elseif citeQ and not citeMismatch['q'] and citeParams['q'][i18n['cite']['q'][aliasesP.statedIn]] then
useCite = citeQ
useParams = citeParams['q']
end
if useCite and useParams then
if mw.isSubsting() then
for i, v in pairs(useParams) do
value = value .. "|" .. i .. "=" .. v
end
value = "{{" .. useCite .. value .. "}}"
else
value = mw.getCurrentFrame():expandTemplate{title=useCite, args=useParams}
end
elseif params[aliasesP.statedIn] or params[aliasesP.referenceURL] or params[aliasesP.title] then
citeParams['default'] = {}
if params[aliasesP.author] and #params[aliasesP.author] > 0 then
end
if params[aliasesP.referenceURL] and params[aliasesP.title] then
end
if params[aliasesP.statedIn] then
end
params[aliasesP.author] = nil
params[
params[
params[
for i, v in pairs(params) do
i = self.conf:getLabel(i)
if i ~= "" then
citeParams['default'][#citeParams['default'] + 1] = i .. ": " .. v[1]
end
end
value = table.concat(citeParams['default'], "; ")
if value ~= "" then
value = value .. "."
end
end
if value ~= "" then
value = {value} -- create one value object
if not self.rawValue then
value.refHash = "pornbasedata-" .. statement.hash .. "-v" .. (tonumber(i18n['cite']['version']) + version)
end
ref = {value}
end
end
return ref
end
function State:getReferenceDetail(snaks, dType, raw, link, anyLang)
local switchLang = anyLang
local value = nil
if not snaks[dType] then
return nil
end
repeat
for
value = self.conf:getValue(v, raw, link, false, anyLang and not switchLang, false, true) -- noSpecial = true
if value then
break
end
end
if value or not anyLang then
break
end
switchLang = not switchLang
until anyLang and switchLang
return value
end
function State:getReferenceDetails(snaks, dType, raw, link, anyLang)
local values = {}
if not snaks[dType] then
return {}
end
for
values[#values + 1] = self.conf:getValue(v, raw, link, false, anyLang, false, true) -- noSpecial = true
end
return values
end
function State:getAlias(object)
local value = object.value
local title = nil
if value and self.linked then
if self.conf.entityID:sub(1,1) == "Q" then
title = mw.wikibase.
elseif self.conf.entityID:sub(1,1) == "P" then
title = "
end
if title then
value = buildWikilink(title, value)
end
end
value = {value}
if #value > 0 then
return {value}
else
return {}
end
end
function State:getBadge(value)
value = self.conf:getLabel(value, self.rawValue, self.linked, self.shortName)
if value == "" then
value = nil
end
value = {value}
if #value > 0 then
return {value}
else
return {}
end
end
Line 2,037 ⟶ 1,729:
function State:callHook(param, hooks, statement, result)
local valuesArray, refHash
if not result[param] and hooks[param] then
valuesArray = self[hooks[param]](self, statement, param, result, hooks)
if #valuesArray > 0 then
result[param] = valuesArray
result.count = result.count + 1
else
result[param] = {}
return
end
end
return false
end
function State:iterate(statements, hooks, matchHook)
matchHook = matchHook or alwaysTrue
local matches = false
local rankPos = nil
local result, gotRequired
for
matches, rankPos = matchHook(self, v)
if matches then
result = {count = 0}
local function walk(formatTable)
local miss
for i2, v2 in pairs(formatTable.req) do
miss = self:callHook(i2, hooks, v, result)
if miss then
return false
end
if result.count == hooks.count then
return true
end
end
for
if result.count == hooks.count then
return true
end
if v2.child then
walk(v2.child)
end
end
return true
end
gotRequired = walk(self.parsedFormat)
if gotRequired then
if rankPos and self.conf.foundRank > rankPos then
self.conf.foundRank = rankPos
end
self.results[#self.results + 1] = result
if self.singleValue then
break
Line 2,122 ⟶ 1,800:
end
end
return self:out()
end
local function getEntityId(arg, eid, page, allowOmitPropPrefix)
if arg then
page = arg
eid = nil
elseif arg:sub(1,1):upper() == "Q" or arg:sub(1,9):lower() == "property:" or allowOmitPropPrefix then
eid = arg
else
prop = arg
end
end
if eid then
if eid:sub(1,9):lower() == "property:" then
id = replaceAlias(mw.text.trim(eid:sub(10)))
if id:sub(1,1):upper() ~= "P" then
id = ""
end
else
id = replaceAlias(eid)
end
elseif page then
if page:sub(1,1) == ":" then
page = mw.text.trim(page:sub(2))
end
id = mw.wikibase.getEntityIdForTitle(page) or ""
end
if not id then
id = mw.wikibase.getEntityIdForCurrentPage() or ""
end
id = id:upper()
if not mw.wikibase.isValidEntityId(id) then
id = ""
end
return id, prop
end
local function nextArg(args)
local arg = args[args.pointer]
if arg then
args.pointer = args.pointer + 1
Line 2,151 ⟶ 1,862:
end
local function claimCommand(args, funcName)
local
local lastArg, parsedFormat, formatParams, claims, value
local hooks = {count = 0}
if args[p.args.date] then
cfg.atDate = {parseDate(args[p.args.date])}
cfg.periods = {false, true, false}
end
repeat
lastArg = nextArg(args)
until not
cfg.entityID, cfg.propertyID = getEntityId(lastArg, args[p.args.eid], args[p.args.page])
if cfg.entityID == "" then
return ""
end
if not cfg.propertyID then
cfg.propertyID = nextArg(args)
end
if not
return ""
end
if not cfg.entity.claims or not cfg.entity.claims[cfg.propertyID] then
return ""
end
claims = cfg.entity.claims[cfg.propertyID]
if cfg.states.qualifiersCount > 0 then
if #args - args.pointer + 1 > cfg.states.qualifiersCount then
cfg.propertyValue = nextArg(args)
end
for i = 1,
cfg.qualifierIDs[parameters.qualifier..i] = replaceAlias(nextArg(args) or ""):upper()
end
elseif
cfg.propertyValue = nextArg(args)
end
if cfg.propertyValue then
if cfg.propertyValue ~= "" and mw.text.trim(cfg.propertyValue) == "" then
else
end
end
-- parse the desired format, or choose an appropriate format
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
elseif
if
parsedFormat, formatParams = parseFormat(formats.propertyWithQualifier)
else
parsedFormat, formatParams = parseFormat(formats.qualifier)
end
elseif
parsedFormat, formatParams = parseFormat(formats.property)
else
parsedFormat, formatParams = parseFormat(formats.reference)
end
if cfg.states.qualifiersCount > 0 and not cfg.states[parameters.property] then
cfg.separators["sep"..parameters.separator][1] = {";"}
end
if cfg.states[parameters.reference] and not cfg.states[parameters.property] and cfg.states.qualifiersCount == 0
cfg.separators["sep"][1] = nil
end
if cfg.states.qualifiersCount == 1 then
cfg.separators["sep"..parameters.qualifier] = cfg.separators["sep"..parameters.qualifier.."1"]
end
cfg:processSeparators(args)
for i, v in pairs(cfg.states) do
if formatParams[i] or formatParams[i:sub(1, 2)] then
hooks[i] = getHookName(i, 1)
Line 2,270 ⟶ 1,965:
end
end
if formatParams[parameters.qualifier] and cfg.states.qualifiersCount > 0 then
hooks[parameters.qualifier] = getHookName(parameters.qualifier, 1)
hooks.count = hooks.count + 1
end
if not cfg.states[parameters.property] then
cfg.states[parameters.property] = State:new(cfg, parameters.property)
if cfg.singleClaim then
cfg.states[parameters.property].singleValue = true
end
end
if cfg.sourcedOnly and not cfg.states[parameters.reference] then
cfg:processFlagOrCommand(p.claimCommands.reference)
end
cfg:setFormatAndSeparators(cfg.states[parameters.property], parsedFormat)
for i, v in pairs(args) do
i = tostring(i)
if i:match('^[Pp]%d+$') or
v = replaceSpecialChars(v)
if v ~= "" and mw.text.trim(v) == "" then
v = " "
end
end
end
claims = sortOnRank(claims)
value = cfg:concatValues(cfg.states[parameters.property]:iterate(claims, hooks, State.claimMatches))
if cfg.editable and value ~= "" then
value = value .. cfg:getEditIcon()
end
return value
end
local function generalCommand(args, funcName)
local
local lastArg
local value = nil
repeat
lastArg = nextArg(args)
until not
cfg.entityID = getEntityId(lastArg, args[p.args.eid], args[p.args.page], true)
if cfg.entityID == "" or not mw.wikibase.entityExists(cfg.entityID) then
return ""
end
if funcName == p.generalCommands.label then
value =
elseif funcName == p.generalCommands.title then
if
value = mw.wikibase.
end
if
value = buildWikilink(value)
end
elseif funcName == p.generalCommands.description then
else
local parsedFormat, formatParams
local hooks = {count = 0}
cfg.entity = mw.wikibase.getEntity(cfg.entityID)
if funcName == p.generalCommands.alias or funcName == p.generalCommands.badge then
end
if funcName == p.generalCommands.alias or funcName == p.generalCommands.aliases then
if not
return ""
end
local aliases =
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
Line 2,403 ⟶ 2,063:
parsedFormat, formatParams = parseFormat(formats.alias)
end
cfg:processSeparators(args)
if formatParams[parameters.alias] then
hooks[parameters.alias] = getHookName(parameters.alias, 1)
hooks.count = hooks.count + 1
end
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
value = cfg:concatValues(cfg.curState:iterate(aliases, hooks))
elseif funcName == p.generalCommands.badge or funcName == p.generalCommands.badges then
if not
return ""
end
local badges =
if args["format"] then
parsedFormat, formatParams = parseFormat(args["format"])
Line 2,435 ⟶ 2,088:
parsedFormat, formatParams = parseFormat(formats.badge)
end
cfg:processSeparators(args)
if formatParams[parameters.badge] then
hooks[parameters.badge] = getHookName(parameters.badge, 1)
hooks.count = hooks.count + 1
end
cfg:setFormatAndSeparators(cfg.curState, parsedFormat)
value = cfg:concatValues(cfg.curState:iterate(badges, hooks))
end
end
value = value or ""
if
value = value .. cfg:getEditIcon()
end
return value
end
local function establishCommands(commandList, commandFunc)
for _, commandName in pairs(commandList) do
local function wikitextWrapper(frame)
local args = copyTable(frame.args)
args.pointer = 1
return commandFunc(args, commandName)
end
p[commandName] = wikitextWrapper
local function luaWrapper(args)
args = copyTable(args)
args.pointer = 1
loadI18n(aliasesP)
return commandFunc(args, commandName)
end
p["_" .. commandName] = luaWrapper
end
end
Line 2,489 ⟶ 2,134:
establishCommands(p.generalCommands, generalCommand)
function p.main(frame)
if not mw.wikibase then return nil end
local f, args
loadI18n(aliasesP, frame)
frame = frame:getParent() or frame
if not frame.args[1] then
throwError("no-function-specified")
end
f = mw.text.trim(frame.args[1])
if f == "main" then
throwError("main-called-twice")
end
assert(p["_"..f], errorText('no-such-function', f))
args = copyTable(frame.args)
table.remove(args, 1)
return p["_"..f](args)
end
| |||