มอดูล:Wikidata2

-- Den ordning fallback language hämtas, om svensk label saknas. Engelska först, därefter bokmål, danska, etc...
local fallback = {'en', 'tl', 'es', 'war', 'de', 'fr', 'es', 'it', 'pt'}
local formatera = require('Module:Math')
local i18n = {
	"errors" = {
		"property-param-not-provided" = "Property parameter not provided.",
		"entity-not-found" = "Entity not found.",
		"unknown-claim-type" = "Unknown claim type.",
		"unknown-snak-type" = "Unknown snak type.",
		"unknown-datatype" = "Unknown datatype.",
		"unknown-entity-type" = "Unknown entity type.",
		"unknown-value-module" = "You must set both value-module and value-function parameters.",
		"value-module-not-found" = "The module pointed by value-module not found.",
		"value-function-not-found" = "The function pointed by value-function not found.",
		"non-convertible unit" = "Denna enhet går inte att konvertera till den önskade"
	},
	"somevalue" = "unknown value",
	"novalue" = "no value"
}
local sortingproperties = {'P585','P571','P580','P569','P582','P570'}
function unithandle(unit, options)
	-- Kontrollerar om det finns någon förkortning för denna 'unit'
	local lab = options.label or formatStatements({property = 'P498', entityId = unit, enbarten = 'true', noref = 'true'})
	if not lab or lab ==  then
		lab = formatStatements({property = 'P558', entityId = unit, enbarten = 'true', langpref = options.langpref, noref = 'true'})
	end
	if lab and ( not options.nounitshort or options.nounitshort ==  ) then
		return formatEntityId( unit, {label = lab, nolink = (options.nounitlink or options.nolink) }).value
	else -- om det inte finns en förkortning
		return formatEntityId( unit, {nolink = options.nounitlink}).value
	end
end
function planeter(t)
	local px = {
		Q2 = 'earth',
		Q308 = 'mercury',
		Q313 = 'venus',
		Q405 = 'moon',
		Q111 = 'mars',
		Q7547 = 'phobos',
		Q7548 = 'deimos',
		Q596 = 'ceres',
		Q3030 = 'vesta',
		Q3169 = 'ganymede',
		Q3134 = 'callisto',
		Q3123 = 'io',
		Q3143 = 'europa',
		Q15034 = 'mimas',
		Q3303 = 'enceladus',
		Q15047 = 'tethys',
		Q15040 = 'dione',
		Q15050 = 'rhea',
		Q2565 = 'titan',
		Q15037 = 'hyperion',
		Q17958 = 'iapetus',
		Q17975 = 'phoebe',
		Q3352 = 'miranda',
		Q3343 = 'ariel',
		Q3338 = 'umbriel',
		Q3322 = 'titania',
		Q3332 = 'oberon',
		Q3359 = 'triton',
		Q339 = 'pluto',
	}
	return pxt or 'earth'
end
function koorder(data, options)
	if not data then
		return nil
	end
	local s = {}
	local planet = planeter(data.globe:match('Q%d+'))
	s.lat_dec = math.abs(data.latitude)
	s.long_dec = math.abs(data.longitude)
	if data.latitude > 0 then
		s.lat_NS = 'N'
	else
		s.lat_NS = 'S'
	end
	if data.longitude > 0 then
		s.long_EW = 'E'
	else
		s.long_EW = 'W'
	end
	local frac = 0
	if data.precision == 1 then
		s.lat_g, frac = math.modf(math.abs(data.latitude) + 0.5)
		s.long_g, frac = math.modf(math.abs(data.longitude) + 0.5)
	else
		if data.precision == 0.1 then
			s.lat_g, frac = math.modf(math.abs(data.latitude) * 10 + 0.5)/10
			s.long_g, frac = math.modf(math.abs(data.latitude) * 10 + 0.5)/10
		else
			if data.precision == 0.01 then
				s.lat_g, frac = math.modf(math.abs(data.latitude) * 100 + 0.5)/100
				s.long_g, frac = math.modf(math.abs(data.latitude) * 100 + 0.5)/100
			else
				if data.precision == 0.001 then
					s.lat_g, frac = math.modf(math.abs(data.latitude) * 1000 + 0.5)/1000
					s.long_g, frac = math.modf(math.abs(data.latitude) * 1000 + 0.5)/1000
				else
					if data.precision == 0.0001 then
						s.lat_g, frac = math.modf(math.abs(data.latitude) * 10000 + 0.5)/10000
						s.long_g, frac = math.modf(math.abs(data.latitude) * 10000 + 0.5)/10000
					else
						if data.precision > 0.0166 and data.precision  0.000277 and data.precision  0.0000277 and data.precision  0.00000277 and data.precision = tonumber(index) then
			table.insert(claims2, claimstonumber(index))
		end
	end
	return claims2
end
function preferqualifier(claims, options)
	local claims2 = {}
	for i, statement in pairs( claims ) do
		if statement.qualifiers and statement.qualifiersoptions.preferqualifier:upper() then
			if options.preferqualifiervalue and options.preferqualifiervalue ~=  then
				local active = false
				for k, t in pairs(mw.text.split(options.preferqualifiervalue,',')) do
					for j, value in pairs(formatStatements({property=options.preferqualifier:upper(), raw = 'true'}, statement.qualifiers)) do
						if value.item == t and not active then
							table.insert( claims2, statement)
							active = true
						end
					end
				end
			else
				table.insert( claims2, statement)
			end
		end
	end
	return claims2
end
function versalisering(label, options)
	local versalisering = options.versalisering
	if options.firstversalisering and options.num == 1 then
		versalisering = options.firstversalisering
	end
	if not versalisering or versalisering ==  then
		return label
	end
	if versalisering == 'lcfirst' then
		return mw.getCurrentFrame():preprocess("")
	elseif versalisering == 'ucfirst' then
		return mw.language.getContentLanguage():ucfirst( label )
	elseif versalisering == 'lc' then
		return mw.getCurrentFrame():preprocess("")
	elseif versalisering == 'uc' then
		return mw.getCurrentFrame():preprocess("")
	end
	return label
end
function getqualifierbysortingproperty(claim, sortingproperty)
	for k, v in pairs(sortingproperty) do
		if claim.qualifiers and claim.qualifiersv and claim.qualifiersv1.snaktype == 'value' then
			return claim.qualifiersv1.datavalue.value.time
		end
	end
	return nil
end
function getDate(claim, options)
	local sortingproperty = sortingproperties
	if type(options.sortingproperty) == 'table' then
		sortingproperty = options.sortingproperty
	elseif type(options.sortingproperty) == 'string' then
		sortingproperty = {options.sortingproperty}
	end
	return getqualifierbysortingproperty(claim, sortingproperty)
end
function getDateArb(claim, options)
	local sortingproperty = options.sortingproperty or 'P569'
	if claim.mainsnak.snaktype == 'value' then
		local item = getEntityIdFromValue( claim.mainsnak.datavalue.value )
		return formatStatements({property = sortingproperty, entityId = item, enbarten = 'ja', sortbytime = 'chronological', noref = 'ja'})
	end
end
function comparedates(a, b)
	if a and b then
		return a > b
	elseif a then
		return true
	end
end
function sortbyqualifier(claims, options)
	table.sort(claims, function(a, b)
		local timeA = getDate(a, options)
		local timeB = getDate(b, options)
		if options.sortbytime == 'inverted' then
			return comparedates(timeB, timeA)
		else
			return comparedates(timeA, timeB)
		end
	end)
	return claims
end
function sortbyarb(claims, options)
	table.sort(claims, function(a,b)
		local timeA = getDateArb(a, options)
		local timeB = getDateArb(b, options)
		if options.sortbyarbitrary == 'inverted' then
			return comparedates(timeB, timeA)
		else
			return comparedates(timeA, timeB)
		end
	end)
	return claims
end
function getLabelFromFallBack( id )
	local entity = getEntityFromId( id )
	if not entity.labels then
		return {value =  .. id .. 'Kategori:Wikidatabaserade länkar som leder till sidor utan label', language = }
	end
	for k, v in pairs(fallback) do
		if entity.labelsv then
			return {value = entity.labelsv.value, language = entity.labelsv.language}
		end
	end
	-- Om inget fallback-språk finns av de i variabeln ovan, så används det först definierade i objektet
	if entity.labels then
		for v, k in pairs(entity.labels) do
			return {value = k.value, language = k.language}
		end
	end
	return {value = '-', language = }
end
function getEntityFromId( id )
	if id then
		return mw.wikibase.getEntityObject( id )
	else
		return mw.wikibase.getEntityObject()
	end
end
function getEntityIdFromValue( value )
	if value'entity-type' == 'item' then
		return 'Q' .. value'numeric-id'
	elseif value'entity-type' == 'property' then
		return 'P' .. value'numeric-id'
	else
		return formatError( 'unknown-entity-type' )
	end
end
function formatError( key )
	return  .. i18n.errorskey .. 
end
function formatStatements( options, ref )
	local formattedStatements = {}
	local claims = {}
	if not options.property then
		return formatError( 'property-param-not-provided' )
	end
	if type(ref) == 'table' then -- för de fall där funktionen anropas och alla claims redan finns i en tabell
		claims = refoptions.property or {}
	else
		--Get entity
		local entity = nil
		
		if options.entity and type( options.entity ) == "table" then
			entity = options.entity
		else
			entity = getEntityFromId( options.entityId )
		end
		if not entity then
			return  --TODO error?
		end
		if not entity.claims or not entity.claimsoptions.property:upper() then
			return  --TODO error?
		end
		--Format statement and concat them cleanly
		if options.rank == 'best' or not options.rank then
			claims = entity:getBestStatements( options.property:upper() )
		elseif options.rank == 'valid' then
			for i, statement in pairs( entity.claimsoptions.property:upper() ) do
				if statement.rank == 'preferred' or statement.rank == 'normal' then
					table.insert( claims, statement )
				end
			end
		elseif options.rank == 'all' then
			for i, statement in pairs( entity.claimsoptions.property:upper() ) do
				table.insert( claims, statement )
			end
		else
			for i, statement in pairs( entity.claimsoptions.property:upper() ) do
				if statement.rank == options.rank then
					table.insert( claims, statement )
				end
			end
		end
		if options.avoidqualifier then
			local claims2 = {}
			for i, statement in pairs( claims ) do
				if not statement.qualifiers or not statement.qualifiersoptions.avoidqualifier:upper() then
					table.insert( claims2, statement)
				end
			end
			claims = claims2
		end
		if options.preferqualifier and options.preferqualifier ~=  then
			claims = preferqualifier(claims, options)
		end
		--om det finns vissa statements som har en qualifier som säger "språk = svenska", ta bara med dessa
		--alternativt om det finns statements som har en qualifier som säger "skriptsystem == latinska alfabetet"
		if not options.langpref or options.langpref ==  then
			local claims2 = {}
			for i, statement in pairs( claims ) do
				if statement.qualifiers and statement.qualifiers.P407 then
					for k, v in pairs( statement.qualifiers.P407 ) do
						if v.snaktype == 'value' and v.datavalue.value'numeric-id' == 9027 then -- Q9027 = 'cebuano'
							table.insert( claims2, statement )
						end
					end
				elseif statement.qualifiers and statement.qualifiers.P282 then
					for k, v in pairs( statement.qualifiers.P282 ) do
						if v.snaktype == 'value' and v.datavalue.value'numeric-id' == 8229 then -- Q8229 = 'latinska alfabetet'
							table.insert( claims2, statement )
						end
					end
				end
			end
			if #claims2 > 0 then
				claims = claims2
			end
		end
		if options.sortbytime == 'chronological' or options.sortbytime == 'inverted' then
			claims = sortbyqualifier(claims, options)
		elseif options.sortbyarbitrary == 'chronological' or options.sortbyarbitrary == 'inverted' then
			claims = sortbyarb(claims, options)
		end
		if options.getonly and options.getonly ~=  then
			claims = getonly(claims, options)
		end
	end
	if options.claimindex and #claims > 0 then
		claims = claimindex(claims, options)
	end
	if options.enbarten and options.enbarten ~=  and #claims > 1 then
		claims = {claims1}
	end
	local statementsraw = {}
	if claims then
		for i, statement in pairs( claims ) do
			options.num = i
			local stat = formatStatement( statement, options )
			if stat then
				local s = stat.value
				local spostref = 
				local d = stat.datum
				local tf = stat.tifr
				local pr = stat.pr
				local utgivort = stat.utgivort
				if s ==  then s = nil end
				if s then
					if d and options.withdate and options.withdate ~=  then
						s = s .. mw.text.tag('small', {}, ' (' .. d .. ')')
					end
					if tf and options.withintervall and options.withintervall ~=  then
						if options.withintervall == 'gift' then
							s = s .. mw.text.tag('br') .. mw.text.tag('small', {}, '(g. ' .. tf .. ')')
						else
							s = s .. mw.text.tag('small', {}, ' (' .. tf .. ')')
						end
					end
					if utgivort and options.withutgivort and options.withutgivort ~=  then
						if options.withutgivort == 'parantes och small' then
							s = s .. ' ' .. mw.text.tag('small', {}, ' (' .. utgivort .. ')')
						else
							s = s .. ' ' .. utgivort
						end
					end
					if options.getsimpleproperty == 'född' and pr and pr ~=  then
						s = s .. ' ' .. mw.text.tag('small', {}, '(f. ' .. pr .. ')')
					end
					if options.getsimpleproperty == 'parentes' and pr and pr ~=  then
						s = s .. ' ' .. mw.text.tag('span', {}, '(' .. pr .. ')')
					end
					if options.getsimpleproperty == 'avnågon' and pr and pr ~=  then
						s = s .. ' ' .. mw.text.tag('span', {}, ' av ' .. pr .. )
					end
					if options.grav and options.grav ~=  then
						if options.grav == 'coordonly' then
							if stat.koord then
								spostref =  .. stat.koord
							end
						else
							if stat.gravid then
								spostref =  .. stat.gravid
							end
							if stat.koord then
								spostref = spostref ..  .. stat.koord
							end
						end
					end
					if type(ref) == 'table' then --Inte leta efter referenser om själva anropet görs från en referens
						table.insert( formattedStatements, s .. spostref )
					else
						local t = formatReferencesNew( statement, options)
						if t.flag then
							table.insert( formattedStatements, s .. t.value .. spostref)
							stat.ref = t.value
							stat.refraw = t.refraw
							stat.refquality = t.refquality
						else
							stat = nil
						end
					end
				end
				if stat then
					table.insert(statementsraw, stat)
				end
			end
		end
	end
	
		
	local tot = mw.text.listToText( formattedStatements, options.separator, options.conjunction )
	if tot ==  then tot = nil end
	if options.wdlink and options.wdlink ~=  then
		local dlink = 
		local wdlabel = 'WD'
		if options.wdlinklabel and options.wdlinklabel ~=  then
			wdlabel = options.wdlinklabel
		end
		if options.entityId then
			dlink = options.entityId .. '#' .. options.property
		else
			dlink = 'Special:ItemByTitle/svwiki/' .. mw.getCurrentFrame():getParent():getTitle() .. '#' .. options.property
		end
		if options.wdlink == 'sub' then
			tot = tot .. ' ' .. mw.text.tag('sub', {},  .. wdlabel .. )
		elseif options.wdlink == 'sup' then
			tot = tot .. ' ' .. mw.text.tag('sup', {},  .. wdlabel .. )
		elseif options.wdlink == 'small' then
			tot = tot .. ' ' .. mw.text.tag('small', {},  .. wdlabel .. )
		else
			tot = tot .. ' '.. wdlabel ..
		end
	end
	if options.raw and options.raw ~=  then
		return statementsraw
	end
	if options.numberofclaims and options.numberofclaims ~=  then
		return #formattedStatements
	end
	return tot
end
function formatReferencesNew( statement, options)
	local reference = {}
	local references = {}
	local quality = 0 -- ingen källa alls
	local flagga = false
	if statement.references then
		local cite = require('Module:Cite')
		for i, ref in pairs(statement.references) do
			local items, s = {}, nil
			if ref.snaks then
				if ref.snaks.P248 then
					for j, prop in pairs(ref.snaks.P248) do
						table.insert(items, getEntityIdFromValue( prop.datavalue.value ))
					end
				end
				if quality  99) or  (options.sources == 'basic' and quality > 9) or (not options.sources or options.sources == ) then
			for i, ref in pairs(reference) do
				table.insert(references, mw.getCurrentFrame():extensionTag( 'ref', ref.value, {name = ref.name}))
			end
			flagga = true
		else
			flagga = false
		end
	else
		if not options.sources or options.sources ==  then
			flagga = true
		end
	end
	return {value = table.concat(references), refquality = quality, refraw = reference, flag = flagga}
end
function formatStatement( statement, options )
	if statement.type == 'statement' then
		local s = formatSnak( statement.mainsnak, options )
		if statement.qualifiers then
			if statement.qualifiers.P585 then
				s.datum = formatStatements({property = "P585", enbarten = 'true', noref = 'true', modifytime = options.modifyqualifiertime}, statement.qualifiers)
			end
			if statement.qualifiers.P574 then
				s.dateoftaxpub = formatStatements({property = "P574", enbarten = 'true', noref = 'true', modifytime = options.modifyqualifiertime}, statement.qualifiers)
			end
			if statement.qualifiers.P625 then
				s.koord = formatStatements({property = "P625", enbarten = 'true', noref = 'true', label = options.koordlabel, typen = options.koordtypen, primary = options.koordprimary}, statement.qualifiers)
			end
			if statement.qualifiers.P965 then
				s.gravid = formatStatements({property = "P965", noref = 'true'}, statement.qualifiers)
			end
			if statement.qualifiers.P405 then
				local auktorer = {}
				for i, j in pairs(statement.qualifiers.P405) do
					if j.snaktype == 'value' then
						local item = getEntityIdFromValue( j.datavalue.value )
						local auktorsnamn = formatStatements({property = "P428", entityId = item, noref = 'ja', enbarten = 'ja'})
						if auktorsnamn and auktorsnamn ~=  then
							table.insert(auktorer, formatEntityId(item, {label = auktorsnamn}).value)
						else
							table.insert(auktorer, formatEntityId(item, {}).value)
						end
					end
				end
				s.auktor = mw.text.listToText(auktorer, ', ', ' & ')
			end
			if s and (statement.qualifiers.P580 or statement.qualifiers.P582) then
				local f = formatStatements({property = "P580", enbarten = 'true', noref = 'true', modifytime = options.modifyqualifiertime}, statement.qualifiers) or 
				local t = formatStatements({property = "P582", enbarten = 'true', noref = 'true', modifytime = options.modifyqualifiertime}, statement.qualifiers) or 
				s.tifr = f .. '–' .. t
			end
			if statement.qualifiers.P291 then
				s.utgivort = formatStatements({property = "P291", noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
			end
			if statement.qualifiers.P2096 then
				s.bildtext = formatStatements({property = "P2096", noref = 'true', langpref = (options.langpref or 'ceb')}, statement.qualifiers)
			end
			if s then
				if options.qual1 and options.qual1 ~=  and statement.qualifiersoptions.qual1 then
					s.qp1 = formatStatements({property = options.qual1, noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
				end
				if options.qual2 and options.qual2 ~=  and statement.qualifiersoptions.qual2 then
					s.qp2 = formatStatements({property = options.qual2, noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
				end
				if options.qual3 and options.qual3 ~=  and statement.qualifiersoptions.qual3 then
					s.qp3 = formatStatements({property = options.qual3, noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
				end
				if options.qual4 and options.qual4 ~=  and statement.qualifiersoptions.qual4 then
					s.qp4 = formatStatements({property = options.qual4, noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
				end
				if options.qual5 and options.qual5 ~=  and statement.qualifiersoptions.qual5 then
					s.qp5 = formatStatements({property = options.qual5, noref = 'true', separator = options.qualifierseparator, conjunction = options.qualifierconjunction}, statement.qualifiers)
				end
			end
		end
		return s
	elseif not statement.type then
		return formatSnak( statement, options )
	end
	return {value = formatError( 'unknown-claim-type' )}
end
function formatSnak( snak, options )
	if snak.snaktype == 'somevalue' then
		if options.somevalue then
			if options.somevalue ==  then
				return nil
			else
				return {value = options.somevalue}
			end
		end
		return {value = i18n'somevalue'}
	elseif snak.snaktype == 'novalue' then
		if options.novalue then
			if options.novalue ==  then
				return nil
			else
				return {value = options.novalue}
			end
		end
		return {value = i18n'novalue'}
	elseif snak.snaktype == 'value' then
		local s = formatDatavalue( snak.datavalue, options, snak.datatype )
		if s and options.prefix and options.prefix ~=  then
			s.value = options.prefix .. s.value
		end
		if s and options.suffix and options.suffix ~=  then
			s.value = s.value .. options.suffix
		end
		if s and s.item and options.getsimpleproperty and options.getsimpleproperty ~=  and options.getproperty and options.getproperty ~=  then
			local pr = formatStatements({property = options.getproperty, entityId = s.item, enbarten = options.getenbarten, noref = 'ja', modifytime = options.getmodifytime, raw = options.getraw})
			if pr then s.pr = pr end
		end
		return s
	else
		return {value = formatError( 'unknown-snak-type' )}
	end
end
function formatDatavalue( datavalue, options, datatype )
	--Use the customize handler if provided
	if options'value-module' or options'value-function' then
		if not options'value-module' or not options'value-function' then
			return {value = formatError( 'unknown-value-module' )}
		end
		local formatter = require ('Module:' .. options'value-module')
		if not formatter then
			return {value = formatError( 'value-module-not-found' )}
		end
		local fun = formatteroptions'value-function'
		if not fun then
			return {value = formatError( 'value-function-not-found' )}
		end
		return {value = fun( datavalue.value, options )}
	end
	--Default formatters
	if datatype == 'wikibase-item' then
		local s = formatEntityId( getEntityIdFromValue( datavalue.value ), options )
		s.item = getEntityIdFromValue( datavalue.value )
		if options.relevans and options.relevans ~=  then
			if not mw.wikibase.sitelink( s.item ) then
				return nil
			end
		end
		return s
	elseif datatype == 'string' or datatype == 'commonsMedia' or datatype == 'external-id' then
		if options.pattern and options.pattern ~=  then
			if options.pattern == "auktoritetsdata" then
				local patter = formatStatements( {property = "P1630", entityId = options.property, enbarten = 'true', noref = 'true' })
				return {value = formatFromPattern( datavalue.value, {pattern = patter} )}
			elseif options.pattern == "auktoritetsdata2" then
				local patter = formatStatements( {property = "P1630", entityId = options.property, enbarten = 'true', noref = 'true' })
				return {value =  .. formatFromPattern( datavalue.value, {pattern = patter} ) .. ' ' .. datavalue.value ..  }
			else
				return {value = formatFromPattern( versalisering(datavalue.value, options), options )}
			end
		else
			return {value = versalisering(datavalue.value, options), label = datavalue.value}
		end
	elseif datatype == 'time' then
		local Time = require 'Module:Time'
		local tid = Time.newFromWikidataValue( datavalue.value ):toHtml()
		if options.modifytime == 'longdate' then
			local mall = 
			if datavalue.value.precision >= 11 then
				mall =  .. string.gsub(datavalue.value.time,'-00','-01') .. 
				tid = mw.getCurrentFrame():preprocess(mall)
			elseif datavalue.value.precision == 10 then
				mall =  .. string.gsub(datavalue.value.time,'-00','-01') .. 
				tid = mw.getCurrentFrame():preprocess(mall)
			elseif datavalue.value.precision == 9 then
				mall =  .. string.gsub(datavalue.value.time,'-00','-01') .. 
				tid = mw.getCurrentFrame():preprocess(mall)
			end
		elseif options.modifytime == 'Y' then
			local mall =  .. string.gsub(datavalue.value.time,'-00','-01') .. 
			tid = mw.getCurrentFrame():preprocess(mall)
		end
		return {value = tid}
	elseif datatype == 'globe-coordinate' then
		return {value = koorder(datavalue.value, options), latitude = datavalue.value.latitude, longitude = datavalue.value.longitude, precision = datavalue.value.precision, globe = datavalue.value.globe:match('Q%d+')}
	elseif datatype == 'quantity' then
		local amount, unit, cat = datavalue.value.amount, datavalue.value.unit, nil
		local amountsi, unitsi, unitrawsi, numbersi, valuesi= nil, nil, nil, nil, nil
		local amountconv, numberconv, unitconv, unitrawconv, valueconv = nil, nil, nil, nil, nil
		
		if unit then
			unit = unit:match('Q%d+')
		end
		local number = formatera.newFromWikidataValue(datavalue.value)
		local unitraw = unit
		if unit then
			unit = unithandle(unit, options)			
			-- Kontrollera om det finns en SI-enhet för denna 'unit'
			if not options.antiloop then
				local a = formatStatements({property = 'P2370', entityId = unitraw, enbarten = 'true', noref = 'true', raw = 'true', antiloop = 'true'})
				if #a > 0 then
					amountsi = tostring(tonumber(amount) * tonumber(a1.amount))
					unitsi = a1.unit
					unitrawsi = a1.unitraw
					local lang = mw.language.new( 'sv' )
					numbersi = lang:formatNum(tonumber(amountsi))
					valuesi = numbersi .. ' ' .. (unitsi or )
					if options.convertunit and options.convertunit ~=  and options.convertunit ~= unitraw  then
						local b = formatStatements({property = 'P2370', entityId = options.convertunit, enbarten = 'true', noref = 'true', raw = 'true', antiloop = 'true'})
						if #b > 0 and b1.unitraw == a1.unitraw then
							amountconv = tostring(tonumber(amount) * tonumber(a1.amount) / tonumber(b1.amount))
							unitrawconv = options.convertunit
							unitconv = unithandle(options.convertunit, options)
							local upperBoundconv, lowerBoundconv = nil, nil
							if datavalue.value.upperBound and datavalue.value.upperBound ~= amount then
								upperBoundconv = tostring(tonumber(datavalue.value.upperBound) * tonumber(a1.upperBound) / tonumber(b1.upperBound))
								lowerBoundconv = tostring(tonumber(datavalue.value.lowerBound) * tonumber(a1.lowerBound) / tonumber(b1.lowerBound))
								numberconv = formatera.newFromWikidataValue({amount = amountconv, upperBound = upperBoundconv, lowerBound = lowerBoundconv})
							else
								numberconv = formatera.avrunda({args = {varde = amountconv, vardesiffror = (options.vardesiffror or '3')}})
							end
							valueconv = numberconv .. ' ' .. (unitconv or )
							return {value = valueconv, amount = amountconv, upperBound = upperBoundconv, lowerBound = lowerBoundconv, unit = unitconv, unitraw = unitrawconv, valuesi = valuesi, amountsi = amountsi, unitrawsi = unitrawsi, unitsi = unitsi}
						end
						if options.convertunit ~= unitraw then
							return {value = number .. ' ' .. (unit or ) .. ' ' .. formatError( 'non-convertible unit') .. 'Kategori:Wikidata:Påståenden som inte går att konvertera', amount = amount, upperBound = datavalue.value.upperBound, lowerBound = datavalue.value.lowerBound, unit = unit, unitraw = unitraw, cat = cat, valuesi = valuesi, amountsi = amountsi, unitrawsi = unitrawsi, unitsi = unitsi}	
						end
					end
				end
			end
		end
		return {value = number .. ' ' .. (unit or ), amount = amount, upperBound = datavalue.value.upperBound, lowerBound = datavalue.value.lowerBound, unit = unit, unitraw = unitraw, valuesi = valuesi, amountsi = amountsi, unitrawsi = unitrawsi, unitsi = unitsi}
	elseif datatype == 'url' then
		if options.label and options.label ~=  then
			return {value =  .. datavalue.value .. ' ' .. options.label .. }
		else
			return {value = datavalue.value}
		end
	elseif datatype == 'monolingualtext' then
		local texten = versalisering(datavalue.value.text, options)
		if not options.langpref or options.langpref ==  then
			return {value = mw.text.tag('span', {title = mw.language.fetchLanguageName(datavalue.value.language, 'sv')}, texten), text = texten}
		else
			if options.langpref == datavalue.value.language then
				return {value = mw.text.tag('span', {title = mw.language.fetchLanguageName(datavalue.value.language, 'sv')}, texten), text = texten}
			end
		end
	else
		return {value = formatError( 'unknown-datatype' )}
	end
end
function formatEntityId( entityId, options )
	local label = options.label or mw.wikibase.label( entityId )
	if label ==  then
		label = mw.wikibase.label( entityId ) or nil
	end
	if options.labelformatter and options.labelformatter ~=  then
		local formatter = require ('Module:Wikidata2/Aux2')
		local fun = formatteroptions.labelformatter
		if fun then
			label = fun(label, options)
		end
	end
	if options.labelgender and options.labelgender ~=  then
		local labelgenus  = formatStatements({property=(options.labelgenderproperty or 'P1549'), entityId=entityId, langpref = (options.labelgenderlangpref or 'sv'), preferqualifier = (options.labelgenderqualifier or 'P518'), preferqualifiervalue = options.labelgender, noref='true', versalisering = options.versalisering, firstversalisering = options.firstversalisering})
		if labelgenus and labelgenus ~=  then
			label = labelgenus
		end
	end
	local link = mw.wikibase.sitelink( entityId )
	if link and (not options.nolink or options.nolink == ) then
		if label and label ~=  then
			return {value =  .. versalisering(label, options) .. , label = label }
		else
			return {value = ':' .. versalisering(link, options) .. , label = link }
		end
	else
		if label then
			return {value = versalisering(label, options), label = label}
		else
			local s = getLabelFromFallBack( entityId )
			local l = mw.language.fetchLanguageName(s.language, 'sv')
			if not l or l ==  then
				l = 'okänt språk'
			end
			if s then
				return {value = mw.text.tag('span', {title = l, 'data-q' = entityId, class='modulwikidata2_missingswedishlabel'}, versalisering(s.value, options) ), cat = 'Wikidataetiketter på ' .. l, label = s.value }
			end
		end
		return {value = entityId, cat = 'som har labels med Qid', label = entityId}
	end
end
function formatFromPattern( str, options )
	return mw.ustring.gsub( options.pattern, '$1', str ) ..  --Hack to get only the first result of the function
end
local p = {}
function p.formatEntityId( entityId, options )
	return formatEntityId( entityId, (options or {}) )
end
function p.formatStatements( frame, key )
	local args = frame.args
	--If a value if already set, use it
	if args.value and args.value ~=  then
		return args.value
	end
	return formatStatements( frame.args, key )
end
function p.formatStatementsFromLua( options, key )
	--If a value if already set, use it
	if options.value and options.value ~=  then
		return options.value
	end
	local s = formatStatements( options, key )
	if s ==  then
		s = nil
	end
	return s
end
-- Return the site link (for the current site) for a given data item.
function p.getSiteLink( frame )
	if frame.args1 == nil then
		entity = mw.wikibase.getEntityObject()
		if not entity then
			entity = mw.wikibase.getEntityObject(frame.args1)
		end
		id = entity.id
	else
		id = frame.args1
	end
	return mw.wikibase.sitelink( id )
end
-- This is used to get the TA98 (Terminologia Anatomica first edition 1998) values like 'A01.1.00.005' (property P1323)
-- which are then linked to http://www.unifr.ch/ifaa/Public/EntryPage/TA98%20Tree/Entity%20TA98%20EN/01.1.00.005%20Entity%20TA98%20EN.htm
-- uses the newer mw.wikibase calls instead of directly using the snaks
-- formatPropertyValues returns a table with the P1323 values concatenated with ", " so we have to split them out into a table in order to construct the return string
p.getTAValue = function(frame)
	local ent = mw.wikibase.getEntityObject()
	local props = ent:formatPropertyValues('P1323')
	local out = {}
	local t = {}
	for k, v in pairs(props) do
		if k == 'value' then
			t = mw.text.split( v, ", ")
			for k2, v2 in pairs(t) do
				out#out + 1 = " .. string.sub(v2, 2) .. "%20Entity%20TA98%20EN.htm " .. v2 .. ""
			end
		end
	end
	ret = table.concat(out, " ")
	if #ret == 0 then
		ret = "Invalid TA"
	end
	return ret
end
return p