Compare commits
3 commits
280095ed0f
...
6f13edba6e
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f13edba6e | |||
| 1df4c6cb25 | |||
| 2ed4bf2b7c |
1 changed files with 148 additions and 27 deletions
175
module_citeq.lua
175
module_citeq.lua
|
|
@ -80,16 +80,56 @@ local function accept_value( param_val, wd_val )
|
||||||
return val
|
return val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Split string of comma-separated first names into table of initials
|
||||||
|
local function getInitials(str)
|
||||||
|
local initials = {}
|
||||||
|
for _, word in pairs(mw.text.split(str, ' ', true)) do
|
||||||
|
local initial = mw.text.trim(word)
|
||||||
|
if #initial > 0 then
|
||||||
|
table.insert(initials, initial:sub(1, 1):upper())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return initials
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return initials given a style (e.g. Vancouver or APA)
|
||||||
|
local function getStyledNames(names, style)
|
||||||
|
if style == 'Vancouver' then
|
||||||
|
return table.concat(getInitials(names))
|
||||||
|
elseif style == 'APA' then
|
||||||
|
return table.concat(getInitials(names), '. ') .. '.'
|
||||||
|
else
|
||||||
|
return mw.text.trim(names:gsub(', ', ' '))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- function to fetch a value to display
|
-- function to fetch a value to display
|
||||||
local function makelink(v, out, link, maxpos, wdl)
|
local function makelink(v, out, link, maxpos, wdl, namestyle)
|
||||||
local label
|
local label
|
||||||
if v.mainsnak.snaktype == "value" then
|
if v.mainsnak.snaktype == "value" then
|
||||||
if v.mainsnak.datatype == "wikibase-item" then
|
if v.mainsnak.datatype == "wikibase-item" then
|
||||||
local qnumber = v.mainsnak.datavalue.value.id
|
local qnumber = v.mainsnak.datavalue.value.id
|
||||||
local sitelink = mw.wikibase.getSitelink(qnumber)
|
local sitelink = mw.wikibase.getSitelink(qnumber)
|
||||||
if qnumber == "Q2818964" then sitelink = nil end -- suppress link to "Various authors"
|
if qnumber == "Q2818964" then sitelink = nil end -- suppress link to "Various authors"
|
||||||
|
|
||||||
|
-- Last name, first name(s) 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 = v.qualifiers.P9687[1].datavalue.value
|
||||||
|
end
|
||||||
|
-- Otherwise, get last name, first name(s) from author item properties
|
||||||
|
last_name = last_name or getValue({"P734", qid=qnumber, maxvals=1, ps=2})
|
||||||
|
first_names = first_names or getValue({"P735", qid=qnumber, maxvals=0, ps=2})
|
||||||
|
if first_names then
|
||||||
|
first_names = getStyledNames(first_names, namestyle)
|
||||||
|
end
|
||||||
|
|
||||||
if v.qualifiers and v.qualifiers.P1932 then
|
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
|
else
|
||||||
label = mw.wikibase.getLabel(qnumber)
|
label = mw.wikibase.getLabel(qnumber)
|
||||||
if label then
|
if label then
|
||||||
|
|
@ -100,14 +140,22 @@ local function makelink(v, out, link, maxpos, wdl)
|
||||||
end
|
end
|
||||||
local position = maxpos + 1 -- Default to 'next' author.
|
local position = maxpos + 1 -- Default to 'next' author.
|
||||||
-- use P1545 (series ordinal) instead of default position.
|
-- use P1545 (series ordinal) instead of default position.
|
||||||
if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
|
if v.qualifiers and v.qualifiers.P1545 and v.qualifiers.P1545[1] then
|
||||||
position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
|
position = tonumber(v.qualifiers.P1545[1].datavalue.value)
|
||||||
end
|
end
|
||||||
maxpos = math.max(maxpos, position)
|
maxpos = math.max(maxpos, position)
|
||||||
if sitelink then
|
if sitelink then
|
||||||
-- just the plain name,
|
-- just the plain name,
|
||||||
-- but keep a record of the links, using the same index
|
-- 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
|
link[position] = sitelink
|
||||||
else
|
else
|
||||||
if wdl then
|
if wdl then
|
||||||
|
|
@ -120,24 +168,68 @@ local function makelink(v, out, link, maxpos, wdl)
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
-- no Wikidata links wanted, so just give the plain label
|
-- 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
|
||||||
end
|
end
|
||||||
elseif v.mainsnak.datatype == "string" then
|
elseif v.mainsnak.datatype == "string" then
|
||||||
local position = maxpos + 1 -- Default to 'next' author.
|
local position = maxpos + 1 -- Default to 'next' author.
|
||||||
-- use P1545 (series ordinal) instead of default position.
|
-- use P1545 (series ordinal) instead of default position.
|
||||||
if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
|
if v.qualifiers and v.qualifiers.P1545 and v.qualifiers.P1545[1] then
|
||||||
position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
|
position = tonumber(v.qualifiers.P1545[1].datavalue.value)
|
||||||
end
|
end
|
||||||
maxpos = math.max(maxpos, position)
|
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 = getStyledNames(v.qualifiers.P9687[1].datavalue.value, namestyle)
|
||||||
|
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
|
else
|
||||||
-- not a wikibase-item or a string!
|
-- not a wikibase-item or a string!
|
||||||
end
|
end
|
||||||
else
|
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
|
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 = getStyledNames(v.qualifiers.P9687[1].datavalue.value, namestyle)
|
||||||
|
end
|
||||||
|
if last_name and first_names then
|
||||||
|
label = {
|
||||||
|
label = label,
|
||||||
|
last = last_name or nil,
|
||||||
|
first = first_names or nil,
|
||||||
|
}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
label = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper) .. (cfg.i18n_t.trackingcats["unknown-author"] or "")
|
label = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper) .. (cfg.i18n_t.trackingcats["unknown-author"] or "")
|
||||||
end
|
end
|
||||||
|
|
@ -213,7 +305,7 @@ local function get_name_list (nl_type, args, qid, wdl)
|
||||||
if props and props[1] then
|
if props and props[1] then
|
||||||
for k, v in pairs(props) do
|
for k, v in pairs(props) do
|
||||||
if 'deprecated' ~= v.rank then -- ignore deprecated names
|
if 'deprecated' ~= v.rank then -- ignore deprecated names
|
||||||
maxpos = makelink(v, out, link, maxpos, wdl)
|
maxpos = makelink(v, out, link, maxpos, wdl, args.namestyle)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -221,7 +313,7 @@ local function get_name_list (nl_type, args, qid, wdl)
|
||||||
-- second properties
|
-- second properties
|
||||||
for k, v in pairs(fallback) do
|
for k, v in pairs(fallback) do
|
||||||
if 'deprecated' ~= v.rank then -- ignore deprecated names
|
if 'deprecated' ~= v.rank then -- ignore deprecated names
|
||||||
maxpos = makelink(v, out, link, maxpos, wdl)
|
maxpos = makelink(v, out, link, maxpos, wdl, args.namestyle)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -235,15 +327,27 @@ local function get_name_list (nl_type, args, qid, wdl)
|
||||||
end
|
end
|
||||||
table.sort(keys) -- as they might be out of order
|
table.sort(keys) -- as they might be out of order
|
||||||
for i, k in ipairs(keys) do
|
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
|
local label
|
||||||
mw.log(i .. " " .. k .. " " .. (out[k]))
|
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
|
if args[nl_type .. i] then -- name gets overwritten
|
||||||
-- pull corresponding -link only if overwritten name is same as WD name
|
-- 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
|
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
|
||||||
end
|
end
|
||||||
else -- name does not get overwritten, so pull name from WD
|
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
|
if link[k] then
|
||||||
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
|
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
|
||||||
end
|
end
|
||||||
|
|
@ -273,11 +377,12 @@ end
|
||||||
|
|
||||||
-- gets the language codes of a Wikidata entry as a table
|
-- gets the language codes of a Wikidata entry as a table
|
||||||
local function _lang_code(qid)
|
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
|
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
|
if lc then return mw.text.split( lc, "[, ]+" ) end
|
||||||
return _getLangOfProp(qid, "P1476")
|
return _getLangOfProp(qid, "P1476") -- "title"
|
||||||
end
|
end
|
||||||
local function lang_code(frame)
|
local function lang_code(frame)
|
||||||
return table.concat(_lang_code(frame.args.qid or mw.text.trim(frame.args[1] or "")), ", ")
|
return table.concat(_lang_code(frame.args.qid or mw.text.trim(frame.args[1] or "")), ", ")
|
||||||
|
|
@ -302,8 +407,11 @@ local function yearFromDate(datestr)
|
||||||
return datestr
|
return datestr
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Attempt to determine heuristically if we're citing a news article
|
-- Attempt to determine heuristically what we're citing
|
||||||
local function isNewsArticle(qid, args)
|
local function getTemplateFromInstance(qid, args)
|
||||||
|
local chapteritems = {
|
||||||
|
'Q1980247', -- chapter
|
||||||
|
}
|
||||||
local newsitems = {
|
local newsitems = {
|
||||||
'Q5707594', -- news article
|
'Q5707594', -- news article
|
||||||
'Q30070590', -- magazine article
|
'Q30070590', -- magazine article
|
||||||
|
|
@ -322,7 +430,9 @@ local function isNewsArticle(qid, args)
|
||||||
}
|
}
|
||||||
-- most of the time a cheap lookup to a single value will work
|
-- most of the time a cheap lookup to a single value will work
|
||||||
if args['instance-of'] and in_array(args['instance-of'], newsitems) then
|
if args['instance-of'] and in_array(args['instance-of'], newsitems) then
|
||||||
return true
|
return 'news'
|
||||||
|
elseif args['instance-of'] and in_array(args['instance-of'], chapteritems) then
|
||||||
|
return 'chapter'
|
||||||
end
|
end
|
||||||
-- otherwise check multiple non-deprecated values
|
-- otherwise check multiple non-deprecated values
|
||||||
local instance_of = mw.wikibase.getBestStatements(qid, 'P31')
|
local instance_of = mw.wikibase.getBestStatements(qid, 'P31')
|
||||||
|
|
@ -330,12 +440,14 @@ local function isNewsArticle(qid, args)
|
||||||
for k, v in pairs(instance_of) do
|
for k, v in pairs(instance_of) do
|
||||||
if v.mainsnak.snaktype == "value" and v.mainsnak.datatype == "wikibase-item" then
|
if v.mainsnak.snaktype == "value" and v.mainsnak.datatype == "wikibase-item" then
|
||||||
if in_array(v.mainsnak.datavalue.value.id, newsitems) then
|
if in_array(v.mainsnak.datavalue.value.id, newsitems) then
|
||||||
return true
|
return 'news'
|
||||||
|
elseif in_array(v.mainsnak.datavalue.value.id, chapteritems) then
|
||||||
|
return 'chapter'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return ''
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Figure out a URL access value, from the "online access status" (P6954) qualifier of an identifier
|
-- Figure out a URL access value, from the "online access status" (P6954) qualifier of an identifier
|
||||||
|
|
@ -426,6 +538,7 @@ local function _cite_q (citeq_args)
|
||||||
citeq_args.qid = nil
|
citeq_args.qid = nil
|
||||||
citeq_args.wdl = nil
|
citeq_args.wdl = nil
|
||||||
citeq_args.template = nil
|
citeq_args.template = nil
|
||||||
|
citeq_args.namestyle = citeq_args.namestyle or citeq_args['name-style'] or nil
|
||||||
|
|
||||||
-- if title supplied, flag to not read html title
|
-- if title supplied, flag to not read html title
|
||||||
local titleforced = (citeq_args.title ~= nil)
|
local titleforced = (citeq_args.title ~= nil)
|
||||||
|
|
@ -702,14 +815,20 @@ local function _cite_q (citeq_args)
|
||||||
-- code to make a guess what template to use from the supplied parameters
|
-- code to make a guess what template to use from the supplied parameters
|
||||||
-- (first draft for proof-of-concept)
|
-- (first draft for proof-of-concept)
|
||||||
local pubyear = yearFromDate(citeq_args['publication-date'])
|
local pubyear = yearFromDate(citeq_args['publication-date'])
|
||||||
local is_news = isNewsArticle(qid, citeq_args)
|
local guessedType = getTemplateFromInstance(qid, citeq_args)
|
||||||
if is_news then
|
if guessedType == 'news' then
|
||||||
template = template or "news"
|
template = template or "news"
|
||||||
-- some items use P123 (publisher) as the newspaper instead of P1433 (published in)
|
-- some items use P123 (publisher) as the newspaper instead of P1433 (published in)
|
||||||
if citeq_args.publisher and not citeq_args.journal then
|
if citeq_args.publisher and not citeq_args.journal then
|
||||||
citeq_args.journal = citeq_args.publisher
|
citeq_args.journal = citeq_args.publisher
|
||||||
citeq_args.publisher = nil
|
citeq_args.publisher = nil
|
||||||
end
|
end
|
||||||
|
elseif guessedType == 'chapter' then
|
||||||
|
template = template or "book"
|
||||||
|
citeq_args['publication-date'] = pubyear or citeq_args['publication-date']
|
||||||
|
citeq_args.chapter = citeq_args.title
|
||||||
|
citeq_args.title = citeq_args.journal
|
||||||
|
citeq_args.journal = nil
|
||||||
elseif citeq_args.journal then
|
elseif citeq_args.journal then
|
||||||
template = template or "journal"
|
template = template or "journal"
|
||||||
citeq_args['publication-date'] = pubyear or citeq_args['publication-date']
|
citeq_args['publication-date'] = pubyear or citeq_args['publication-date']
|
||||||
|
|
@ -874,6 +993,8 @@ local function _cite_q (citeq_args)
|
||||||
|
|
||||||
-- remove any remaining non-CS1 fields
|
-- remove any remaining non-CS1 fields
|
||||||
citeq_args['instance-of'] = nil
|
citeq_args['instance-of'] = nil
|
||||||
|
citeq_args.namestyle = nil
|
||||||
|
citeq_args['name-style'] = nil
|
||||||
|
|
||||||
-- render the template
|
-- render the template
|
||||||
local lc_template = template and template:lower() or "citation"
|
local lc_template = template and template:lower() or "citation"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue