Mô đun:Autotaxobox-collapsible

--
This module provides support to the automated taxobox system – the templates
Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc.
In particular it provides a way of traversing the taxonomic hierarchy encoded
in taxonomy templates (templates with names of the form
"Template:Taxonomy/TAXON_NAME") without causing template expansion depth errors.
local TaxonItalics = require('Module:TaxonItalics') -- use a function from Module:TaxonItalics to italicize a taxon name
local p = {}
local l = {} -- keep internal functions separate
local colour =  -- colour for taxobox and taxonomy listings
--=====================================================================**
Limit the maximum depth of a taxonomic hierarchy that can be traversed;
avoids excessive processing time and protects against incorrectly set up
hierarchies, e.g. loops.

**=====================================================================**
local MaxSearchLevels = 100
function p.getMaxSearchLevels()
	return MaxSearchLevels
end
--========================== taxoboxColour ============================**
Determines the correct colour for a taxobox, by searching up the taxonomic
hierarchy from the supplied taxon for the first taxon (other than
'incertae sedis') that sets a taxobox colour. It is assumed that a valid
taxobox colour is defined using CSS rgb() syntax.
If no taxon that sets a taxobox colour is found, then 'transparent' is
returned unless the taxonomic hierarchy is too deep, when the error colour is
returned.
Usage: TAXON

**=====================================================================**
function p.taxoboxColour(frame)
	-- note that colour is global to this function; default is empty string
	local currTaxon = frame.args1 or 
	local i = 1 -- count levels processed
	local searching = currTaxon ~=  -- still searching for a colour?
	local foundICTaxon = false -- record whether 'incertae sedis' found
	while searching and i = i), virus = virus } }
	end
	-- display greatgreatgrandparent, if it exists
	if taxonTable.n >= 5 then
		res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon-collapsible', args = { taxonTable5, authority = gggParentAuth, fc = tostring(displayN >= 5), virus = virus } }
	end
	-- display greatgrandparent, if it exists; force the display if an infrataxon is below
	if taxonTable.n >= 4 then
		local force = tostring(displayN >= 4) or
		              frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable3 } } == 'true' or
		              frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable2 } } == 'true'
		res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon-collapsible', args = { taxonTable4, authority = ggParentAuth, fc = tostring(force), virus = virus } }
	end
	-- display grandparent, if it exists; force the display if an infrataxon is below
	if taxonTable.n >= 3 then
		local force = tostring(displayN >= 3) or
frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable2 } } == 'true'
res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon-collapsible', args = { taxonTable3, authority = gParentAuth, fc = tostring(force), virus = virus } }
	end
	-- display parent, if it exists
	if taxonTable.n >= 2 then
		res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon-collapsible', args = { taxonTable2, authority = parentAuth, fc = tostring(displayN >= 2), virus = virus } }
	end
	-- display target taxon
	res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon-collapsible', args = { taxonTable1, authority = auth, fc = 'true', format = boldFirst, virus = virus  } }
	return res
end
--========================== taxonomyList =============================**
Returns the cells of the taxonomy table displayed on the right hand side of
"Template:Taxonomy...." pages.
Usage: TAXON

**=====================================================================**
function p.taxonomyList(frame)
	local currTaxon = frame.args1 or 
	if currTaxon ==  then return '| 
ERROR: no taxon supplied\n
	local taxonTable = l.makeTable(frame, currTaxon)
	local rankTable = l.getRankTable()
	local lastRankVal = 1000000
	local orderOk = true
	local res = 
	-- check whether the taxonomy is for viruses; use already determined taxon colour if possible
	local virus = 'no'
	local taxoColour = colour
	if taxoColour ==  then
		taxoColour = frame:expandTemplate{ title = 'Template:Taxobox colour', args = { taxonTabletaxonTable.n - 1 } }
	end
	if taxoColour == frame:expandTemplate{ title = 'Template:Taxobox colour', args = { 'virus' } } then
		virus = 'yes'
	end
	-- deal first with the top level taxon; if there are no errors, it should be Life/Veterovata/Ichnos, which are 
	-- not displayed
	local taxon = taxonTabletaxonTable.n
	if taxon ~= 'Life' and taxon ~= 'Veterovata' and taxon ~= 'Ichnos' then
		local msg = 'Taxonomy template missing'
		if mw.title.new('Taxonomy/'..taxon, 'Template').exists then
			msg = 'Parent taxon needed'
		end
		res = res .. '\n|colspan=2|' .. frame:expandTemplate{title = 'Template:Create taxonomy', args = {taxon, msg = msg}} .. '\n
	end
	-- now output the rest of the table
	for i = taxonTable.n-1, 1, -1 do
		-- check ranks are in right order in the hierarchy
		taxon = taxonTablei
		local ok, rank = l.getTaxonInfoItem(frame, taxon, 'rank')
		local currRankVal = rankTablestring.lower(rank)
		if currRankVal then
			orderOk = currRankVal no taxon supplied' end
	local rank = frame.args2 or 
	if rank ==  then return 'no rank supplied' end
	local inHierarchy = true -- still in the taxonomic hierarchy or off the top?
	local searching = true -- still searching
	while inHierarchy and searching do
		local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent')
			if ok and parent ~=  then
			currTaxon = parent
			local ok, currRank = l.getTaxonInfoItem(frame, currTaxon, 'rank')
			if currRank == rank then
				searching = false
			end
		else
			inHierarchy = false
		end
	end
	if inHierarchy and not searching then return currTaxon
	else return 'rank not found'
	end
end
--=============================== nth =================================**
External utility function primarily intended for use in checking and debugging.
Returns the nth level above a taxon in a taxonomic hierarchy, where the taxon
itself is counted as the first level.
Usage: n=N

**=====================================================================**
function p.nth(frame)
	local currTaxon = frame.args1 or 
	if currTaxon ==  then return 'ERROR: no taxon supplied' end
	local n = tonumber(frame.args'n' or 1)
	if n > MaxSearchLevels then
		return 'Exceeded maximum number of levels allowed (' .. MaxSearchLevels .. ')'
	end
	local i = 1
	local inHierarchy = true -- still in the taxonomic hierarchy or off the top?
	while i  (?)'
		end
	else
		info = 'Template:Taxonomy/' .. taxon ..  --error indicator in code before conversion to Lua
	end
	return ok, info
end
function l.getTaxonInfoLink(frame, taxon)
	local ok, linkText, linkTarget
	local link = 
	ok, linkText = l.getTaxonInfoItem(frame, taxon, 'link_text')
	if ok then
		ok, linkTarget = l.getTaxonInfoItem(frame, taxon, 'link_target')
		if ok then
			if linkText == linkTarget then link = linkText
			else link = linkTarget .. '|' .. linkText
			end
		end
	end
	return ok, link
end
--= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Internal utility function to return a table (array) constructed from a
taxonomic hierarchy stored in "Template:Taxonomy/..." templates.
TABLE.n holds the total number of taxa; TABLE1..TABLETABLE.n the taxon
names.
The last taxon in the table will either (a) have a taxonomy template but with
no parent given (e.g. 'Life') or (b) not have a taxonomy template.
**= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
function l.makeTable(frame, currTaxon)
	local i = 1
	local inHierarchy = true -- still in the taxonomic hierarchy or off the top?
	local taxonTable = {}
	taxonTable1 = currTaxon;
	while i < MaxSearchLevels and inHierarchy do
		local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent')
		if ok and parent ~=  then
			currTaxon = parent
			i = i + 1
			taxonTablei = currTaxon
		else
			inHierarchy = false -- run off the top of the hierarchy or tried to use non-existent taxonomy template
		end
	end
	taxonTable.n = i
	return taxonTable
end
--= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Internal utility function 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 correspond to those in Template:Anglicise ranks.
**= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
function l.getRankTable()
	return {
		classis = 1400,
		cohort = 1100,
		divisio = 1500,
		domain = 1700,
		familia = 800,
		forma = 100,
		genus = 600,
		grandordo = 1005,
		'grandordo-mb' = 1002,
		infraclassis = 1397,
		infralegio = 1197,
		infraordo = 997,
		infraphylum = 1497,
		infraregnum = 1597,
		infratribus = 697,
		legio = 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,
		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,
		superordo = 1003,
		superphylum = 1503,
		superregnum = 1603,
		supertribus = 703,
		tribus = 700,
		varietas = 200,
		zoodivisio = 1300,
		zoosectio = 900,
		zoosubdivisio = 1298,
		zoosubsectio = 898,
	}
end
return p