Module:Cite Q/sandbox: Difference between revisions

Content deleted Content added
Ederporto (talk | contribs)
Adding replaced by (P1366) tracking category
only include |id= parameter if template is not arxiv, add guessing of arxiv template based on arxiv identifier
 
(140 intermediate revisions by 8 users not shown)
Line 1:
-- Version: 2021-10-19
require('Module:No globals')
 
local p = {}
 
require('strict')
local wdib = require('Module:WikidataIB')
local getValue = wdib._getValue
local getPropOfProp = wdib._getPropOfProp
local followQid = wdib._followQid
local getPropertyIDs = wdib._getPropertyIDs
 
local i18n = {
["unknown-author"] = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper),
["unknown-author-trackingcat"] = "[[Category:Cite Q - author unknown]]",
["ordinal"] = {
[1] = "st",
[2] = "nd",
[3] = "rd",
["default"] = "th"
},
["months"] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
},
}
 
-------------------------------------------------------------------------------
local simple_properties = { -- PXXX, is multiple?, linked?
-- makeOrdinal needs to be internationalised along with the above i18n
-- takes cardinal number as a numeric and returns the ordinal as a string
-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.
-------------------------------------------------------------------------------
p.makeOrdinal = function(cardinal)
local card = tonumber(cardinal)
if not card then return cardinal end
local ordsuffix = i18n.ordinal.default
if card % 10 == 1 then
ordsuffix = i18n.ordinal[1]
elseif card % 10 == 2 then
ordsuffix = i18n.ordinal[2]
elseif card % 10 == 3 then
ordsuffix = i18n.ordinal[3]
end
-- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th'
-- similarly for 12 and 13, etc.
if (card % 100 == 11) or (card % 100 == 12) or (card % 100 == 13) then
ordsuffix = i18n.ordinal.default
end
return card .. ordsuffix
end
 
-- Table of simple properties that can be fetched in roughly the same way:
-- id = PXXX
-- maxvals = maximum number of multiple values (0 for all)
-- linked = "no" suppresses linking
-- populate_from_journal = true/false determines whether to look in a journal where the source is published
-- rank = "best", "preferred", normal, etc. determines how Wikidata ranks are treated
-- others = true - the value for the property goes to "others" section
local simple_properties = {
publisher = {id = "P123", maxvals = 1},
oclc = {id = "P243", maxvals = 1},
Line 52 ⟶ 98:
volume = {id = "P478", maxvals = 0, populate_from_journal = true},
-- part = {id = "P1545"?, maxvals = 0}, -- to be added to {{citation}} / COinS &rft.part=
title = {id = "P1476", maxvals rank="p 1n"},
-- url = {id = "P953", maxvals = 1}, -- fulldeal workwith availablethis atalong with archive-url
pages = {id = "P304", maxvals = 0, populate_from_journal = true},
at = {id = "P958", maxvals = 0, populate_from_journal = true}, -- also incorporate lines (P7421) and columns (P3903) into this (cite map also supports |section=)
Line 72 ⟶ 118:
performer = {id = "P175", maxvals = 10, others = true}, -- goes to "others" section
}
 
local citeq = {}
 
--[[--------------------------< I S _ S E T >--------------------------------------------------------------
 
 
Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
 
]]
local function is_set( var )
return not (var == nil or var == '');
end
 
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
 
Whether needle is in haystack (taken from Module:Citation/CS1/Utilities)
 
]]
 
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
 
 
--[[--------------------------< A C C E P T _ V A L U E >-------------------------------------------------------
 
Accept WD value by framing in ((...)) if param_val is equal to keyword; else pass-through WD value as is.
 
]]
 
local function accept_value( param_val, wd_val )
local val = param_val
Line 137 ⟶ 172:
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"
if v.qualifiers and v.qualifiers.P1932 then
label = v.qualifiers.P1932[1].datavalue.value
elseif v.qualifiers and v.qualifiers.P1810 then
label = v.qualifiers.P1810[1].datavalue.value
else
label = mw.wikibase.getLabel(qnumber)
Line 184 ⟶ 218:
if v.qualifiers and v.qualifiers.P1932 then
label = v.qualifiers.P1932[1].datavalue.value
elseif v.qualifiers and v.qualifiers.P1810 then
label = v.qualifiers.P1810[1].datavalue.value
else
label = i18n["unknown-author"] .. (i18n["unknown-author-trackingcat"] or "")
Line 193 ⟶ 225:
end
return maxpos
end
end -- of local function makelink
 
--[=[-------------------------< G E T _ N A M E _ L I S T >----------------------------------------------------
 
get_name_list -- adapted from getAuthors code taken from Module:RexxS
arguments:
Line 203 ⟶ 234:
qid - value from |qid= parameter; the Q-id of the source (book, etc.) in qid
wdl - value from the |wdl= parameter; a Boolean passed to enable links to Wikidata when no article exists
 
returns nothing; modifies the args table
 
]=]
 
Line 211 ⟶ 240:
local propertyID = "P50"
local fallbackID = "P2093" -- author name string
 
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 241 ⟶ 270:
end
 
local entity = mw.wikibase.getEntity(qid)
local props = nil
local fallback = nil
if mw.wikibase.entityExists(qid) then
if entity and entity.claims then
props = entitymw.claims[wikibase.getAllStatements(qid, propertyID])
if props and fallbackID then
fallback = entitymw.claims[wikibase.getAllStatements(qid, fallbackID])
end
end
 
-- Make sure it actually has at least one of the properties requested
if not (props and props[1]) and not (fallback and fallback[1]) then
return nil
end
Line 283 ⟶ 311:
table.sort(keys) -- as they might be out of order
for i, k in ipairs(keys) do
out[k] = out[k]:gsub ('&#39;', '\''); -- prevent cs1|2 multiple names categorization; replace html entity with the actual character
mw.log(i .. " " .. k .. " " .. (out[k]))
if args[nl_type .. i] then -- name gets overwritten
Line 298 ⟶ 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)
local lc = getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P424", ps = 1} )
if lc then return mw.text.split( lc, "[, ]+" ) end
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
Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1=
function p.getPropOfProp(frame)
are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to
return getPropOfProp(frame.args)
{{citation}} for rendering.
end
 
]]
 
-- wraps a string in nowiki unless disable flag is set
local function wrap_nowiki(str)
local function wrap_nowiki(str, disable)
if disable then return str or '' end
return mw.text.nowiki(str or '')
end
 
-- sort sequence table whose values are key-value pairs by key
function citeq.cite_q (frame)
local citeq_argsfunction =comp_key(a, {};b)
return a[1] < b[1]
local expand = ''; -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code>
end
 
-- sort sequence table whose values are key-value pairs by value
for k, v in pairs(frame:getParent().args) do
local function comp_val(a, b)
if in_array (k, {'expand', '_debug'}) then
return a[2] < b[2]
if is_set(v) then
end
expand = v; -- record setting but don't pass |expand= to {{citation}}
end
else
citeq_args[k] = v
end
end
 
--[[-------------------------< C I T E _ Q >------------------------------------------------------------------
for k, v in pairs(frame.args) do
Takes standard CS1|2 template parameters and passes all to {{citation}}. If neither of |author= and |author1=
citeq_args[k] = v
are set, calls get_authors() to try to get an author name-list from Wikidata. The result is passed to
end
{{citation}} for rendering.
--]]
local qid = citeq_args.qid
function p._cite_q (citeq_args)
local frame = mw.getCurrentFrame()
 
-- parameters that don't get passed to Citation
local expand = citeq_args.expand -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code>
local qid = citeq_args.qid or citeq_args[1]
local wdl = citeq_args.wdl
local template = citeq_args.template
citeq_args.expand = nil
citeq_args[1] = nil
citeq_args.qid = nil
citeq_args.wdl = nil
citeq_args.template = nil
 
-- if title supplied, flag to not read html title
local titleforced = (citeq_args.title ~= nil)
 
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
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 citeq_args.languagelangcodes[1] then
-- try to find language of work
langcodes = _lang_code(qid)
end
if not langcodes[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, psfwd = 1"ALL", osd = "no", noicon = "true", qid = qid, maxvals = data.maxvals, linked = data.linked, rank = data.rank or "best", citeq_args[name] } )
if data.populate_from_journal then
citeq_args[name]local publishedin = getValue( {"P1433", ps = 1, qid = qid, maxvals = 0, citeq_args[name], qual = data.id, qualsonly = 'yes'} )
citeq_args[name] = citeq_args[name]publishedin or getPropOfProp({qid = qid, prop1 = "P1433", prop2 = data.id, maxvals = data.maxvals, ps = 1})
end
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 if no lang specified
citeq_args.language = citeq_args.language or qid_languages[1]
end
end
Line 386 ⟶ 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
citeq_args.url = getValue( {"P2699", ps = 1, qid = qid, maxvals = 0, citeq_args.url } ) -- try url
 
-- if url then see if there's an archive: citeq_args.url
local slink = mw.wikibase.getSitelink(qid)
local url
local label = mw.wikibase.getLabel(qid) or citeq_args.language and mw.wikibase.getLabelByLang(qid, citeq_args.language)
if not citeq_args.url then
local slink_flag = false
for i, pr in ipairs( {"P953", "P856", "P2699"} ) do
local wrap_title = ''
url = getValue( {pr, ps = 1, qid = qid, maxvals = 1, qual="P1065" } )
if citeq_args.title then
if slinkurl then
citeq_args.url = nilmw.text.split( url, " (", true )[1]
local arcurl = mw.ustring.match( url, " %((.*)%)" ) -- when there is an archive url, <url> holds: url<space>(archive url); here extract the archive url if present
wrap_title = wrap_nowiki(citeq_args.title)
if arcurl then
slink_flag = true
local arcy, arcm, arcd = arcurl:match("(20%d%d)%p?(%d%d)%p?(%d%d)")
else
if arcy and arcm and arcd then
citeq_args.title = wrap_nowiki(citeq_args.title)
citeq_args["archive-url"] = arcurl
end
citeq_args["archive-date"] = tonumber(arcd) .. " " .. i18n.months[tonumber(arcm)] .. " " .. arcy
else
end
if slink then
end
citeq_args.url = nil
break
if slink:lower() == label:lower() then
citeq_args.title = '[[' .. slink .. ']]'
else
wrap_title = wrap_nowiki(slink:gsub("%s%(.+%)$", ""):gsub(",.+$", ""))
slink_flag = true
end
else
citeq_args.title = wrap_nowiki(label)
end
end
 
if slink_flag then
if slinkciteq_args.publisher == wrap_title"Unknown" then -- directlook linkfor "stated as" (P1932)
local stated_as = getValue( {"P123", ps = 1, qid = qid, maxvals = 1, qual="P1932", qo="y"} )
citeq_args.title = '[[' .. slink .. ']]'
if stated_as then citeq_args.publisher = stated_as end
else -- piped link
end
citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]'
 
if not titleforced then
-- Handle subtitle.
if citeq_args.title then
local subtitle = mw.wikibase.getBestStatements (qid, 'P1680');
if 0 ~= #subtitle then
subtitle = subtitle[1].mainsnak.datavalue.value.text;
citeq_args.title = citeq_args.title .. ": " .. subtitle
end
end
local htmltitle = getValue( {"P1476", qual = "P6833", ps = 1, qid = qid, maxvals = 1, qo = "y"} )
if htmltitle then
citeq_args.title = htmltitle:gsub("</?i>", "''")
else
local title_display = citeq_args.title
or mw.wikibase.getLabel(qid)
or (langcodes[1] and mw.wikibase.getLabelByLang(qid, langcodes[1]))
or ("No label or title -- debug: " .. qid)
if citeq_args.url then
citeq_args.title = wrap_nowiki(title_display)
else
local slink = mw.wikibase.getSitelink(qid)
local slink_flag = false
local wrap_title = ''
local wslink = false
if not slink then
-- See if we have wikisource
if not citeq_args.url then
local wikisource_sitelink = mw.wikibase.getSitelink(qid, "enwikisource") or nil
if wikisource_sitelink then
slink = ':s:'..wikisource_sitelink
wslink = true
end
end
end
if citeq_args.title then
if slink then
wrap_title = wrap_nowiki(citeq_args.title)
slink_flag = true
else
citeq_args.title = wrap_nowiki(citeq_args.title)
end
else
if slink and not wslink then
if slink:lower() == title_display:lower() then
citeq_args.title = '[[' .. slink .. ']]'
else
wrap_title = wrap_nowiki(slink:gsub("%s%(.+%)$", ""):gsub(",.+$", ""))
slink_flag = true
end
elseif wslink then
wrap_title = wrap_nowiki(title_display)
slink_flag = true
else
citeq_args.title = wrap_nowiki(title_display)
end
end
if slink_flag then
if slink == wrap_title and not wslink then -- direct link
citeq_args.title = '[[' .. slink .. ']]'
else -- piped link
citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]'
end
end
end
end
end
Line 446 ⟶ 583:
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 452 ⟶ 589:
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 458 ⟶ 595:
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 477 ⟶ 614:
end
if author_count > 8 then -- convention in astronomy journals, optional mode for this?
citeq_args[if 'display-authorsall'] == citeq_args['display-authors'] or 3then
citeq_args['display-authors'] = nil; -- unset because no longer needed
else
citeq_args['display-authors'] = citeq_args['display-authors'] or 3 -- limit to three displayed names
end
end
 
local editor_count = 0
for k, v in pairs(citeq_args) do
if k:find("^editor%d+$") then
editor_count = editor_count + 1
end
end
if editor_count > 8 then -- convention in astronomy journals, optional mode for this?
citeq_args[if 'display-editorsall'] == citeq_args['display-editors'] or 3then
citeq_args['display-editors'] = nil; -- unset because no longer needed
else
citeq_args['display-editors'] = citeq_args['display-editors'] or 3 -- limit to three displayed names
end
end
 
-- change edition to ordinal if it's set and numeric
-- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list
citeq_args.edition = citeq_args.edition and p.makeOrdinal(citeq_args.edition)
local list_sep = '. ';
 
if citeq_args.mode ~= 'cs1' then
-- code to make a guess what template to use from the supplied parameters
list_sep = ', ';
-- (first draft for proof-of-concept)
if citeq_args.isbn then
template = template or "book"
citeq_args.asin = nil -- suppress ASIN if ISBN exists
elseif citeq_args.journal then
template = template or "journal"
elseif citeq_args.website then
template = template or "web"
elseif citeq_args.arxiv then
template = template or "arxiv"
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}}.
-- support arXiv classification
local old_id = citeq_args.id;
if wdlciteq_args.arxiv then -- show WD logo
local arxiv_class
id = id .. '[[File:Wikidata-logo.svg|16px|alt=|link=]]'; -- possibly replace by WD edit icon?
arxiv_class = getValue( {"P818", qual = "P820", qid = qid, maxvals = 1, rank="best", qualsonly=true} )
end
if is_set (old_id)arxiv_class then
-- See https://en.wikipedia.org/wiki/Template:Cite_arXiv
citeq_args.id = old_id .. list_sep .. id; -- append to user-specified contents
-- "class: arXiv classification, e.g. hep-th. Optional.
else
-- To be used only with new-style (2007 and later) eprint identifiers
citeq_args.id = id;
-- that do not include the classification."
citeq_args.class = arxiv_class
end
end
 
-- ************* |id= parameter **********************
if is_set(expand) then -- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like
-- Only include |id= if template is not arxiv
local expand_args = {'{{citation'}; -- init with citation template
if expandtemplate =~= "selfarxiv" then
-- |id= could hold more than one identifier pulled from Wikidata not supported by {{citation}}, right now only add our qid to the list
citeq_args.id = old_id; -- restore original |id= parameter
local list_sep = '. '
expand_args = {'{{cite Q|' .. qid}; -- expand to itself
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}}.
for p, v in pairs (citeq_args) do -- spin through citeq_args and
local old_id = citeq_args.id
table.insert (expand_args, p .. '=' .. v); -- add parameter name = value
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
 
-- clean up any blank parameters
for k, v in pairs(citeq_args) do
if v == "" then citeq_args[k] = nil end
end
 
-- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like
if expand then
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
local sorttable = {}
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 frame:preprocess (table.concat ({'<syntaxhighlight lang="wikitext" inline="1">', table.concat (expand_args, ' |') .. '}}', '</syntaxhighlight>'}));
end
-- make the nowiki'd string and done
return table.concat ({'<code>', frame:callParserFunction ('#tag:nowiki', table.concat (expand_args, ' |') .. '}}'), '</code>'})
end
 
-- ************* Assign template **********************
-- template is CS1 designator: journal, web, news, etc.
if template then
-- citeq_args.mode = citeq_args.mode or "cs1" -- a cs1 template already knows that it is cs1 so this line is superfluous
template = "Cite " .. template
else
-- citeq_args.mode = citeq_args.mode or "cs2" -- a cs2 template already knows that it is cs2 so this line is superfluous
template = "Citation"
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 = 'citation'template, args = citeq_args} .. erratumid .. opt_cat -- render the template
end
 
function p.cite_q (frame)
return citeq
local args = {}
for k, v in pairs(frame:getParent().args) do
if v ~= "" then args[k] = v end
end
for k, v in pairs(frame.args) do
if v ~= "" then args[k] = v end
end
args.qid = args.qid or args[1] or ""
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
return p