「モジュール:Wd」の版間の差分

en:Module:Wd 2016年12月10日 (土) 18:20‎(UTC)より
template>K-iczn
(en:Module:Wd 2016年11月28日 (月) 17:09‎(UTC)より)
 
template>K-iczn
(en:Module:Wd 2016年12月10日 (土) 18:20‎(UTC)より)
2行目: 2行目:


local aliasesP = {
local aliasesP = {
coord     = "P625",
author          = "P50",
startTime = "P580",
publisher      = "P123",
endTime   = "P582",
importedFrom    = "P143",
shortName = "P1813"
statedIn        = "P248",
coord           = "P625",
publicationDate = "P577",
startTime       = "P580",
endTime         = "P582",
retrieved      = "P813",
referenceURL    = "P854",
archiveURL      = "P1065",
title          = "P1476",
quote          = "P1683",
shortName       = "P1813",
language        = "P2439",
archiveDate    = "P2960"
}
}


32行目: 44行目:
stt.period = 0
stt.period = 0
stt.linked = false
stt.propertyWithQualifier = false
stt.propertyWithQualifier = false
stt.pageTitle = false
stt.withUnit = false
stt.linked = false
stt.rawValue = false
stt.shortName = false
stt.shortName = false
stt.singleValue = false
stt.singleValue = false
stt.mdyDate = false
stt.withRefs = false
stt.langCode = mw.language.getContentLanguage().code
stt.langCode = mw.language.getContentLanguage().code
stt.langName = mw.language.fetchLanguageName(stt.langCode, stt.langCode)
stt.langObj = mw.language.new(stt.langCode)
stt.langObj = mw.language.new(stt.langCode)
133行目: 149行目:
end
end


function State:convertUnit(unit, addLink)
function State:convertUnit(unit, link)
addLink = addLink or false
link = link or false
local itemID, label, target
local itemID, label, title
if unit == "" or unit == "1" then
if unit == "" or unit == "1" then
148行目: 164行目:
else
else
label = mw.wikibase.label(itemID)
label = mw.wikibase.label(itemID)
target = nil
title = nil
if addLink or label == nil then
if link or label == nil then
target = mw.wikibase.sitelink(itemID)
title = mw.wikibase.sitelink(itemID)
end
end
if addLink then
if link then
if target then
if title then
return " " .. "[[" .. target .. "|" .. (label or target) .. "]]"
return " " .. "[[" .. title .. "|" .. (label or title) .. "]]"
end
end
if not label then
if not label then
return " " .. "[[:d:" .. itemID .. "|" .. itemID .. "]]"
return " " .. "[[d:" .. itemID .. "|" .. itemID .. "]]"
end
end
end
end
return " " .. (label or target or itemID)
return " " .. (label or title or itemID)
end
end
end
end
173行目: 189行目:
function State:getShortName(itemID)
function State:getShortName(itemID)
return p._property({"single", itemID, aliasesP.shortName})
return p._property({"single", itemID, aliasesP.shortName})
end
function State:getLabel(ID)
return p._label({ID})
end
end


193行目: 213行目:
end
end


function State:getValue(snak, addUnit, addLink)
function State:addDecimalMarks(n)
addUnit = addUnit or false
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
addLink = addLink or false
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
 
function State:getValue(snak, raw, link, anyLang)
raw = raw or false
link = link or false
anyLang = anyLang or false
if snak.snaktype == 'value' then
if snak.snaktype == 'value' then
201行目: 227行目:
return snak.datavalue.value
return snak.datavalue.value
elseif snak.datavalue.type == 'monolingualtext' then
elseif snak.datavalue.type == 'monolingualtext' then
if snak.datavalue.value['language'] == self.langCode then
if anyLang then
return snak.datavalue.value['text'], snak.datavalue.value['language']
elseif snak.datavalue.value['language'] == self.langCode then
return snak.datavalue.value['text']
return snak.datavalue.value['text']
else
else
210行目: 238行目:
local value = mw.ustring.gsub(snak.datavalue.value['amount'], "^\+(.+)$", "%1")
local value = mw.ustring.gsub(snak.datavalue.value['amount'], "^\+(.+)$", "%1")
if addUnit then
if not raw then
local unit = self:convertUnit(snak.datavalue.value['unit'], addLink)
value = self:addDecimalMarks(value)
local unit = self:convertUnit(snak.datavalue.value['unit'], link)
if unit then
if unit then
value = value .. unit
value = value .. unit
219行目: 248行目:
return value
return value
elseif snak.datavalue.type == 'time' then
elseif snak.datavalue.type == 'time' then
local y, m, d, p, yDiv, yRound, yFull, value, calendarID
local y, m, d, p, yDiv, yRound, yFull, value, calendarID, dateStr
local yFactor = 1
local yFactor = 1
local sign = 1
local sign = 1
255行目: 284行目:
yRound = math.ceil(yDiv)
yRound = math.ceil(yDiv)
if addUnit then
if not raw then
if precision == 6 then
if precision == 6 then
suffix = "千年紀"
suffix = " millennium"
else
else
suffix = "世紀"
suffix = " century"
end
end
suffix = self:getOrdinalSuffix(yRound) .. suffix
suffix = self:getOrdinalSuffix(yRound) .. suffix
else
else
-- if no unit added, take the first year of the century/millennium
-- if not verbose, take the first year of the century/millennium
-- (e.g. 1901 for 20th century or 2001 for 3rd millennium)
-- (e.g. 1901 for 20th century or 2001 for 3rd millennium)
yRound = (yRound - 1) * yFactor + 1
yRound = (yRound - 1) * yFactor + 1
273行目: 302行目:
yRound = math.floor(yDiv) * yFactor
yRound = math.floor(yDiv) * yFactor
if addUnit then
if not raw then
suffix = ""
suffix = "s"
end
end
end
end
if not addUnit and sign < 0 then
if raw and sign < 0 then
-- if BCE then compensate for "counting backwards"
-- if BCE then compensate for "counting backwards"
-- (e.g. -2019 for 2010s BCE, -2000 for 20th century BCE or -3000 for 3rd millennium BCE)
-- (e.g. -2019 for 2010s BCE, -2000 for 20th century BCE or -3000 for 3rd millennium BCE)
376行目: 405行目:
end
end
if addUnit then
if not raw then
local ce = nil
local ce = nil
386行目: 415行目:
if ce then
if ce then
if addLink then
if link then
ce = "[[:en:Common Era|" .. ce .. "]]"
ce = "[[:en:Common Era|" .. ce .. "]]"
end
end
395行目: 424行目:
if m then
if m then
value = self.langObj:formatDate("F", "1-"..m.."-1") .. " " .. value
dateStr = self.langObj:formatDate("F", "1-"..m.."-1")
if d then
if d then
value = d .. " " .. value
if self.mdyDate then
dateStr = dateStr .. " " .. d .. ","
else
dateStr = d .. " " .. dateStr
end
end
end
value = dateStr .. " " .. value
end
end
430行目: 465行目:
local partsGlue = ", "
local partsGlue = ", "
if not addUnit then
if raw then
degSymbol = "/"
degSymbol = "/"
minSymbol = "/"
minSymbol = "/"
492行目: 527行目:
value = latValue .. partsGlue .. lonValue
value = latValue .. partsGlue .. lonValue
if addLink then
if link then
globe = self:parseWikidataURL(snak.datavalue.value['globe'])
globe = self:parseWikidataURL(snak.datavalue.value['globe'])
507行目: 542行目:
elseif snak.datavalue.type == 'wikibase-entityid' then
elseif snak.datavalue.type == 'wikibase-entityid' then
local value = ""
local value = ""
local target = nil
local title = nil
local itemID = "Q" .. snak.datavalue.value['numeric-id']
local itemID = "Q" .. snak.datavalue.value['numeric-id']
if raw then
if link then
return "[[d:" .. itemID .. "|" .. itemID .. "]]"
else
return itemID
end
end
if self.shortName then
if self.shortName then
518行目: 561行目:
end
end
if addLink or value == nil then
if link or value == nil then
target = mw.wikibase.sitelink(itemID)
title = mw.wikibase.sitelink(itemID)
end
end
if addLink then
if link then
if target then
if title then
value = "[[" .. target .. "|" .. (value or target) .. "]]"
value = "[[" .. title .. "|" .. (value or title) .. "]]"
elseif not value then
elseif not value then
value = "[[:d:" .. itemID .. "|" .. itemID .. "]]"
value = "[[d:" .. itemID .. "|" .. itemID .. "]]"
end
end
elseif not value then
elseif not value then
value = (target or itemID)
value = (title or itemID)
end
end
537行目: 580行目:
end
end
elseif snak.snaktype == 'somevalue' then
elseif snak.snaktype == 'somevalue' then
return "unknown"
if raw then
return " "  -- single space represents 'somevalue'
else
return "unknown"
end
elseif snak.snaktype == 'novalue' then
elseif snak.snaktype == 'novalue' then
return "none"
if raw then
return ""  -- empty value represents 'novalue'
else
return "none"
end
else
else
return nil
return nil
end
end
function State:getRawValue(snak)
if snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then
return "Q" .. snak.datavalue.value['numeric-id']
elseif snak.snaktype == 'somevalue' then
return " "  -- single space represents 'somevalue'
elseif snak.snaktype == 'novalue' then
return ""  -- empty value represents 'novalue'
else
return self:getValue(snak, false, false)
end
end
end
end
563行目: 602行目:
if qualifiers and qualifiers[1] then
if qualifiers and qualifiers[1] then
return self:getRawValue(qualifiers[1])
return self:getValue(qualifiers[1], true) -- raw = true
else
else
return nil
return nil
570行目: 609行目:


function State:snakEqualsValue(snak, value)
function State:snakEqualsValue(snak, value)
local snakValue = self:getRawValue(snak)
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
if snakValue and snak.snaktype == 'value' and snak.datavalue.type == 'wikibase-entityid' then value = value:upper() end
690行目: 729行目:
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
startTime = self:getSingleRawQualifier(claim, aliasesP.startTime)
if startTime ~= "" and startTime ~= " " then
if startTime and startTime ~= "" and startTime ~= " " then
startTimeY, startTimeM, startTimeD = self:parseDate(startTime)
startTimeY, startTimeM, startTimeD = self:parseDate(startTime)
end
end
endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
endTime = self:getSingleRawQualifier(claim, aliasesP.endTime)
if endTime ~= "" and endTime ~= " " then
if endTime and endTime ~= "" and endTime ~= " " then
endTimeY, endTimeM, endTimeD = self:parseDate(endTime)
endTimeY, endTimeM, endTimeD = self:parseDate(endTime)
elseif endTime == " " then
elseif endTime == " " then
799行目: 838行目:
return out
return out
end
-- logic based on https://www.wikidata.org/wiki/Help:Sources
function State:getReferences(claim)
local snaks, snakValue, lang, params, leadParams, property, ref
local value = ""
if not claim.references then
return ""
end
for i, v in ipairs(claim.references) do
if v.snaks then
ref = ""
snaks = {}
params = {}
leadParams = {}
for i2, v2 in pairs(v.snaks) do
if v2[1] then
snaks[i2] = v2[1]
end
end
if snaks[aliasesP.importedFrom] then
snaks[aliasesP.importedFrom] = nil
end
if snaks[aliasesP.referenceURL] and snaks[aliasesP.title] then
params["url"] = self:getValue(snaks[aliasesP.referenceURL])
params["title"] = self:getValue(snaks[aliasesP.title], false, false, true)
if snaks[aliasesP.publicationDate] then params["date"]        = self:getValue(snaks[aliasesP.publicationDate])          end
if snaks[aliasesP.retrieved]      then params["access-date"]  = self:getValue(snaks[aliasesP.retrieved])                end
if snaks[aliasesP.archiveURL]      then params["archive-url"]  = self:getValue(snaks[aliasesP.archiveURL])                end
if snaks[aliasesP.archiveDate]    then params["archive-date"] = self:getValue(snaks[aliasesP.archiveDate])              end
if snaks[aliasesP.author]          then params["author"]      = self:getValue(snaks[aliasesP.author])                    end
if snaks[aliasesP.publisher]      then params["publisher"]    = self:getValue(snaks[aliasesP.publisher])                end
if snaks[aliasesP.quote]          then params["quote"]        = self:getValue(snaks[aliasesP.quote], false, false, true) end
if snaks[aliasesP.language] then
snakValue = self:getValue(snaks[aliasesP.language])
if self.langName ~= snakValue then
params["language"] = snakValue
end
end
ref = mw.getCurrentFrame():expandTemplate{title="cite_web", args=params}
else
for i2, v2 in pairs(snaks) do
property = self:getLabel(i2)
if property ~= "" then
snakValue, lang = self:getValue(v2, false, (i2 == aliasesP.statedIn), true)
if lang and lang ~= self.langCode then
snakValue = "''" .. snakValue .. "'' (" .. mw.language.fetchLanguageName(lang, self.langCode) .. ")"
end
if i2 == aliasesP.referenceURL or i2 == aliasesP.statedIn then
leadParams[#leadParams + 1] = snakValue
elseif i2 ~= aliasesP.language or self.langName ~= snakValue then
params[#params + 1] = property .. ": " .. snakValue
end
end
end
ref = table.concat(leadParams, "; ")
params = table.concat(params, "; ")
if params ~= "" then
if ref ~= "" then
ref = ref .. "; "
end
ref = ref .. params
end
if ref ~= "" then
ref = ref .. "."
end
end
if ref ~= "" then
value = value .. mw.getCurrentFrame():extensionTag("ref", ref)
end
end
end
return value
end
end


805行目: 934行目:
self.linked = true
self.linked = true
return true
return true
elseif flag == "unit" then
elseif flag == "raw" then
self.withUnit = true
self.rawValue = true
return true
return true
elseif flag == "short" then
elseif flag == "short" then
813行目: 942行目:
elseif flag == "single" then
elseif flag == "single" then
self.singleValue = true
self.singleValue = true
return true
elseif flag == "mdy" then
self.mdyDate = true
return true
elseif flag == "refs" then
self.withRefs = true
return true
return true
elseif flag == "best" or flag:match('^preferred[+-]?$') or flag:match('^normal[+-]?$') or flag:match('^deprecated[+-]?$') then
elseif flag == "best" or flag:match('^preferred[+-]?$') or flag:match('^normal[+-]?$') or flag:match('^deprecated[+-]?$') then
835行目: 970行目:
end
end


function p._property(args)
function p._property(args, _)
local _ = State.new()
_ = _ or State.new()
local entity, propertyID, claims, rankPos, value, done
local entity, propertyID, claims, rankPos, value, done
866行目: 1,001行目:
rankPos = _:convertRank(v.rank)
rankPos = _:convertRank(v.rank)
if _:rankMatches(rankPos) and _:timeMatches(v) then
if _:rankMatches(rankPos) and _:timeMatches(v) then
value = _:getValue(v.mainsnak, _.withUnit, _.linked)
value = _:getValue(v.mainsnak, _.rawValue, _.linked)
if value then
if value then
if _.withRefs then
value = value .. _:getReferences(v)
end
done = _:appendOutput(value, rankPos)
done = _:appendOutput(value, rankPos)
if done then
if done then
955行目: 1,093行目:
if _.propertyWithQualifier then
if _.propertyWithQualifier then
-- get the property value first
-- get the property value first
outValue = _:getValue(v.mainsnak, _.withUnit, _.linked)
outValue = _:getValue(v.mainsnak, _.rawValue, _.linked)
if outValue and _.withRefs then
outValue = outValue .. _:getReferences(v)
end
end
end
962行目: 1,104行目:
-- get a bare qualifier, or the qualifiers connected to the property if it had a value
-- get a bare qualifier, or the qualifiers connected to the property if it had a value
for i2, v2 in ipairs(qualifiers) do
for i2, v2 in ipairs(qualifiers) do
outInter = _:getValue(v2, _.withUnit, _.linked)
outInter = _:getValue(v2, _.rawValue, _.linked)
if outInter then
if outInter then
if not _.propertyWithQualifier then
if not _.propertyWithQualifier then
1,003行目: 1,145行目:
end
end


function p._propertyWithQualifier(args)
function p._propertyWithQualifier(args, _)
local _ = State.new()
_ = _ or State.new()
_.propertyWithQualifier = true
_.propertyWithQualifier = true
_.withUnit = true
return p._qualifier(args, _)
return p._qualifier(args, _)
end
end
1,014行目: 1,155行目:
end
end


function p._label(args)
function p._label(args, _)
local _ = State.new()
_ = _ or State.new()
local ID
local label = ""
local label = ""
local target = ""
local title = nil
local nextArg = mw.text.trim(args[1] or "")
local nextArg = mw.text.trim(args[1] or "")
local nextIndex = 2
local nextIndex = 2
1,027行目: 1,170行目:
end
end
if nextArg then
ID = nextArg
if nextArg:sub(1,1):upper() == "Q" then
if _.shortName then
if ID ~= "" then
label = _:getShortName(nextArg)
if aliasesP[ID] then
ID = aliasesP[ID]
end
ID = ID:upper()
-- check if this is a valid ID, and if the number is not larger than max int (to prevent error)
if not string.match(ID, '^[QP]%d+$') or tonumber(string.match(ID, '%d+')) > 2147483647 then
return ""
end
if _.rawValue then
if mw.wikibase.getEntity(ID) or mw.wikibase.resolvePropertyId(ID) then
if _.linked then
if ID:sub(1,1) == "P" then
label = "[[d:Property:" .. ID .. "|" .. ID .. "]]"
else
label = "[[d:" .. ID .. "|" .. ID .. "]]"
end
else
label = ID
end
end
else
if ID:sub(1,1) == "P" then
if not _.pageTitle then
label = mw.wikibase.label(ID) or ""
if _.linked and label ~= "" then
label = "[[d:Property:" .. ID .. "|" .. label .. "]]"
end
end
else
if not _.pageTitle then
if _.shortName then
label = _:getShortName(ID)
end
-- at this point, 'label' will be a string and not nil
if label == "" then
label = mw.wikibase.label(ID)
end
else
-- set 'label' to nil so 'title' will always prevail
label = nil
end
-- at this point, 'label' will be nil or a non-empty string
if _.linked or label == nil then
title = mw.wikibase.sitelink(ID)
end
if _.linked and title then
label = "[[" .. title .. "|" .. (label or title) .. "]]"
else
label = label or title or ""
end
end
end
end
else
if _.rawValue then
label = mw.wikibase.getEntityIdForCurrentPage() or ""
if label == "" then
if _.linked and label ~= "" then
label = mw.wikibase.label(nextArg)
label = "[[d:" .. label .. "|" .. label .. "]]"
end
else
if not _.pageTitle then
label = mw.wikibase.label()
else
-- set 'label' to nil so 'title' will always prevail
label = nil
end
end
if _.linked or label == nil then
if _.linked or label == nil then
target = mw.wikibase.sitelink(nextArg)
title = mw.title.getCurrentTitle().prefixedText
end
end
if _.linked and target then
if _.linked then
label = "[[" .. target .. "|" .. (label or target) .. "]]"
label = "[[" .. title .. "|" .. (label or title) .. "]]" -- not much use since it links to the current page, but does add wiki mark-up
else
label = label or title
end
end
else
label = mw.wikibase.label(nextArg)
end
end
return (label or target)
else
return mw.wikibase.label()
end
end
return label
end
function p.title(frame)
return p._title(frame.args)
end
function p._title(args, _)
_ = _ or State.new()
_.pageTitle = true
return p._label(args, _)
end
end


匿名利用者