Modul:Brug Wikidata
Udseende
![]() | Dette Lua-modul bruges på ca. 155.000 sider, eller omkring 16% af alle sider. For at undgå store forstyrrelser og unødvendigt pres på serverne, bør alle ændringer af skabelonen først afprøves i dens tilhørende modulets /sandkasse eller /test-undersider, eller i din egen module sandkasse. De færdigafprøvede ændringer kan derefter overføres til denne side ved en enkelt redigering. Du bør også overveje at diskutere ændringer på diskussionssiden før du implementerer dem. |
Modul til at hente oplysninger fra Wikidata. Det bruges af følgende skabeloner:
Skabelon | Indgangsfunktion |
---|---|
Skabelon:Wikidata-emne | p.hent_emne |
Skabelon:Wikidata-tal | p.hent_tal |
Skabelon:Wikidata-tid | p.hent_tid |
Skabelon:Wikidata-tekst | p.hent_tekst |
Skabelon:Wikidata-streng | p.hent_streng |
Skabelon:Wikidata-matematik | p.hent_matematik |
Skabelon:Wikidata-koord | p.hent_koord |
Skabelon:Wikidata-id | p.hent_id |
Disse skabeloner, på nær den sidste, har mange fælles parametre. Parametrene er:
Parameter | Beskrivelse | Default | Bruges for værdier af type | |||||||
---|---|---|---|---|---|---|---|---|---|---|
alle | emne | tal | tid | tekst | streng | koord. | kvalifikator-værdier | |||
1. uden navn | Wikidata-egenskab ('Pxxx') | ![]() |
||||||||
2. uden navn | brug denne værdi i stedet for Wikidata | ![]() |
||||||||
q | Wikidata-emne ('Qxxx') | emnet for aktuel side | ![]() |
|||||||
feltnavn | navn for denne brug af skabelonen. Hvis angivet tjekkes om Wikidata skal bruges for navnet. | ![]() |
||||||||
wikidata | liste med ønskede feltnavne. 'ja' eller 'alle' godkender alle navne | ![]() |
||||||||
ingen_wikidata | liste med uønskede feltnavne. Undtagelser fra wikidata=ja | ![]() |
||||||||
link | angiver om der skal linkes til emner hvis der er en artikel | ja | ![]() |
![]() | ||||||
kunlink | ja: vis kun værdien hvis der er en wikiside at linke til | ![]() |
![]() | |||||||
adskil | angiver hvad værdier skal adskilles med | ", " | ![]() |
|||||||
liste | angiver at værdierne skal være på en punktliste | ![]() |
||||||||
maks | angiver det maksimale antal værdier | ![]() |
||||||||
mere_end_maks | angiver tekst som bruges hvis værdier er udeladt pga. maks | "med flere" | ![]() |
|||||||
medstort | ja: første værdi skrives med stort begyndelsesbogstav, alle: alle værdier skrives med stort begyndelsesbogstav | ![]() |
![]() | |||||||
kursiv | ja: skriv værdier med kursiv | ![]() |
![]() | |||||||
ikon | ja: vis blyantikon med link til Wikidata | ![]() |
||||||||
ental | afsluttende tekst hvis der er én værdi | ![]() |
||||||||
flertal | afsluttende tekst hvis der er mere end én værdi | ![]() |
||||||||
kun | medtag kun værdier fra emner med denne værdi. Angives som 'Qxxx'. | ![]() |
![]() | |||||||
msk | ja: hvis emnet er en tidszone i Rusland, vis også MSK. | ![]() |
![]() | |||||||
land | hvis udfyldt, vis land for emnet i angivet format | ![]() |
![]() | |||||||
sted | ja: tilføj land, og for store lande også delstat, med kommaer | ![]() |
![]() | |||||||
tid | ja: skriv tidspunkter fra kvalifikatorerne P580, P582, P585 | ![]() |
||||||||
kunår | skriv tidspunkter som årstal alene | ![]() |
![]() | |||||||
parti | hvis udfyldt, vis partimedlemskab i angivet format | ![]() |
![]() | |||||||
kvalifikator1, kvalifikator2, ... | brug denne kvalifikator ('Pxxx') | ![]() |
||||||||
kvalifikatorformat1, kvalifikatorformat2, ... | format for brug af kvalifikator | ![]() |
||||||||
kvalifikatorformatuden1, kvalifikatorformatuden2, ... | format hvis kvalifikatoren ikke er brugt for værdien | ![]() |
||||||||
kvalifikatorbrug1, kvalifikatorbrug2, ... | anvendelse af kvalifikator. Kan være: "alle" (alle værdier bruges), "med" (værdier med kvalifikatoren bruges), "uden" (værdier uden kvalifikatoren bruges), værdi (værdier med denne værdi bruges - label eller 'Qxxx') | ![]() |
||||||||
ingen | tekst for den særlige værdi "ingen værdi" | medtages ikke ("ingen" for kval.) | ![]() |
![]() | ||||||
ukendt | tekst for den særlige værdi "ukendt værdi" | medtages ikke ("ukendt" for kval.) | ![]() |
![]() | ||||||
sprognote | nej: lav ikke note om værdi uden dansk navn | ![]() |
![]() | |||||||
sprognotegroup | group-parameter i sprognote | ![]() |
![]() | |||||||
sprogkat | nej: ingen sporingskategori for værdi uden dansk navn | ![]() |
![]() | |||||||
alder | vis alder ved det hentede tidspunkt. Værdien er egenskab ('Pxxx') for starttidspunkt/fødsel | ![]() |
||||||||
aldernu | vis alder nu. Værdien er "ja" eller en egenskab ('Pxxx') for sluttidspunkt/død som forhindrer visning hvis der er en ikke-decrepated værdi for egenskaben | ![]() |
||||||||
alderformat | udskriftsformat for brug af alder og aldernu | $1 ($3 år) | ![]() |
|||||||
decimaler | antal decimaler i tal. "smart" for 0-3 afhængig af værdien. "orig" for samme antal som wikidata | ![]() |
![]() | |||||||
forkort_store_tal | ja for at vise tal større end 1000 med talord som tusind, million og milliard | ![]() |
![]() | |||||||
visusikkerhed | nej for ikke at vise usikkerhed på tal | ![]() |
![]() | |||||||
enhed | omregn tallet til denne enhed | ![]() |
![]() | |||||||
visenhed | nej for ikke at vise enheden | ![]() |
![]() | |||||||
visusikkerhed | nej for ikke at vise usikkerhed på tal | ![]() |
![]() | |||||||
arealogtæthed | vis areal og befolkningstæthed i det anførte format | ![]() |
||||||||
arealogtætheduden | format for indbyggertal hvis værdi for areal mangler | ![]() |
||||||||
ref | ja for at angive Wikidatas referencer (virker kun delvist) | ![]() |
||||||||
format | format for værdien | ![]() |
||||||||
brugskabelon | Kald angivet skabelon med værdien | ![]() |
||||||||
sprog | ønskede sprogkoder for tekster. "alle" for alle sprog | da | ![]() |
![]() | ||||||
skrivsprog | ja for skriv sproget for en tekst i parentes | ![]() |
![]() | |||||||
eneste | ja for at vise den eneste tekst uanset sprog | ![]() |
||||||||
koordlink | nej for ikke at bruge geoHack og interaktivt kort | ![]() |
![]() | |||||||
format [note 1] | format for koordinater: dec for at bruge grader med decimaler, dms for at bruge grader, minutter, sekunder | samme som koordinaterne er indtastet med på Wikidata | ![]() |
![]() | ||||||
dim [note 1] | størrelsen på området i m eller km | ![]() |
![]() | |||||||
scale [note 1] | størrelsesforhold på kort | ![]() |
![]() | |||||||
type [note 1] | hvilken slags sted koordinaterne refererer til | ![]() |
![]() | |||||||
name [note 1] | navn på stedet for koordinaterne | ![]() |
![]() | |||||||
display [note 1] | inline,i for visning hvor skabelonen er; title,t for visning øverst på side | ![]() |
![]() | |||||||
region [note 1] | lande- eller regionskode for stedet | Koden for landet som angivet på Wikidata | ![]() |
![]() |
Note 1: format, scale, type, name, display og region bruges på samme måde som de tilsvarende parametre til {{coord}} og {{coord}}. Se Wikipedia:Geografiske koordinater for en mere uddybende beskrivelse.
-- 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 = '<span style="color:gray; cursor:help;"><small>Navnet er anført på %s og stammer fra [[d:%s|Wikidata]] hvor navnet endnu ikke findes på dansk.</small></span>'
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 = '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'},
-- 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' },
-- 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' },
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
Q180154 = { name = 'km/t', show_as = 'km/t', conv = 0.2777777777777777778, type = 'speed' },
Q128822 = { name = 'knob', show_at = 'kt', conv = 0.51444444444444444444, type = 'speed' }
}
-- Units as requested in parameter 'enhed'
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' }
}
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 = {
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 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
-- Get and format a reference to a statement
local get_reference = function(ref)
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
else
add_tracking_category(category_unknown_ref)
end
end
end
mw.logObject(refargs, 'refargs')
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. Return text unchanged until it is ready.
if true then return text end
if not text then return nil end
mw.logObject(references,'references')
local refs = {}
if not references or not next(references) then
refs[1] = text .. '\nOplysningen er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som ikke har kilder til den.'
else -- NOTE vent med at tælle ...
if #references == 1 then
refs[1] = text .. '\nOplysningen er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som har denne kilde:'
else
refs[1] = text .. '\nOplysningen er fra [[d:' .. the_qid .. '#' .. the_pid .. '|Wikidata]] som har disse kilder:'
end
for _ ,ref in pairs(references) do
table.insert(refs, get_reference(ref))
end
end
return table.concat(refs, '\n*')
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 = {}
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
table.insert(qualtext, p.format_number(args, q.datavalue.value))
elseif datatype == 'wikibase-entityid' then
table.insert(qualtext, p.get_label(args, q.datavalue.value.id, nil, nil))
end
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
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 '[[' .. 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.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 = '[[' .. link .. '|' .. 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
local lang, labeltable = next(labels)
if lang then
return format_label(args, extra_format, labeltable.value, extra_text, entity, lang, use_ucfirst, qid)
else
return nil
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)
-- 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.ental or '')
else
suffix = mw.text.trim(args.flertal or '')
end
local list = args.liste or ''
if (list == 'ja') then
return '<ul><li>' .. table.concat(output, '</li><li>', 1, number) .. '</li></ul>' .. icon .. suffix .. tracking_categories
else
local separator = args.adskil or ', '
return table.concat(output, separator, 1, number) .. 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)
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
return p.output_all_statements(args, output)
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)
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
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)
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)
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)
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