diff --git a/module_citeq.lua b/module_citeq.lua index 65ec733..dc20f64 100644 --- a/module_citeq.lua +++ b/module_citeq.lua @@ -88,8 +88,16 @@ local function makelink(v, out, link, maxpos, wdl) local qnumber = v.mainsnak.datavalue.value.id local sitelink = mw.wikibase.getSitelink(qnumber) if qnumber == "Q2818964" then sitelink = nil end -- suppress link to "Various authors" + + -- Last name, first name(s) + local last_name = getValue({"P734", qid=qnumber, maxvals=1, ps=2}) + local first_names = getValue({"P735", qid=qnumber, maxvals=0, ps=2}) + if first_names then + first_names = mw.text.trim(first_names:gsub(', ', ' ')) + end + if v.qualifiers and v.qualifiers.P1932 then - label = v.qualifiers.P1932[1].datavalue.value -- object named as + label = v.qualifiers.P1932[1].datavalue.value -- "object named as" else label = mw.wikibase.getLabel(qnumber) if label then @@ -100,14 +108,22 @@ local function makelink(v, out, link, maxpos, wdl) end local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. - if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then - position = tonumber(v.qualifiers["P1545"][1].datavalue.value) + if v.qualifiers and v.qualifiers.P1545 and v.qualifiers.P1545[1] then + position = tonumber(v.qualifiers.P1545[1].datavalue.value) end maxpos = math.max(maxpos, position) if sitelink then -- just the plain name, -- but keep a record of the links, using the same index - out[position] = label + if last_name and first_names then + out[position] = { + label = label, + last = last_name or nil, + first = first_names or nil, + } + else + out[position] = label + end link[position] = sitelink else if wdl then @@ -120,24 +136,70 @@ local function makelink(v, out, link, maxpos, wdl) ) else -- no Wikidata links wanted, so just give the plain label - out[position] = label + if last_name and first_names then + out[position] = { + label = label, + last = last_name or nil, + first = first_names or nil, + } + else + out[position] = label + end end end elseif v.mainsnak.datatype == "string" then local position = maxpos + 1 -- Default to 'next' author. -- use P1545 (series ordinal) instead of default position. - if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then - position = tonumber(v.qualifiers["P1545"][1].datavalue.value) + if v.qualifiers and v.qualifiers.P1545 and v.qualifiers.P1545[1] then + position = tonumber(v.qualifiers.P1545[1].datavalue.value) end maxpos = math.max(maxpos, position) - out[position] = v.mainsnak.datavalue.value + + -- Names from "author given names" and "author last names" qualifiers + local last_name + local first_names + if v.qualifiers and v.qualifiers.P9688 and v.qualifiers.P9688[1] then + last_name = v.qualifiers.P9688[1].datavalue.value + end + if v.qualifiers and v.qualifiers.P9687 and v.qualifiers.P9687[1] then + first_names = mw.text.trim(v.qualifiers.P9687[1].datavalue.value:gsub(', ', ' ')) + end + + if last_name and first_names then + out[position] = { + label = v.mainsnak.datavalue.value, + last = last_name or nil, + first = first_names or nil, + } + else + out[position] = v.mainsnak.datavalue.value + end else -- not a wikibase-item or a string! end else - -- code here if we want to return something when author is "unknown" + -- try the "object named as" qualifier, otherwise use the unknown author item if v.qualifiers and v.qualifiers.P1932 then - label = v.qualifiers.P1932[1].datavalue.value + label = v.qualifiers.P1932[1].datavalue.value -- "object named as" + + -- Names from "author given names" and "author last names" qualifiers + local last_name + local first_names + if v.qualifiers and v.qualifiers.P9688 and v.qualifiers.P9688[1] then + last_name = v.qualifiers.P9688[1].datavalue.value + end + if v.qualifiers and v.qualifiers.P9687 and v.qualifiers.P9687[1] then + first_names = mw.text.trim(v.qualifiers.P9687[1].datavalue.value:gsub(', ', ' ')) + end + if last_name and first_names then + out[position] = { + label = label, + last = last_name or nil, + first = first_names or nil, + } + else + out[position] = label + end else label = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper) .. (cfg.i18n_t.trackingcats["unknown-author"] or "") end @@ -235,15 +297,27 @@ local function get_name_list (nl_type, args, qid, wdl) end table.sort(keys) -- as they might be out of order for i, k in ipairs(keys) do - out[k] = out[k]:gsub (''', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character - mw.log(i .. " " .. k .. " " .. (out[k])) + local label + if out[k].label then + label = out[k].label + else + label = out[k] + end + label = label:gsub(''', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character + mw.log(i .. " " .. k .. " " .. label) if args[nl_type .. i] then -- name gets overwritten -- pull corresponding -link only if overwritten name is same as WD name - if link[k] and (args[nl_type .. i] == out[k]) then + if link[k] and (args[nl_type .. i] == label) then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end else -- name does not get overwritten, so pull name from WD - args[nl_type .. i] = out[k] + if out[k].first and out[k].last then + -- First/last names were found, so add them + args[nl_type .. '-last' .. i] = args[nl_type .. '-last' .. i] or out[k].last + args[nl_type .. '-first' .. i] = args[nl_type .. '-first' .. i] or out[k].first + else + args[nl_type .. i] = label + end if link[k] then args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn end @@ -273,11 +347,12 @@ end -- gets the language codes of a Wikidata entry as a table local function _lang_code(qid) - local lc = _getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P424", ps = 1} ) + -- P407 "language of work or name" + local lc = _getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P424", ps = 1} ) -- "Wikimedia language code" if lc then return mw.text.split( lc, "[, ]+" ) end - lc = _getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P218", ps = 1} ) + lc = _getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P218", ps = 1} ) -- "ISO 639-1 code" if lc then return mw.text.split( lc, "[, ]+" ) end - return _getLangOfProp(qid, "P1476") + return _getLangOfProp(qid, "P1476") -- "title" end local function lang_code(frame) return table.concat(_lang_code(frame.args.qid or mw.text.trim(frame.args[1] or "")), ", ") @@ -717,6 +792,15 @@ local function _cite_q (citeq_args) if not citeq_args.isbn then citeq_args.publisher = nil end + -- only display ISSN if there are no article identifiers + if citeq_args.issn then + if citeq_args.doi or citeq_args.pmid or citeq_args.pmc or citeq_args.arxiv or + citeq_args.bibcode or citeq_args.jstor or citeq_args.ssrn or citeq_args.s2cid or + citeq_args.hdl or citeq_args.biorxiv or citeq_args.osti or citeq_args.zbl or + citeq_args.jfm or citeq_args.mr then + citeq_args.issn = nil + end + end elseif is_thesis then template = template or "thesis" elseif citeq_args.isbn then @@ -826,6 +910,32 @@ local function _cite_q (citeq_args) citeq_args.erratum = nil citeq_args['erratum-checked'] = nil + -- Indicator if item has an expression of concern notice (P14891) + local eoc = "" + if citeq_args['expression-of-concern'] then + opt_cat = opt_cat .. cfg.i18n_t.trackingcats['expression-of-concern'] + local eoc_params = { + citeq = 'yes', + id = frame:expandTemplate{ + title = 'QID', args = {qid = string.gsub(citeq_args['expression-of-concern'], 'Q', '')} + } + } + eoc_params.doi = getValue({"P356", ps = 1, qid = citeq_args['expression-of-concern']}) or nil + eoc_params.doi = eoc_params.doi and eoc_params.doi:lower() or nil + eoc_params.bibcode = getValue({"P819", ps = 1, qid = citeq_args['expression-of-concern']}) or nil + eoc_params.pmc = getValue({"P932", ps = 1, qid = citeq_args['expression-of-concern']}) or nil + eoc_params.pmid = getValue({"P698", ps = 1, qid = citeq_args['expression-of-concern']}) or nil + -- check qualifiers for access=free + eoc_params['doi-access'] = getIdentifierAccess(citeq_args['expression-of-concern'], eoc_params, 'doi') + eoc_params['bibcode-access'] = getIdentifierAccess(citeq_args['expression-of-concern'], eoc_params, 'bibcode') + if 'yes' == citeq_args['eoc-intentional'] then + eoc_params.intentional = 'yes' + end + eoc = ' ' .. frame:expandTemplate{ title = "Expression of concern", args = eoc_params } + end + citeq_args['expression-of-concern'] = nil + citeq_args['eoc-intentional'] = nil + if citeq_args.replaced_by then opt_cat = opt_cat .. cfg.i18n_t.trackingcats.replaced citeq_args.replaced_by = nil @@ -851,7 +961,7 @@ local function _cite_q (citeq_args) title = "Cite "..template, args = citeq_args } .. cfg.i18n_t.trackingcats["unknown-template"] end - return output .. erratumid .. retract .. opt_cat + return output .. erratumid .. eoc .. retract .. opt_cat end local function cite_q (frame) diff --git a/module_citeq_config.lua b/module_citeq_config.lua index 8a53038..bd209f0 100644 --- a/module_citeq_config.lua +++ b/module_citeq_config.lua @@ -24,6 +24,7 @@ local i18n_t = { ["default"] = "th" }, ["trackingcats"] = { + ['expression-of-concern'] = "[[Category:Cite Q - cites a work with an expression of concern notice]]", ["erratum"] = "[[Category:Cite Q - cites a work with an erratum]]", ["missing-wikidata"] = "[[Category:Articles with missing Wikidata information]]", -- TODO: point to a {{cite q}}-specific category; this one is specific to Module:WikidataIB ['no-label-or-title'] = '[[Category:Cite Q - missing label or title]]', @@ -77,13 +78,14 @@ local simple_properties_t = { retracted_by = {id = "P5824", qidonly=true, maxvals = 1}, -- transient, non-CS1 replaced_by = {id = "P1366", qidonly=true, maxvals = 1}, -- transient, non-CS1 erratum = {id = "P2507", qidonly=true, maxvals = 1}, -- transient, non-CS1 + ['expression-of-concern'] = {id = "P14891", qidonly=true, maxvals = 1}, -- transient, non-CS1 -- citeseerx = {id = "P3784", maxvals = 1}, osti = {id = "P3894", maxvals = 1}, -- take care of |osti-access=? biorxiv = {id = "P3951", maxvals = 1}, asin = {id = "P5749", maxvals = 1}, -- What about |asin-tld=? (WD examples resolve to .com at present, but may change) ['article-number'] = {id = "P2322", maxvals = 1, populate_from_journal = true}, isbn = {id = "P212", maxvals = 1, populate_from_journal = true}, -- ISBN 13 --- issn = {id = "P236", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? + issn = {id = "P236", maxvals = 1, populate_from_journal = true}, -- distinguish from |eissn= for electronic issues? -- jfm = {id = "P?", maxvals = 1}, -- Jahrbuch über die Fortschritte der Mathematik (not Zbl) -- sbn = {id = "P?", maxvals = 1}, -- Standard Book Number (predecessor of ISBN, not ICCU) -- message-id = {id = "P?", maxvals = 1}, -- Usenet message ID