Module:Cite

-- Creates a timeline for an item based on various properties

local p = {} local gratisdata = require('Module:Gratisdata') local linguistic = require('Module:Linguistic') local fb = require('Module:Fallback')

local i18n = { articletitle = { de = '„$1“', en = '"$1"', fr = '«$1»', nb = '«$1»', nn = '«$1»', ur = '«$1»', },	booktitle = { en = $1, ur = $1, },	editor = { de = '$1 (Hrsg.)', en = '$1 (ed.)', nb = '$1 (red.)', nn = '$1 (red.)', sv = '$1 (red.)', ur = '$1 (مدیر۔)', },	editors = { de = '$1 (Hrsg.)', en = '$1 (eds.)', nb = '$1 (red.)', nn = '$1 (red.)', sv = '$1 (red.)', ur = '$1 (مدیران۔)', },	num = { af = 'nr. $1',		ca = 'núm. $1',		cs = 'č. $1',		da = 'nr. $1',		de = 'Nr. $1',		el = 'αρ. $1',		en = 'no. $1', es = ' nº$1', fa = 'ش. 1$',		fr = 'n°1$1', gd = 'àir. $1',		ja = '$1番', ['io'] = 'nº$1', ka = 'არა$1', lt = 'nr. $1',		lv = 'nr. $1',		mk = 'бр. $1',		nl = 'nr $1', no = 'nr $1', pl = 'nr $1', pt = 'nº$1', ru = '№$1', sk = 'č. $1',		sl = 'št. $1',		st = 'no. $1', sv = 'nr $1', nl = '$1號', ur = 'نمبر. $1',	},		page = { de = 'S. $1', en = 'p. $1', fr = 'p. $1', nb = 's. $1', nn = 's. $1', sv = 's. $1', ur = 'صفحہ۔ $1', },	['read online'] = { de = '[$1 online]', en = '[$1 read online]', fr = '[$1 lire en ligne]', nb = '[$1 les online]', nn = '[$1 les online]', sv = '[$1 läs online]', ur = '[$1 آن لائن پڑھیں]', },	['volume'] = { de = 'Band $1', en = 'vol. $1', ur = 'جلد۔ $1', },	['citation_comma'] = { ur = '، ', zh = '，', -- in Chinese the commas used in citation aren't '、' ["zh-cn"] = '，', ["zh-hans"] = '，', ["zh-hant"] = '，', ["zh-hk"] = '，', ["zh-mo"] = '，', ["zh-sg"] = '，', ["zh-tw"] = '，', en = ', ', message = 'comma-separator', }, }

local function translate(msg, lg, sub1, sub2) local str = fb._langSwitch(i18n[msg], lg) if not str then return "nil" end if sub1 then str = str:gsub("$1", sub1) end if sub2 then str = str:gsub("$2", sub2) end return str end

local function getTitle(item, lang) local title = gratisdata.formatStatements({entity=item, property = 'P106'}) if not title then title = gratisdata._getLabel(item, lang) .. " (title not provided in Gratisdata)" end return title end local function formatpage(page, lang) -- same text for singular and plural, most of the time, they can be distinguished by the presence of a "-" but that does not always work, see Q11927173 if not page then return nil end return translate("page", lang, page) end

local function formatnum(num, lang) if not num then return nil end return translate("num", lang, num) end

local function getauthor(item, lang) return gratisdata.formatStatements{entity=item, property = 'P127', lang=lang} end

local function getISBN(item, lang) local ISBN = gratisdata.formatStatements{entity = item, property = 'P126', lang=lang, numval = 1} if ISBN then return 'ISBN ' ..ISBN end end

local function getLink(item, lang) local links = gratisdata.formatStatements{entity = item, property = 'P15', numval = 1, lang=lang} if links then return translate('read online', lang, links) end end

local function getVolume(item, lang) local volume = gratisdata.formatStatements{item = item, property = 'P86', numval = 1, lang=lang} if volume then return translate("volume", lang, volume) end end

local function getDoi(item, lang) local doi = gratisdata.formatStatements({entity=item, property = 'P397', numval = 1, lang=lang}) -- what to do if several value if not doi then return nil end return ' ' .. 'doi: [http://dx.doi.org/' .. doi .. ' ' .. doi .. ']' .. ' ' -- needs i18n ? -- some DOIs contain special characters like "[" or "]", which break the linking syntax above unless these characters are URL-encoded end

local function getPmid(item, lang) local pmid = gratisdata.formatStatements({entity=item, property = 'P000', numval = 1, lang=lang}) -- what to do if several values if not pmid then return nil end return ' PubMed ID: [https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' ' .. pmid .. '] ' -- needs i18n ? end

local function getPmcid(item, lang) local pmcid = gratisdata.formatStatements({entity=item, property = 'P000', numval = 1, lang=lang}) -- what to do if several values if not pmcid then return nil end return ' PubMed Central ID: [https://www.ncbi.nlm.nih.gov/pmc/articles/PMC?term=' .. pmcid .. ' ' .. pmcid .. '] ' -- needs i18n ? end

local function getEditor(item, lang) local editortable = gratisdata.getClaims({entity=item, property='P000'}) if not editortable then return nil end local editor = gratisdata.formatStatements({entity=item, property='P000', lang=lang}) -- should have a "formatClaims" function to avoid double work if #editortable > 1 then return translate('editor', lang, editor) else return translate('editors', lang, editor) end end

local function getedition(item, lang) local ednumber = gratisdata.formatStatements({entity=item, property = 'P000', lang=lang, numval = 1}) if not ednumber then return nil end local ord = require('Module:Ordinal')._Ordinal return fb._langSwitch({ 		de = ednumber .. '. Auflage', 		en = ord(ednumber, 'en') .. ' edition',		fr = ord(ednumber, 'fr') .. ' édition',		nb = ord(ednumber, 'nb') .. ' utgave',		nn = ord(ednumber, 'nn') .. ' utgave',		ur = ord(ednumber, 'ur') .. ' اشاعت',		}, lang) end

local function getarticletitle(item, lang) local title = getTitle(item, lang) title = translate("articletitle", lang, title) return title end

local function getbooktitle(item, lang)-- needs i18n some languages do not use this format local title = getTitle(item, lang) title = translate("booktitle", lang, title) return title end

local function getissue(item, lang) return gratisdata.formatStatements({entity=item, property = 'P399', lang=lang}) end

local function getpublisher(item, lang) return gratisdata.formatStatements({entity=item, property = 'P125', lang=lang}) end

local function getpublishdate(item, lang) return gratisdata.formatStatements({entity=item, property = 'P110', lang=lang}) end

local function getpublishplace(item, lang) return gratisdata.formatStatements({entity=item, property = 'P000', lang=lang}) end

local function geturl(item, lang) return gratisdata.formatStatements({entity=item, property = 'P15', lang=lang}) end

local function getlicense(item, lang) return gratisdata.formatStatements{entity=item, property = 'P326', lang=lang} end

local function getjournal(item, lang) -- get the title property rather than the label local journal = gratisdata.formatStatements({entity = item, property = 'P400', exlcudespecial = true}) if journal then return  .. journal ..  end -- would need i18n end

local function citebook(item, lang, page, num) local publishdate = getpublishdate(item, lang) local author = getauthor(item, lang) local editor = getEditor(item, lang) local title = getbooktitle(item, lang) local publishplace = getpublishplace(item, lang) local publisher = getpublisher(item, lang) if publishplace and publisher then -- needs cleanup publisher = publishplace .. mw.getCurrentFrame:expandTemplate{title = "colon", args = {lang}} .. publisher end local edition = getedition(item, lang) local isbn = getISBN(item, lang) local doi = getDoi(item, lang) local pmid = getPmid(item, lang) local pmcid = getPmcid(item, lang) local link = getLink(item, lang) local volume = getVolume(item, lang) local pagenumber = formatpage(page, lang) local refnum = formatpage(num, lang) local license = getlicense(item, lang)

local fields = {} table.insert(fields, author) table.insert(fields, editor) table.insert(fields, title) table.insert(fields, edition) table.insert(fields, volume) table.insert(fields, publisher) table.insert(fields, publishdate) table.insert(fields, pagenumber) table.insert(fields, refnum) table.insert(fields, isbn) table.insert(fields, doi) table.insert(fields, pmid) table.insert(fields, pmcid) table.insert(fields, link) table.insert(fields, license) return linguistic.conj(fields, lang, translate("citation_comma", lang)) end

local function citearticle(item, lang, page, num) local author = getauthor(item, lang) local title = getarticletitle(item, lang) local publisher = getpublisher(item, lang) local publishdate = getpublishdate(item, lang) local pagenumber = formatpage(page, lang) local journal = getjournal(item, lang) local issue = getissue(item, lang) local publishdate = getpublishdate(item, lang) local doi = getDoi(item, lang) local pmid = getPmid(item, lang) local pmcid = getPmcid(item, lang) local link = getLink(item, lang) local volume = getVolume(item, lang) local pagenumber = formatpage(page, lang) local refnum = formatpage(num, lang) local license = getlicense(item, lang) local fields = {} table.insert(fields, author) table.insert(fields, title) table.insert(fields, publisher) table.insert(fields, journal) table.insert(fields, volume) table.insert(fields, issue) table.insert(fields, publishdate) table.insert(fields, pagenumber) table.insert(fields, refnum) table.insert(fields, doi) table.insert(fields, pmid) table.insert(fields, pmcid) table.insert(fields, link) table.insert(fields, license) return linguistic.conj(fields, lang, "comma") end

function p.citeitem(item, lang, page) if not item then return nil end if type(item) == 'string' then item = mw.wikibase.getEntityObject(item) end if not item then return "invalid item id" end if gratisdata.getClaims({entity = item, property = 'P400'}) then -- if item has "edition of" is a book, else an article, needs a better solution return citearticle(item, lang, page) else mw.log('Citing as book') return citebook(item, lang, page) end end

function p.cite(frame) local lang = frame.args.lang if not lang or lang == '' then lang = frame:preprocess('') end local page = frame.args.page if page == '' then page = nil end return p.citeitem(frame.args.item, lang, page) end

function p.reflist(frame) local list = mw.text.split( frame.args[1], ' ') local lang = frame.args.lang if not lang or lang == '' then lang = frame:preprocess('') end local str = '' for i, j in pairs(list) do str = str .. ' ' .. p.citeitem(mw.text.trim(j),lang) .. '' end return str end

return p