Jump to content

Module:Taxobox ranks

Permanently protected module
From Wikipedia, the free encyclopedia

--[[*************************************************************************
This module provides support to the automated taxobox system – the templates
Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc.

In particular it is part of the configuration of the system, defining the
rank names that are recognized and the way they are displayed in English in
taxoboxes and viewed taxonomy templates.
*****************************************************************************]]
require('strict')

local TableRow = '|-\n'
local TableEnd = '|}\n'
local p = {} -- functions made public
local l = {} -- internal functions, kept separate

--*************************** CONFIGURATION *********************************

--[[============================ ranks ======================================
Set up a constant to hold the rank names and their English equivalents.
If adding to this list, note that rank names containing spaces or - must be
enclosed in [' '].
=============================================================================]]
local ranks =
	{
		--Special cases, alphabetic order
		alliance = '<i>Alliance</i>',
		['basic shell type'] = '<i>Basic shell type</i>',
		branch = '<i>Branch</i>',
		clade = '<i>Clade</i>',
		cladus= '<i>Clade</i>',
		['form taxon'] = '<i>Form taxon</i>',
		grade = '<i>Grade</i>',
		gradus = '<i>Grade</i>',
		informal = '<i>Informal group</i>',
		['informal group'] = '<i>Informal group</i>',
		morphotype = '<i>Morphotype</i>',
		node = '<i>Node</i>',
		plesion = '<i>Plesion</i>',
		['plesion-group'] = '<i>Plesion-group</i>',
		['possible clade'] = '<i>Clade?</i>',
		['species complex'] = '<i>Species complex</i>',
		['species group'] = '<i>Species group</i>',
		['species subgroup'] = '<i>Species subgroup</i>',
		['stem group'] = '<i>Stem group</i>',
		['total group'] = '<i>Total group</i>',
		--Special virus ranks
		realm = 'Realm',
		serotype = 'Serotype',
		strain = 'Strain',
		virus = 'Virus',
		['virus group'] = 'Group',
		--Linnaean taxonomy, alphabetic order
		classis = 'Class',
		cohort = 'Cohort',
		divisio = 'Division',
		domain = 'Domain',
		epifamilia = 'Epifamily',
		familia = 'Family',
		forma = 'Form',
		genus = 'Genus',
		grandordo = 'Grandorder',
		['grandordo-mb'] = 'Grandorder', --McKenna & Bell version
		hyperfamilia = 'Hyperfamily',
		infraclassis = 'Infraclass',
		infralegio = 'Infralegion',
		infralegion = 'Infralegion',
		infraordo = 'Infraorder',
		infraphylum = 'Infraphylum',
		infraregnum = 'Infrakingdom',
		infratribus = 'Infratribe',
		legio = 'Legion',
		legion = 'Legion',
		magnordo = 'Magnorder',
		micrordo = 'Microrder',
		microphylum = 'Microphylum',
		mirordo = 'Mirorder',
		['mirordo-mb'] = 'Mirorder', --McKenna & Bell version
		nanordo = 'Nanorder',
		nanophylum = 'Nanophylum',
		ordo = 'Order',
		parafamilia = 'Parafamily',
		parvclassis = 'Parvclass',
		parvordo = 'Parvorder',
		phylum = 'Phylum',
		regnum = 'Kingdom',
		sectio = 'Section',
		series = 'Series',
		species = 'Species',
		subclassis = 'Subclass',
		subcohort = 'Subcohort',
		subdivisio = 'Subdivision',
		subfamilia = 'Subfamily',
		subgenus = 'Subgenus',
		sublegio = 'Sublegion',
		sublegion = 'Sublegion',
		subordo = 'Suborder',
		subphylum = 'Subphylum',
		subregnum = 'Subkingdom',
		subsectio = 'Subsection',
		subseries = 'Subseries',
		subspecies = 'Subspecies',
		subterclassis = 'Subterclass', --used in WoRMS
		subtribus = 'Subtribe',
		superclassis = 'Superclass',
		supercohort = 'Supercohort',
		superdivisio = 'Superdivision',
		superdomain = 'Superdomain',
		superfamilia = 'Superfamily',
		superlegio = 'Superlegion',
		superlegion = 'Superlegion',
		superordo = 'Superorder',
		superphylum = 'Superphylum',
		superregnum = 'Superkingdom',
		supersectio = 'Supersection',
		supertribus = 'Supertribe',
		tribus = 'Tribe',
		varietas = 'Variety',
		zoodivisio = 'Division',
		zoosectio = 'Section',
		zooseries = 'Series',
		zoosubdivisio = 'Subdivision',
		zoosubsectio = 'Subsection',
		--trace fossil taxonomy, alphabetic order-->',
		ichnoclassis = 'Ichnoclass',
		ichnocohort = 'Ichnocohort',
		ichnodivisio = 'Ichnodivision',
		ichnofamilia = 'Ichnofamily',
		ichnogenus = 'Ichnogenus',
		ichnograndordo = 'Ichnograndorder',
		['ichnograndordo-mb'] = 'Ichnograndorder', --McKenna & Bell version
		ichnoinfraclassis = 'Ichnoinfraclass',
		ichnoinfradivisio = 'Ichnoinfradivision',
		ichnoinfraordo = 'Ichnoinfraorder',
		ichnolegio = 'Ichnolegion',
		ichnolegion = 'Ichnolegion',
		ichnomagnordo = 'Ichnomagnorder',
		ichnomicrordo = 'Ichnomicrorder',
		ichnoordo = 'Ichnoorder',
		ichnoparvordo = 'Ichnoparvorder',
		ichnospecies = 'Ichnospecies',
		['ichnostem-group'] = 'Ichnostem-Group',
		ichnosubclassis = 'Ichnosubclass',
		ichnosubdivisio = 'Ichnosubdivision',
		ichnosubfamilia = 'Ichnosubfamily',
		ichnosublegio = 'Ichnosublegion',
		ichnosublegion = 'Ichnosublegion',
		ichnosubordo = 'Ichnosuborder',
		ichnosuperclassis = 'Ichnosuperclass',
		ichnosupercohort = 'Ichnosupercohort',
		ichnosuperfamilia = 'Ichnosuperfamily',
		ichnosuperordo = 'Ichnosuperorder',
		--fossilized egg taxonomy, alphabetic order
		ooclassis = 'Ooclass',
		oocohort = 'Oocohort',
		oofamilia = 'Oofamily',
		oogenus = 'Oogenus',
		oomagnordo = 'Oomagnorder',
		oordo = 'Oorder',
		oospecies = 'Oospecies',
		oosubclassis = 'Oosubclass',
		oosubgenus = 'Oosubgenus',
		oosubspecies = 'Oosubspecies',
		oosupercohort = 'Oosupercohort',
		oosuperordo = 'Oosuperorder',
	}
	
--[[========================== rank values===================================
Constant to set up a table of numerical values corresponding
to 'Linnaean' ranks, with upper ranks having higher values. In a valid
taxonomic hierarchy, a lower rank should never have a higher value than a
higher rank. The actual numerical values are arbitrary so long as they are
ordered.
The ranks should be a subset of those in Template:Anglicise ranks.
=============================================================================]]
local rankValTable =
	{
		classis = 1400,
		cohort = 1100,
		divisio = 1500,
		domain = 1700,
		epifamilia =  802,
		familia = 800,
		forma = 100,
		genus = 600,
		grandordo = 1005,
		['grandordo-mb'] = 1002,
		hyperfamilia = 805;
		infraclassis = 1397,
		infralegio = 1197,
		infralegion = 1197,
		infraordo = 997,
		infraphylum = 1497,
		infraregnum = 1597,
		infratribus = 697,
		legio = 1200,
		legion = 1200,
		magnordo = 1006,
		microphylum = 1495,
		micrordo = 995,
		mirordo = 1004,
		['mirordo-mb'] = 1001,
		nanophylum = 1494,
		nanordo = 994,
		ordo = 1000,
		parafamilia = 800,
		parvclassis = 1396; -- same as subterclassis
		parvordo = 996,
		phylum = 1500,
		regnum = 1600,
		sectio = 500,
		--series = 400, used too inconsistently to check
		species = 300,
		subclassis = 1398,
		subcohort = 1098,
		subdivisio = 1498,
		subfamilia = 798,
		subgenus = 598,
		sublegio = 1198,
		sublegion = 1198,
		subordo = 998,
		subphylum = 1498,
		subregnum = 1598,
		subsectio = 498,
		subspecies = 298,
		subterclassis = 1396; -- same as parvclassis
		subtribus = 698,
		superclassis = 1403,
		supercohort = 1103,
		superdivisio = 1503,
		superdomain = 1703,
		superfamilia = 803,
		superlegio = 1203,
		superlegion = 1203,
		superordo = 1003,
		superphylum = 1503,
		superregnum = 1603,
		supersectio = 503,
		supertribus = 703,
		tribus = 700,
		varietas = 200,
		zoodivisio = 1300,
		zoosectio = 900,
		zoosubdivisio = 1298,
		zoosubsectio = 898,
	}

--***************** Process ranks + English equivalents *********************

--[[======================== angliciseRank ==================================
Returns the English language equivalent of a rank name used in a taxonomy
template.
If the rank name is not in the table of ranks, then the first letter
of the rank name is capitalized and used as the English name.
If checked=yes, then the generated English name is highlighted in red. If
called from a taxonomy template, the page is put in
Category:Taxonomy templates using capitalized rank parameters
=============================================================================]]
function p.doAngliciseRank(rankName, check)
	rankName = string.gsub(rankName, '_', ' ') -- replace all underscores by spaces
	-- is rankName capitalized?
	local testName = string.lower(string.sub(rankName,1,1)) .. string.sub(rankName,2)
	local wasCapitalized = testName ~= rankName
	if wasCapitalized then rankName = testName end -- try uncapitalized version
	if string.sub(rankName, 1,8) == 'unranked' then return '(unranked)' end
	-- now look for an English version of the rank name
	local res = ranks[rankName]
	local notFound = not res
	if notFound then
		--rankName is not in the table of recognized ranks; just capitalize rankName
		res = string.upper(string.sub(rankName,1,1)) .. string.sub(rankName,2)
	end
	if check == 'no' then
		return res
	elseif notFound then
		res = '<span style="background-color:#F99">' .. res .. '</span>' -- highlight returned English name
	end
	-- tracking caegories required only if called from a taxonomy template
	local pageTitle =  mw.title.getCurrentTitle()
	if pageTitle.nsText == 'Template' and pageTitle.rootText == 'Taxonomy' then
		if notFound then res = res .. '[[Category:Taxonomy templates using unrecognized rank parameters]]'
		elseif wasCapitalized then res = res .. '[[Category:Taxonomy templates using capitalized rank parameters]]'
		end
	end
	return res
end

function p.angliciseRank(frame)
	local rankName = frame.args[1]
	local check = frame.args['check'] or 'no'
	return p.doAngliciseRank(rankName, check)
end

--[[========================== showRanks ====================================
Returns a wikitable showing all the recognized ranks, how they are shown in
taxoboxes, whether they are automatically italicized, and whether they are
checked for consistency of rank order.
Usage: {{#invoke:Taxobox ranks|showRanks}}
=============================================================================]]
function p.showRanks(frame)
	local res = '{| class="wikitable sortable"\n'
	res = res ..'|+ Ranks recognized in taxonomy templates\n'
	res = res .. '!style="text-align: left;"|Rank name in<br/>taxonomy<br/>template'
	res = res .. '!!style="text-align: left;"|Shown in<br/>taxobox as'
	res = res .. '!! style="text-align: left;" |Taxon name<br/>automatically<br/>italicized?'
	res = res .. '!! style="text-align: left;" |Rank checked<br/>for consistent<br/>order?'
	res = res .. '\n'
	for k, t in pairs(ranks) do
		res = res .. TableRow .. '|' .. k .. '||' .. t .. '||' .. frame:expandTemplate{ title = 'Is italic taxon', args = { k } } .. '||' .. l.hasRankVal(k) .. '\n'
	end
	return res .. TableEnd
end

--************************* Process rank values *****************************

--[[========================= lookupRankVal =================================
Function to look up the arbitrary numerical value of a rank in a rank value
table. "Ichno" and "oo" ranks are not stored separately, so if present the
prefix is removed.
=============================================================================]]
function p.lookupRankVal(rank)
	local rankVal = rankValTable[rank]
	if not rankVal then
		-- may be an "ichno" or "oo" rank; try removing "ichno-" or "oo-"
		local baseRank = mw.ustring.gsub(mw.ustring.gsub(rank, '^ichno', ''), '^oo', '')
		if baseRank == 'rdo' then baseRank = 'ordo' end
		-- if an "ichno" or "oo" rank, lower rank value slightly so it is ok below the base rank
		rankVal = rankValTable[baseRank]
		if rankVal then
			rankVal = rankVal - 0.1
		end
	end
	return rankVal
end

--[[=========================== hasRankVal =================================
Utility function to determine whether the rank has a value in rank value
table. Returns 'yes' or 'no'.
=============================================================================]]
function l.hasRankVal(rank)
	if rank == '' then return 'no' end
	local rankVal = p.lookupRankVal(rank)
	if not rankVal then rankVal = 'no' else rankVal = 'yes' end
	return rankVal
end

--[[========================== showRankTable ================================
Returns a wikitable showing the ranks and their values as set up in the
constant rankValTable.
Usage: {{#invoke:Taxobox ranks|showRankTable}}
=============================================================================]]
function p.showRankTable(frame)
	local res = '{| class="wikitable sortable"\n|+ Ranks checked in taxonomy templates\n! Rank !! Shown as !! Value\n'
	for k, v in pairs(rankValTable) do
		local rankShown = frame:expandTemplate{ title = 'Anglicise rank', args = { k } }
		res = res .. TableRow .. '|' .. k .. '||' .. rankShown .. '||' .. v .. '\n'
	end
	return res .. TableEnd
end

return p