Modul:Bruk Wikidata
Moduldokumentasjon
[opprett]
-- Overførte parametere til funksjoner hent_emne, hent_tid, hent_tall, hent_streng, hent_tekst:
-- Felles:
-- 1: Wikidata egenskap (Pxxx)
-- 2: Lokal spesifisert verdi. Wikidata brukes bare hvis det er tomt eller ikke spesifisert
-- feltnavn. Brukes til å sjekke om Wikidata skal brukes til dette feltet.
-- wikidata: Liste over feltnavn. Bruk Wikidata hvis '' feltnavn '' er på listen eller hvis verdien er 'ja' eller 'alle',
-- og '' navn '' ikke på listen '' ingen_wikidata ''.
-- ingen_wikidata: Liste over feltnavn. Ikke bruk Wikidata hvis '' feltnavn '' er på listen.
-- adskil: Separasjon mellom flere verdier
-- liste: Sett opp flere verdier i punktlisten
-- ingen: tekst for novalue
-- ukjent: Tekst for somevalue
-- maks: Maks antall resultater
-- q: Wikidata-emne (Qxxx). Hvis definert, bruk dette Wikidata-emnet i stedet for det som er knyttet til den viste siden (mest for testing)
-- Ikon: Opprett et ikon med link til Wikidata hvis verdien er 'ja'
-- tid: Hvis verdien er 'ja': Angi tid eller start- og sluttid som er oppnådd fra kvalifiserende spillere. (ikke for nedlastingstid)
-- kvalifisering1, kvalifisering2, kvalifisering3, etc.: kvalifiseringer
-- kvalifiseringsformat1, kvalifiseringsformat2, kvalifiseringsformat3, etc .: format for å vise verdier med kvalifiseringsprogrammer
-- kvalifiseringsformatut1, Kvalifiseringsformatut2, Kvalifiseringsformatut3, etc .: Format for å vise verdier uten kvalifiseringsprogrammer
-- kvalifisatorbruk1, kvalifisatorbruk2, kvalifisatorbruk3, etc.: 'med': kun verdier uten kvalifiseringsenhet, 'med': kun verdier uten kvalifikator,
-- entall: Tekst etter resultat hvis det er et resultat
-- flertall: Tekst etter resultater hvis det er flere
-- For hent_emne:
-- sprogkat: Bruk kategori etter språk tilbakebetaling
-- sprognotat: Bruk notat ved tilbakekalling av språk
-- srpognotategruppe: Gruppetributt etter språknotat
-- msk: Vis MSK-tidssone for UTC-tidssoner i Russland
-- pari: Skriv politisk parti for emnet i det angitte formatet
-- storboks: 'ja': skriv første verdi med første bokstav,
-- 'alle': skriv inn alle verdier med stor bokstav
-- kursiv: Skriv verdiene kursiv hvis verdien er 'ja'
-- land: Skriv land for emnet i det angitte formatet
-- kun: Inkluder kun resultater med det angitte emnet som verdi
-- For hent_tall:
-- Decimaler: Antall decimaler i tall
-- enhet: Konverter nummeret til den angitte enheten (må være i wanted_units-tabellen)
-- visusikkerhet: Vis usikkerhet (standard: ja)
-- visningsenhet: visningsenhet (standard: ja)
-- areal tetthet: Visningsverdi, område og tetthet i spesifisert format ($ 1 = tallet, $ 2 = området, $ 3 = tettheten)
-- områdealgoritme: vis verdi i spesifisert format hvis ikke område ($ 1 = tall)
-- For hent_tekst:
-- sprog: Liste over språkkoder for ønsket språk. 'alle' for alle språk. (standard: da)
-- skrivsprog: Skriv inn navnet på språket i parentes hvis 'ja'
-- For hent_streng:
-- format: Format for streng. $ 1 i formatet vil bli erstattet med strengen.
-- For hent_tid:
-- kunaar: Skriv kun året hvis verdien er 'ja' (gjelder også for andre datatyper med tidskvalifiserende)
-- alder: Beregn alder i forhold til en tidsverdi
-- aldersformat: format for aldersindikasjon
local preferred_language = 'nb'
local fallback_languages = { 'da', 'nn', 'sv', 'en', 'de', 'nl', 'fr', 'sp', 'it', 'pt' }
local fallback_languages_humans = { 'da', 'nn', 'sv' }
local fallback_note = '<span style="color:gray; cursor:help;"><small>Navnet er anført på %s og stammer fra [[d:%s|Wikidata]] hvor navnet enda ikke finnes på norsk.</small></span>'
local bc = ' fvt.'
local months = {
['1'] = 'januar ', ['2'] = 'februar ', ['3'] = 'mars ',
['4'] = 'april ', ['5'] = 'mai ', ['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 = 'km<sup>2</sup>', conv = 1e6, type = 'area' },
Q25343 = { name = 'm2', show_as = 'm<sup>2</sup>', conv = 1, type = 'area' },
Q232291 = { name = 'mi2', show_as = 'mi<sup>2</sup>', 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
Q8146 = { name = 'JPY', show_as = "¥", conv = 1, type = 'currency' }, -- Japanese yen
Q25344 = { name = 'CHF', show_as = "CHF", conv = 1, type = 'currency' }, -- Swiss franc
Q202040 = { name = 'KRW', show_as = "₩", conv = 1, type = 'currency' }, -- South Korean won
-- 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 = 'mil', conv_to = 'km', conv = 1609.344, type = 'length' },
Q3710 = { name = 'fot', show_as = 'fot', conv_to = 'm', conv = 0.3048006, type = 'length' },
Q174728 = { name = 'cm', show_as = 'cm', conv = 0.01, type = 'length' },
Q174789 = { name = 'mm', show_as = 'mm', conv = 0.001, type = 'length' },
Q218593 = { name = 'in', show_as = '″', 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 = 'knop', 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 'enhet'
local wanted_units = {
m2 = { show_as = 'm<sup>2</sup>', conv = 1, type = 'area' },
km2 = { show_as = 'km<sup>2</sup>', 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 = ' ([[Moskva tid|MSK]]-1)', -- UTC+2
Q6760 = ' ([[Moskva tid|MSK]])', -- UTC+3
Q6779 = ' ([[Moskva tid|MSK]]+1)', -- UTC+4
Q6806 = ' ([[Moskva tid|MSK]]+2)', -- UTC+5
Q6906 = ' ([[Moskva tid|MSK]]+3)', -- UTC+6
Q6940 = ' ([[Moskva tid|MSK]]+4)', -- UTC+7
Q6985 = ' ([[Moskva tid|MSK]]+5)', -- UTC+8
Q7041 = ' ([[Moskva tid|MSK]]+6)', -- UTC+9
Q7056 = ' ([[Moskva tid|MSK]]+7)', -- UTC+10
Q7069 = ' ([[Moskva tid|MSK]]+8)', -- UTC+11
Q7105 = ' ([[Moskva tid|MSK]]+9)', -- UTC+12
}
local fallback_langues_after_country = {
Q35 = 'da', --Danmark
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:Informasjon fra Wikidata på et annet språk enn norsk]]'
local category_human_missing_name ='[[Kategori:Personnavn fra Wikidata på et annet språk enn norsk]]'
local many_p106_category='[[Kategori:Masse informasjon fra WikiData for P106 (beskjeftigelse)]]'
local tiplus_p106_category='[[Kategori:Mer enn 10 opplysninger fra WikiData for P106 (beskjeftigelse)]]'
local many_p166_category ='[[Kategori:Masse informasjon fra WikiData for P166 (utmerkelse)]]'
local many_p463_category ='[[Kategori:Masse informasjon fra WikiData for P463 (medlem av)]]'
local many_p737_category ='[[Kategori:Masse informasjon fra Wikidata for P737 (influert av)]]'
local many_p800_category ='[[Kategori:Masse informasjon fra Wikidata for P800 (verk)]]'
local many_p802_category ='[[Kategori:Masse informasjon fra Wikidata for P802 (elev)]]'
local many_p1082_category ='[[Kategori:Masse informasjon fra Wikidata for P1082 (folketall)]]'
local many_p1344_category ='[[Kategori:Masse informasjon fra Wikidata for P1344 (deltatt i)]]'
local category_unrecognized_unit = '[[Kategori:Enhet fra Wikidata Ukjent]]'
local category_missing_russian_name = '[[Kategori:Navn mangler på Wikidata for russere eller steder i Russland]]'
local category_repeated_ref = '[[Kategori:Wikidata-referanse bruker samme eierskap mer enn en gang]]'
local category_unknown_ref = '[[Kategori:Wikidata-referansen bruker ukjente egenskaper]]'
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
local 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
-- Opprett en linktekst fra url
-- finn startpros.
local j1 = string.find(reftext,'//',1,true)
-- Fjern den første delen av strengen gjennom de to skråstreker hvis de eksisterer
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
-- Finn posisjonen til neste skråstrek i strengen
local i1 = string.find(reftext,'/',1,true)
-- Bruk bare delen av strengen som ligger foran skråstreket hvis den eksisterer
if i1 then reftext = string.sub(reftext,1,i1-1) end
text = 'Opplysningen er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som viser til 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..'Importert 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.
-- kilderef er satt til 'ja' hvis du vil ha referanser
local kilderef = mw.text.trim(args['ref'] or '')
if kilderef ~= 'ja' then return text end
if not text then return nil end
-- kunurl er satt til 'ja' hvis du kun ønskes ref-url (P854)
local kunurl = mw.text.trim(args['kunurl'] or '')
-- viskm er satt til 'ja' hvis det skulle være et notat om at kilder mangler
local viskm = mw.text.trim(args['viskm'] or '')
local reference = ''
-- refs er en tabell av referansene funnet
local refs = {}
if not references or not next(references) then
--refs[1] = '\nOpplysning er fra [[d:' .. the_qid .. '#' .. the_pid .. '|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
-- innholdet i notatet
innhold = ''
-- Antall referanser funnet
if #refs == 1 then
innhold = '\n'..refs[1]
elseif #refs > 1 then
innhold = '\nOpplysningen er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som har disse referansene: \n*'..table.concat(refs, '\n*')
elseif viskm == 'ja' then innhold = '\nOpplysning er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som ikke har referanser til den.'
end
--mw.logObject(table.concat(refs, '\n*'),'slutprodukt')
if innhold ~= '' then
local nr -- index for innhold i ref_texts
local itabel = has_value(ref_texts, innhold)
if not itabel then
table.insert(ref_texts, innhold)
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 = innhold, args = ref_args }
--mw.logObject(innhold..nr,'innhold')
end
--elseif viskm == 'ja' blir da text = text .. '<sup><small>[kildeløs]</small></sup>' 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 == 'uten' 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~= '' ) -- 'uten' er elementer 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, 'ukjent')
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['kvalifisering1' .. tostring(qualno)] or '')
if qual == '' then break end
local format = mw.text.trim(args['kvalifiseringsformat' .. tostring(qualno)] or '$1 ($2)')
local formatwithout = mw.text.trim(args['kvalifiseringsformatut' .. tostring(qualno)] or '$1')
local use = mw.text.trim(args['kvalifisatorbruk' .. 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 to a page if wanted from a label
-- Make the link to the entity 'entity' if not nil, else to 'qid'
p.make_link = function(args, label, entity, qid)
-- 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 == 'nei' then
-- link is not wanted
return label
end
local sitelink
if entity then
sitelink = entity:getSitelink()
else
sitelink = mw.wikibase.getSitelink(qid)
end
if sitelink == nil then
-- link is not possible
return label
end
if sitelink == label then
return '[[' .. sitelink .. ']]'
else
return '[[' .. sitelink .. '|' .. 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.sprognotat or '')
if language_note ~= 'nei' then
local ref_args = { name = 'sprog ' .. langcode .. qid }
local language_notegroup = mw.text.trim(args.sprognotategruppe 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 ~= 'nei' 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 is wanted, or else nil
-- If requested there is linked to 'entity', or 'qid' if no entity
local format_label = function(args, format, text, extra_text, entity, qid, lang, use_ucfirst, make_note)
if use_ucfirst then
text = mw.getLanguage(lang):ucfirst(text)
end
local text = p.make_link(args, text, entity, qid)
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)
-- In order to save memory we will only get the entire entity for qid if necessary.
-- It isn't needed if country or political party isn't requsted,
-- and the entity have a label in the preferred language
-- Find out if which extra, if any, are requested, and get extra_format
local extra_format
local get_party
local get_country
if get_extras then
extra_format = mw.text.trim(args.parti or '')
if extra_format ~= '' then
get_party = true
else
extra_format = mw.text.trim(args.land or '')
if extra_format ~= '' then
get_country = true
else
get_extras = nil
end
end
end
if not get_extras then
-- Try for a label in the the preferred language
local label = mw.wikibase.getLabelByLang(qid, preferred_language)
if label then
return format_label(args, nil, label, nil, nil, qid, preferred_language, use_ucfirst, nil)
end
end
-- OK, we will need the entity to continue
local entity = mw.wikibase.getEntity(qid)
if not entity then return nil end
local extra_text
local country_id, tried_to_get_country_id
-- Find political party of the item if requested
if get_party 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
if get_country 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 "") ~= 'nei' 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 = '[[' .. link .. '|' .. extra_text .. ']]'
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, nil, 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, nil, lang, use_ucfirst, nil)
end
end
if country_id == 'Q159' or -- Q159 is Russia
country_id == 'Q34266' or -- Q34266 is Russian Empire
country_id == 'Q15180' then -- Q15180 is Soviet Union
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, nil, 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, nil, lang, use_ucfirst, nil)
end
end
if citizenship == 'Q159' or -- Q159 is Russia
citizenship == 'Q34266' or -- Q34266 is Russian Empire
citizenship == 'Q15180' then -- Q15180 is Soviet Union
add_tracking_category(category_missing_russian_name)
end
end
add_tracking_category(category_human_missing_name)
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, nil, 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, nil, 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.ukjent 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_enn_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 = '[[File:Blue pencil.svg|frameless|text-top|5px|alt=Rediger på Wikidata|link=d:' ..
the_qid .. '#' .. the_pid .. '|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.entall or '')
else
suffix = mw.text.trim(args.flertall or '')
end
local list = args.liste or ''
if (list == 'ja') then
if mere_enn_maks then mere_enn_maks = '</li><li>' .. mere_enn_maks
else mere_enn_maks = '' end
return '<ul><li>' .. table.concat(output, '</li><li>', 1, number) .. mere_enn_maks .. '</li></ul>' .. icon .. suffix .. tracking_categories
else
local separator = args.adskil or ', '
if mere_enn_maks then mere_enn_maks = separator .. mere_enn_maks
else mere_enn_maks = '' end
return table.concat(output, separator, 1, number) .. mere_enn_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.storboks or '')
local firstvalue = true
local qual1 = mw.text.trim(args.kvalifisering1 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_enn_maks = nil -- Et tillegg som sier at ikke alt vises fordi listen er lengre enn maks
if tonumber(args.maks) and #statements > tonumber(args.maks) then
mere_enn_maks = mw.text.trim(args.mere_enn_maks or '')
if mere_enn_maks == '' then mere_enn_maks = 'med flere' end
end
return p.output_all_statements(args, output, mere_enn_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['kunaar'] 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({['kunaar']=args['kunaar']}, 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. tiår' .. bc_text
else
-- Make sure the number ends with 0
return tostring(math.floor(year_num/10)*10) .. "-årene" .. 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. århundre' .. 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.ukjent 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.visusikkerhet or "") ~= 'nei' 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.visningsenhet or "") ~= 'nei' 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['areal_tetthet'] 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({ enhet='km2', visningsenhet='nei', visusikkerhet=args.visusikkerhet, 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['områdealgoritme'] 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.enhet 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_tall = 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
if #statements > 1 then -- mer enn 1 resultat hentes fra Wikidata
if the_pid =='P1082' then add_tracking_category(many_p1082_category) end -- Innbyggertall
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.ukjent 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.ukjent 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.ukjent 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