Mòdul:Authority control/proves
Aparença
Podeu crear la pàgina d'ús per documentar aquest mòdul Lua. |
local p = {}
-- ============ Format validation functions ============
local valid = {}
-- NCDA: NOID Check Digit Algorithm; see [[wikipedia:Check digit#NCDA]]
local ncda -- leave this as a local since NCDA is commonly used among ARK identifiers and could be useful for validating other identifiers later
do -- initialize these constants only once but scope them in a block so local namespace doesn't get cluttered with these
local r29s = [[0123456789bcdfghjkmnpqrstvwxz]] -- radix 29 "betanumeric" digit string
local r29n = r29s:len()
local r29v2d, r29d2v = {}, {}
for i = 1, r29n do
local v, d = i-1, r29s:sub(i, i)
r29v2d[v], r29d2v[d] = d, v
end
function ncda(sid)
local n, sum = sid:len(), 0
for i = 1, n do
sum = sum + i * (r29d2v[sid:sub(i, i)] or 0)
end
return r29v2d[sum % r29n]
end
end
function valid.validateBNF(id)
--P268's format regex: \d{8}[0-9bcdfghjkmnpqrstvwxz] (e.g. 123456789)
local FRBNF = id:sub(1, -2)
return FRBNF:match('^%d%d%d%d%d%d%d%d$') ~= nil and ncda('cb'..FRBNF) == id:sub(-1) and id
end
--Validate ISNI (and ORCID) and returns it as a 16 characters string or returns false if it's invalid.
-- See http://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier
--P213 (ISNI) format regex: [0-9]{4} [0-9]{4} [0-9]{4} [0-9]{3}[0-9X] (e.g. 0000-0000-6653-4145)
function valid.validateIsni(id)
id = id:gsub( '[ %-]', '' ):upper()
if not id:match( '^%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d[%dX]$' ) then
return false
end
local total = 0
for i = 1, 15 do
local digit = id:byte( i ) - 48 --Get integer value
total = (total + digit) * 2
end
local remainder = total % 11
local result = (12 - remainder) % 11
local checkdigit
if result == 10 then
checkdigit = 'X'
else
checkdigit=tostring( result )
end
if checkdigit ~= string.char( id:byte( 16 ) ) then
return false
end
return id
end
function valid.validateOrcid(id)
--P496 (ORCID) format regex: 0000-000(1-[5-9]|2-[0-9]|3-[0-4])\d{3}-\d{3}[\dX] (e.g. 0000-0002-7398-5483)
id = valid.validateIsni(id)
if not id then
return false
end
return id:sub( 1, 4 )..'-'..id:sub( 5, 8 )..'-'..id:sub( 9, 12 )..'-'..id:sub( 13, 16 )
end
function valid.validateEuropeana(id)
--P7704's format regex: (place|agent|concept|organisation)/.* (e.g. agent/base/59832)
local s1, s2, s3 = string.match(id, '([^/]+)([^%d]+)(%d+)')
if not (s1 and s2 and s3) and not (s1 == 'place' or s1 == 'agent' or s1 == 'concept' or s1 == 'organisation') then
return false
end
return s1 .. s2 .. s3
end
-- ============ Local functions ============
local function validValue(conf_id, id)
if not id then
return
end
local valid_value
if conf_id.pattern then -- check pattern to determine validity
valid_value = string.match(id, '^' .. conf_id.pattern .. '$')
elseif conf_id.patterns then -- check multiple patterns to determine validity
for _, pattern in ipairs(conf_id.patterns) do
valid_value = id:match('^' .. pattern .. '$')
if valid_value then
break
end
end
elseif conf_id.valid and type(valid[conf_id.valid]) == 'function' then -- use function to determine validity
valid_value = valid[conf_id.valid](id)
else -- no validation possible
valid_value = id
end
return valid_value
end
local title = mw.title.getCurrentTitle()
local namespace = title.namespace
local function addCat(cat)
if cat and namespace == 0 then
return '[[Category:Articles amb identificador ' .. cat .. ']]'
end
return ''
end
local function getIdsFromWikidata(item, property)
if item.claims[property] then
local claims = mw.wikibase.getBestStatements(item.id, property)
for _, statement in ipairs(claims) do
if statement.mainsnak.datavalue and statement.mainsnak.datavalue.value then
return statement.mainsnak.datavalue.value
end
end
end
return
end
local function getLinkFromWikidata(property)
local claims = mw.wikibase.getBestStatements(property, 'P1630')
for _, statement in ipairs(claims) do
if statement.mainsnak.datavalue and statement.mainsnak.datavalue.value then
return statement.mainsnak.datavalue.value
end
end
return
end
local function createId(params, id)
local arg_link = params.link
if not arg_link then
arg_link = getLinkFromWikidata('P' .. params.property)
end
if arg_link then
local link = mw.ustring.gsub(arg_link, '$1', id)
if params.prefix then
return '* ' .. params.prefix .. ' ([' .. link .. ' 1])' .. addCat(params.category) .. '\n'
else
return '* [' .. link .. ' ' .. params.label .. ']' .. addCat(params.category) .. '\n'
end
end
return ''
end
-- ============ Main ============
local config = mw.loadData('Module:Authority control/config')
function p.authorityControl(frame)
local conf = config.config
local parentArgs = frame:getParent().args
local auxCats = ''
local rct = false -- boolean to track if there are any links to be returned
-- Create sections
local numsections, sections = 0, {}
for _, _ in ipairs(config.sections) do -- count number of regular sections
numsections = numsections + 1
end
for _ = 1, numsections do
table.insert(sections, {})
end
-- fetch data with Wikidata fallback
local item_obj = mw.wikibase.getEntityObject(parentArgs.item)
if item_obj ~= nil and item_obj.claims ~= nil then
for _, params in ipairs(conf) do
local args_id = parentArgs[params.label]
if args_id and args_id == '' then
-- paràmetre definit però buit, no el mostrarà
elseif params.property ~= 0 then
local wikidata_id = getIdsFromWikidata(item_obj, 'P' .. params.property)
local valid_id = validValue(params, args_id or wikidata_id)
if valid_id then
rct = true
if wikidata_id then
if args_id and args_id ~= wikidata_id then
table.insert(sections[params.section], createId(params, valid_id))
auxCats = auxCats .. "[[Categoria:Pàgines amb paràmetres d'autoritat diferents de Wikidata]]"
else
table.insert(sections[params.section], createId(params, valid_id))
end
elseif args_id then
table.insert(sections[params.section], createId(params, valid_id))
end
end
end
end
end
--configure Navbox
if rct then -- there is at least one link to display
local Navbox = require('Module:Navbox')
local sect = 0
local navboxArgs = {
name = 'Autoritat',
navboxclass = 'authority-control',
bodyclass = 'hlist',
}
for c = 1, numsections do
if #sections[c] > 0 then -- section is non-empty
sect = sect + 1
navboxArgs['group' .. sect] = config.sections[c].name
navboxArgs['list' .. sect] = table.concat(sections[c])
end
end
return Navbox._navbox(navboxArgs) .. auxCats
end
return ''
end
return p