Bruger:NisJørgensen/sandkasse/Modul:Brug Wikidata

Fra Wikipedia, den frie encyklopædi

-- Module to fetch information from Wikidata, primarily for use in infoboxes

-- Overførte parametre til funktioner hent_emne, hent_tid, hent_tal, hent_streng, hent_tekst: -- Fælles: -- 1: Wikidata-egenskab (Pxxx) -- 2: Lokal angivet værdi. Wikidata bruges kun hvis tom eller ikke angivet -- feltnavn. Bruges til at undersøge om Wikidata skal bruges for dette felt. -- wikidata: Liste med feltnavne. Brug Wikidata hvis feltnavn er på listen eller hvis værdien er "ja" eller "alle", -- og navn ikke på listen ingen_wikidata. -- ingen_wikidata: Liste med feltnavne. Brug ikke Wikidata hvis feltnavn er på listen. -- adskil: Adskillelse mellem flere værdier -- liste: Opstil flere værdier i punktliste -- ingen: Tekst for novalue -- ukendt: Tekst for somevalue -- maks: Maksimalt antal resultater -- q: Wikidata-emne (Qxxx). Hvis defineret brug dette Wikidata-emne i stedet for det som er tilknyttet den viste side (mest til testning) -- ikon: Lav et ikon med link til Wikidata hvis værdien er 'ja' -- tid: Hvis værdien er 'ja': Angiv tidspunkt eller start- og sluttid hentet fra kvalifikatorer. (ikke for hent_tid) -- kvalifikator1, kvalifikator2, kvalifikator3 osv.: kvalifikatorer -- kvalifikatorformat1, kvalifikatorformat2, kvalifikatorformat3 osv.: format for visning af værdier med kvalifikatorer -- kvalifikatorformatuden1, kvalifikatorformatuden2, kvalifikatorformatuden3 osv.: format for visning af værdier uden kvalifikatorer -- kvalifikatorbrug1, kvalifikatorbrug2, kvalifikatorbrug3 osv.: 'med': kun værdier uden kvalifikator, 'med': kun værdier uden kvalifikator, -- ental: tekst efter resultatet hvis der er et resultat -- flertal: tekst efter resultaterne hvis der er flere

-- For hent_emne: -- sprogkat: Brug kategori ved sprogfallback -- sprognote: Brug note ved sprogfallback -- sprognotegroup: group-attribute ved sprognote -- msk: Vis MSK-tidzone for UTC-tidszoner i Rusland -- parti: Skriv politisk parti for emnet i det angivne format -- medstort: 'ja': skriv første værdi med stort begyndelsesbogstav, -- 'alle': skriv alle værdier med stort begyndelsesbogstav -- kursiv: Skriv værdierne i kursiv hvis værdien er 'ja' -- land: Skriv land for emnet i det angivne format -- kun: Medtag kun resultater med det anførte emne som værdi

-- For hent_tal: -- decimaler: Antal decimaler i tal -- enhed: Omregn tallet til den anførte enhed (skal være i tabellen wanted_units) -- visusikkerhed: Vis usikkerheden (default: ja) -- visenhed: Vis enheden (default: ja) -- arealogtæthed: Vis værdi, areal og tæthed i det angivne format ($1 = tallet, $2 = arealet, $3 = tætheden) -- arealogtætheduden: Vis værdi i det angivne format hvis ikke er areal ($1 = tallet)

-- For hent_tekst: -- sprog: Liste med sprogkoder for ønskede sprog. 'alle' for alle sprog. (default: da) -- skrivsprog: Skriv navnet på sprog i parentes hvis 'ja'

-- For hent_streng: -- format: Format for streng. $1 i formatet vil blive udskiftet med strengen.

-- For hent_tid: -- kunår: Skriv kun årstallet hvis værdien er 'ja' (gælder også andre datatyper med tidskvalifikatorer) -- alder: Beregn alder i forhold til en tidsværdi -- alderformat: Format for angivelse af alder

local preferred_language = 'da' local fallback_languages = { 'nb', 'nn', 'sv', 'en', 'de', 'nl', 'fr', 'sp', 'it', 'pt' } local fallback_languages_humans = { 'nb', 'nn', 'sv' } local fallback_note = 'Navnet er anført på %s og stammer fra Wikidata hvor navnet endnu ikke findes på dansk.' local bc = ' f.v.t.' local months = { ['1'] = 'januar ', ['2'] = 'februar ', ['3'] = 'marts ', ['4'] = 'april ', ['5'] = 'maj ', ['6'] = 'juni ', ['7'] = 'juli ', ['8'] = 'august ', ['9'] = 'september ', ['10'] = 'oktober ', ['11'] = 'november ', ['12'] = 'december ' }

-- Units used for quantity values. For each give name to display, conversion factor, local wd_units = { -- area units Q712226 = { name = 'km2', show_as = 'km2', conv = 1e6, type = 'area' }, Q25343 = { name = 'm2', show_as = 'm2', conv = 1, type = 'area' }, Q232291 = { name = 'mi2', show_as = 'mi2', conv_to = 'km2', conv = 2589988.110336, type = 'area'}, Q35852 = { name = 'ha', show_as = 'ha', conv_to = 'km2', conv = 10000, type = 'area'}, -- currency units

   Q25417 = { name = 'DKK', show_as = "dkk", conv = 1, type = 'currency' },
   Q4916 = { name = 'EUR', show_as = "€", conv = 1, type = 'currency' },
   Q25224 = { name = 'GBP', show_as = "£", conv = 1, type = 'currency' },
   Q132643 = { name = 'NOK', show_as = "nok", conv = 1, type = 'currency' },
   Q122922 = { name = 'SEK', show_as = "sek", conv = 1, type = 'currency' },
   Q4917 = { name = 'USD', show_as = "$", conv = 1, type = 'currency' },
   Q41044 = { name = 'RUB', show_as = "rub", conv = 1, type = 'currency' }, -- russiske rubler
   Q1104069 = { name = 'CAD', show_as = "cad", conv = 1, type = 'currency' }, -- canadiske dollar

-- length units Q11573 = { name = 'm', show_as = 'm', conv = 1, type = 'length' }, Q828224 = { name = 'km', show_as = 'km', conv = 1e3, type = 'length' }, Q253276 = { name = 'mile', show_as = 'mi', conv_to = 'km', conv = 1609.344, type = 'length' }, Q3710 = { name = 'foot', show_as = 'fod', conv_to = 'm', conv = 0.3048006, type = 'length' }, Q174728 = { name = 'cm', show_as = 'cm', conv = 0.01, type = 'length' }, Q218593 = { name = 'in', show_as = 'm', conv = 0.0254, type = 'length' }, -- mass units Q11570 = { name = 'kg', show_as = 'kg', conv = 1, type = 'mass' }, Q100995 = { name = 'lb', show_as = "lb", conv = 0.45359237, type = 'mass' }, -- time units Q11574 = { name = 's', show_as = 's', conv = 1, type = 'time' }, Q7727 = { name = 'minut', show_as = 'min.', conv = 60, type ='time' }, Q25235 = { name = 'time', show_as = 't', conv = 3600, type = 'time' }, -- speed units Q182429 = { name = 'm/s', show_as = 'm/s', conv = 1, type = 'speed' }, Q180154 = { name = 'km/t', show_as = 'km/t', conv = 0.2777777777777777778, type = 'speed' }, Q128822 = { name = 'knob', show_as = 'kn', conv = 0.51444444444444444444, type = 'speed' }, Q748716 = { name = 'ft/s', show_as = 'ft/s', conv = 0,3048, type = 'speed' } }

-- Units as requested in parameter 'enhed' local wanted_units = { m2 = { show_as = 'm2', conv = 1, type = 'area' }, km2 = { show_as = 'km2', conv = 1e-6, type = 'area' }, m = { show_as = 'm', conv = 1, type = 'length' }, km = { show_as = 'km', conv = 1e-3, type = 'length' }, cm = { show_as = 'cm', conv = 100, type = 'length' }, kg = { show_as = 'kg', conv = 1, type = 'mass' }, ['km/t'] = { show_as = 'km/t', conv = 3.6, type = 'speed' }, ['m/s'] = { show_as = 'm/s', conv = 1, type = 'speed' }, min = { show_as = 'min.', conv = 1/60, type = 'time' } }

local msk_timezones = { Q6723 = ' (MSK-1)', -- UTC+2 Q6760 = ' (MSK)', -- UTC+3 Q6779 = ' (MSK+1)', -- UTC+4 Q6806 = ' (MSK+2)', -- UTC+5 Q6906 = ' (MSK+3)', -- UTC+6 Q6940 = ' (MSK+4)', -- UTC+7 Q6985 = ' (MSK+5)', -- UTC+8 Q7041 = ' (MSK+6)', -- UTC+9 Q7056 = ' (MSK+7)', -- UTC+10 Q7069 = ' (MSK+8)', -- UTC+11 Q7105 = ' (MSK+9)', -- UTC+12 }

local fallback_langues_after_country = { Q20 = 'nb', --Norway Q30 = 'en', -- USA Q34 = 'sv', -- Sweden Q142 = 'fr', -- France Q145 = 'en', -- UK Q183 = 'de' -- Germany }

local fallback_langues_for_persons = { Q29 = 'sp', -- Spain Q30 = 'en', -- USA Q33 = 'fi', -- Finland Q38 = 'it', -- Italy Q40 = 'de', -- Austria Q45 = 'pt', -- Portugal Q55 = 'nl', -- Netherlands Q96 = 'sp', -- Mexico Q142 = 'fr', -- France Q145 = 'en', -- UK Q155 = 'pt', -- Brazil Q183 = 'de', -- Germany Q189 = 'is', -- Iceland Q298 = 'sp', -- Chile Q408 = 'en', -- Australia Q414 = 'sp', -- Argentina Q664 = 'en' -- New Zealand }

local p = {}

local fallback_category ='Kategori:Oplysninger fra Wikidata på et andet sprog end dansk' local many_p463_category ='Kategori:Mange oplysninger fra Wikidata for P463 (medlem af)' local many_p106_category='Kategori:Mange oplysninger fra Wikidata for P106 (beskæftigelse)' local tiplus_p106_category='Kategori:Mere end 10 oplysninger fra Wikidata for P106 (beskæftigelse)' local many_p1344_category ='Kategori:Mange oplysninger fra Wikidata for P1344 (deltog i)' local many_p802_category ='Kategori:Mange oplysninger fra Wikidata for P802 (elev)' local many_p800_category ='Kategori:Mange oplysninger fra Wikidata for P800 (hovedværk)' local many_p737_category ='Kategori:Mange oplysninger fra Wikidata for P737 (påvirket af)' local many_p166_category ='Kategori:Mange oplysninger fra Wikidata for P166 (udmærkelser)' local category_unrecognized_unit = 'Kategori:Enhed for størrelse på Wikidata ikke genkendt' local category_missing_russian_name = 'Kategori:Navn mangler på Wikidata for russer eller sted i Rusland' local category_repeated_ref = 'Kategori:Wikidata-reference bruger samme egenskab mere end en gang' local category_unknown_ref = 'Kategori:Wikidata-reference bruger ikke-genkendt egenskab' local tracking_categories = local add_tracking_category = function(cat) tracking_categories = tracking_categories .. cat end

-- The following values are set by get_statements local the_entity -- Used when finding additionel information from statements for other properties local the_qid -- Used to make links to Wikidata local the_pid -- Used to make links to Wikidata -- The following value is set by get_references ref_texts = {}

local function has_value (tab, val)

   for index, value in ipairs(tab) do
       if value == val then
           return index
       end
   end
   return false

end

-- Get and format a reference to a statement local get_reference = function(ref, kunurl) local refargs = {} -- go throug all reference properties local snaks = ref.snaks for refpid, ref in pairs(snaks) do --mw.logObject(refpid, 'refpid') --mw.logObject(ref, 'ref') -- There may be more than more than value with the same property, but ignore all but the first ref1 = ref[1] if ref[2] then add_tracking_category(category_repeated_ref) end if ref1.snaktype == 'value' then -- We have a reel value, as in not 'somevalue' or 'novalue' if refpid == 'P248' then -- P248 is stated in -- Get the item the rerefence is stated in local refentity = mw.wikibase.getEntity(ref1.datavalue.value.id) -- Check these: for book editions -- P1476 is title (monolingual text, the language can be default for language) -- P1680 is subtitle (monolingual text, include this?) -- P50 is author (item) -- P2093 is author name strin (string), check also for qualifier P1545 (series ordinal, warning: it is type string!) -- P393 is edition number (string) -- P98 is editor (item, check no) -- P123 is publisher (item) -- P291 is place of publication (item) -- P577 is publication date (time) -- P407 is language of work or name (item) -- P1683 is quote (monolinual text) -- for journals -- P433 is issue (string) -- P1433 is published in (item, go to it for journal=title, other info from this?) -- P478 is volume -- P698 is PubMed ID (pmid, external identifier) -- P932 is PMCID (pmc, external identifier) -- P356 is DOI (doi, external identifier) -- P1065 is archive URL (URL) -- P2960 is archive date (time) -- P179 is series (item) (Should this be used??) -- P31 is instance of (could be checked to know which properties to look for?) local reftypestatements = refentity:getBestStatements('P31') local instancesof = {} if reftypestatements then mw.logObject(reftypestatements, 'reftypestatements') for _, io in pairs(reftypestatements) do mw.logObject(io, 'io') if io.mainsnak.snaktype == 'value' then instancesof[io.mainsnak.datavalue.value.id] = true end end end elseif refpid == 'P854' then -- P854 is reference URL refargs.url = ref1.datavalue.value elseif refpid == 'P813' then -- P813 is retrieved refargs.accessdate = p.format_time({}, ref1.datavalue.value) elseif refpid == 'P304' then -- P304 is page(s) refargs.page = ref1.datavalue.value elseif refpid == 'P792' then -- P792 is chapter refargs.chapter = ref1.datavalue.value elseif refpid == 'P143' then -- P143 is "imported from" refargs.importedfrom = ref1.datavalue.value local refentity = mw.wikibase.getEntity(ref1.datavalue.value.id) local label, lang = refentity:getLabelWithLang(preferred_language) if label then refargs.importedfrom["label"] = label end --mw.logObject(ref1,'ref1') else add_tracking_category(category_unknown_ref) end end end local text = -- mw.logObject(refargs, 'refargs') if refargs.url then local reftext = refargs.url -- skab en linktekst ud fra url'en -- find startposition local j1 = string.find(reftext,'//',1,true) -- fjern første del af strengen til og med de to skråstreger, hvis de findes if j1 then reftext = string.sub(reftext,j1+2,string.len(reftext)) else reftext = end -- mw.logObject(reftext,'reftext') -- hvis strengen ikke er tom if reftext ~= then -- find positionen af næste skråstreg i strengen local i1 = string.find(reftext,'/',1,true) -- brug kun den del af strengen der ligger før skråstregen, hvis den findes if i1 then reftext = string.sub(reftext,1,i1-1) end text = 'Oplysningen er fra Wikidata som opgiver kilden: ['..refargs.url..' '..reftext..']. ' end end if refargs.accessdate and text ~= then text = text..'Hentet '..refargs.accessdate..'. ' end if refargs.importedfrom and kunurl ~= 'ja' then text = text..'Importeret fra '..refargs.importedfrom.label..'. ' end mw.logObject(text,'text') return text end

-- Get and format all references to a statement -- Append the references to text and return the new text -- If text is nil, return nil again local get_references = function(args, text, references) -- This function is work in progess. -- parameter ref er sat til 'ja' hvis der ønskes referencer local kilderef = mw.text.trim(args['ref'] or ) if kilderef ~= 'ja' then return text end if not text then return nil end -- kunurl er sat til 'ja' hvis der kun ønskes reference-url'er (P854) local kunurl = mw.text.trim(args['kunurl'] or ) -- viskm er sat til 'ja' hvis der skal være en note om at kilder mangler local viskm = mw.text.trim(args['viskm'] or ) local reference = -- refs er en tabel med de fundne referencer local refs = {} if not references or not next(references) then --refs[1] = '\nOplysningen er fra Wikidata som ikke har kilder til den.' else for _ ,ref in pairs(references) do reference = get_reference(ref, kunurl) if reference ~= then table.insert(refs, reference) end end end -- indholdet af noten indhold = -- antallet af fundne referencer if #refs == 1 then indhold = '\n'..refs[1] elseif #refs > 1 then indhold = '\nOplysningen er fra Wikidata som har disse kilder: \n*'..table.concat(refs, '\n*') elseif viskm == 'ja' then indhold = '\nOplysningen er fra Wikidata som ikke har kilder til den.' end --mw.logObject(table.concat(refs, '\n*'),'slutprodukt') if indhold ~= then local nr -- index for indhold i ref_texts local itabel = has_value(ref_texts, indhold) if not itabel then table.insert(ref_texts, indhold) nr = #ref_texts else nr = itabel end

       local ref_args = { name = 'kilde ' .. the_pid .. the_qid .. nr }

text = text .. p.frame:extensionTag{ name = 'ref', content = indhold, args = ref_args } --mw.logObject(indhold..nr,'indhold') end --elseif viskm == 'ja' then text = text .. '[kilde mangler]' end return text end

-- Looks at the arguments 'sprog' og 'skrivsprog' in args -- Returns 3 values: 1) get_all: true if all languages are wanted -- 2) show_language: true if language name is wanted -- 3) a table with keys for wanted languages. local get_lang_args = function(args) local languages = mw.text.trim(args.sprog or preferred_language) local show_language = mw.text.trim(args.skrivsprog or ) == 'ja' local get_all = false local wanteds = {} if languages == 'alle' then get_all = true else for key in mw.text.gsplit(languages, '%s*,%s*') do wanteds[key] = true end end return get_all, show_language, wanteds end

-- Get values from a qualifier with data type time -- Insert the values in the table given as first argument -- The table elements are tables with the uformatted and the formatted value -- Return the table local get_time_qualifier = function(args, times, qualifiers) if qualifiers then for key, qualifier in pairs(qualifiers) do if qualifier.snaktype == "value" then local value = qualifier.datavalue.value local text = p.format_time(args, value) if text then table.insert(times, { value.time, text }) end end end end return times end

-- combine the formated dates in the second element of the element in the dates table local combine_dates = function(dates) local text = if dates and dates[1] then text = dates[1][2] end for i = 2, #dates do text = text .. '/' .. dates[i][2] end return text end

-- Get time values from the qualifiers and add them to the table times -- The elements of times are tables with unformated and formated time values -- Returns the times table local get_qualifier_times = function(args, times, qualifiers) if qualifiers then get_time_qualifier(args, times, qualifiers.P585) -- P585 is point of time local starts = get_time_qualifier(args, {}, qualifiers.P580) -- P580 is start time local ends = get_time_qualifier(args, {}, qualifiers.P582) -- P582 is end time if #starts > 0 then -- There can more than one start time, e.g. if the sources don't agree if #ends > 0 then -- Period with start and end time table.insert(times, { starts[1][1], combine_dates(starts) .. '-' .. combine_dates(ends) } ) else -- Only start time table.insert(times, { starts[1][1], 'fra ' .. combine_dates(starts) } ) end else if #ends > 0 then -- Only end time table.insert(times, { ends[1][1], 'til ' .. combine_dates(ends) } ) end end end return times end

-- Sort and combine the qualifier time values in the table times. -- The elements of times are tables with unformated and formated time values. -- Returns text ready to append to the value. local format_qualifier_times = function(times)

local text = if #times > 0 then table.sort(times, function (a,b) -- Use the unformated ISO 8601 time string for sorting local signa, signb = a[1]:sub(1, 1), b[1]:sub(1, 1) if signa == '+' then if signb == '+' then return a[1] < b[1] -- 2 AD times: The higher number is greater else return false -- AD time is greater than BC time end else if signb == '+' then return true -- BC time is lesser than AD time else return a[1] > b[1] -- 2 BC times: The higher number is lesser end end end) text = text .. ' (' .. times[1][2] for i = 2, #times do text = text .. ', ' .. times[i][2] end text = text .. ')' end return text end

-- Handle a qualifier -- Return new text inkl. the qualifier or nil to remove the statement from the results local get_qualifier = function(args, text, qual, format, formatwithout, use) if not qual then -- No such qualifier if use == 'med' then -- Only statements with the qualifier is wanted, so remove this statement return nil else -- Otherwise return the statement with the formatwithout applied -- Use the table version of string.gsub to avoid having to escape % chars return (string.gsub(formatwithout, '$1', { ['$1'] = text })) end end if use == 'uden' then -- Only statements without the qualifier is wanted, so remove this statement return nil end

-- These are used for monolingual texts. We will only get values for them if necessary local get_all, show_language, wanteds = false, false, false

-- Get the qualifier. There can be several values, loop over them and separate with comma local qualtext, qualpure, testUseValue = {}, {}, ( use ~= 'alle' and use ~= 'med' and use~= ) -- 'uden' er elimineret her for key, q in pairs(qual) do if q.snaktype == 'novalue' then table.insert(qualtext, 'ingen') elseif q.snaktype == 'somevalue' then table.insert(qualtext, 'ukendt') else local datatype = q.datavalue.type if datatype == 'time' then table.insert(qualtext, p.format_time(args, q.datavalue.value)) elseif datatype == 'monolingualtext' then if not wanteds then -- wanteds will be true if the language args are already fetched get_all, show_language, wanteds = get_lang_args(args) end if get_all or wanteds[q.datavalue.value.language] then if show_language then table.insert(qualtext, mw.text.nowiki(q.datavalue.value.text) .. ' (' .. mw.language.fetchLanguageName(q.datavalue.value.language, preferred_language) .. ')') else table.insert(qualtext, mw.text.nowiki(q.datavalue.value.text)) end end elseif datatype == 'string' then table.insert(qualtext, mw.text.nowiki(q.datavalue.value)) elseif datatype == 'url' or datatype == 'commonsMedia' or datatype == 'external-id' then table.insert(qualtext, q.datavalue.value) elseif datatype == 'quantity' then local textvalue = p.format_number(args, q.datavalue.value) table.insert(qualtext, textvalue) elseif datatype == 'wikibase-entityid' then table.insert(qualtext, p.get_label(args, q.datavalue.value.id, nil, nil)) if testUseValue then -- q-value table.insert(qualpure, q.datavalue.value.id) -- label without link local entity = mw.wikibase.getEntity(q.datavalue.value.id) if entity then local label, lang = entity:getLabelWithLang(preferred_language) if label then table.insert(qualpure,label) end end end end end end if testUseValue then local function useValueInTable( tbl ) for _, qualTextHere in pairs( tbl ) do if qualTextHere == use then return true end end return false end if ( not useValueInTable( qualtext ) and ( not useValueInTable( qualpure ) ) ) then return nil end end

return (string.gsub(format, '$[12]', { ['$1'] = text, ['$2'] = table.concat(qualtext, ', ') })) end

-- Handle requets for qualifiers for a statement -- text is the already formated statement -- Return the new text with qualifiers or nil to remove the statement from the results local get_qualifiers = function(args, text, qualifiers, notime) if not notime and mw.text.trim(args.tid or ) == 'ja' then -- Check qualifiers for point of time, start time, and end time local times = get_qualifier_times(args, {}, qualifiers) text = text .. format_qualifier_times(times) end

  -- mw.logObject(qualifiers,'qualifiers')

local qualno = 1 repeat local qual = mw.text.trim(args['kvalifikator' .. tostring(qualno)] or ) if qual == then break end local format = mw.text.trim(args['kvalifikatorformat' .. tostring(qualno)] or '$1 ($2)') local formatwithout = mw.text.trim(args['kvalifikatorformatuden' .. tostring(qualno)] or '$1') local use = mw.text.trim(args['kvalifikatorbrug' .. tostring(qualno)] or 'alle') text = get_qualifier(args, text, qualifiers and qualifiers[qual], format, formatwithout, use) qualno = qualno + 1 until not text return text end

-- Determine if the string 'name' is in the list 'list' med comma separated names -- Returns true if 'name' is in the list. local function inlist (name, list) for n in mw.text.gsplit(list, '%s*,%s*') do if n == name then return true end end return false end

-- Determine if Wikidata should be used in this case -- Uses the arguments ingen_wikidata (blacklist), wikidata (whitelist), navn (fieldname) -- Returns true if OK to use Wikidata p.use_wikidata = function(args) -- The name of the field that this function is called from is passed in the parameter "feltnavn" local fieldname = mw.text.trim(args.feltnavn or ) -- Use Wikidata if not specified if #fieldname == 0 then return true end

-- The blacklist is passed in the parameter "ingen_wikidata" local blacklist = args.ingen_wikidata if blacklist and inlist(fieldname, blacklist) then return false end

-- The whitelist is passed in the parameter "wikidata" local whitelist = mw.text.trim(args.wikidata or ) if whitelist == 'alle' or whitelist == 'ja' or inlist(fieldname, whitelist) then return true else return false end end


-- Get the best statements (rank preferred if it exist, or else rank normal) for the required item and property -- Sets the values the_entity, the_pid, the_qid p.get_statements = function(args) -- Get the item to use from either the parameter q or the item connected to the current page the_qid = mw.text.trim(args.q or ) if the_qid == then the_qid = mw.wikibase.getEntityIdForCurrentPage() end the_entity = mw.wikibase.getEntity(the_qid) if not the_entity then return nil end

-- Get the best statements (rank preferred if exist, else rank normal) for the required property the_pid = mw.text.trim(args[1] or "") return the_entity:getBestStatements(the_pid) end

-- Make a link if wanted from a label p.make_link = function(args, label, entity) -- Convert characters with special meaning in wikitext to HTML entities label = mw.text.nowiki(label)

-- Use italics if requested local use_italics = mw.text.trim(args.kursiv or "") if use_italics == 'ja' then label = "" .. label .. "" end

local link = mw.text.trim(args.link or "") if link == 'nej' then -- link is not wanted return label end local sitelink = entity:getSitelink() if sitelink == nil then -- link is not possible return label end if sitelink == label then return '' .. sitelink .. '' else return '' .. label .. '' end end

-- Make text with message, reference, and category about using a fallback language p.make_language_message = function(args, langcode, qid) local language = mw.language.fetchLanguageName(langcode, preferred_language) -- No language in parenthesis for now -- local text =' (' .. language .. ')' local text = local language_note = mw.text.trim(args.sprognote or ) if language_note ~= 'nej' then local ref_args = { name = 'sprog ' .. langcode .. qid } local language_notegroup = mw.text.trim(args.sprognotegroup or ) if language_notegroup ~= then ref_args.group = language_notegroup end text = text .. p.frame:extensionTag{ name = 'ref', content = string.format(fallback_note, language, qid), args = ref_args } end local language_cat = mw.text.trim(args.sprogkat or ) if language_cat ~= 'nej' then add_tracking_category(fallback_category) end return text end

-- Get a value of type item from an entity if it is unique. local get_unique_item_value = function(entity, pid) local statements = entity:getBestStatements(pid) if statements and #statements == 1 and statements[1].mainsnak and statements[1].mainsnak.snaktype == 'value' then return statements[1].mainsnak.datavalue.value.id end return nil end

-- Format the label with upper case, link, extras (party or country), and language note -- make_note is the item ID to link to if a note wanted, or else nil local format_label = function(args, format, text, extra_text, entity, lang, use_ucfirst, make_note) if use_ucfirst then text = mw.getLanguage(lang):ucfirst(text) end local text = p.make_link(args, text, entity) if make_note then text = text .. p.make_language_message(args, lang, make_note) end if extra_text then return (string.gsub(format, '$[12]', { ['$1'] = text, ['$2'] = extra_text })) else return text end end

-- Get the label of an item. -- Creates a link using the sitelink if it exists unless the link argument is set to no -- Converts the first character of the label to uppercase if use_ucfirst -- Finds and adds country or political party for the item if requested in the args and get_extras is true p.get_label = function(args, qid, use_ucfirst, get_extras)

-- first we need the entity local entity = mw.wikibase.getEntity(qid) if not entity then return nil end

local extra_text, extra_format local country_id, tried_to_get_country_id

if get_extras then

-- Find political party of the item if requested extra_format = mw.text.trim(args.parti or ) if extra_format ~= then -- P102 is member of political party local party_id = get_unique_item_value(entity, 'P102') if party_id then -- First try a shortname/abbreviation for the party local party_entity = mw.wikibase.getEntity(party_id) if party_entity then -- P1813 is short name shortname_statements = party_entity:getBestStatements('P1813') for key, statement in pairs(shortname_statements) do if statement.mainsnak.snaktype == 'value' and statement.mainsnak.datavalue.value.language == 'da' then extra_text = statement.mainsnak.datavalue.value.text break -- one is enough. As we don't know which is best, take the first end end if not extra_text then -- No shortname, get the label local label, lang = party_entity:getLabelWithLang(preferred_language) if lang == preferred_language then extra_text =label end end if extra_text then extra_text = p.make_link(args, extra_text, party_entity) end end end else -- Party was not requested. Get country if requested extra_format = mw.text.trim(args.land or "") if extra_format ~= then -- P17 is country country_id, tried_to_country_id = get_unique_item_value(entity, 'P17'), true -- Don't repeat the country if it refers to itself if country_id and country_id ~= qid then local label, lang = mw.wikibase.getLabelWithLang(country_id) if lang == preferred_language then extra_text = mw.text.nowiki(label) if mw.text.trim(args.link or "") ~= 'nej' then -- link to the country local link = mw.wikibase.sitelink(country_id) if link then -- There is an article (consider to use tracking category otherwise) extra_text = '' .. extra_text .. '' end end end end end end end

-- Try the preferred language local label, lang = entity:getLabelWithLang(preferred_language) if lang == preferred_language then return format_label(args, extra_format, label, extra_text, entity, lang, use_ucfirst, nil) end

-- Next try the local language if the item is located in certain countries if not country_id and not tried_to_get_country_id then -- P17 is country country_id, tried_to_country_id = get_unique_item_value(entity, 'P17'), true end if country_id then local fallback = fallback_langues_after_country[country_id] if fallback then local label, lang = entity:getLabelWithLang(fallback) if lang == fallback then return format_label(args, extra_format, label, extra_text, entity, lang, use_ucfirst, nil) end end if country_id == 'Q159' then -- Q159 is Russia add_tracking_category(category_missing_russian_name) end end

-- Find out if the item is a human local ishuman = nil -- P31 is instance of local instanceof = entity:getBestStatements('P31') for key, statement in pairs(instanceof) do -- Q5 is human if statement.mainsnak.snaktype == 'value' and statement.mainsnak.datavalue.value.id == 'Q5' then ishuman = true break end end

if ishuman then -- Next for humans try first group of fallback languags for humans (Norgewian and Swedish) for i, fallback in ipairs(fallback_languages_humans) do local label, lang = entity:getLabelWithLang(fallback) if lang == fallback then return format_label(args, extra_format, label, extra_text, entity, lang, use_ucfirst, nil) end end

-- Next for humans try the language of their country if there is one main language -- and it is written in a Latin script (the table of these is probably incomplete) -- P27 is country of citizenship local citizenship = get_unique_item_value(entity, 'P27') if citizenship then local fallback = fallback_langues_after_country[citizenship] if fallback then local label, lang = entity:getLabelWithLang(fallback) if lang == fallback then return format_label(args, extra_format, label, extra_text, entity, lang, use_ucfirst, nil) end end if citizenship == 'Q159' then -- Q159 is Russia add_tracking_category(category_missing_russian_name) end end end

-- Try the fallback languages for i, fallback in ipairs(fallback_languages) do local label, lang = entity:getLabelWithLang(fallback) if lang == fallback then return format_label(args, extra_format, label, extra_text, entity, lang, use_ucfirst, qid) end end

-- Last resort: try any label local labels = entity.labels if labels then for lang,labeltable in pairs(labels) do if lang then return format_label(args, extra_format, labeltable.value, extra_text, entity, lang, use_ucfirst, qid) else return -- ingen label hos wikidata resulterer i manglende tekst (kun evt. et blyantikon) end break end end return nil end

p.format_statement_group = function(args, statements, startrange, endrange, use_ucfirst) local text = nil if statements[startrange].sortkey == 'novalue' then text = mw.text.trim(args.ingen or "") if (text == ) then return nil end elseif statements[startrange].sortkey == "somevalue" then text = mw.text.trim(args.ukendt or "") if (text == ) then return nil end else text = p.get_label(args, statements[startrange].sortkey, use_ucfirst, true)

-- if the entity is a timezone in Russia, then add the MSK time if requested if mw.text.trim(args.msk or ) == 'ja' and msk_timezones[statements[startrange].sortkey] then text = text .. msk_timezones[statements[startrange].sortkey] end

-- Go through all statements for time qualifiers if requested if mw.text.trim(args.tid or ) == 'ja' then local times = {} for i = startrange, endrange - 1 do local qualifiers = statements[i].qualifiers get_qualifier_times(args, times, qualifiers) end text = text .. format_qualifier_times(times) end end

-- handle qualifier arguments except for "tid" which may be used for statement groups -- and is handled separately above. When grouping is used, this call will have no effect -- because the qualifier arg will have turned grouping off in hent_emne(). text = get_qualifiers(args, text, statements[startrange].qualifiers, true) text = get_references(args, text, statements[startrange].references) return text end

-- format the list of statements with the wanted separator p.output_all_statements = function(args, output, mere_end_maks)

-- Avoid empty lists if #output == 0 then -- No tracking categories for empty results, as infoboxes or others may test if the result is empty or not return end

-- Prepare an icon with link to Wikidata local icon = if mw.text.trim(args.ikon or ) == 'ja' then icon = 'Rediger på Wikidata' end

local max = tonumber(args.maks or 1e6) local number = math.min(#output, max) local suffix if number == 1 then suffix = mw.text.trim(args.ental or ) else suffix = mw.text.trim(args.flertal or ) end

local list = args.liste or if (list == 'ja') then

if mere_end_maks then mere_end_maks = '

  • ' .. mere_end_maks else mere_end_maks = end return '
    • ' .. table.concat(output, '
    • ', 1, number) .. mere_end_maks .. '
    ' .. icon .. suffix .. tracking_categories

    else local separator = args.adskil or ', ' if mere_end_maks then mere_end_maks = separator .. mere_end_maks else mere_end_maks = end return table.concat(output, separator, 1, number) .. mere_end_maks .. icon .. suffix .. tracking_categories end end

    p.hent_emne = function(frame)

    p.frame = frame

    -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. local args

       if frame == mw.getCurrentFrame() then
    

    args = frame:getParent().args else args = frame.args end

    -- There may be a local parameter supplied. If set and not empty, return it unconditionally local input_parm = mw.text.trim(args[2] or "") if input_parm and (#input_parm > 0) then return input_parm end

    -- Now test if Wikidate should be used for the current field. if not p.use_wikidata(args) then return end

    local statements = p.get_statements(args) if statements == nil or #statements == 0 then return end

    -- Sort the statements after snaktype (value, novalue, somevalue) and id -- This makes id possible to find and group equal values together for key, statement in pairs(statements) do if statement.mainsnak.snaktype == 'value' then if statement.mainsnak.datatype ~= 'wikibase-item' then -- The property has a wrong datatype, ignore it. return end statement.sortkey = statement.mainsnak.datavalue.value.id else statement.sortkey = statement.mainsnak.snaktype end end table.sort(statements, function (a,b) return (a.sortkey < b.sortkey) end)

       if #statements > 5 then -- finder sider hvor meget hentes fra Wikidata
       	if the_pid =='P463' then add_tracking_category(many_p463_category)
       	elseif the_pid =='P106' and #statements > 10 then add_tracking_category(tiplus_p106_category)
       	elseif the_pid =='P106' then add_tracking_category(many_p106_category)
       	elseif the_pid =='P1344' then add_tracking_category(many_p1344_category)
       	elseif the_pid =='P802' then add_tracking_category(many_p802_category)
       	elseif the_pid =='P800' then add_tracking_category(many_p800_category)
       	elseif the_pid =='P737' then add_tracking_category(many_p737_category)
       	elseif the_pid =='P166' then add_tracking_category(many_p166_category)
       	end
       end
    

    local output = {} local upper_case_labels = mw.text.trim(args.medstort or ) local firstvalue = true

    local qual1 = mw.text.trim(args.kvalifikator1 or ) local no_statement_grouping = qual1 ~=

    -- Go thru the statements and format them for displaying local startrange = 1 local endrange = 1 local only = mw.text.trim(args.kun or ) -- We need to keep track of the maximal allowed number of results here, so references -- made with frame:extensionTag() for removed results will not stay behind. local max = tonumber(args.maks) if not max then max = 1e6 end -- if no limit then set some limit we will never reach while max > 0 and startrange <= #statements do local sortkey = statements[startrange].sortkey while endrange <= #statements and statements[endrange].sortkey == sortkey do endrange = endrange + 1 if no_statement_grouping then -- We have qualifiers to check for each statement, so we cannot group -- statements with equal values together. break end end -- Check if only results with a certain value is requested if only == or only == sortkey then local use_ucfirst = upper_case_labels == 'alle' or (upper_case_labels == 'ja' and firstvalue) local text = p.format_statement_group(args, statements, startrange, endrange, use_ucfirst) if text then table.insert(output, text) max = max - 1 firstvalue = false end end startrange = endrange end

    local mere_end_maks = nil -- en tilføjelse der fortæller, at ikke alt vises, fordi listen er længere end maks if tonumber(args.maks) and #statements > tonumber(args.maks) then mere_end_maks = mw.text.trim(args.mere_end_maks or ) if mere_end_maks == then mere_end_maks = 'med flere' end end

    return p.output_all_statements(args, output, mere_end_maks) end

    -- Format a time value -- Return formatted text for the date p.format_time = function(args, value) -- Parse the ISO 8601 time value -- The format is like '+2000-00-00T00:00:00Z'. -- For now the value can only contain date. Their is no timezone or time.

    local sign, year, month, day = string.match(value.time, '^([%+-])0*(%d+)-0?(%d+)-0?(%d+)T') if not sign then -- No match. We can consider an error message or category for this, but ignore for now return nil end

    -- handle year and AD/BC local bc_text = -- text for AD or BC if sign == '-' then -- Year 0 doesn't exist, year 1,2,3 BC etc is given as -1,-2,-3 etc. -- (or maybe also in some cases as 0,-1,-2 etc.?) -- (see also d:Help:Dates#Years BC) bc_text = bc end

    if value.precision >= 9 then -- precision is year or greater local date = year .. bc_text local yearonly = mw.text.trim(args['kunår'] or "") == 'ja' if not yearonly and value.precision >= 10 then -- precision is month or greater: Prepend the month date = months[month] .. date if value.precision >= 11 then -- precision is day or greater: Prepend the day date = day .. '. ' .. date

    -- Compare the date with another date and calculate age if requested local agepid = mw.text.trim(args['alder'] or "") if agepid ~= then local ageformat = mw.text.trim(args['alderformat'] or "$1 ($3 år)") local agestatements = the_entity:getBestStatements(agepid) local agevalue = agestatements and #agestatements == 1 and agestatements[1].mainsnak and agestatements[1].mainsnak.snaktype == 'value' and agestatements[1].mainsnak.datavalue.value if agevalue and agevalue.precision >= 11 then agedate = p.format_time({['kunår']=args['kunår']}, agevalue) local age local agesign, ageyear, agemonth, ageday = string.match(agevalue.time, '^([%+-])0*(%d+)-0?(%d+)-0?(%d+)T') -- First get the difference in the years. Remember that year 0 doesn't exist. if agesign == '-' then if sign == '-' then age = tonumber(ageyear) - tonumber(year) -- e.g. 100 BC - 50 BC else age = tonumber(ageyear) + tonumber(year) - 1 -- e.g. 10 BC - 40 AD end else if sign == '-' then age = 1 - tonumber(year) - tonumber(ageyear) -- e.g 40 AD - 10 BC (negative gives no sense) else age = tonumber(year) - tonumber(ageyear) -- e.g. 50 AD - 100 AD end end --Substract a year if the birthday isn't reached in the last year if tonumber(month) < tonumber(agemonth) or (tonumber(month) == tonumber(agemonth) and tonumber(day) < tonumber(ageday)) then age = age - 1 end return (string.gsub(ageformat, '$[123]', { ['$1'] = date, ['$2'] = agedate, ['$3'] = tostring(age) })) end -- if agevalue end -- if agepid end -- if value.precision >= 11 then end -- if value.precision >= 10 then return date end --if value.precision >= 9 then

    -- precision is less than year local year_num = tonumber(year) if value.precision == 8 then -- precision is decade -- 10 (or any number in the period) seems to mean years 10-19, -- 20 (or any number in the period) seems to mean years 20-29, -- 2010 (or any number in the period) seems to mean years 2010-2019 if year_num <= 10 then return '1. årti' .. bc_text else -- Make sure the number ends with 0 return tostring(math.floor(year_num/10)*10) .. "'erne" .. bc_text end end

    if value.precision == 7 then -- precision is century -- 100 (or any number in the period) seems to mean years 1-100, -- 200 (or any number in the period) seems to mean years 101-200, -- 2100 (or any number in the period) seems to mean years 2001-2100 if year_num <= 100 then return '1. århundrede' .. bc_text else -- Make sure the number ends with 00 and convert the period one year down return tostring(math.floor((year_num - 1)/100)*100) .. '-tallet' .. bc_text end end

    -- precision less than century is not handled return nil -- if value.precision == 6 then -- precision is 1000 years -- if value.precision == 5 then -- precision is 10.000 years -- if value.precision == 4 then -- precision is 100.000 years -- if value.precision == 3 then -- precision is million years -- if value.precision == 2 then -- precision is 10 million years -- if value.precision == 1 then -- precision is 100 million years -- if value.precision == 0 then -- precision is 1 billion years end

    p.hent_tid = function(frame)

    p.frame = frame

    -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. local args

       if frame == mw.getCurrentFrame() then
    

    args = frame:getParent().args else args = frame.args end

    -- There may be a local parameter supplied. If set and not empty, return it unconditionally local input_parm = mw.text.trim(args[2] or "") if input_parm and (#input_parm > 0) then return input_parm end

    -- Now test if Wikidate should be used for the current field. if not p.use_wikidata(args) then return end

    local statements = p.get_statements(args) if statements == nil or #statements == 0 then return end

    local output = {}

    -- Go thru the statements and format them for displaying for key, statement in pairs(statements) do local text = nil if statement.mainsnak.snaktype == 'value' then if statement.mainsnak.datatype == 'time' then text = p.format_time(args, statement.mainsnak.datavalue.value) end elseif statement.mainsnak.snaktype == 'novalue' then text = mw.text.trim(args.ingen or "") elseif statement.mainsnak.snaktype == 'somevalue' then text = mw.text.trim(args.ukendt or "") end if text then text = get_qualifiers(args, text, statement.qualifiers) text = get_references(args, text, statement.references) if text and text ~= then table.insert(output, text) end end end

    return p.output_all_statements(args, output, nil) end

    local insert_delimiters = function(number) -- first change the decimal mark to comma number = string.gsub(number, '%.', ',') repeat -- Find the group of 3 digits and insert delimiter local matches number, matches = string.gsub(number, "^(-?%d+)(%d%d%d)", '%1.%2') until matches == 0 return number end

    local make_the_number = function(args, amount, diff, unit)

    local decimals = mw.text.trim(args.decimaler or '0') if decimals == 'smart' then if amount > 100 then decimals = '0' elseif amount > 10 then decimals = '1' elseif amount > 1 then decimals = '2' else decimals = '3' end else decimals = tostring(math.floor(tonumber(decimals) or 0)) end

    -- First the amount local text = insert_delimiters(string.format('%.' .. decimals .. 'f', amount))

    -- Second the variation if diff > 0 and mw.text.trim(args.visusikkerhed or "") ~= 'nej' then local difftext = string.format('%.' .. decimals .. 'f', diff) -- Don't show the diff it if is rounded to 0 if tonumber(difftext) ~= 0 then text = text .. '±' .. insert_delimiters(difftext) end end

    -- Third the unit if unit and mw.text.trim(args.visenhed or "") ~= 'nej' then text = text .. ' ' .. unit end return text end

    -- Format a quantity value and return the formated value -- Also return the amount as a number if it a quantity with a recogniced unit -- (used to get area) p.format_number = function(args, value)

    local amount = tonumber(value.amount) local diff1, diff2 = 0, 0 if value.lowerBound then diff1 = amount - tonumber(value.lowerBound) end if value.upperBound then diff2 = tonumber(value.upperBound) - amount end local diff = math.max(diff1, diff2)

    local unit = value.unit if unit == '1' then -- Number without unit local text = make_the_number(args, amount, diff, nil)

    -- We may have to find the area and calculate the density local densityformat = mw.text.trim(args['arealogtæthed'] or ) if densityformat ~= then local area_text, area_number, density_text -- P2046 is area area_statements = the_entity:getBestStatements('P2046') if area_statements and #area_statements == 1 and area_statements[1].mainsnak.snaktype == 'value' then area_text, area_number = p.format_number({ enhed='km2', visenhed='nej', visusikkerhed=args.visusikkerhed, decimaler='smart' }, area_statements[1].mainsnak.datavalue.value) if area_number then density_text = p.format_number({ decimaler='smart' }, { amount=amount / area_number, unit='1' }) return (string.gsub(densityformat, '$[123]', { ['$1'] = text, ['$2'] = area_text, ['$3'] = density_text })) end end -- No area found. Return the value with densityformatwithout applied local densityformatwithout = mw.text.trim(args['arealogtætheduden'] or '$1') return (string.gsub(densityformatwithout, '$1', { ['$1'] = text })) end -- area and density was not asked for. return text end

    unit_qid = string.match(unit, 'http://www%.wikidata%.org/entity/(Q%d+)$') if not unit_qid then -- Unknown unit format return nil end

    wd_unit = wd_units[unit_qid] if not wd_unit then -- The unit is not in our table. Here we could read information -- about the unit entity. Maybe to be done later add_tracking_category (category_unrecognized_unit) return make_the_number(args, amount, diff, nil) end wanted_unit = mw.text.trim(args.enhed or "") if wanted_unit == and wd_unit.conv_to then wanted_unit = wd_unit.conv_to end

    local wanted = wanted_units[wanted_unit] if wanted and wd_unit.name ~= wanted_unit and wd_unit.type == wanted.type then amount = amount * wd_unit.conv * wanted.conv diff = diff * wd_unit.conv * wanted.conv return make_the_number(args, amount, diff, wanted.show_as), amount end return make_the_number(args, amount, diff, wd_unit.show_as), amount end

    p.hent_tal = function(frame)

    p.frame = frame

    -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. local args

       if frame == mw.getCurrentFrame() then
    

    args = frame:getParent().args else args = frame.args end

    -- There may be a local parameter supplied. If set and not empty, return it unconditionally local input_parm = mw.text.trim(args[2] or "") if input_parm and (#input_parm > 0) then return input_parm end

    -- Now test if Wikidate should be used for the current field. if not p.use_wikidata(args) then return end

    local statements = p.get_statements(args) if statements == nil or #statements == 0 then return end local output = {}

    -- Go thru the statements and format them for displaying for key, statement in pairs(statements) do local text = nil if statement.mainsnak.snaktype == 'value' then if statement.mainsnak.datatype == 'quantity' then text = p.format_number(args, statement.mainsnak.datavalue.value) end elseif statement.mainsnak.snaktype == 'novalue' then text = mw.text.trim(args.ingen or "") elseif statement.mainsnak.snaktype == 'somevalue' then text = mw.text.trim(args.ukendt or "") end -- mw.logObject(statement.references,'statement.references') if text then text = get_qualifiers(args, text, statement.qualifiers) text = get_references(args, text, statement.references) if text and text ~= then table.insert(output, text) end end end

    return p.output_all_statements(args, output, nil) end

    -- Handle datatypes string, url, commonsMedia, external-id which have similar structures p.hent_streng = function(frame)

    p.frame = frame

    -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. local args if frame == mw.getCurrentFrame() then args = frame:getParent().args else args = frame.args end

    -- There may be a local parameter supplied. If set and not empty, return it unconditionally local input_parm = mw.text.trim(args[2] or "") if input_parm and (#input_parm > 0) then return input_parm end

    -- Now test if Wikidate should be used for the current field. if not p.use_wikidata(args) then return end

    local statements = p.get_statements(args) if statements == nil or #statements == 0 then return end local output = {}

    -- For formating of strings. $1 in the format vil be replaced by the string local format = mw.text.trim(args.format or ) if format == then format = nil end

    -- Go thru the statements and format them for displaying for key, statement in pairs(statements) do local text = nil if statement.mainsnak.snaktype == 'value' then if statement.mainsnak.datatype == 'string' then text = mw.text.nowiki(statement.mainsnak.datavalue.value) elseif statement.mainsnak.datatype == 'url' or statement.mainsnak.datatype == 'commonsMedia' or statement.mainsnak.datatype == 'external-id' then text = statement.mainsnak.datavalue.value end if format and text then -- We have to escape any % in the found string with another % before using it as repl in string.gsub text = string.gsub(text, '%%', '%%%%') text = string.gsub(format, '$1', text) end elseif statement.mainsnak.snaktype == 'novalue' then text = mw.text.trim(args.ingen or "") elseif statement.mainsnak.snaktype == 'somevalue' then text = mw.text.trim(args.ukendt or "") end if text then text = get_qualifiers(args, text, statement.qualifiers) text = get_references(args, text, statement.references) if text and text ~= then table.insert(output, text) end end end

    return p.output_all_statements(args, output, nil) end

    p.hent_tekst = function(frame)

    p.frame = frame

    -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. local args if frame == mw.getCurrentFrame() then args = frame:getParent().args else args = frame.args end

    -- There may be a local parameter supplied. If set and not empty, return it unconditionally local input_parm = mw.text.trim(args[2] or "") if input_parm and (#input_parm > 0) then return input_parm end

    -- Now test if Wikidate should be used for the current field. if not p.use_wikidata(args) then return end

    local statements = p.get_statements(args) if statements == nil or #statements == 0 then return end local output = {}

    local get_all, show_language, wanteds = get_lang_args(args)

    -- Go thru the statements and format them for displaying for key, statement in pairs(statements) do local text = nil if statement.mainsnak.snaktype == 'value' then if statement.mainsnak.datatype == 'monolingualtext' then if get_all or wanteds[statement.mainsnak.datavalue.value.language] then text = mw.text.nowiki(statement.mainsnak.datavalue.value.text) if show_language then text = text .. ' (' .. mw.language.fetchLanguageName(statement.mainsnak.datavalue.value.language, preferred_language) .. ')' end end end elseif statement.mainsnak.snaktype == 'novalue' then text = mw.text.trim(args.ingen or "") elseif statement.mainsnak.snaktype == 'somevalue' then text = mw.text.trim(args.ukendt or "") end if text then text = get_qualifiers(args, text, statement.qualifiers) text = get_references(args, text, statement.references) if text and text ~= 0 then table.insert(output, text) end end end

    return p.output_all_statements(args, output, nil) end

    -- Get Wikidata entity ID for the current page. -- Arguments: format: format string with $1 for the ID, ingen: text to return for no entity p.hent_id = function(frame) local args if frame == mw.getCurrentFrame() then args = frame:getParent().args else args = frame.args end

    -- Get the item to use from either the parameter q or the item connected to the current page local qid = mw.text.trim(args.q or ) if qid == then qid = mw.wikibase.getEntityIdForCurrentPage() end

    if qid then local format = mw.text.trim(args.format or '$1') return (string.gsub(format, '$1', { ['$1'] = qid })) else return mw.text.trim(args.ingen or ) end end

    return p