Module:Cite Q: Difference between revisions

Content deleted Content added
update from sandbox
Version: 2021-02-06 sync from sandbox
Line 1:
-- Version: 2021-0102-2006
 
local p = {}
Line 8:
local getPropOfProp = wdib._getPropOfProp
local followQid = wdib._followQid
local getPropertyIDs = wdib._getPropertyIDs
 
local i18n = {
Line 118 ⟶ 119:
]]
local function is_set( var )
return not (var == nil or var == '');
end
 
Line 126 ⟶ 127:
local function in_array( needle, haystack )
if needle == nil then
return false;
end
for n, v in ipairs( haystack ) do
if v == needle then
return n;
end
end
return false;
end
 
Line 241 ⟶ 242:
 
if nl_type =="author" then
propertyID = 'P50'; -- for authors
fallbackID = 'P2093'; -- author-string
elseif nl_type =="editor" then
propertyID = 'P5769'; -- "editor-in-chief"
fallbackID = 'P98'; -- for editors - So-called "fallbacks" are actually a second set of properties processed
-- TBD. Take book series editors into account as well (if they have a separate P code as well)?
elseif nl_type == "translator" then
propertyID = 'P655'; -- for translators
fallbackID = nil;
-- elseif 'contributor' == nl_type then
-- f.e. author of forewords (P2679) and afterwords (P2680); requires |contribution=, |title= and |author=
-- propertyID = 'P'; -- for contributors
-- fallbackID = nil;
else
return; -- not specified so return
end
 
Line 326 ⟶ 327:
end
 
-- gets language codes used for a monolingual text property as a table
function p._getLangOfProp(qid, pid)
if not pid then return {} end
local out = {}
local props = mw.wikibase.getAllStatements(qid, pid)
for i, v in ipairs(props) do
if v.mainsnak.datatype == "monolingualtext" and v.mainsnak.datavalue then
out[#out + 1] = v.mainsnak.datavalue.value.language
end
end
return out
end
function p.getLangOfProp(frame)
local pid = frame.args.pid or mw.text.trim(frame.args[1] or "")
if pid == "" then return end
local qid = frame.args.qid
if qid == "" then qid = nil end
return table.concat(p._getLangOfProp(qid, pid), ", ")
end
 
-- gets the language codes of a Wikidata entry as a table
--[[-------------------------< C I T E _ Q >------------------------------------------------------------------
local function _lang_code(qid)
Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1=
local lc = getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P424", ps = 1} )
are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to
if lc then return mw.text.split( lc, "[, ]+" ) end
{{citation}} for rendering.
lc = getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P218", ps = 1} )
]]
if lc then return mw.text.split( lc, "[, ]+" ) end
return p._getLangOfProp(qid, "P1476")
end
function p.lang_code(frame)
return table.concat(_lang_code(frame.args.qid or mw.text.trim(frame.args[1] or "")), ", ")
end
 
-- export for debug
function p.getPropOfProp(frame)
return getPropOfProp(frame.args)
end
 
-- wraps a string in nowiki unless disable flag is set
Line 339 ⟶ 370:
end
 
-- sort sequence table whose values are key-value pairs by key
local function comp_key(a, b)
return a[1] < b[1]
end
 
-- sort sequence table whose values are key-value pairs by value
local function comp_val(a, b)
return a[2] < b[2]
end
 
--[[-------------------------< C I T E _ Q >------------------------------------------------------------------
Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1=
are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to
{{citation}} for rendering.
--]]
function p._cite_q (citeq_args)
local frame = mw.getCurrentFrame()
Line 358 ⟶ 404:
local oth = {}
 
-- put the language codes into a sequential table langcodes[]
citeq_args.language = citeq_args.language or getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P218", ps = 1} )
local langcodes = {}
if citeq_args.language == '' then -- is this needed now?
if citeq_args.language = nilthen
-- check these are a supported language codes
for lc in mw.text.gsplit( citeq_args.language, "[, ]+", false ) do
langcodes[#langcodes+1] = mw.language.isSupportedLanguage(citeq_args.language) and citeq_args.language
end
end
if not langcodes[1] then
-- try to find language of work
langcodes = _lang_code(qid)
end
if not citeq_args.languagelangcodes[1] then
-- try fallback to journal's language
local journal_qid = followQid({qid = qid, props = "P1433"})
citeq_args.languagelangcodes = journal_qid and getPropOfProp_lang_code( {qid = journal_qid, prop1 = "P407", prop2 = "P218", ps = 1} )
end
citeq_args.language = citeq_args.language or table.concat(langcodes, ", ")
 
-- loop through list of simple properties and get their values in citeq_args
for name, data in pairs(simple_properties) do
citeq_args[name] = getValue( {data.id, fwd = "ALL", osd = "no", noicon = "true", qid = qid, maxvals = data.maxvals, linked = data.linked, rank = data.rank or "best", citeq_args[name] } )
Line 376 ⟶ 432:
if citeq_args[name] and citeq_args[name]:find('[[Category:Articles with missing Wikidata information]]', 1, true) then
-- try fallback to work's native language
citeq_args[name] = getValue( {data.id, ps = 1, qid = qid, maxvals = data.maxvals, linked = "no", lang = citeq_args.languagelangcodes[1] } )
if citeq_args[name]:find('^Q%d+$') then -- qid was returned
-- try fallback to qid's native language
local qid_languageqid_languages = getPropOfProp_lang_code( {qid = citeq_args[name], prop1 = "P407", prop2 = "P218", ps = 1} )
citeq_args[name] = getValue( {data.id, ps = 1, qid = qid, maxvals = data.maxvals, linked = "no", lang = qid_languageqid_languages[1] } )
if citeq_args[name]:find('^Q%d+$') then -- qid was returned again
citeq_args[name] = nil
else
-- record the language found
citeq_args.language = citeq_args.language or qid_languages[1]
end
end
Line 407 ⟶ 466:
citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv)
 
citeq_args.isbn = getValue( {"P957", ps = 1, qid = qid, maxvals = 01, rank="best", citeq_args.isbn } ) -- try ISBN 10 (only one value accepted)
 
citeq_args.url = getValue( {"P856", ps = 1, qid = qid, maxvals = 0, citeq_args.url } ) -- try official website
Line 424 ⟶ 483:
local title_display = citeq_args.title
or mw.wikibase.getLabel(qid)
or (citeq_args.languagelangcodes[1] and mw.wikibase.getLabelByLang(qid, citeq_args.languagelangcodes[1]))
or ("No label or title -- debug: " .. qid)
if citeq_args.url then
Line 484 ⟶ 543:
and not is_set (citeq_args['author-last']) and not is_set (citeq_args['author-last1']) and not is_set (citeq_args['author1-last'])
and not is_set (citeq_args['author-surname']) and not is_set (citeq_args['author-surname1']) and not is_set (citeq_args['author1-surname1']) then -- if neither are set, try to get authors from Wikidata
get_name_list ('author', citeq_args, qid, wdl); -- modify citeq_args table with authors from Wikidata
end
 
Line 490 ⟶ 549:
and not is_set (citeq_args['editor-last']) and not is_set (citeq_args['editor-last1']) and not is_set (citeq_args['editor1-last'])
and not is_set (citeq_args['editor-surname']) and not is_set (citeq_args['editor-surname1']) and not is_set (citeq_args['editor1-surname']) then -- if neither are set, try to get editors from Wikidata
get_name_list ('editor', citeq_args, qid, wdl); -- modify citeq_args table with editors from Wikidata
end
 
Line 496 ⟶ 555:
and not is_set (citeq_args['translator-last']) and not is_set (citeq_args['translator-last1']) and not is_set (citeq_args['translator1-last'])
and not is_set (citeq_args['translator-surname']) and not is_set (citeq_args['translator-surname1']) and not is_set (citeq_args['translator1-surname']) then -- if neither are set, try to get translators from Wikidata
get_name_list ('translator', citeq_args, qid, wdl); -- modify citeq_args table with translators from Wikidata
end
end
Line 552 ⟶ 611:
 
-- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list
local list_sep = '. ';
if citeq_args.mode ~= 'cs1' then
list_sep = ', ';
end
local id = '[[WDQ (identifier)|Wikidata]]&nbsp;[[:d:' .. qid .. '|' .. qid .. ']]'; -- go through "WDQ (identifier)" redirect to reduce clutter in "What links here" and improve reverse lookup. Keep in sync with {{QID}}.
local old_id = citeq_args.id;
if wdl then -- show WD logo
id = id .. '[[File:Wikidata-logo.svg|16px|alt=|link=]]'; -- possibly replace by WD edit icon?
end
if is_set (old_id) then
citeq_args.id = old_id .. list_sep .. id; -- append to user-specified contents
else
citeq_args.id = id;
end
 
Line 576 ⟶ 635:
local expand_args = { "{{" .. template } -- init with citation template
if expand == "self" then
citeq_args.id = old_id; -- restore original |id= parameter
expand_args = { "{{cite Q|" .. qid } -- expand to itself
end
-- make a sortable table and sort it by param name
for p, v in pairs (citeq_args) do -- spin through citeq_args and
local sorttable = {}
table.insert (expand_args, p .. '=' .. v) -- add parameter name = value
for param, val in pairs (citeq_args) do
table.insert(sorttable, {param, val})
end
table.sort(sorttable, comp_key)
-- add contents to expand_args
for idx, val in ipairs(sorttable) do
table.insert(expand_args, val[1] .. '=' .. val[2])
end
-- make the nowiki'd string and done
return "<code>" .. table.concat (expand_args, ' |') .. "}}</code>"
end
 
local erratumid = getPropertyIDs( { "P2507", qid = qid, fwd = "ALL", osd = "no", rank = "best", maxvals = 1 } )
if erratumid then
erratumid = " [[d:" .. erratumid .. "|(erratum)]]" .. "[[Category:Cite Q - cites a work with an erratum]]"
else
erratumid = ""
end
 
local opt_cat = ''
if getValue( {"P5824", ps = 1, qid = qid} ) then
opt_cat = '[[Category:Cite Q - cites a retracted work]]<!-- retracted -->'
end
if getValue( {"P1366", ps = 1, qid = qid} ) then
opt_cat = opt_cat .. '[[Category:Cite Q - cites a replaced work]]<!-- replaced -->'
end
return frame:expandTemplate{title = template, args = citeq_args} .. erratumid .. opt_cat -- render the template
end
 
Line 604 ⟶ 677:
if v ~= "" then args[k] = v end
end
args.qid = args.qid or args[1] or ""
return p._cite_q(args)
if args.qid == "" then return nil end
args[1] = nil
 
local citesep = (args.citesep or "")
if citesep == "" then citesep = ", " end
citesep = citesep:gsub('"', '') -- strip double quotes after setting default to allow |citesep="" as a blank separator
args.citesep = nil
 
local tag = args.tag or ""
if tag == "" then tag = nil end
args.tag = nil
 
local list = args.list or ""
if list == "" then list = nil end
args.list = nil
 
args.language = args.language or args.lang
args.lang = nil
 
local cites = {}
for q in args.qid:gmatch("Q%d+") do
-- make a new copy of the arguments
local newargs = {}
for k, v in pairs(args) do
if k ~= "qid" then
newargs[k] = v
end
end
newargs.qid = q
if tag == "ref" then
cites[#cites + 1] = frame:callParserFunction{ name = "#tag:ref", args = { p._cite_q(newargs), name = q } }
-- expand like this: args = { p._cite_q(newargs), name = 'foo', group = 'bar' }
else
cites[#cites + 1] = p._cite_q(newargs)
end
end
 
if list then
return frame:expandTemplate{ title = list, args = cites }
else
return table.concat(cites, citesep)
end
end