diff --git a/module_citeq.lua b/module_citeq.lua index 21d07d7..0b73d54 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -8,6 +8,7 @@ local followQid = wdib._followQid local cite_cfg = mw.loadData ('Module:Cite/config') local cfg = mw.loadData ('Module:Cite_Q/config') local cs1_module = 'Module:Citation/CS1' -- don't load the module yet, may not be needed +local cs1_cfg = 'Module:Citation/CS1/Configuration' -------------------------------------------------------------------------------- -- makeOrdinal needs to be internationalised along with cfg.i18n_t @@ -337,6 +338,58 @@ local function isNewsArticle(qid, args) return false end +-- Figure out a URL access value, from the "online access status" (P6954) qualifier of an identifier +-- The [[Template:Cite journal]] docs state these should only allow "free" +-- e.g. DOI = P356 +local function getIdentifierAccess(qid, args, identifier) + if not args[identifier] then + return nil + end + + -- check DOI registrant is known free, using CS1 config + -- TODO: this should also be modelled in Wikidata + if identifier == 'doi' then + local cs1 = require(cs1_cfg) + local registrant, suffix = mw.ustring.match(args.doi:lower(), '^10%.([^/]+)/([^%s–]+)$'); + if registrant and suffix and cs1.known_free_doi_registrants_t[registrant] then + return 'free' + elseif registrant and suffix and cs1.extended_registrants_t[registrant] then + for _, incipit in ipairs(cs1.extended_registrants_t[registrant]) do + if mw.ustring.find (suffix, '^' .. incipit:lower()) then + return 'free' + end + end + end + end + + -- fetch statement values to examine qualifiers + local ids = mw.wikibase.getBestStatements(qid, cfg.simple_properties_t[identifier]['id']) + if not ids or not ids[1] then + return nil + end + if not ids[1].qualifiers or not ids[1].qualifiers.P6954 then + return nil + end + + -- Check property constraints (P2302) in definition of online access status (P6954) + -- Q66439598 = 'limited', -- partial open access + -- Q107459441 = 'registration', -- registration required + -- Q910845 = 'subscription', -- paywall + -- Q16572632 = 'subscription', -- login (see note on P6954) + local free_status = { + 'Q24707952', -- free to read + 'Q232932', -- open access + } + local access = ids[1].qualifiers.P6954[1] + if access.datatype == "wikibase-item" then + local accessQID = access.datavalue.value.id + if in_array(accessQID, free_status) then + return 'free' + end + end + return nil +end + -- sort sequence table whose values are key-value pairs by key local function comp_key(a, b) local param_a, enum_a = a[1]:match ('(%D+)(%d+)$'); -- get param name and enumerator from @@ -437,6 +490,17 @@ local function _cite_q (citeq_args) citeq_args.doi = citeq_args.doi and citeq_args.doi:lower() or nil; -- force |doi= value to be lower case + -- URL access for identifiers, from P6954 online access status + -- The [[Template:Cite journal]] docs state these should only allow "free" + citeq_args['bibcode-access'] = citeq_args['bibcode-access'] or getIdentifierAccess(qid, citeq_args, 'bibcode'); + citeq_args['doi-access'] = citeq_args['doi-access'] or getIdentifierAccess(qid, citeq_args, 'doi'); + citeq_args['hdl-access'] = citeq_args['hdl-access'] or getIdentifierAccess(qid, citeq_args, 'hdl'); + citeq_args['jstor-access'] = citeq_args['jstor-access'] or getIdentifierAccess(qid, citeq_args, 'jstor'); + -- citeq_args['ol-access'] = citeq_args['ol-access'] or getIdentifierAccess(qid, citeq_args, 'ol'); + citeq_args['osti-access'] = citeq_args['osti-access'] or getIdentifierAccess(qid, citeq_args, 'osti'); + citeq_args['ssrn-access'] = citeq_args['ssrn-access'] or getIdentifierAccess(qid, citeq_args, 'ssrn'); + citeq_args['s2cid-access'] = citeq_args['s2cid-access'] or getIdentifierAccess(qid, citeq_args, 's2cid'); + citeq_args.others = citeq_args.others or table.concat(oth, ". ") if citeq_args.others == "" then citeq_args.others = nil @@ -698,6 +762,9 @@ local function _cite_q (citeq_args) retr_params.bibcode = getValue({"P819", ps = 1, qid = citeq_args.retracted_by}) or nil retr_params.pmc = getValue({"P932", ps = 1, qid = citeq_args.retracted_by}) or nil retr_params.pmid = getValue({"P698", ps = 1, qid = citeq_args.retracted_by}) or nil + -- check qualifiers for access=free + retr_params['doi-access'] = getIdentifierAccess(citeq_args.retracted_by, retr_params, 'doi') + retr_params['bibcode-access'] = getIdentifierAccess(citeq_args.retracted_by, retr_params, 'bibcode') if 'yes' == citeq_args['retracted-intentional'] then retr_params.intentional = 'yes' end @@ -749,6 +816,9 @@ local function _cite_q (citeq_args) erratum_params.bibcode = getValue({"P819", ps = 1, qid = citeq_args.erratum}) or nil erratum_params.pmc = getValue({"P932", ps = 1, qid = citeq_args.erratum}) or nil erratum_params.pmid = getValue({"P698", ps = 1, qid = citeq_args.erratum}) or nil + -- check qualifiers for access=free + erratum_params['doi-access'] = getIdentifierAccess(citeq_args.erratum, erratum_params, 'doi') + erratum_params['bibcode-access'] = getIdentifierAccess(citeq_args.erratum, erratum_params, 'bibcode') if 'yes' == citeq_args['erratum-checked'] then erratum_params.checked = 'yes' end