Module:Cite Q
This module depends on the following other modules: |
Usage
[edit]A wrapper for {{Citation}}
, which calls available values from Wikidata.
An example of an article using this template for all of its references is en:South Pole Telescope; an example using Harvard style citations is en:Suffix automaton.
By default, if there are more than eight author names, the template displays three, followed by "et al". This can be changed using |display-authors=
; using that parameter with no value displays them all. The same applies to multiple editors - see the test-case pages.
Future developments
[edit]- Once robust the functionality should be merged into
{{Citation}}
- Eventually, each signed-in reader should be able to set, under their "Preferences", the style in which they wish to see citations rendered.
- We should have a [[:mediawiki:|Global templates|lobal template repository]], so the code can be used by multiple wikis, without having to manually copy it after every update.g
Parameters
[edit]|1=
= Wikidata QID for the article
Additionally, any named parameter used in {{Citation}}
may be entered and will overwrite the value in Wikidata. Using such parameters, with a value of unset
, will suppress display of data from Wikidata.
Blank
[edit]<ref name="">{{Cite Q| XXQIDXX }}</ref>
Reference naming
[edit]For ease of use, you may wish to name your references to reflect the cited work, for example:
<ref name="Williams-2010">{{Cite Q|Q15625490}}</ref>
Parameter / entity map
[edit]This section lists where each of the template's supported parameters gets its data. P734}}
Bibliographic parameters
[edit]|authorn=
= author (P50); author name string (P2093)|chapter=
= chapter (P792)|date=
= publication date (P577)|editorn=
= editor (P98)|issue=
= issue (P433)|journal=
= published in (P1433)|language=
= language of work or name (P407)|others=
= composer (P86), illustrator (P110)|place=
= place of publication (P291)|publisher=
= publisher (P123)|series=
= part of the series (P179)|title=
= title (P1476)|title=
= Wikidata label|url=
= full work available at URL (P953), official website (P856), URL (P2699)|volume=
= volume (P478)
Identifier parameters
[edit]|arxiv=
= arXiv ID (P818)|bibcode=
= ADS bibcode (P819)|biorxiv=
= BioRxiv ID (P3951)|citeseerx=
= CiteSeerX article ID (P3784)|doi=
= DOI (P356)|hdl=
= Handle ID (P1184)|isbn=
= ISBN-13 (P212)|isbn=
= ISBN-10 (P957)|ismn=
= ISMN (P1208)|jstor=
= JSTOR article ID (P888)|lccn=
= Library of Congress Control Number (LCCN) (bibliographic) (P1144)|mr=
= Mathematical Reviews ID (P889)|oclc=
= OCLC control number (P243)|ol=
= Open Library ID (P648)|osti=
= OSTI article ID (P3894)|pmc=
= PMC publication ID (P932)|pmid=
= PubMed publication ID (P698)|ssrn=
= SSRN article ID (P893)
Examples
[edit]{{Cite Q|Q15625490}}
- Jeffrey T. Williams; Kent E. Carpenter; James L. Van Tassell; Paul Hoetjes; Wes Toller; Peter Etnoyer; Michael Smith (21 May 2010), "Biodiversity Assessment of the Fishes of Saba Bank Atoll, Netherlands Antilles", ISSN 1932-6203, 5 (5), Bibcode:2010PLoSO...510676W, doi:10.1371/JOURNAL.PONE.0010676, ISSN 1932-6203, PMC 2873961, PMID 20505760, Wikidata Q15625490
{{Cite Q|Q15625490|page=42}}
- Jeffrey T. Williams; Kent E. Carpenter; James L. Van Tassell; Paul Hoetjes; Wes Toller; Peter Etnoyer; Michael Smith (21 May 2010), "Biodiversity Assessment of the Fishes of Saba Bank Atoll, Netherlands Antilles", ISSN 1932-6203, 5 (5): 42, Bibcode:2010PLoSO...510676W, doi:10.1371/JOURNAL.PONE.0010676, ISSN 1932-6203, PMC 2873961, PMID 20505760, Wikidata Q15625490
{{Cite Q|Q15625490|access-date=18 May 2017}}
- Jeffrey T. Williams; Kent E. Carpenter; James L. Van Tassell; Paul Hoetjes; Wes Toller; Peter Etnoyer; Michael Smith (21 May 2010), "Biodiversity Assessment of the Fishes of Saba Bank Atoll, Netherlands Antilles", ISSN 1932-6203, 5 (5), Bibcode:2010PLoSO...510676W, doi:10.1371/JOURNAL.PONE.0010676, ISSN 1932-6203, PMC 2873961, PMID 20505760, Wikidata Q15625490, retrieved 18 May 2017
{{Cite Q|Q15625490|quote=lorem ipsum}}
- Jeffrey T. Williams; Kent E. Carpenter; James L. Van Tassell; Paul Hoetjes; Wes Toller; Peter Etnoyer; Michael Smith (21 May 2010), "Biodiversity Assessment of the Fishes of Saba Bank Atoll, Netherlands Antilles", ISSN 1932-6203, 5 (5), Bibcode:2010PLoSO...510676W, doi:10.1371/JOURNAL.PONE.0010676, ISSN 1932-6203, PMC 2873961, PMID 20505760, Wikidata Q15625490,
lorem ipsum
{{Cite Q|Q25766745}}
- Andy Mabbett (2010), Chris Charlesworth (ed.), Pink Floyd: The Music and the Mystery, Omnibus Press, OCLC 762731304, OL 16228023W, Wikidata Q25766745
{{Cite Q|Q25766745 |chapter=The Final Cut}}
(with chapter specified)- Andy Mabbett (2010), "The Final Cut", in Chris Charlesworth (ed.), Pink Floyd: The Music and the Mystery, Omnibus Press, OCLC 762731304, OL 16228023W, Wikidata Q25766745
{{Cite Q|Q25766745 |pages=48-52}}
(with pages)- Andy Mabbett (2010), Chris Charlesworth (ed.), Pink Floyd: The Music and the Mystery, Omnibus Press, pp. 48–52, OCLC 762731304, OL 16228023W, Wikidata Q25766745
{{Cite Q|Q15625490|access-date=18 May 2017}}
- Jeffrey T. Williams; Kent E. Carpenter; James L. Van Tassell; Paul Hoetjes; Wes Toller; Peter Etnoyer; Michael Smith (21 May 2010), "Biodiversity Assessment of the Fishes of Saba Bank Atoll, Netherlands Antilles", ISSN 1932-6203, 5 (5), Bibcode:2010PLoSO...510676W, doi:10.1371/JOURNAL.PONE.0010676, ISSN 1932-6203, PMC 2873961, PMID 20505760, Wikidata Q15625490, retrieved 18 May 2017
{{Cite Q|Q25766745|mode=cs1}}
- Andy Mabbett (2010). Chris Charlesworth (ed.). Pink Floyd: The Music and the Mystery. Omnibus Press. OCLC 762731304. OL 16228023W. Wikidata Q25766745.
{{Cite Q|Q25766745|mode=cs2}}
- Andy Mabbett (2010), Chris Charlesworth (ed.), Pink Floyd: The Music and the Mystery, Omnibus Press, OCLC 762731304, OL 16228023W, Wikidata Q25766745
{{Cite Q|Q25766745|author-mask=1}}
- — (2010), Chris Charlesworth (ed.), Pink Floyd: The Music and the Mystery, Omnibus Press, OCLC 762731304, OL 16228023W, Wikidata Q25766745
For additional examples, see testcases.
Module:Wd
[edit]Module:Wd can automatically cause this template to be invoked, e.g.,
{{Wikidata|references|raw|Q2978|P2046}}
- Error: Unable to display the reference properly. See the documentation for details. Alle politisch selbständigen Gemeinden mit ausgewählten Merkmalen am 31.12.2018 (4. Quartal). Federal Statistical Office.
currently causes the following to be invoked:
{{Cite Q|Q15707237|pages=242}}
- Bavarian State Office for Statistics and Data, ed. (1991), Amtliches Ortsverzeichnis für Bayern (in German), Munich: Bavarian State Office for Statistics and Data, p. 242, Wikidata Q15707237
because an area (P2046) statement on Regensburg (Q2978) is referenced to be stated in (P248) Amtliches Ortsverzeichnis für Bayern (1991) (Q15707237) with page(s) (P304) = 242.
Issues
[edit]See en:Template:Cite Q/doc#Issues
require('strict')
local wdib = require('Module:WikidataIB')
local getValue = wdib._getValue
local getPropOfProp = wdib._getPropOfProp
local followQid = wdib._followQid
local i18n = {
["unknown-author"] = mw.wikibase.getLabel("Q4233718"):gsub("^%l", mw.ustring.upper),
["unknown-author-trackingcat"] = "[[Category:Cite Q - author unknown]]",
}
local simple_properties = { -- PXXX, is multiple?, linked?
publisher = {id = "P123", maxvals = 1},
oclc = {id = "P243", maxvals = 1},
['publication-place'] = {id = "P291", maxvals = 0, linked = 'no'}, -- publication place (don't put into |place=; is treated specially in {{citation}} if both are given)
doi = {id = "P356", maxvals = 1}, -- take care of |doi-broken-date= (WD "reason for deprecation"/"stated as") and |doi-access= (WD "access status")?
issue = {id = "P433", maxvals = 0, populate_from_journal = true}, -- distinguish from |number= ("P1545"?) if both are given (still blocked by {{citation}}, but will be supported in the future)
pmid = {id = "P698", maxvals = 1},
-- gbooks = {id = "P675", maxvals = 1}, -- to be added to {{citation}}
-- ia = {id = "P724", maxvals = 1}, -- to be added to {{citation}}
arxiv = {id = "P818", maxvals = 1},
bibcode = {id = "P819", maxvals = 1}, -- take care of |bibcode-access=?
jstor = {id = "P888", maxvals = 1}, -- take care of |jstor-access=?
mr = {id = "P889", maxvals = 1},
rfc = {id = "P892", maxvals = 1},
zbl = {id = "P894", maxvals = 1},
ssrn = {id = "P893", maxvals = 1},
place = {id = "P1071", maxvals = 0, linked = 'no'}, -- written-at place
-- ['total-pages'] = {id = "P1104", maxvals = 0, linked = 'no'}, -- to be added to {{citation}} / COinS &rft.tpages=
-- coden = {id = "P1159", maxvals = 1}, -- to be added to {{citation}} / COinS &rft.coden=
s2cid = {id = "P8299", maxvals = 1}, -- take care of |s2cid-access=?
pmc = {id = "P932", maxvals = 1}, -- take care of |pmc-embargo-date= (WD "reason for deprecation")?
lccn = {id = "P1144", maxvals = 1},
hdl = {id = "P1184", maxvals = 1}, -- take care of |hdl-access=?
ismn = {id = "P1208", maxvals = 1},
journal = {id = "P1433", maxvals = 1},
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)
-- ['catalog-number'] = {id = "P528", maxvals = 0}, -- to be added to {{citation}} / COinS &rft.artnum=
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?
-- 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
chapter = {id = "P792", maxvals = 1},
['publication-date'] = {id = "P577", maxvals = 1, populate_from_journal = true}, -- publication date (don't use |date=; is treated specially in {{citation}} if both are given.)
series = {id = "P179", maxvals = 1, populate_from_journal = true},
version = {id = "P348", maxvals = 0},
edition = {id = "P393", maxvals = 0},
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 = 1},
url = {id = "P953", maxvals = 1}, -- full work available at
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=)
-- sheets = {id = "P7416", maxvals = 0, populate_from_journal = true},
-- interviewer = {id = "P?", maxvals = 0}, -- does **not** go to "others" section! Multiple interviewers should be n-enumerated
illustrator = {id = "P110", maxvals = 10, others = true}, -- goes to "others" section
-- foreword and afterword, when contributions to another author's work, are contributions so belong in |contribution=;
-- the writer's name goes in |contributor=; requires |title= and |author=
-- However, this might need to add support for multiple contributors and their roles to {{citation}}, see Help_talk:Citation_Style_1#Others
-- foreword = {id = "P2679", maxvals = 10, others = true}, -- goes to "others" section
-- afterword = {id = "P2680", maxvals = 10, others = true}, -- goes to "others" section
composer = {id = "P86", maxvals = 10, others = true}, -- goes to "others" section
animator = {id = "P6942", maxvals = 10, others = true}, -- goes to "others" section
director = {id = "P57", maxvals = 10, others = true}, -- goes to "others" section
screenwriter = {id = "P58", maxvals = 10, others = true}, -- goes to "others" section
signatory = {id = "P1891", maxvals = 10, others = true}, -- goes to "others" section
presenter = {id = "P371", maxvals = 10, others = true}, -- goes to "others" section
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
if val then
if in_array (val, {'accept', '))((', ':d:'}) then
val = '((' .. wd_val .. '))'
elseif '((accept))' == val then
val = 'accept'
elseif '(())(())' == val then
val = '))(('
elseif '((:d:))' == val then
val = ':d:'
else
val = wd_val
end
end
return val
end
-- function to fetch a value to display
local function makelink(v, out, link, maxpos, wdl)
local label
if v.mainsnak.snaktype == "value" then
if v.mainsnak.datatype == "wikibase-item" then
local qnumber = v.mainsnak.datavalue.value.id
local sitelink = mw.wikibase.getSitelink(qnumber)
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)
if label then
label = mw.text.nowiki(label)
else
label = qnumber -- should add tracking category
end
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)
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
link[position] = sitelink
else
if wdl then
-- show that there's a Wikidata entry available
out[position] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]] <span title='" .. i18n["errors"]["local-article-not-found"] .. "'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>"
else
-- no Wikidata links wanted, so just give the plain label
out[position] = label
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)
end
maxpos = math.max(maxpos, position)
out[position] = v.mainsnak.datavalue.value
else
-- not a wikibase-item or a string!
end
else
-- code here if we want to return something when author is "unknown"
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 "")
end
maxpos = maxpos + 1
out[maxpos] = label
end
return maxpos
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:
nl_type - type of name list to fetch: nl_type = 'author' for authors; 'editor' for editors; 'translator' for translators
args - pointer to the parameter arguments table from the template call
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
]=]
local function get_name_list (nl_type, args, qid, wdl)
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
-- wdl is a Boolean passed to enable links to Wikidata when no article exists
-- if "false" or "no" or "0" is passed set it false
-- if nothing or an empty string is passed set it false
if wdl and (#wdl > 0) then
wdl = wdl:lower()
wdl = in_array (wdl, {"false", "no", "0"})
else
-- wdl is empty, so
wdl = false
end
local entity = mw.wikibase.getEntity(qid)
local props = nil
local fallback = nil
if entity and entity.claims then
props = entity.claims[propertyID]
if fallbackID then
fallback = entity.claims[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
-- So now we have something to return:
-- table 'out' is going to store the names(s):
-- and table 'link' will store any links to the name's article
local out = {}
local link = {}
local maxpos = 0
if props and props[1] then
for k, v in pairs(props) do
maxpos = makelink(v, out, link, maxpos, wdl)
end
end
if fallback and fallback[1] then
-- second properties
for k, v in pairs(fallback) do
maxpos = makelink(v, out, link, maxpos, wdl)
end
end
-- if there's anything to return, then insert the additions in the template arguments table
-- in the form |author1=firstname secondname |author2= ...
-- Renumber, in case we have inconsistent numbering
local keys = {}
for k, v in pairs(out) do
keys[#keys + 1] = k
end
table.sort(keys) -- as they might be out of order
for i, k in ipairs(keys) do
mw.log(i .. " " .. k .. " " .. (out[k]))
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
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 link[k] then
args[nl_type .. '-link' .. i] = args[nl_type .. '-link' .. i] or link[k] -- author-linkn or editor-linkn
end
end
end
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.
]]
local function wrap_nowiki(str)
return mw.text.nowiki(str or '')
end
function citeq.cite_q (frame)
local citeq_args = {};
local expand = ''; -- when set to anything, causes {{cite q}} to render <code><nowiki>{{citation|...}}</nowiki></code>
for k, v in pairs(frame:getParent().args) do
if in_array (k, {'expand', '_debug'}) then
if is_set(v) then
expand = v; -- record setting but don't pass |expand= to {{citation}}
end
else
citeq_args[k] = v
end
end
for k, v in pairs(frame.args) do
citeq_args[k] = v
end
local qid = citeq_args.qid
local wdl = citeq_args.wdl
citeq_args.qid = nil
citeq_args.wdl = nil
local oth = {}
citeq_args.language = citeq_args.language or getPropOfProp( {qid = qid, prop1 = "P407", prop2 = "P218", ps = 1} )
if citeq_args.language == '' then
citeq_args.language = nil
end
if not citeq_args.language then
-- try fallback to journal's language
local journal_qid = followQid({qid = qid, props = "P1433"})
citeq_args.language = journal_qid and getPropOfProp( {qid = journal_qid, prop1 = "P407", prop2 = "P218", ps = 1} )
end
for name, data in pairs(simple_properties) do
citeq_args[name] = getValue( {data.id, ps = 1, qid = qid, maxvals = data.maxvals, linked = data.linked, citeq_args[name] } )
if data.populate_from_journal then
citeq_args[name] = getValue( {"P1433", ps = 1, qid = qid, maxvals = 0, citeq_args[name], qual = data.id, qualsonly = 'yes'} )
citeq_args[name] = citeq_args[name] 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.language } )
if citeq_args[name]:find('^Q%d+$') then -- qid was returned
-- try fallback to qid's native language
local qid_language = getPropOfProp( {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_language } )
if citeq_args[name]:find('^Q%d+$') then -- qid was returned again
citeq_args[name] = nil
end
end
end
if data.others then
oth[#oth + 1] = citeq_args[name] and (name:gsub("^%l", string.upper) .. ": " .. citeq_args[name])
citeq_args[name] = nil
end
end
citeq_args.others = citeq_args.others or table.concat(oth, ". ")
if citeq_args.others == "" then
citeq_args.others = nil
end
citeq_args.journal = citeq_args.journal and citeq_args.journal:gsub("^''", ""):gsub("''$", ""):gsub("|''", "|"):gsub("'']]", "]]")
citeq_args.ol = (getValue( {"P648", ps = 1, qid = qid, maxvals = 1, citeq_args.ol } ) or ''):gsub("^OL(.+)$", "%1")
if citeq_args.ol == "" then
citeq_args.ol = nil
end
-- TBD. Take care of |ol-access=?
citeq_args.biorxiv = citeq_args.biorxiv and ("10.1101/" .. citeq_args.biorxiv)
citeq_args.isbn = getValue( {"P957", ps = 1, qid = qid, maxvals = 0, citeq_args.isbn } ) -- try ISBN 10
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
local slink = mw.wikibase.getSitelink(qid)
local label = mw.wikibase.getLabel(qid) or citeq_args.language and mw.wikibase.getLabelByLang(qid, citeq_args.language)
local slink_flag = false
local wrap_title = ''
if citeq_args.title then
if slink then
citeq_args.url = nil
wrap_title = wrap_nowiki(citeq_args.title)
slink_flag = true
else
citeq_args.title = wrap_nowiki(citeq_args.title)
end
else
if slink then
citeq_args.url = nil
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 slink == wrap_title then -- direct link
citeq_args.title = '[[' .. slink .. ']]'
else -- piped link
citeq_args.title = '[[' .. slink .. '|' .. wrap_title .. ']]'
end
end
-- TBD: incorporate |at, |sheets= and |sheet= here as well
-- Sort out what should happen if several of them are given at the same time
if citeq_args.page or citeq_args.p then -- let single take precedence over multiple
citeq_args.pages = nil
citeq_args.pp = nil
end
if citeq_args.pages then
local _, count = string.gsub(citeq_args.pages, "[,;%s]%d+", "")
if count == 1 then
citeq_args.page = citeq_args.pages
citeq_args.pages = nil
end
end
if is_set (qid) then
if not is_set (citeq_args.author) and not is_set (citeq_args.author1)
and not is_set (citeq_args.subject) and not is_set (citeq_args.subject1)
and not is_set (citeq_args.host) and not is_set (citeq_args.host1)
and not is_set (citeq_args.last) and not is_set (citeq_args.last1)
and not is_set (citeq_args.surname) and not is_set (citeq_args.surname1)
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
if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1)
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
if not is_set (citeq_args.translator) and not is_set (citeq_args.translator1)
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
for k, v in pairs(citeq_args) do
if in_array (v, {'(())', 'unset', 'ignore'}) or 'string' ~= type(k) then -- empty accept-as-is-written (()) markup to indicate an empty/unused parameter value, other ((...)) markups are deliberately passed down to {{citation}}
citeq_args[k] = nil
elseif in_array (v, {'((unset))', '((ignore))'}) then -- strip off markup for free-text values clashing with local keywords
citeq_args[k] = 'unset'
end
end
local author_count = 0
for k, v in pairs(citeq_args) do
if k:find("^author%d+$") then
author_count = author_count + 1
end
end
if author_count > 8 then -- convention in astronomy journals, optional mode for this?
citeq_args['display-authors'] = citeq_args['display-authors'] or 3
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['display-editors'] = citeq_args['display-editors'] or 3
end
-- |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 = '[[Wikispecies:Wikidata|Wikidata]] [[: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
if is_set(expand) then -- if |expand=<anything>, write a nowiki'd version to see what the {{citation}} template call looks like
local expand_args = {'{{citation'}; -- 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
for p, v in pairs (citeq_args) do -- spin through citeq_args and
table.insert (expand_args, p .. '=' .. v); -- add parameter name = value
end
-- make the nowiki'd string and done
return table.concat ({'<code>', frame:callParserFunction ('#tag:nowiki', table.concat (expand_args, ' |') .. '}}'), '</code>'})
end
local opt_cat = ''
if getValue( {"P5824", ps = 1, qid = qid} ) then
opt_cat = '[[Category:Cite Q - cites a retracted work]]'
end
if getValue( {"P1366", ps = 1, qid = qid} ) then
opt_cat = opt_cat .. '[[Category:Cite Q - cites a replaced work]]'
end
return frame:expandTemplate{title = 'citation', args = citeq_args} .. opt_cat -- render the template
end
return citeq