Modul:Wikidata/chronology
Bu modul istifadəyə hazır olaraq dəyərləndirilib. Bütün səhvlərin düzəldildiyi və geniş istifadəyə hazır olduğu güman edilir. Modul kömək səhifələrində göstərilə və yeni üzvlərin istifadəsi üçün tövsiyə edilə bilər. Modulu dəyişdirmək və ya sınamaq üçün zəhmət olmasa qaralama səhifəsindən istifadə edin. |
local p = {} -- p stands for package
-- technical functions for takeAdjacentNumbersFromStrings
function isYear(number) -- TODO: settings not hardcoded
return number >= 1800 and number <= 2100
end
function isAr(number)
return number >= 0 and number < 100
end
function notTooFar(number1, number2, maximalPeriod)
return number2 - number1 > 0 and number2 - number1 <= maximalPeriod
end
-- takes two strings and returns either two substrings that form the only difference between them or nil
-- considers several possible formats of substrings given in options.formats
function takeAdjacentNumbersFromStrings(options, string1, string2)
if type(string1) == 'string' and type(string2) == 'string' then
local formats = options.formats or '' -- TODO: not repeat with properties
if formats == '' then
formats = 'year, year/ar, year/year'
elseif formats == '-' then
formats = ''
end
local formats = mw.text.split(formats, ', ?')
local line = '!' .. string1 .. '!!' .. string2.. '!' -- -- TODO: without hacks
local maximalPeriod = tonumber(options.maximalPeriod) or 5 -- TODO: here or in main function?
for _, format in pairs(formats) do
if format == 'year' or format == 'number' then
local match = {mw.ustring.match(line, '^(.*%D)(%d+)(%D.*)%1(%d+)%3$')}
if #match > 0 then
local number1 = tonumber(match[2])
local number2 = tonumber(match[4])
if notTooFar(number1, number2, maximalPeriod) then
if (format == 'year' and isYear(number1) and isYear(number2))
or (format == 'number')
then
return {number1, number2}
end
end
end
elseif format == 'year/ar' or format == 'year/year' then
local match = {mw.ustring.match(line, '^(.*%D)((%d+)[-–\/](%d+))(%D.*)%1((%d+)\/(%d+))%5$')}
if #match > 0 then
local period1 = match[2]
local period1_start = tonumber(match[3])
local period1_end = tonumber(match[4])
local period2 = match[6]
local period2_start = tonumber(match[7])
local period2_end = tonumber(match[8])
if notTooFar(period1_start, period2_start, maximalPeriod) and isYear(period1_start) and isYear(period2_start)
and period2_start - period1_start == period2_end - period1_end
then
if (format == 'year/ar' and isAr(period1_end) and isAr(period2_end))
or (format == 'year/year' and isYear(period1_end) and isYear(period2_end))
then
return {period1, period2}
end
end
end
end
end
end
return nil
end
-- takes two Wikidata entities and returns either two strings or nil
-- considers sitelinks and labels in the local langauge and in English
function takeAdjacentNumbersFromEntities(options, entity1, entity2)
if entity1 and entity2 then
local adjacentNumbers = nil
local languageCodes = {mw.getContentLanguage():getCode(), 'en'}
for _, languageCode in pairs(languageCodes) do
local wikiCode = languageCode .. 'wiki'
local sitelink1 = entity1:getSitelink(wikiCode)
local sitelink2 = entity2:getSitelink(wikiCode)
adjacentNumbers = takeAdjacentNumbersFromStrings(options, sitelink1, sitelink2)
if adjacentNumbers then
return adjacentNumbers
end
local label1 = entity1:getLabel(languageCode) -- TODO: get rid of fallback?
local label2 = entity2:getLabel(languageCode)
adjacentNumbers = takeAdjacentNumbersFromStrings(options, label1, label2)
if adjacentNumbers then
return adjacentNumbers
end
end
end
return nil
end
function formatAdjacentSnak(context, options, snak)
local direction = options.direction or ''
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.id then
local mainText = nil
local adjacentEntity = mw.wikibase.getEntity(snak.datavalue.value.id)
if direction == 'P155' then -- previous
local adjacentNumbers = takeAdjacentNumbersFromEntities(options, adjacentEntity, options.entity) -- or reverse order
if adjacentNumbers then
mainText = adjacentNumbers[1] -- or 2
end
elseif direction == 'P156' then -- next
local adjacentNumbers = takeAdjacentNumbersFromEntities(options, options.entity, adjacentEntity)
if adjacentNumbers then
mainText = adjacentNumbers[2]
end
end
-- options should not be changed, as they are reused for P155 and P156
local optionsCopy = {}
for k, v in pairs(options) do
optionsCopy[k] = v
end
if (not optionsCopy.text) and mainText then
local prefix = options.prefix or ''
local postfix = options.postfix or ''
optionsCopy.text = prefix .. mainText .. postfix
end
local link = context.formatSnak(optionsCopy, snak)
if mainText or (options.formats and options.formats == '-') then
return link
else
if link ~= nil then
return link .. '[[Kateqoriya:Vikipediya:Xronologiya xətası olan məqalələr]]'
end
end
end
return nil
end
-- function is available from outside, see documentation
function p.formatAdjacentProperty(context, options)
if (not context) then error('context not specified'); end;
if (not options) then error('options not specified'); end;
if (not options.entity) then error('options.entity missing'); end;
if options.value == '-' then
return ''
end
if options.value then
return options.value
end
local properties = options.property or '' -- TODO: properties vs. property?
if properties == '' then
properties = 'Q'
elseif properties == '-' then
properties = ''
end
local properties = mw.text.split(properties, ', ?')
local direction = options.direction or '' -- TODO: not repeating inside
local formattedClaims = {}
for _, property in pairs(properties) do
if property == 'Q' then
local claims = context.selectClaims(options, direction)
if claims then
for _, claim in pairs(claims) do
if claim.mainsnak then
local link = formatAdjacentSnak(context, options, claim.mainsnak)
if link and link ~= '' then
local formattedClaim = '<span class="wikidata-claim" data-wikidata-property-id="' .. direction .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. link .. '</span>'
table.insert(formattedClaims, formattedClaim)
end
end
end
end
elseif mw.ustring.match(property, '^P%d+$') then
local claims = context.selectClaims(options, property)
if claims then
for _, claim in pairs(claims) do
if claim.qualifiers and claim.qualifiers[direction] then
for _, snak in pairs(claim.qualifiers[direction]) do
local link = formatAdjacentSnak(context, options, snak)
if link and link ~= '' then
local formattedClaim = '<span class="wikidata-claim" data-wikidata-property-id="' .. property .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. link .. '</span>'
table.insert(formattedClaims, formattedClaim)
end
end
end
end
end
end
end
-- from wikidata.selectClaims
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber(options.limit, 10);
while #formattedClaims > limit do
table.remove(formattedClaims);
end
end
-- from wikidata.formatPropertyDefault
local out = mw.text.listToText(formattedClaims, options.separator, options.conjunction)
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
return p