Jump to content

Module:Autotaxobox/doc

From Simple English Wikipedia, the free encyclopedia
Revision as of 16:59, 3 January 2017 by Peter coxhead (talk | changes) (update to tested sandbox version)

This is the documentation page for 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. ]]

local p = {}

--[[========================================================================= 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

--[[============================ 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', 'link', '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 = p.getTaxonInfoItem(frame, taxon, item) return info 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) 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 local colour = -- default is no colour while searching and i <= MaxSearchLevels do local plainCurrTaxon = p.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 = p.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 return colour elseif foundICTaxon then return frame:expandTemplate{ title = 'Template:Taxobox colour', args = { 'incertae sedis' } } elseif searching then -- hierarchy exceeds MaxSearchLevels levels return frame:expandTemplate{ title = 'Template:Taxobox/Error colour', args = { } } else return 'transparent' end end

--[[=========================== taxoboxList ================================= Returns the rows of taxa in an automated taxobox, based on the taxonomic hierarchy for the supplied taxon. Usage:

|- |Unrecognized taxon (fix): |[[TAXON ]] |-

|-

=============================================================================]] function p.taxoboxList(frame) local currTaxon = frame.args[1] or 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 taxonTable = p.makeTable(frame, currTaxon) local res = -- display all taxa above possible greatgreatgrandparent for i = taxonTable.n, 6, -1 do res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[i], fc = tostring(displayN >= i) } } end -- display greatgreatgrandparent, if it exists if taxonTable.n >= 5 then res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[5], authority = gggParentAuth, fc = tostring(displayN >= 5) } } 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 = { taxonTable[3] } } == 'true' or frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable[2] } } == 'true' res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[4], authority = ggParentAuth, fc = tostring(force) } } 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 = { taxonTable[2] } } == 'true'
       res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[3], authority = gParentAuth, fc = tostring(force) } }

end -- display parent, if it exists if taxonTable.n >= 2 then res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[2], authority = parentAuth, fc = tostring(displayN >= 2) } } end -- display target taxon res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[1], authority = auth, fc = 'true', format = boldFirst } } return res end

--[[========================== taxonomyList ================================= Returns the cells of the taxonomy table displayed on "Template:Taxonomy...." pages.

Usage:

Bold ranks show taxa that will be shown in taxoboxes
because rank is principal or always_display=yes.

Ancestral taxa
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 = p.makeTable(frame, currTaxon) local rankTable = p.getRankTable() local lastRankVal = 1000000 local orderOk local res = for i = taxonTable.n, 1, -1 do -- check ranks are in right order in the hierarchy local ok, rank = p.getTaxonInfoItem(frame, taxonTable[i], 'rank') local currRankVal = rankTable[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 if orderOk then res = res .. frame:expandTemplate{ title = 'Template:Taxonomy links', args = { taxonTable[i] } } else if i ~= 1 then res = res .. frame:expandTemplate{ title = 'Template:Taxonomy links', args = { taxonTable[i], error = 'true' } } else res = res .. frame:expandTemplate{ title = 'Template:Taxonomy links', args = { taxonTable[i], error = 'true', last_error = 'true' } } end end end 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:

ERROR: no taxon supplied

Wikipedia does not yet have an article about value of 'link' parameter in taxonomy template. The page that you are currently viewing contains information about value of 'link' parameter in taxonomy template's taxonomy. Not sure why you're here? Get started with the automated taxobox system.

Parent: [Taxonomy; edit]
Rank: (displays as )– a rank must be supplied
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: {Placeholder error message}.

=============================================================================]] function p.callTaxonomyKey(frame) local parent = frame.args['parent'] or local rank = frame.args['rank'] or local extinct = frame.args['extinct'] or local alwaysDisplay = frame.args['always_display'] or local linkTarget = frame.args['link_target'] or local linkText = frame.args['link_text'] or local sameAsTaxon = frame.args['same_as'] or if sameAsTaxon ~= then local sameAsInfoStr = frame:expandTemplate{ title = 'Template:Taxonomy/' .. sameAsTaxon, args = {['machine code'] = 'all' } } local sameAsInfo = mw.text.split(sameAsInfoStr, '$', true) if parent == then parent = sameAsInfo[1] end if rank == then rank = sameAsInfo[2] end if extinct == then extinct = sameAsInfo[6] end if alwaysDisplay == then alwaysDisplay = sameAsInfo[5] end if linkTarget == then linkTarget = sameAsInfo[3] end if linkText == then linkText = sameAsInfo[4] end end local link = linkTarget if linkText ~= then link = link .. "|" .. linkText end return frame:expandTemplate{ title = 'Template:Taxonomy key', args = {parent=parent, rank=rank, extinct=extinct, always_display=alwaysDisplay, link_target=linkTarget, link=link} } end

--[[========================== showRankTable ================================ Returns a wikitable showing the ranks and their values as set up by getRankTable(). Usage:

Ranks checked in taxonomy templates
Rank Shown as Value
infratribus Infratribe 697
infraphylum Infraphylum 1497
infraordo Infraorder 997
cohort Cohort 1100
micrordo Microrder 995
zoosubsectio Subsection 898
genus Genus 600
zoosubdivisio Subdivision 1298
superclassis Superclass 1403
grandordo Grandorder 1005
microphylum Microphylum 1495
sublegio Sublegion 1198
hyperfamilia Hyperfamily 805
parvclassis Parvclass 1396
supercohort Supercohort 1103
nanordo Nanorder 994
parafamilia Parafamily 800
varietas Variety 200
tribus Tribe 700
magnordo Magnorder 1006
superlegio Superlegion 1203
supersectio Supersection 503
subordo Suborder 998
superfamilia Superfamily 803
superphylum Superphylum 1503
parvordo Parvorder 996
infraregnum Infrakingdom 1597
grandordo-mb Grandorder 1002
supertribus Supertribe 703
zoodivisio Division 1300
superdivisio Superdivision 1503
zoosectio Section 900
subtribus Subtribe 698
subterclassis Subterclass 1396
subspecies Subspecies 298
divisio Division 1500
subsectio Subsection 498
classis Class 1400
subregnum Subkingdom 1598
infraclassis Infraclass 1397
subcohort Subcohort 1098
subfamilia Subfamily 798
subphylum Subphylum 1498
superregnum Superkingdom 1603
species Species 300
subgenus Subgenus 598
subdivisio Subdivision 1498
subclassis Subclass 1398
ordo Order 1000
sectio Section 500
regnum Kingdom 1600
legio Legion 1200
epifamilia Epifamily 802
domain Domain 1700
superdomain Superdomain 1703
superordo Superorder 1003
nanophylum Nanophylum 1494
familia Family 800
mirordo-mb Mirorder 1001
infralegio Infralegion 1197
forma Form 100
mirordo Mirorder 1004
phylum Phylum 1500

=============================================================================]]

function p.showRankTable(frame) local rankTable = p.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

--[[=============================== 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 in Module:Autotaxobox at line 584: 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 = p.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 = p.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 p.listTaxa(p.makeTable(frame, currTaxon)) 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 p.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 convert a taxon table to a comma-separated list. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function p.listTaxa(taxonTable) local lst = taxonTable[1] for i = 2, taxonTable.n, 1 do lst = lst .. ', ' .. taxonTable[i] end return lst end

--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Script error: The function "taxonInfoItem" does not exist. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function p.taxonInfoItem(frame) local itemVal = frame.args[1] if itemVal == then local item = frame.args[2] local sameAsTaxon = frame.args[3] if sameAsTaxon ~= then itemVal = frame:expandTemplate{ title = 'Template:Taxonomy/' .. sameAsTaxon, args = {['machine code'] = item } } end end return itemVal end

--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = Internal utility function to extract an item of information from a taxonomy template, following one 'same as' link if required. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function p.getTaxonInfoItem(frame, taxon, item) local 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 } }) if not ok then info = 'Template:Taxonomy/' .. sameAsTaxon .. '' end end end else info = 'Template:Taxonomy/' .. taxon .. '' 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. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] function p.makeTable(frame, currTaxon) local i = 1 local inHierarchy = true -- still in the taxonomic hierarchy or off the top? local taxonTable = {} taxonTable[1] = currTaxon; while i < MaxSearchLevels and inHierarchy do local ok, parent = p.getTaxonInfoItem(frame, currTaxon, 'parent') if ok and parent ~= then currTaxon = parent i = i + 1 taxonTable[i] = 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 p.getRankTable() return { classis = 1400, cohort = 1100, divisio = 1500, domain = 1700, familia = 800, genus = 600, grandordo = 1005, ['grandordo-mb'] = 1002, infraclassis = 1397, infralegio = 1197, infraordo = 997, infraphylum = 1497, infraregnum = 1597, infratribus = 697, legio = 1200, magnordo = 1006, micrordo = 995, mirordo = 1004, ['mirordo-mb'] = 1001, nanordo = 999, ordo = 1000, parafamilia = 800, 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, 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