模組:Taxobox wikidata

require('strict')

local l = {}
local gFrame

local rankList = {
	regnum = '',
	phylum = '',
	classis = '',
	ordo = '',
	familia = '',
	genus = '',
	subgenus = '',
	sectio = '',
	species = '',
	divisio = ''
}
local binomial = ''
local binomialAuthority = ''

local acceptableRank = {
	['Q35409'] = 'familia',
	['Q7432'] = 'species',
	['Q3181348'] = 'sectio',
	['Q3238261'] = 'subgenus',
	['Q34740'] = 'genus',
	['Q36602'] = 'ordo',
	['Q37517'] = 'classis',
	['Q38348'] = 'phylum',
	['Q36732'] = 'regnum',
	['Q334460'] = 'divisio'
}
local iucnCategories = {
	['Q3350324'] = 'NE',
	['Q3245245'] = 'DD',
	['Q211005'] = 'LC',
	['Q719675'] = 'NT',
	['Q278113'] = 'VU',
	['Q11394'] = 'EN',
	['Q219127'] = 'CR',
	['Q239509'] = 'EW',
	['Q123509'] = 'EX'
}
local baseColors = {
	['Animalia'] = 'rgb(235,235,210)',
	['Plantae'] = 'rgb(180,250,180)'
}

local p = {}

function p.main(frame)
	gFrame = frame
	local args
	if frame.args['direct'] == 'yes' then args = frame.args
	else args = frame:getParent().args end
	
	local from = args['from'] or ''
	
	local currName =  l.getData({'label', from})
	local currTaxonName = l.getData({'property', from, 'P225'})
	local currRank = l.getData({'property', 'raw', from, 'P105'})
	local colour = ''
	
	l.setRank(currRank, currName, currTaxonName, true, args['authority'] or '')
	
	local parent = l.getData({'property', 'raw', from, 'P171'})
	local parentRank = l.getData({'property', 'raw', parent, 'P105'})
	local preRank = currRank
	local maxStep = 30
	local step = 0
	while true
	do
		step = step + 1
		local gen = true
		
		if parent == '' or parentRank == currRank or (preRank ~= '' and parentRank == preRank)
		then
			break
		end
		
		if parentRank == ''
		then
			gen = false
		else
			if l.isNilOrEmpty(acceptableRank[parentRank])
			then
				gen = false
			end
		end
		
		local parentTaxonName
		
		if gen
		then
			parentTaxonName = l.getData({'property', parent, 'P225'})
			local parentName = l.getData({'label', parent})
			
			l.setRank(parentRank, parentName, parentTaxonName)
		end
		
		-- 界
		if parentRank == 'Q36732' or step > maxStep
		then
			colour = baseColors[parentTaxonName] or ''
			break
		end
		
		preRank = parentRank
		parent = l.getData({'property', 'raw', parent, 'P171'})
		parentRank = l.getData({'property', 'raw', parent, 'P105'})
	end
	
	local res = frame:expandTemplate{ title = 'Taxobox/core', args = {
		name = currName,
		image = l.getData({'property', 'raw', from, 'P18'}),
		image_caption = l.getData({'qualifier', from, 'P18', 'P2096'}),
		colour = colour,
		regnum = rankList.regnum,
		phylum = rankList.phylum,
		classis = rankList.classis,
		ordo = rankList.ordo,
		familia = rankList.familia,
		genus = rankList.genus,
		subgenus = rankList.subgenus,
		sectio = rankList.sectio,
		species = rankList.species,
		divisio = rankList.divisio,
		binomial = binomial,
		binomial_authority = binomialAuthority,
		status = iucnCategories[l.getData({'property', 'raw', from, 'P141'})] or '',
		status_system = 'iucn3.1',
		range_map = l.getData({'property', 'raw', from, 'P181'}),
		range_map_caption = l.getData({'qualifier', from, 'P181', 'P2096'}),
		synonyms = args['synonyms'] or '',
		}
	}
	return res
end

function l.getData(args)
	return gFrame:expandTemplate{ title = 'Wikidata', args = args }
end

local italicList = {
	sectio = true,
	subgenus = true,
	genus = true
}

function l.setRank(qid, article, taxonName, curr, authority)
	local rank = acceptableRank[qid]
	
	if l.isNilOrEmpty(rank)
	then
		return
	end
	
	local link = "[[" .. article .. "]]"
	local partialItalics
	local normal
	local rank = acceptableRank[qid]
	
	if curr
	then
		partialItalics = l.bold(article .. " " .. l.italic(taxonName))
		normal = l.bold(article .. " " .. taxonName)
	else
		partialItalics = link .. " " .. l.italic(taxonName)
		normal = link .. " " .. taxonName
	end
	
	if rank == 'species'
	then
		local displayTaxonName = l.italic(string.gsub(taxonName, '([%u])[%l]+ ', '%1. '))
		if curr
		then
			rankList[rank] = l.bold(article .. ' ' .. displayTaxonName)
			binomial = l.italic(taxonName)
			binomialAuthority = authority
		else
			rankList[rank] = link .. ' ' .. displayTaxonName
		end
		return
	elseif italicList[rank]
	then
		rankList[rank] = partialItalics
		return
	elseif rank == 'divisio'
	then
		if(rankList[rank] ~= '')
		then
			return
		end
	end
	
	rankList[rank] = normal
end

function l.bold(str)
	return "'''" .. str .. "'''"
end

function l.italic(str)
	return "''" .. str .. "''"
end

function l.isNilOrEmpty(thing)
	if thing == nil or thing == '' then
		return true
	end
	return nil
end

return p