Modul:Citeq

Documentation icon Moduldokumentation
require('Module:No globals')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--[[--------------------------< D A T E _ F R O M _ T I M E S T A M P >----------------------------------------E X P E R I M E N T A LThis code adapted from c:Module:Wikidata date returns an English language dmy format date.  Intended as a stopgapreturns a dmy English language date because Module:Citation/CS1/Date validation only understands en.wiki dateformats.This is an experiment and may not be required.  How reliable are wikidata dates?  Is it possible to enter invaliddates into wikidata?  If yes, then this experiment and the cs1|2 date validation is required; if no, then thisexperiment is not required but cs1|2 date validation may require modification to make sure that ancilliary functionalitylike COinS dates is still handled correctly.{{#invoke:Citeq|date_from_timestamp|item=Q19858624|property=P577}}]]local month_name = {'januar', 'februar', 'marts', 'april', 'maj', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'december'};function citeq.date_from_timestamp (frame) local entity = mw.wikibase.getEntity (frame.args.item); local wd_date_table = {}-- table to store QuickStatements if entity and entity.claims and entity.claims[frame.args.property] then-- if we have wikidata item and item has the propertyfor _, statement in pairs (entity:getBestStatements (frame.args.property)) dolocal snak = statement.mainsnakif (snak.snaktype == 'value' and snak.datatype == 'time') then local v = snak.datavalue.valuetable.insert (wd_date_table, v.time ..'/' .. v.precision)endend-- for loopelsereturn '';-- no value, return an empty stringend-- if entity thenlocal year, month, day, precision = wd_date_table[1]:match ('(%d%d%d%d)%-(%d%d)%-(%d%d)[^/]+/(%d+)');local date_tbl = {};if '00' ~= day then-- for now ignore precisiontable.insert (date_tbl, tonumber(day));-- non-zero day valuesendif '00' ~= month thentable.insert (date_tbl, month_name[tonumber(month)]);-- for now, English names only; requires change to cs1|2 date validation module to support other date formats/namesendtable.insert (date_tbl, year);return table.concat (date_tbl, ' ') or '';-- return a dmy format dateend--[[--------------------------< W I K D A T A _ L A B E L >----------------------------------------------------Make a linked label to the appropriate language wikipedia article; plain-text label else.{{#invoke:citeq|wikidata_label}}]]function citeq.wikidata_label ()local this_wiki_code = mw.language.getContentLanguage():getCode();-- get this wikipedia's language code (subdomain)if string.match (mw.site.server, 'wikidata') thenthis_wiki_code = mw.getCurrentFrame():preprocess('{{int:lang}}');-- on wikidata so use interface language setting insteadendlocal wd_article = mw.wikibase.getEntity ('Q2013'):getSitelink (this_wiki_code .. 'wiki');-- fetch wikidata article title from wdif wd_article thenwd_article = table.concat ({'[[:', this_wiki_code, ':', wd_article, '|', wd_article, ']]'});-- make interwiki link if taken from wd; leading colon requiredelsewd_article = 'Wikidata';-- no article so return plain text labelendreturn wd_article;end--[=[-------------------------< 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 editorsargs - pointer to the parameter arguments table from the template callqid - value from |qid= parameter; the Q-id of the source (book, etc.) in qidwdl - value from the |wdlinks= parameter; a boolean passed to enable links to Wikidata when no article existsreturns nothing; modifies the args table]=]local function get_name_list (nl_type, args, qid, wdl)local propertyID = "P50"local fallbackID = "P2093" -- author name stringif 'author' == nl_type thenpropertyID = 'P50';-- for authorsfallbackID = 'P2093';elseif 'editor' == nl_type thenpropertyID = 'P98';-- for editorsfallbackID = nil;elsereturn;-- not specified so returnend-- wdlinks 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 falseif wdl and (#wdl > 0) thenwdl = wdl:lower()wdl = (wdl == "false") or (wdl == "no") or (wdl == "0")else-- wdl is empty, sowdl = falseendlocal entity = mw.wikibase.getEntity(qid)local props = nillocal fallback = nilif entity and entity.claims thenprops = entity.claims[propertyID]if fallbackID thenfallback = entity.claims[fallbackID]endend-- Make sure it actually has at least one of the properties requestedif not (props and props[1]) and not (fallback and fallback[1]) then return nilend-- 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 articlelocal out = {}local link = {}local maxpos = 0if props and props[1] thenfor k, v in pairs(props) dolocal qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]local sitelink = mw.wikibase.sitelink(qnumber)local label = mw.wikibase.label(qnumber)if label thenlabel = mw.text.nowiki(label)elselabel = qnumberendlocal 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] thenposition = tonumber(v.qualifiers["P1545"][1].datavalue.value)endmaxpos = math.max(maxpos, position)if sitelink then-- just the plain name,-- but keep a record of the links, using the same indexout[position] = labellink[position] = sitelinkelse-- no sitelink, so check first for a redirect with that label-- this code works, but causes the article to appear in WhatLinksHere for the possible destination, so remove-- local artitle = mw.title.new(label, 0)-- if artitle.id > 0 then--if artitle.isRedirect then-- no sitelink,-- but there's a redirect with the same title as the label;-- so store the link to that--out[position] = label--link[position] = label--else-- no sitelink and not a redirect but an article exists with the same title as the label-- that's probably a dab page, so output the plain label--out[position] = label--end--else-- no article or redirect with the same title as the labelif wdl then-- show that there's a Wikidata entry availableout[position] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]&nbsp;<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 labelout[position] = labelend-- endendendendif fallback and fallback[1] then-- Fallback to name-only authors / editorsfor k, v in pairs(fallback) dolocal label = v.mainsnak.datavalue["value"]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] thenposition = tonumber(v.qualifiers["P1545"][1].datavalue.value)endmaxpos = math.max(maxpos, position)out[position] = labelendend-- 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 numberinglocal keys = {}for k,v in pairs(out) dokeys[#keys+1] = kendtable.sort(keys) -- as they might be out of orderfor i, k in ipairs(keys) domw.log(i.." "..k.." "..out[k])args[nl_type .. i] = out[k]-- author-n or editor-nif link[k] thenargs[nl_type .. '-link' .. i] = link[k]-- author-linkn or editor-linknendendend--[[-------------------------< 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 citeq.cite_q (frame)local citeq_args = {};local qid;local wdl;local pframe = frame:getParent()local args = pframe.args;-- first get parent frame arguments - these from the template callfor k, v in pairs (args) do-- copy named parameters and their values into citeq_argsif type( k ) == 'string' then-- numbered parameters ignoredciteq_args[k] = v;endendargs = frame.args;-- now get frame arguments (from the template wikisource) for k, v in pairs (args) do-- copy args into citeq_argsif 'qid' == k then-- don't copy qidqid = v;-- save its valueelseif 'wdlinks' == k then-- don't copy wdlinkswdl = v;-- save its valueelseciteq_args[k] = v-- but copy everything elseendendif is_set (qid) thenif not is_set (citeq_args.author) and not is_set (citeq_args.author1) then-- if neither are set, try to get authors from wikidataget_name_list ('author', citeq_args, qid, wdl);-- modify citeq_args table with authors from wikidataendif not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) then-- if neither are set, try to get editors from wikidataget_name_list ('editor', citeq_args, qid, wdl);-- modify citeq_args table with editors from wikidataendendreturn frame:expandTemplate{title = 'citation', args = citeq_args};-- render the citationendreturn citeq