Module:Autotaxobox
--[[ 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. ]]
require('Module:No globals') 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: transparent =============================================================================]] function p.taxoboxColour(frame) -- note that colour is global to this function; default is empty string local currTaxon = frame.args[1] 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 <= MaxSearchLevels do local plainCurrTaxon = l.stripExtra(currTaxon) -- remove trailing text after / if string.lower(plainCurrTaxon) == 'incertae sedis' then foundICTaxon = true else local possibleColour = frame:expandTemplate{ title = 'Template:Taxobox colour', args = { plainCurrTaxon } } if string.sub(possibleColour,1,3) == 'rgb' then colour = possibleColour searching = false end end if searching then local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') if ok and parent ~= then currTaxon = parent i = i + 1 else searching = false -- run off the top of the hierarchy or tried to use non-existent taxonomy template end end end if colour == then if foundICTaxon then colour = frame:expandTemplate{ title = 'Template:Taxobox colour', args = { 'incertae sedis' } } elseif searching then -- hierarchy exceeds MaxSearchLevels levels colour = frame:expandTemplate{ title = 'Template:Taxobox/Error colour', args = { } } else colour = 'transparent' end end return colour end
--[[========================== topLevelTaxon ================================ Defines the correct top level taxa, one of which should terminate every taxonomic hierarchy encoded in taxonomy templates. =============================================================================]] function l.topLevelTaxon(taxon) return taxon == 'Life' or taxon == 'Veterovata' or taxon == 'Ichnos' end
--[[=========================== taxoboxList ================================= Returns the rows of taxa in an automated taxobox, based on the taxonomic hierarchy for the supplied taxon. Usage: Lua error at line 165: attempt to index a nil value. =============================================================================]] function p.taxoboxList(frame) local currTaxon = frame.args[1] or if currTaxon == then return end local displayN = (tonumber(frame.args['display_taxa']) or 1) + 1 local auth = frame.args['authority'] or local parentAuth = frame.args['parent_authority'] or local gParentAuth = frame.args['gparent_authority'] or local ggParentAuth = frame.args['ggparent_authority'] or local gggParentAuth = frame.args['gggparent_authority'] or local boldFirst = frame.args['bold_first'] or 'link' -- values 'link' or 'bold' local virus = frame.args['virus'] or 'no' -- values 'yes' or 'no' local offset = tonumber(frame.args['offset'] or 0) local taxonTable, taxonRankTable = l.makeTable(frame, currTaxon) local authTable = {} authTable[1] = auth authTable[2] = parentAuth authTable[3] = gParentAuth authTable[4] = ggParentAuth authTable[5] = gggParentAuth if offset ~= 0 then for i = 1, 5 do local j = i + offset if j <= 5 then authTable[i] = authTable[j] else authTable[i] = end end end local res = local topTaxonN = taxonTable.n -- display all taxa above possible greatgreatgrandparent for i = topTaxonN, 6, -1 do res = res .. l.showTaxon(frame, taxonTable[i], taxonRankTable[i], topTaxonN==i, , displayN >= i, , virus) end -- display greatgreatgrandparent, if it exists if taxonTable.n >= 5 then res = res .. l.showTaxon(frame, taxonTable[5], taxonRankTable[5], topTaxonN==5, authTable[5], displayN >= 5, , virus) end -- display greatgrandparent, if it exists if taxonTable.n >= 4 then res = res .. l.showTaxon(frame, taxonTable[4], taxonRankTable[4], topTaxonN==4, authTable[4], displayN >= 4, , virus) end -- display grandparent, if it exists if taxonTable.n >= 3 then res = res .. l.showTaxon(frame, taxonTable[3], taxonRankTable[3], topTaxonN==3, authTable[3], displayN >= 3, , virus) end -- display parent, if it exists if taxonTable.n >= 2 then res = res .. l.showTaxon(frame, taxonTable[2], taxonRankTable[2], topTaxonN==2, authTable[2], displayN >= 2, , virus) end -- display target taxon res = res .. l.showTaxon(frame, taxonTable[1], taxonRankTable[1], topTaxonN==1, authTable[1], true, boldFirst, virus) return res end
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Show one taxon row in a taxobox. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
function l.showTaxon(frame, taxon, rank, isTopTaxon, auth, force, boldFirst, virus)
-- it's an error if this is the top taxon and it's not a top level taxon (e.g. "Life")
if isTopTaxon then
if l.topLevelTaxon(taxon) then
return -- don't display a top level taxon
elseif mw.title.new('Taxonomy/'..taxon, 'Template').exists then
-- taxonomy template for this taxon has no parent specified
return frame:expandTemplate{ title = 'Template:Create taxonomy', args = {taxon, msg='Taxonomy template does not specify a parent'} } .. '\n|-\n'
else
-- no taxonomy template for this taxon
return frame:expandTemplate{ title = 'Template:Create taxonomy', args = {taxon, msg='Missing taxonomy template'} } .. '\n|-\n'
end
else
-- if showing is not already forced, force if it's a principal rank or an authority is specified
force = force or frame:expandTemplate{ title = 'Template:Principal rank', args = {rank} } == 'yes' or
auth ~=
if not force then
-- if showing is still not already forced, force if the taxonomy template has 'always_display' set
local ok, alwaysDisplay = l.getTaxonInfoItem(frame, taxon, 'always_display')
force = alwaysDisplay == 'yes' or alwaysDisplay == 'true'
end
if force then
local res = '|' .. frame:expandTemplate{ title = 'Template:Anglicise rank', args = {rank} } .. ':'
local bold = 'no'
if boldFirst == 'bold' then bold = 'yes' end
local res = res .. '||' .. l.getTaxonLink(frame, taxon, rank, bold, , virus)
if auth ~= then
res = res .. '
' .. auth .. ''
end
return res .. '\n|-\n'
else
return
end
end
end
--[[========================== taxonomyList ================================= Returns the cells of the taxonomy table displayed on the right hand side of "Template:Taxonomy...." pages. Usage: |colspan=2| |- |Unrecognized taxon (fix): |TAXON |-
|-
=============================================================================]] function p.taxonomyList(frame) local currTaxon = frame.args[1] or if currTaxon == then return '| ||ERROR: no taxon supplied\n|-' end local taxonTable, taxonRankTable = 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 = { taxonTable[taxonTable.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 = taxonTable[taxonTable.n] if not l.topLevelTaxon(taxon) 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|-\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 = taxonTable[i] local rank = taxonRankTable[i] local currRankVal = rankTable[string.lower(rank)] if currRankVal then orderOk = currRankVal < lastRankVal if orderOk then lastRankVal = currRankVal end else orderOk = true end -- now return a row of the taxonomy table with anomalous ranks marked local errorStr = if not orderOk then errorStr = 'yes' end local link = l.getTaxonLink(frame, taxon, rank, 'no', , virus) res = res .. '\n' .. l.createTaxonTableRow(frame, taxon, rank, link, errorStr) end -- if the last row has an anomalous rank, put the page in the error-tracking category; category statements don't work -- inside tables, so need to close the current table first and then open a dummy one (close is in Template:Taxonomy key) if not orderOk then res = res .. '\n|}\n\n{|\n' end return res end
--[[======================== createTaxonTableRow =============================== Returns a single row of the taxonomy table displayed on the right hand side
of "Template:Taxonomy...." pages.
=============================================================================]] function l.createTaxonTableRow(frame, taxon, rank, link, error) local res = if taxon == or rank == then return res end -- if appropriate, make it clear that some taxa have been skipped if mw.ustring.sub(taxon, -5) == '/skip' then res = res .. '| ..... || .....\n|-\n' end -- now generate a line of the table, ending with '|-' res = res .. '|' if error == 'yes' then res = res .. '' end local anglicizedRank = frame:expandTemplate{ title = 'Template:Anglicise rank', args = { rank } } res = res .. anglicizedRank if error == 'yes' then res = res .. '' end res = res .. ':||' .. link .. '' .. frame:expandTemplate{ title = 'Template:Edit a taxon', args = { taxon } } .. '\n|-' return res end
--[[========================= callTaxonomyKey =============================== Prepares for, and then calls, Template:Taxonomy key to display a taxonomy template page. It does this by building up the information the template requires, following one 'same as' link, if required. Usage:
Ancestral taxa | |
---|---|
You're currently creating: | [[ ]] |
Template:Error If the table below looks correct, then the necessary taxonomic information for the target taxon exists.
Template:Taxonomy key/missing template Not sure why you're here? Tell Keenan about it.
=============================================================================]] local PARENT = 1 local RANK = 2 local LINK_TARGET = 3 local LINK_TEXT = 4 local ALWAYS_DISPLAY = 5 local EXTINCT = 6 local SAME_AS = 7 local REFS = 8 function p.callTaxonomyKey(frame) local taxon = frame.args['taxon'] or local parent = frame.args['parent'] or local rank = frame.args['rank'] or local extinct = string.lower(frame.args['extinct']) or local alwaysDisplay = string.lower(frame.args['always_display']) or local linkTarget = frame.args['link_target'] or local linkText = frame.args['link_text'] or -- this is the "raw" link text, and can be local refs = frame.args['refs'] or local sameAsTaxon = frame.args['same_as'] or if sameAsTaxon ~= then -- try using the 'same as' taxon; it's an error if it doesn't exist local ok, sameAsInfoStr = pcall(frame.expandTemplate, frame, { title = 'Template:Taxonomy/' .. sameAsTaxon, args = {['machine code'] = 'all' } }) if ok then local sameAsInfo = mw.text.split(sameAsInfoStr, '$', true) --'same as' taxon's taxonomy template must not have a 'same as' link if sameAsInfo[SAME_AS] == then if parent == then parent = sameAsInfo[PARENT] end if rank == then rank = sameAsInfo[RANK] end if extinct == then extinct = string.lower(sameAsInfo[EXTINCT]) end if alwaysDisplay == then alwaysDisplay = string.lower(sameAsInfo[ALWAYS_DISPLAY]) end if linkTarget == then linkTarget = sameAsInfo[LINK_TARGET] end if linkText == then linkText = sameAsInfo[LINK_TEXT] end if refs == and parent == sameAsInfo[PARENT] then refs = sameAsInfo[REFS] end else return 'Error: attempt to follow two "same as" links:same_as = ' .. sameAsTaxon .. '
, but Template:Taxonomy/' .. sameAsTaxon .. ' also has asame_as
parameter.'
end
else
return frame:expandTemplate{ title = 'Template:Taxonomy key/missing template', args = {taxon=sameAsTaxon, msg='given as the value of same as
'} }
end
end
local link = linkTarget
if linkText ~= and linkText ~= linkTarget then link = link .. "|" .. linkText end
return frame:expandTemplate{ title = 'Template:Taxonomy key',
args = {taxon=taxon, parent=parent, rank=rank, extinct=extinct, always_display=alwaysDisplay, link_target=linkTarget, link=link, refs=refs, same_as=sameAsTaxon} }
end
--[[============================ taxonInfo ==================================
Extracts and returns information from Template:Taxonomy/TAXON, following
one 'same as' link if required.
Usage: Template:Taxonomy/TAXON
ITEM is one of: 'parent', 'rank', 'link target', 'link text', 'extinct',
'always display', 'refs', 'same as' or 'all'.
If ITEM is not specified, the default is 'all' – all values in a single string
separated by '$'.
=============================================================================]]
function p.taxonInfo(frame)
local taxon = frame.args[1] or
local item = frame.args[2] or
if item == then item = 'all' end
local ok, info = l.getTaxonInfoItem(frame, taxon, item)
return info
end
--[[============================ taxonLink ==================================
Returns a wikilink to a taxon, if required including '†' before it and
' (?)' after it, and optionally italicized or bolded without a wikilink.
Usage:
: text of the wikilink (may be same as link_target), without †, italics, etc.
=============================================================================]]
function p.taxonLink(frame)
local taxon = frame.args['taxon'] or
local extinct = string.lower(frame.args['extinct'] or )
local bold = frame.args['bold'] or
local italic = frame.args['italic'] or
local linkTarget = frame.args['link_target'] or
local linkText = frame.args['link_text'] or frame.args['plain_link_text'] or --temporarily allow alternative args
return l.makeLink(taxon, extinct, bold, italic, linkTarget, linkText)
end
-- internal function to drive l.makeLink()
function l.getTaxonLink(frame, taxon, rank, bold, italic, virus)
local ok, extinct = l.getTaxonInfoItem(frame, taxon, 'extinct')
if italic == then
italic = frame:expandTemplate{ title = 'Template:Is italic taxon', args = { rank, virus = virus } }
end
local ok, linkTarget = l.getTaxonInfoItem(frame, taxon, 'link_target')
local ok, linkText = l.getTaxonInfoItem(frame, taxon, 'link_text')
return l.makeLink(taxon, extinct, bold, italic, linkTarget, linkText)
end
-- actually make the link
function l.makeLink(taxon, extinct, bold, italic, linkTarget, linkText)
-- if link text is missing, try to find a replacement
if linkText == then
if string.find(taxon, 'Incertae sedis', 1, true) then
linkText = "incertae sedis"
linkTarget = 'Incertae sedis'
else
linkText = l.stripExtra(taxon)
end
end
if linkTarget == then linkTarget = linkText end
if italic == 'yes' then linkText = TaxonItalics.italicizeTaxonName(linkText, false) end
local link =
if bold == 'yes' then link = '' .. linkText .. ''
else
if linkTarget == linkText then link = linkText
else link = linkTarget .. '|' .. linkText
end
link = '' .. link .. ''
end
if (extinct == 'yes' or extinct == 'true') and not string.find(link, '†', 1, true) then
link = '†' .. link
end
if string.sub(taxon, -2) == '/?' and not string.find(link, '?', 1, true) then
link = link .. ' (?)'
end
return link
end
--[[========================== showRankTable ================================
Returns a wikitable showing the ranks and their values as set up by
getRankTable().
Usage:
Parent: | [Taxonomy; edit]
|
Rank: | (displays as )
|
Link: | value of 'link' parameter in taxonomy template|value of parameter 2 in taxonomy template (links to value of 'link' parameter in taxonomy template )
|
Extinct: | no |
Always displayed: | no |
Taxonomic references: | – |
Parent's taxonomic references: | Template:Taxonomy/ |
Rank | Shown as | Value |
---|---|---|
infratribus | Infratribe | 697 |
infraphylum | Infraphylum | 1497 |
infraordo | Infraorder | 997 |
cohort | Cohort | 1100 |
micrordo | Microrder | 995 |
genus | Genus | 600 |
grandordo | Grandorder | 1005 |
microphylum | Microphylum | 1495 |
sublegio | Sublegion | 1198 |
zoosubsectio | Subsection | 898 |
parvclassis | Parvclass | 1396 |
supercohort | Supercohort | 1103 |
nanordo | Nanorder | 994 |
parafamilia | Parafamily | 800 |
zoosubdivisio | Subdivision | 1298 |
regnum | Kingdom | 1600 |
magnordo | Magnorder | 1006 |
mirordo | Mirorder | 1004 |
varietas | Variety | 200 |
tribus | Tribe | 700 |
superfamilia | Superfamily | 803 |
superphylum | Superphylum | 1503 |
subregnum | Subkingdom | 1598 |
infraregnum | Infrakingdom | 1597 |
grandordo-mb | Grandorder | 1002 |
supertribus | Supertribe | 703 |
zoodivisio | Division | 1300 |
superlegio | Superlegion | 1203 |
zoosectio | Section | 900 |
superdivisio | Superdivision | 1503 |
superclassis | Superclass | 1403 |
subtribus | Subtribe | 698 |
divisio | Division | 1500 |
subterclassis | Subterclass | 1396 |
classis | Class | 1400 |
subspecies | Subspecies | 298 |
infraclassis | Infraclass | 1397 |
subcohort | Subcohort | 1098 |
subfamilia | Subfamily | 798 |
subsectio | Subsection | 498 |
superregnum | Superkingdom | 1603 |
species | Species | 300 |
subphylum | Subphylum | 1498 |
subordo | Suborder | 998 |
subgenus | Subgenus | 598 |
ordo | Order | 1000 |
subdivisio | Subdivision | 1498 |
subclassis | Subclass | 1398 |
legio | Legion | 1200 |
sectio | Section | 500 |
domain | Domain | 1700 |
superdomain | Superdomain | 1703 |
superordo | Superorder | 1003 |
parvordo | Parvorder | 996 |
familia | Family | 800 |
nanophylum | Nanophylum | 1494 |
infralegio | Infralegion | 1197 |
forma | Form | 100 |
mirordo-mb | Mirorder | 1001 |
phylum | Phylum | 1500 |
=============================================================================]] function p.showRankTable(frame) local rankTable = l.getRankTable() local res = '{| class="wikitable sortable"\n|+ Ranks checked in taxonomy templates\n! Rank !! Shown as !! Value\n' for k, v in pairs(rankTable) do local rankShown = frame:expandTemplate{ title = 'Template:Anglicise rank', args = { k } } res = res .. '|-\n|' .. k .. '||' .. rankShown .. '||' .. v .. '\n' end return res .. '|}\n' end
--[[============================== find ===================================== Returns the taxon above the specified taxon with a given rank. Usage: rank not found =============================================================================]] function p.find(frame) local currTaxon = frame.args[1] or if currTaxon == then return 'no taxon supplied' end local rank = frame.args[2] 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: Lua error at line 474: attempt to compare number with nil. =============================================================================]] function p.nth(frame) local currTaxon = frame.args[1] 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 < n and inHierarchy do local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') if ok and parent ~= then currTaxon = parent i = i + 1 else inHierarchy = false end end if inHierarchy then return currTaxon else return 'Level ' .. n .. ' is past the top of the taxonomic hierarchy' end end
--[[============================= nLevels =================================== External utility function primarily intended for use in checking and debugging. Returns number of levels in a taxonomic hierarchy, starting from the supplied taxon as level 1. Usage: 1 =============================================================================]] function p.nLevels(frame) local currTaxon = frame.args[1] or if currTaxon == then return 'ERROR: no taxon supplied' end local i = 1 local inHierarchy = true -- still in the taxonomic hierarchy or off the top? while inHierarchy and i < MaxSearchLevels do local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') if ok and parent ~= then currTaxon = parent i = i + 1 else inHierarchy = false end end if inHierarchy then return MaxSearchLevels .. '+' else return i end end
--[[============================= listAll =================================== External utility function primarily intended for use in checking and debugging. Returns a comma separated list of a taxonomic hierarchy, starting from the supplied taxon. Usage: TAXON- =============================================================================]] function p.listAll(frame) local currTaxon = frame.args[1] or if currTaxon == then return 'ERROR: no taxon supplied' end return l.doListAll(l.makeTable(frame, currTaxon)) end
function l.doListAll(taxonTable, taxonRankTable) local lst = taxonTable[1] .. '-' .. tostring(taxonRankTable[1]) for i = 2, taxonTable.n, 1 do lst = lst .. ', ' .. taxonTable[i] .. '-' .. taxonRankTable[i] end return lst end
--[[============================== showRefs ================================= Shows the refs field in a taxonomy template, handing incertae sedis taxa and using '–' for absent refs. Usage: REFS =============================================================================]] function p.showRefs(frame) local taxonName = frame.args[1] or local refs = frame.args[2] or return l.doShowRefs(taxonName, refs) end
function l.doShowRefs(taxonName, refs) if mw.text.split(taxonName, '/', true)[1] == 'Incertae sedis' then refs = 'not applicable (incertae sedis)' elseif refs == then refs = '–' end return refs end
--[[========================================================================= Internal functions =============================================================================]]
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Internal utility function to strip off any extra parts of a taxon name, i.e. anything after a '/'. Thus "Felidae/?" would be reduced to "Felidae". = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function l.stripExtra(taxonName) local i = string.find(taxonName,'/') if i then return string.sub(taxonName,1,i-1) else return taxonName end end
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Internal utility function to extract an item of information from a taxonomy template, following one 'same as' link if required. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function l.getTaxonInfoItem(frame, taxon, item) local ok, info -- item == 'dagger' is a special case if item == 'dagger' then ok, info = l.getTaxonInfoItem(frame, taxon, 'extinct') if ok then if info == 'yes' or info == 'true' then info = '†' else info = end end -- item ~= 'dagger' else ok, info = pcall(frame.expandTemplate, frame, { title = 'Template:Taxonomy/' .. taxon, args = {['machine code'] = item } }) if ok then if info == then -- try 'same as' local sameAsTaxon = frame:expandTemplate{ title = 'Template:Taxonomy/' .. taxon, args = {['machine code'] = 'same as' } } if sameAsTaxon ~= then ok, info = pcall(frame.expandTemplate, frame, { title = 'Template:Taxonomy/' .. sameAsTaxon, args = {['machine code'] = item } }) end end end end if ok then -- if item is 'link_text', trim info and check whether '(?)' needs to be added if item == 'link_text' then -- there is a newline at the end of linkText when taxonomy template has "|link = LINK_TARGET|LINK_TEXT" info = mw.text.trim(info) if string.sub(taxon, -2) == '/?' and not string.find(info, '?', 1, true) then info = info .. ' (?)' end end else info = 'Template:Taxonomy/' .. taxon .. '' --error indicator in code before conversion to Lua end return ok, info 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; TABLE[1]..TABLE[TABLE.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 = {} local taxonRankTable = {} local ok, parent, rank taxonTable[1] = currTaxon; ok, rank = l.getTaxonInfoItem(frame, currTaxon, 'rank') if ok then taxonRankTable[1] = rank else taxonRankTable[1] = end while i < MaxSearchLevels and inHierarchy do ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') if ok and parent ~= then currTaxon = parent i = i + 1 taxonTable[i] = currTaxon ok, rank = l.getTaxonInfoItem(frame, currTaxon, 'rank') if ok then taxonRankTable[i] = rank else taxonRankTable[i] = end 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, taxonRankTable 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