From Wikipedia, the free encyclopedia

local p = {}



local infobox = require("Module:Infobox")

local infoboxImage = require("Module:InfoboxImage")

local arguments = require("Module:Arguments")

local ifPreview = require("Module:If preview")



local colors = {

	animalia = "ebebd2",

	archaea = "c3f5fa",

	archaeplastida = "b4fab4",

	bacteria = "dcebf5",

	eukaryota = "f5d7ff",

	fungi = "91fafa",

	incertae_sedis = "faf0e6",

	sar = "c8fa50",

	veterovata = "fafadc",

	virus = "fafabe",

}



-- aliases that use the same color

-- TODO: combine the tables?

local colorAliases = {

	animal = "animalia",

	

	nanoarchaeota = "archaea",

	nanarchaeota = "archaea",

	korarchaeota = "archaea",

	thaumarchaeota = "archaea",

	crenarchaeota = "archaea",

	euryarchaeota = "archaea",

	

	plantae = "archaeplastida",

	plant = "archaeplastida",

	viridiplantae = "archaeplastida",

	

	firmicutes = "bacteria",

	eubacteria = "bacteria",

	

	eukaryote = "eukaryota",

	eukarya = "eukaryota",

	excavata = "eukaryota",

	excavates = "eukaryota",

	protista = "eukaryota",

	protists = "eukaryota",

	amoebozoa = "eukaryota",

	opisthokonta = "eukaryota",

	choanozoa = "eukaryota",

	

	acritarcha = "incertae_sedis",

	

	chromalveolata = "sar",

	

	viroid = "virus",

	viroids = "virus",

	viruses = "virus",

	i = "virus",

	ii = "virus",

	iii = "virus",

	iv = "virus",

	v = "virus",

	vi = "virus",

	vii = "virus",

	vii = "virus",

}



-- This table shows which order the color search should go

local taxonOrder = {

	"phylum", "unranked_phylum", "divisio", "unranked_superdivisio", "superphylum", "unranked_superphylum", "superdivision", "unranked_superdivisio",

	"subregnum", "unranked_subregnum", "regnum", "unranked_regnum", "superregnum", "unranked_superregnum", "domain", "unranked_domain", "virus_group"

}



-- Gets the background color as a hex code, if possible

--

-- @param args the arguments passed in to the template

--

-- @return a hex color, or nil if no color should be shown

local function getColor(args)

	for _, taxon in ipairs(taxonOrder) do

		local v = argstaxon

		if v then

			local delinked = mw.ustring.gsub(mw.ustring.lower(v), "[%]%[']", "") -- delink, converting "[[''name'']]" to "name"

			local i = mw.ustring.find(delinked, "|")

			local sanitized = i and mw.ustring.sub(delinked, 0, i - 1) or delinked -- get "abx" from "abc|xyz"

			local hex = colorssanitized or colorscolorAliasessanitized]]

			if hex then

				return hex

			end

		end

	end

end



local classification = {

	{ arg_name = "superdomain", label = "Superdomain" },

	{ arg_name = "domain", label = "Domain" },

	{ arg_name = "superregnum", label = "Superkingdom" },

	{ arg_name = "regnum", label = "Kingdom" },

	{ arg_name = "subregnum", label = "Subkingdom" },

	{ arg_name = "superdivisio", label = "Superdivision" },

	{ arg_name = "superphylum", label = "Superphylum" },

	{ arg_name = "divisio", label = "Division" },

	{ arg_name = "phylum", label = "Phylum" },

	{ arg_name = "subdivisio", label = "Subdivision" },

	{ arg_name = "subphylum", label = "Subphylum" },

	{ arg_name = "infraphylum", label = "Infraphylum" },

	{ arg_name = "microphylum", label = "Microphylum" },

	{ arg_name = "nanophylum", label = "Nanophylum" },

	{ arg_name = "superclassis", label = "Superclass" },

	{ arg_name = "classis", label = "Class" },

	{ arg_name = "subclassis", label = "Subclass" },

	{ arg_name = "infraclassis", "Infraclass" },

	{ arg_name = "magnordo", label = "Magnorder" },

	{ arg_name = "superordo", label = "Superorder" },

	{ arg_name = "ordo", label = "Order" },

	{ arg_name = "subordo", label = "Suborder" },

	{ arg_name = "infraordo", label = "Infraorder" },

	{ arg_name = "parvordo", label = "Parvorder" },

	{ arg_name = "zoodivisio", label = "Division" },

	{ arg_name = "zoosectio", label = "Section" },

	{ arg_name = "zoosubsectio", label = "Subsection" },

	{ arg_name = "superfamilia", label = "Superfamily" },

	{ arg_name = "familia", label = "Family" },

	{ arg_name = "subfamilia", label = "Subfamily" },

	{ arg_name = "supertribus", label = "Supertribe" },

	{ arg_name = "tribus", label = "Tribe" },

	{ arg_name = "subtribus", label = "Subtribe" },

	{ arg_name = "alliance", label = "''Alliance''" },

	{ arg_name = "genus", label = "Genus" },

	{ arg_name = "subgenus", label = "Subgenus" },

	{ arg_name = "sectio", label = "Section" },

	{ arg_name = "subsectio", label = "Subsection" },

	{ arg_name = "series", label = "Series" },

	{ arg_name = "subseries", label = "Subseries" },

	{ arg_name = "species_group", label = "''Species group''" },

	{ arg_name = "species_subgroup", label = "''Species subgroup''" },

	{ arg_name = "species_complex", label = "''Species complex''" },

	{ arg_name = "species", label = "Species" },

	{ arg_name = "subspecies", label = "Subspecies" },

	{ arg_name = "variety", label = "Variety" }, -- no unranked

	{ arg_name = "varias", label = "Variety" }, -- no unranked; alias of variety

	{ arg_name = "forma", label = "Form" }, -- no unranked

}



-- InfoboxImage: [[File:Status <status_system> <file>.svg|link=|alt=<category>]]

-- AddCaption: <label>

-- AddCategory: [[Category:<category>]]

local statusSystems = {

	"iucn2.3" = {

		link = "IUCN Red List",

		EX = { file = "EX", label = "[[Extinct]]", category = "IUCN Red List extinct species" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "IUCN Red List extinct in the wild species" },

		CR = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

		EN = { file = "EN", label = "[[Endangered species|Endangered]]", category = "IUCN Red List endangered species" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "IUCN Red List vulnerable species" },

		LR = {file = "blank", label = "Lower risk", category = "Invalid conservation status" },

		CD = { file = "CD", label = "[[Conservation dependent]]", category = "IUCN Red List conservation dependent species" },

		"LR/CD" = { file = "CD", label = "[[Conservation dependent]]", category = "IUCN Red List conservation dependent species" }, -- duplicate

		NT = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" },

		"LR/NT" = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" }, -- duplicate

		LC = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List near threatened species" },

		"LR/LC" = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List near threatened species" },

		DD = { file = "blank", label = "[[Least deficient]]", category = "IUCN Red List data deficient species" },

		NE = { label = "''Not evaluated''" },

		NR = { label = "''Not recognized''" },

		PE = { file = "CR", label = "[[Critically endangered]], possibly extinct", category = "IUCN Red List critically endangered species" },

		PEW = { file = "CR", label = "[[Critically endangered]], possibly extinct in the wild", category = "IUCN Red List critically endangered species" },

	},

	"iucn3.1" = {

		link = "IUCN Red List",

		EX = { file = "EX", label = "[[Extinct]]", category = "IUCN Red List extinct species" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "IUCN Red List extinct in the wild species" },

		CR = { file = "CR", label = "[[Critically endangered species|Critically endangered]]", category = "IUCN Red List critically endangered species" },

		EN = { file = "EN", label = "[[Endangered species (IUCN status)|Endangered]]", category = "IUCN Red List endangered species" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "IUCN Red List vulnerable species" },

		NT = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" },

		LC = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List least concern species" },

		DD = { file = "blank", label = "[[Data deficient]]", category = "IUCN Red List data deficient species" },

		NE = { label = "''Not evaluated''" },

		NR = { label = "''Not recognized''" },

		PE = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

		PEW = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

	},

	"epbc" = {

		link = "EPBC Act",

		EX = { file = "EX", label = "[[Extinct]]", category = "EPBC Act extinct biota" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "EPBC Act extinct in the wild biota" },

		CR = { file = "CR", label = "[[Critically endangered]]", category = "EPBC Act critically endangered biota" },

		EN = { file = "EN", label = "[[Endangered]]", category = "EPBC Act endangered biota" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "EPBC Act vulnerable biota" },

		CD = { file = "CD", label = "[[Conservation dependent]]", category = "EPBC Act conservation dependent biota" },

		DL = { file = "DL", label = "Delisted" },

	},

}



local function getFirst(e, p)

	return e and ep and ep][1

end



function p.main(frame)

	local args = arguments.getArgs(frame)

	return p._main(args, frame)

end



-- Helper function to dynamically retrieve the taxon "authority"

-- and present it in paretheses

--

-- @param args the table of arguments passed into the template

-- @param taxon the taxon to check

--

-- @return nil or text to serve as the taxon name and its authority

local function authorityHelp(args, taxon)

	if argstaxon then

		local authority = argstaxon .. "_authority"

		return argstaxon .. (authority and " (" .. authority .. ")" or "") -- when authority is nil no parentheses appear

	end

end



-- uses the qualifiers table provided to construct an authority string

function p._authorityHelp(qualifiers)

	local p405 = getFirst(qualifiers, "P405")

	local authority = p405 and p405"datavalue" and p405"datavalue"]["value" and p405"datavalue"]["value"]["id"

	local q = authority and mw.wikibase.getEntity(authority)

	local lastNameP = q and q"claims" and getFirst(q"claims"], "P835")

	local lastName = lastNameP and lastNameP"mainsnak" and lastNameP"mainsnak"]["datavalue" and lastNameP"mainsnak"]["datavalue"]["value"

	

	local p574 = getFirst(qualifiers, "P574")

	local year = p574 and p574"datavalue" and p574"datavalue"]["value" and p574"datavalue"]["value"]["time"

	

	if lastName and year then return " (" .. lastName .. ", " .. year .. ")"

	elseif lastName or year then return " (" .. (lastName or year) .. ")"

	else return ""

	end

end



function p._main(args, frame)

	

	local warnings = {} -- warnings to display on preview

	local passing = {} -- arguments passed to Module:Infobox

	

	-- Safely replace spaces in parameters with underscores, removing the original parameter and sending a warning

	for k, _ in pairs(args) do

		if mw.ustring.find(k, " ") then

			local k1 = mw.ustring.gsub(s, " ", "_")

			if not argsk1 then

				table.insert(warnings, "deprecated parameter \"" .. k .. "\". Please use \"" .. k1 .. "\" instead.")

				argsk1 = argsk -- copy value

				argsk = nil -- empty

			else

				table.insert(warnings, "found \"" .. k .. "\" and \"" .. k1 .. "\". Using \"" .. k1 .. "\" instead.")

			end

		end

	end

	

	if args.name then

		passing.above = args.name

	elseif args.genus or args.species or args.binomial then

		local title = mw.title.getCurrentTitle().baseText

		local g = mw.ustring.gsub(args.genus or args.species or args.binomial, "'", "")

		if title == g or "<abbr title=\"Extinct\" aria-label=\"Extinct\" style=\"border: none; text-decoration: none; cursor: inherit; font-weight: normal; font-style: normal;\">†</abbr>" .. title == g or "†" .. title == g then

			passing.above = "''" .. g .. "''"

			-- TODO: add {{Italic title}}

		else

			passing.above = title

		end

	else

		passing.above = mw.title.getCurrentTitle().baseText

	end

	

	if args.fossil_range then

		passing.subheader = "Temporal range: " .. args.fossil_range

	end

	

	-- apply header styles

	local hex = args.color_as or args.colour_as or getColor(args)

	if hex then

		local style = "background-color: #" .. hex .. ";"

		passing.abovestyle = style

		passing.subheaderstyle = style

		passing.headerstyle = style

	end

	

	if args.image then

		passing.image = infoboxImage.InfoboxImage({args = {image = args.image, upright = args.upright or args.image_upright, alt = args.alt or args.image_alt}})

		passing.caption = args.caption or args.image_caption

	end

	if args.image2 then

		passing.image2 = infoboxImage.InfoboxImage({args = {image = args.image2, upright = args.upright2 or args.image2_upright, alt = args.alt2 or args.image2_alt}})

		passing.caption2 = args.caption2 or args.image2_caption

	end

	

	

	local i = 1

	

	-- Embed photos into the infobox via frame:expandTemplate

	-- Trying to call Module:Infobox keeps the previous state

	if args.status or args.status2 then

		local subbox = {

			child = "yes",

		}

		

		if args.status and args.status_system then

			args.status = mw.ustring.upper(args.status)

			if args.status_system == "IUCN2.3" or args.status_system == "IUCN3.1" then

				args.status_system = mw.ustring.lower(args.status_system)

			end

			

			if statusSystemsargs.status_system and statusSystemsargs.status_system][args.status then

				local x = statusSystemsargs.status_system][args.status

				subbox.image1 = infoboxImage.InfoboxImage({args = { image = "Status " .. args.status_system .. " " .. args.status .. ".svg", alt = (x.category or nil)}})

				subbox.caption1 = x.label .. " ([[" .. statusSystemsargs.status_system].link .. "|" .. args.status_system .. "]])" .. (args.status_ref or "")

			end

		end

		

		if args.status2 and args.status2_system then

			args.status2 = mw.ustring.upper(args.status2)

			if args.status2_system == "IUCN2.3" or args.status2_system == "IUCN3.1" then

				args.status2_system = mw.ustring.lower(args.status2_system)

			end

			

			if statusSystemsargs.status2_system and statusSystemsargs.status2_system][args.status2 then

				local x = statusSystemsargs.status2_system][args.status2

				subbox.image2 = infoboxImage.InfoboxImage({args = { image = "Status " .. args.status2_system .. " " .. args.status .. ".svg", alt = (x.category or nil)}})

				subbox.caption2 = x.label .. " ([[" .. statusSystemsargs.status2_system].link .. "|" .. args.status2_system .. "]])" .. (args.status2_ref or "")

			end

		end

		

		passing"header" .. i = "[[Conservation status]]"

		passing"data" .. i + 1 = frame:expandTemplate({title = "infobox", args = subbox})

		

		i = i + 2

	end

	

	if args.virus or args.virus_group then

		passing"header" .. i = "[[Virus classification]]"

	elseif args.ichnos then

		passing"header" .. i = "[[Trace fossil classification]]"

	elseif args.veterovata then

		passing"header" .. i = "[[Egg fossil classification]]"

	else

		passing"header" .. i = "[[Scientific classification]]"

	end

	

	i = i + 1

	

	if args.virus_group then

		local g = {

			i = "Group I ([[dsDNA]])",

			ii = "Group II ([[ssDNA]])",

			iii = "Group III ([[dsRDNA]])",

			iv = "Group IV ([[(+)ssRNA]])",

			v = "Group V ([[(-)ssRNA]])",

			vi = "Group VI ([[ssRNA-RT]])",

			"vi/vii" = "Groups VI and VII",

			vii = "Group VII ([[dsDNA-RT]])",

		}

		

		passing"label" .. i = "Virus group"

		passing"data" .. i = gargs.virus_group or args.virus_group

		i = i + 1

	end

	

	local q = args'wikidata_item' or args'qid'];

	local entity = mw.wikibase.getEntity(q)

	

	if args.superdomain or args.domain or args.superregnum or args.regnum or args.subregnum or args.superdivisio

	or args.superphylum or args.divisio or args.phylum or args.subdivisio or args.subphylum or args.infraphylum

	or args.microphylum or args.nanophylum or args.superclassis or args.classis or args.subclassis or args.infraclassis

	or args.magnordo or args.superordo or args.ordo or args.subordo or args.infraordo or args.parvordo or args.zoodivisio

	or args.zoosectio or args.zoosubsectio or args.superfamilia or args.familia or args.subfamilia or args.supertribus

	or args.tribus or args.subtribus or args.alliance or args.genus or args.subgenus or args.sectio or args.subsectio

	or args.series or args.subseries or args.species_group or args.species_subgroup or args.species_complex

	or args.species or args.subspecies or args.variety or args.varias or args.forma then

	

		for _, t in ipairs(classification) do

			local k = t.arg_name

			local v = t.label

			if args"unranked_" .. k then

				passing"label" .. i = "(unranked)"

				passing"data" .. i = authorityHelp(args, "unranked_" .. k)

				i = i + 1

			end

			if argsk then

				passing"label" .. i = v

				passing"data" .. i = authorityHelp(args, k)

				i = i + 1

			end

		end

	elseif entity then

		local p171 = getFirst(entity"claims"], "P171")

		if p171 and p171"mainsnak" and p171"mainsnak"]["datavalue" and p171"mainsnak"]["datavalue"]["value" and p171"mainsnak"]["datavalue"]["value"]["id" then

			local parent = mw.wikibase.getEntity(p171"mainsnak"]["datavalue"]["value"]["id"])

			if parent then

				local p105 = getFirst(parent"claims"], "P105")

				passing"label" .. i = p105 and p105"mainsnak" and p105"mainsnak"]["datavalue" and p105"mainsnak"]["datavalue"]["value" and p105"mainsnak"]["datavalue"]["value"]["id" or nil

				local p225 = getFirst(parent"claims"], "P225")

				passing"data" .. i = p225 and p225"mainsnak" and p225"mainsnak"]["datavalue" and p225"mainsnak"]["datavalue"]["value" or nil

				i = i + 2

			end

		end

	end

	

	if args.virus_infrasp and not args.virus_infrasp_rank then

		table.insert(warnings, "\"virus_infrasp_rank\" missing")

	elseif args.virus_infrasp then

		passing"label" .. i = args.virus_infrasp_rank

	end

	

	if args.binomial then

		passing"header" .. i = "[[Binomial name]]"

		passing"data" .. i + 1 = authorityHelp(args, "binomial")

		i = i + 2

	elseif entity then

		local binomial = getFirst(entity"claims"], "P225")

		if binomial and binomial"mainsnak" and binomial"mainsnak"]["datavalue" and binomial"mainsnak"]["datavalue"]["value" then

			passing"header" .. i = "[[Binomial name]]"

			passing"data" .. i + 1 = binomial"mainsnak"]["datavalue"]["value" .. p._authorityHelp(binomial"qualifiers"])

		end

	end

	

	if args.trinomial then

		passing"header" .. i = "[[Trinomial name]]"

		passing"data" .. i + 1 = authorityHelp(args, "trinomial")

		i = i + 2

	end

	

	if args.range_map then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map, alt = args.range_map_alt, upright = args.range_map_upright}}), caption = args.range_map_caption}})

		i = i + 1

	end

	

	if args.range_map2 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map2, alt = args.range_map2_alt, upright = args.range_map2_upright}}), caption = args.range_map2_caption}})

		i = i + 1

	end

	

	if args.range_map3 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map3, alt = args.range_map3_alt, upright = args.range_map3_upright}}), caption = args.range_map3_caption}})

		i = i + 1

	end

	

	if args.range_map4 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map4, alt = args.range_map4_alt, upright = args.range_map4_upright}}), caption = args.range_map4_caption}})

		i = i + 1

	end

	

	if args.type_genus then

		passing"header" .. i = "[[Type ichnogenus]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_genus")

		i = i + 2

	end

	

	if args.type_oogenus then

		passing"header" .. i = "[[Type oogenus]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_oogenus")

		i = i + 2

	end

	

	if args.type_species then

		passing"header" .. i = "[[Type species]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_species")

		i = i + 2

	end

	

	if args.type_oospecies then

		passing"header" .. i = "[[Type oospecies]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_oospecies")

		i = i + 2

	end

	

	if args.type_strain then

		passing"header" .. i = "[[Type strain]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_strain") .. (args.type_strain_ref or "")

		i = i + 2

	end

	

	if args.subdivision then

		mw.log(args.subdivision)

		passing"header" .. i = args.subdivision_ranks or "Species" .. (args.subdivision_ref or "")

		passing"data" .. i + 1 = "<div style=\"text-align: left;\">\n" .. args.subdivision .. "</div>"

		i = i + 2

	end

	

	if args.possible_subdivision then

		passing"header" .. i = args.possible_subdivision_ranks or "Possible species" .. (args.possible_subdividion_ref or "")

		passing"data" .. i + 1 = args.possible_subdivision

		i = i + 2

	end

	

	if args.synonyms then

		passing"header" .. i = "[[Synonym (taxonomy)|Synonyms]]" .. ( args.synonyms_ref or "")

		passing"data" .. i + 1 = "<div style=\"text-align: left;\">\n" .. args.synonyms .. "</div>"

	end

	

	local out = infobox.infobox(passing)

	

	for _, warning in ipairs(warnings) do

		local w = ifPreview._warning({warning})

		if w and w ~= '' then

			out = out .. w

		end

	end

	

	return out

end



return p
From Wikipedia, the free encyclopedia

local p = {}



local infobox = require("Module:Infobox")

local infoboxImage = require("Module:InfoboxImage")

local arguments = require("Module:Arguments")

local ifPreview = require("Module:If preview")



local colors = {

	animalia = "ebebd2",

	archaea = "c3f5fa",

	archaeplastida = "b4fab4",

	bacteria = "dcebf5",

	eukaryota = "f5d7ff",

	fungi = "91fafa",

	incertae_sedis = "faf0e6",

	sar = "c8fa50",

	veterovata = "fafadc",

	virus = "fafabe",

}



-- aliases that use the same color

-- TODO: combine the tables?

local colorAliases = {

	animal = "animalia",

	

	nanoarchaeota = "archaea",

	nanarchaeota = "archaea",

	korarchaeota = "archaea",

	thaumarchaeota = "archaea",

	crenarchaeota = "archaea",

	euryarchaeota = "archaea",

	

	plantae = "archaeplastida",

	plant = "archaeplastida",

	viridiplantae = "archaeplastida",

	

	firmicutes = "bacteria",

	eubacteria = "bacteria",

	

	eukaryote = "eukaryota",

	eukarya = "eukaryota",

	excavata = "eukaryota",

	excavates = "eukaryota",

	protista = "eukaryota",

	protists = "eukaryota",

	amoebozoa = "eukaryota",

	opisthokonta = "eukaryota",

	choanozoa = "eukaryota",

	

	acritarcha = "incertae_sedis",

	

	chromalveolata = "sar",

	

	viroid = "virus",

	viroids = "virus",

	viruses = "virus",

	i = "virus",

	ii = "virus",

	iii = "virus",

	iv = "virus",

	v = "virus",

	vi = "virus",

	vii = "virus",

	vii = "virus",

}



-- This table shows which order the color search should go

local taxonOrder = {

	"phylum", "unranked_phylum", "divisio", "unranked_superdivisio", "superphylum", "unranked_superphylum", "superdivision", "unranked_superdivisio",

	"subregnum", "unranked_subregnum", "regnum", "unranked_regnum", "superregnum", "unranked_superregnum", "domain", "unranked_domain", "virus_group"

}



-- Gets the background color as a hex code, if possible

--

-- @param args the arguments passed in to the template

--

-- @return a hex color, or nil if no color should be shown

local function getColor(args)

	for _, taxon in ipairs(taxonOrder) do

		local v = argstaxon

		if v then

			local delinked = mw.ustring.gsub(mw.ustring.lower(v), "[%]%[']", "") -- delink, converting "[[''name'']]" to "name"

			local i = mw.ustring.find(delinked, "|")

			local sanitized = i and mw.ustring.sub(delinked, 0, i - 1) or delinked -- get "abx" from "abc|xyz"

			local hex = colorssanitized or colorscolorAliasessanitized]]

			if hex then

				return hex

			end

		end

	end

end



local classification = {

	{ arg_name = "superdomain", label = "Superdomain" },

	{ arg_name = "domain", label = "Domain" },

	{ arg_name = "superregnum", label = "Superkingdom" },

	{ arg_name = "regnum", label = "Kingdom" },

	{ arg_name = "subregnum", label = "Subkingdom" },

	{ arg_name = "superdivisio", label = "Superdivision" },

	{ arg_name = "superphylum", label = "Superphylum" },

	{ arg_name = "divisio", label = "Division" },

	{ arg_name = "phylum", label = "Phylum" },

	{ arg_name = "subdivisio", label = "Subdivision" },

	{ arg_name = "subphylum", label = "Subphylum" },

	{ arg_name = "infraphylum", label = "Infraphylum" },

	{ arg_name = "microphylum", label = "Microphylum" },

	{ arg_name = "nanophylum", label = "Nanophylum" },

	{ arg_name = "superclassis", label = "Superclass" },

	{ arg_name = "classis", label = "Class" },

	{ arg_name = "subclassis", label = "Subclass" },

	{ arg_name = "infraclassis", "Infraclass" },

	{ arg_name = "magnordo", label = "Magnorder" },

	{ arg_name = "superordo", label = "Superorder" },

	{ arg_name = "ordo", label = "Order" },

	{ arg_name = "subordo", label = "Suborder" },

	{ arg_name = "infraordo", label = "Infraorder" },

	{ arg_name = "parvordo", label = "Parvorder" },

	{ arg_name = "zoodivisio", label = "Division" },

	{ arg_name = "zoosectio", label = "Section" },

	{ arg_name = "zoosubsectio", label = "Subsection" },

	{ arg_name = "superfamilia", label = "Superfamily" },

	{ arg_name = "familia", label = "Family" },

	{ arg_name = "subfamilia", label = "Subfamily" },

	{ arg_name = "supertribus", label = "Supertribe" },

	{ arg_name = "tribus", label = "Tribe" },

	{ arg_name = "subtribus", label = "Subtribe" },

	{ arg_name = "alliance", label = "''Alliance''" },

	{ arg_name = "genus", label = "Genus" },

	{ arg_name = "subgenus", label = "Subgenus" },

	{ arg_name = "sectio", label = "Section" },

	{ arg_name = "subsectio", label = "Subsection" },

	{ arg_name = "series", label = "Series" },

	{ arg_name = "subseries", label = "Subseries" },

	{ arg_name = "species_group", label = "''Species group''" },

	{ arg_name = "species_subgroup", label = "''Species subgroup''" },

	{ arg_name = "species_complex", label = "''Species complex''" },

	{ arg_name = "species", label = "Species" },

	{ arg_name = "subspecies", label = "Subspecies" },

	{ arg_name = "variety", label = "Variety" }, -- no unranked

	{ arg_name = "varias", label = "Variety" }, -- no unranked; alias of variety

	{ arg_name = "forma", label = "Form" }, -- no unranked

}



-- InfoboxImage: [[File:Status <status_system> <file>.svg|link=|alt=<category>]]

-- AddCaption: <label>

-- AddCategory: [[Category:<category>]]

local statusSystems = {

	"iucn2.3" = {

		link = "IUCN Red List",

		EX = { file = "EX", label = "[[Extinct]]", category = "IUCN Red List extinct species" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "IUCN Red List extinct in the wild species" },

		CR = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

		EN = { file = "EN", label = "[[Endangered species|Endangered]]", category = "IUCN Red List endangered species" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "IUCN Red List vulnerable species" },

		LR = {file = "blank", label = "Lower risk", category = "Invalid conservation status" },

		CD = { file = "CD", label = "[[Conservation dependent]]", category = "IUCN Red List conservation dependent species" },

		"LR/CD" = { file = "CD", label = "[[Conservation dependent]]", category = "IUCN Red List conservation dependent species" }, -- duplicate

		NT = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" },

		"LR/NT" = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" }, -- duplicate

		LC = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List near threatened species" },

		"LR/LC" = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List near threatened species" },

		DD = { file = "blank", label = "[[Least deficient]]", category = "IUCN Red List data deficient species" },

		NE = { label = "''Not evaluated''" },

		NR = { label = "''Not recognized''" },

		PE = { file = "CR", label = "[[Critically endangered]], possibly extinct", category = "IUCN Red List critically endangered species" },

		PEW = { file = "CR", label = "[[Critically endangered]], possibly extinct in the wild", category = "IUCN Red List critically endangered species" },

	},

	"iucn3.1" = {

		link = "IUCN Red List",

		EX = { file = "EX", label = "[[Extinct]]", category = "IUCN Red List extinct species" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "IUCN Red List extinct in the wild species" },

		CR = { file = "CR", label = "[[Critically endangered species|Critically endangered]]", category = "IUCN Red List critically endangered species" },

		EN = { file = "EN", label = "[[Endangered species (IUCN status)|Endangered]]", category = "IUCN Red List endangered species" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "IUCN Red List vulnerable species" },

		NT = { file = "NT", label = "[[Near threatened]]", category = "IUCN Red List near threatened species" },

		LC = { file = "LC", label = "[[Least concern]]", category = "IUCN Red List least concern species" },

		DD = { file = "blank", label = "[[Data deficient]]", category = "IUCN Red List data deficient species" },

		NE = { label = "''Not evaluated''" },

		NR = { label = "''Not recognized''" },

		PE = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

		PEW = { file = "CR", label = "[[Critically endangered]]", category = "IUCN Red List critically endangered species" },

	},

	"epbc" = {

		link = "EPBC Act",

		EX = { file = "EX", label = "[[Extinct]]", category = "EPBC Act extinct biota" },

		EW = { file = "EW", label = "[[Extinct in the wild]]", category = "EPBC Act extinct in the wild biota" },

		CR = { file = "CR", label = "[[Critically endangered]]", category = "EPBC Act critically endangered biota" },

		EN = { file = "EN", label = "[[Endangered]]", category = "EPBC Act endangered biota" },

		VU = { file = "VU", label = "[[Vulnerable species|Vulnerable]]", category = "EPBC Act vulnerable biota" },

		CD = { file = "CD", label = "[[Conservation dependent]]", category = "EPBC Act conservation dependent biota" },

		DL = { file = "DL", label = "Delisted" },

	},

}



local function getFirst(e, p)

	return e and ep and ep][1

end



function p.main(frame)

	local args = arguments.getArgs(frame)

	return p._main(args, frame)

end



-- Helper function to dynamically retrieve the taxon "authority"

-- and present it in paretheses

--

-- @param args the table of arguments passed into the template

-- @param taxon the taxon to check

--

-- @return nil or text to serve as the taxon name and its authority

local function authorityHelp(args, taxon)

	if argstaxon then

		local authority = argstaxon .. "_authority"

		return argstaxon .. (authority and " (" .. authority .. ")" or "") -- when authority is nil no parentheses appear

	end

end



-- uses the qualifiers table provided to construct an authority string

function p._authorityHelp(qualifiers)

	local p405 = getFirst(qualifiers, "P405")

	local authority = p405 and p405"datavalue" and p405"datavalue"]["value" and p405"datavalue"]["value"]["id"

	local q = authority and mw.wikibase.getEntity(authority)

	local lastNameP = q and q"claims" and getFirst(q"claims"], "P835")

	local lastName = lastNameP and lastNameP"mainsnak" and lastNameP"mainsnak"]["datavalue" and lastNameP"mainsnak"]["datavalue"]["value"

	

	local p574 = getFirst(qualifiers, "P574")

	local year = p574 and p574"datavalue" and p574"datavalue"]["value" and p574"datavalue"]["value"]["time"

	

	if lastName and year then return " (" .. lastName .. ", " .. year .. ")"

	elseif lastName or year then return " (" .. (lastName or year) .. ")"

	else return ""

	end

end



function p._main(args, frame)

	

	local warnings = {} -- warnings to display on preview

	local passing = {} -- arguments passed to Module:Infobox

	

	-- Safely replace spaces in parameters with underscores, removing the original parameter and sending a warning

	for k, _ in pairs(args) do

		if mw.ustring.find(k, " ") then

			local k1 = mw.ustring.gsub(s, " ", "_")

			if not argsk1 then

				table.insert(warnings, "deprecated parameter \"" .. k .. "\". Please use \"" .. k1 .. "\" instead.")

				argsk1 = argsk -- copy value

				argsk = nil -- empty

			else

				table.insert(warnings, "found \"" .. k .. "\" and \"" .. k1 .. "\". Using \"" .. k1 .. "\" instead.")

			end

		end

	end

	

	if args.name then

		passing.above = args.name

	elseif args.genus or args.species or args.binomial then

		local title = mw.title.getCurrentTitle().baseText

		local g = mw.ustring.gsub(args.genus or args.species or args.binomial, "'", "")

		if title == g or "<abbr title=\"Extinct\" aria-label=\"Extinct\" style=\"border: none; text-decoration: none; cursor: inherit; font-weight: normal; font-style: normal;\">†</abbr>" .. title == g or "†" .. title == g then

			passing.above = "''" .. g .. "''"

			-- TODO: add {{Italic title}}

		else

			passing.above = title

		end

	else

		passing.above = mw.title.getCurrentTitle().baseText

	end

	

	if args.fossil_range then

		passing.subheader = "Temporal range: " .. args.fossil_range

	end

	

	-- apply header styles

	local hex = args.color_as or args.colour_as or getColor(args)

	if hex then

		local style = "background-color: #" .. hex .. ";"

		passing.abovestyle = style

		passing.subheaderstyle = style

		passing.headerstyle = style

	end

	

	if args.image then

		passing.image = infoboxImage.InfoboxImage({args = {image = args.image, upright = args.upright or args.image_upright, alt = args.alt or args.image_alt}})

		passing.caption = args.caption or args.image_caption

	end

	if args.image2 then

		passing.image2 = infoboxImage.InfoboxImage({args = {image = args.image2, upright = args.upright2 or args.image2_upright, alt = args.alt2 or args.image2_alt}})

		passing.caption2 = args.caption2 or args.image2_caption

	end

	

	

	local i = 1

	

	-- Embed photos into the infobox via frame:expandTemplate

	-- Trying to call Module:Infobox keeps the previous state

	if args.status or args.status2 then

		local subbox = {

			child = "yes",

		}

		

		if args.status and args.status_system then

			args.status = mw.ustring.upper(args.status)

			if args.status_system == "IUCN2.3" or args.status_system == "IUCN3.1" then

				args.status_system = mw.ustring.lower(args.status_system)

			end

			

			if statusSystemsargs.status_system and statusSystemsargs.status_system][args.status then

				local x = statusSystemsargs.status_system][args.status

				subbox.image1 = infoboxImage.InfoboxImage({args = { image = "Status " .. args.status_system .. " " .. args.status .. ".svg", alt = (x.category or nil)}})

				subbox.caption1 = x.label .. " ([[" .. statusSystemsargs.status_system].link .. "|" .. args.status_system .. "]])" .. (args.status_ref or "")

			end

		end

		

		if args.status2 and args.status2_system then

			args.status2 = mw.ustring.upper(args.status2)

			if args.status2_system == "IUCN2.3" or args.status2_system == "IUCN3.1" then

				args.status2_system = mw.ustring.lower(args.status2_system)

			end

			

			if statusSystemsargs.status2_system and statusSystemsargs.status2_system][args.status2 then

				local x = statusSystemsargs.status2_system][args.status2

				subbox.image2 = infoboxImage.InfoboxImage({args = { image = "Status " .. args.status2_system .. " " .. args.status .. ".svg", alt = (x.category or nil)}})

				subbox.caption2 = x.label .. " ([[" .. statusSystemsargs.status2_system].link .. "|" .. args.status2_system .. "]])" .. (args.status2_ref or "")

			end

		end

		

		passing"header" .. i = "[[Conservation status]]"

		passing"data" .. i + 1 = frame:expandTemplate({title = "infobox", args = subbox})

		

		i = i + 2

	end

	

	if args.virus or args.virus_group then

		passing"header" .. i = "[[Virus classification]]"

	elseif args.ichnos then

		passing"header" .. i = "[[Trace fossil classification]]"

	elseif args.veterovata then

		passing"header" .. i = "[[Egg fossil classification]]"

	else

		passing"header" .. i = "[[Scientific classification]]"

	end

	

	i = i + 1

	

	if args.virus_group then

		local g = {

			i = "Group I ([[dsDNA]])",

			ii = "Group II ([[ssDNA]])",

			iii = "Group III ([[dsRDNA]])",

			iv = "Group IV ([[(+)ssRNA]])",

			v = "Group V ([[(-)ssRNA]])",

			vi = "Group VI ([[ssRNA-RT]])",

			"vi/vii" = "Groups VI and VII",

			vii = "Group VII ([[dsDNA-RT]])",

		}

		

		passing"label" .. i = "Virus group"

		passing"data" .. i = gargs.virus_group or args.virus_group

		i = i + 1

	end

	

	local q = args'wikidata_item' or args'qid'];

	local entity = mw.wikibase.getEntity(q)

	

	if args.superdomain or args.domain or args.superregnum or args.regnum or args.subregnum or args.superdivisio

	or args.superphylum or args.divisio or args.phylum or args.subdivisio or args.subphylum or args.infraphylum

	or args.microphylum or args.nanophylum or args.superclassis or args.classis or args.subclassis or args.infraclassis

	or args.magnordo or args.superordo or args.ordo or args.subordo or args.infraordo or args.parvordo or args.zoodivisio

	or args.zoosectio or args.zoosubsectio or args.superfamilia or args.familia or args.subfamilia or args.supertribus

	or args.tribus or args.subtribus or args.alliance or args.genus or args.subgenus or args.sectio or args.subsectio

	or args.series or args.subseries or args.species_group or args.species_subgroup or args.species_complex

	or args.species or args.subspecies or args.variety or args.varias or args.forma then

	

		for _, t in ipairs(classification) do

			local k = t.arg_name

			local v = t.label

			if args"unranked_" .. k then

				passing"label" .. i = "(unranked)"

				passing"data" .. i = authorityHelp(args, "unranked_" .. k)

				i = i + 1

			end

			if argsk then

				passing"label" .. i = v

				passing"data" .. i = authorityHelp(args, k)

				i = i + 1

			end

		end

	elseif entity then

		local p171 = getFirst(entity"claims"], "P171")

		if p171 and p171"mainsnak" and p171"mainsnak"]["datavalue" and p171"mainsnak"]["datavalue"]["value" and p171"mainsnak"]["datavalue"]["value"]["id" then

			local parent = mw.wikibase.getEntity(p171"mainsnak"]["datavalue"]["value"]["id"])

			if parent then

				local p105 = getFirst(parent"claims"], "P105")

				passing"label" .. i = p105 and p105"mainsnak" and p105"mainsnak"]["datavalue" and p105"mainsnak"]["datavalue"]["value" and p105"mainsnak"]["datavalue"]["value"]["id" or nil

				local p225 = getFirst(parent"claims"], "P225")

				passing"data" .. i = p225 and p225"mainsnak" and p225"mainsnak"]["datavalue" and p225"mainsnak"]["datavalue"]["value" or nil

				i = i + 2

			end

		end

	end

	

	if args.virus_infrasp and not args.virus_infrasp_rank then

		table.insert(warnings, "\"virus_infrasp_rank\" missing")

	elseif args.virus_infrasp then

		passing"label" .. i = args.virus_infrasp_rank

	end

	

	if args.binomial then

		passing"header" .. i = "[[Binomial name]]"

		passing"data" .. i + 1 = authorityHelp(args, "binomial")

		i = i + 2

	elseif entity then

		local binomial = getFirst(entity"claims"], "P225")

		if binomial and binomial"mainsnak" and binomial"mainsnak"]["datavalue" and binomial"mainsnak"]["datavalue"]["value" then

			passing"header" .. i = "[[Binomial name]]"

			passing"data" .. i + 1 = binomial"mainsnak"]["datavalue"]["value" .. p._authorityHelp(binomial"qualifiers"])

		end

	end

	

	if args.trinomial then

		passing"header" .. i = "[[Trinomial name]]"

		passing"data" .. i + 1 = authorityHelp(args, "trinomial")

		i = i + 2

	end

	

	if args.range_map then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map, alt = args.range_map_alt, upright = args.range_map_upright}}), caption = args.range_map_caption}})

		i = i + 1

	end

	

	if args.range_map2 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map2, alt = args.range_map2_alt, upright = args.range_map2_upright}}), caption = args.range_map2_caption}})

		i = i + 1

	end

	

	if args.range_map3 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map3, alt = args.range_map3_alt, upright = args.range_map3_upright}}), caption = args.range_map3_caption}})

		i = i + 1

	end

	

	if args.range_map4 then

		passing"data" .. i = frame:expandTemplate({title = "Infobox", args = { child = "yes", image = infoboxImage.InfoboxImage({args = {image = args.range_map4, alt = args.range_map4_alt, upright = args.range_map4_upright}}), caption = args.range_map4_caption}})

		i = i + 1

	end

	

	if args.type_genus then

		passing"header" .. i = "[[Type ichnogenus]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_genus")

		i = i + 2

	end

	

	if args.type_oogenus then

		passing"header" .. i = "[[Type oogenus]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_oogenus")

		i = i + 2

	end

	

	if args.type_species then

		passing"header" .. i = "[[Type species]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_species")

		i = i + 2

	end

	

	if args.type_oospecies then

		passing"header" .. i = "[[Type oospecies]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_oospecies")

		i = i + 2

	end

	

	if args.type_strain then

		passing"header" .. i = "[[Type strain]]"

		passing"data" .. i + 1 = authorityHelp(args, "type_strain") .. (args.type_strain_ref or "")

		i = i + 2

	end

	

	if args.subdivision then

		mw.log(args.subdivision)

		passing"header" .. i = args.subdivision_ranks or "Species" .. (args.subdivision_ref or "")

		passing"data" .. i + 1 = "<div style=\"text-align: left;\">\n" .. args.subdivision .. "</div>"

		i = i + 2

	end

	

	if args.possible_subdivision then

		passing"header" .. i = args.possible_subdivision_ranks or "Possible species" .. (args.possible_subdividion_ref or "")

		passing"data" .. i + 1 = args.possible_subdivision

		i = i + 2

	end

	

	if args.synonyms then

		passing"header" .. i = "[[Synonym (taxonomy)|Synonyms]]" .. ( args.synonyms_ref or "")

		passing"data" .. i + 1 = "<div style=\"text-align: left;\">\n" .. args.synonyms .. "</div>"

	end

	

	local out = infobox.infobox(passing)

	

	for _, warning in ipairs(warnings) do

		local w = ifPreview._warning({warning})

		if w and w ~= '' then

			out = out .. w

		end

	end

	

	return out

end



return p

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook