Administrators, upwizcampeditors
0
edits
(Created page with "--[[ This module provides support to the automated taxobox system – the templates Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc. In particular it provi...") |
m (1 revision imported) |
||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
--[[ | --[[************************************************************************* | ||
This module provides support to the automated taxobox system – the templates | This module provides support to the automated taxobox system – the templates | ||
Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc. | Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc. | ||
Line 5: | Line 5: | ||
In particular it provides a way of traversing the taxonomic hierarchy encoded | In particular it provides a way of traversing the taxonomic hierarchy encoded | ||
in taxonomy templates (templates with names of the form | in taxonomy templates (templates with names of the form | ||
"Template:Taxonomy/TAXON_NAME") without causing template expansion depth errors. | "Template:Taxonomy/TAXON_NAME") without causing template expansion depth | ||
]] | errors. | ||
*****************************************************************************]] | |||
local p = {} | require('Module:No globals') | ||
local TaxonItalics = require('Module:TaxonItalics') -- use a function from Module:TaxonItalics to italicize a taxon name | |||
local p = {} -- functions made public | |||
local l = {} -- internal functions, kept separate | |||
local colour = '' -- colour for taxobox and taxonomy listings | |||
--[[========================================================================= | --[[========================================================================= | ||
Line 14: | Line 19: | ||
avoids excessive processing time and protects against incorrectly set up | avoids excessive processing time and protects against incorrectly set up | ||
hierarchies, e.g. loops. | hierarchies, e.g. loops. | ||
The value can be obtained externally via | |||
{{#invoke:Autotaxobox|getMaxSearchLevels}} | |||
=============================================================================]] | =============================================================================]] | ||
local MaxSearchLevels = 100 | local MaxSearchLevels = 100 | ||
Line 32: | Line 39: | ||
=============================================================================]] | =============================================================================]] | ||
function p.taxoboxColour(frame) | function p.taxoboxColour(frame) | ||
-- note that colour is global to this function; default is empty string | |||
local currTaxon = frame.args[1] or '' | local currTaxon = frame.args[1] or '' | ||
local i = 1 -- count levels processed | local i = 1 -- count levels processed | ||
local searching = currTaxon ~= '' -- still searching for a colour? | local searching = currTaxon ~= '' -- still searching for a colour? | ||
local foundICTaxon = false -- record whether 'incertae sedis' found | local foundICTaxon = false -- record whether 'incertae sedis' found | ||
while searching and i <= MaxSearchLevels do | while searching and i <= MaxSearchLevels do | ||
local plainCurrTaxon = | local plainCurrTaxon = l.stripExtra(currTaxon) -- remove trailing text after / | ||
if string.lower(plainCurrTaxon) == 'incertae sedis' then | if string.lower(plainCurrTaxon) == 'incertae sedis' then | ||
foundICTaxon = true | foundICTaxon = true | ||
Line 49: | Line 56: | ||
end | end | ||
if searching then | if searching then | ||
local ok, parent = | local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') | ||
if ok and parent ~= '' then | if ok and parent ~= '' then | ||
currTaxon = parent | currTaxon = parent | ||
Line 58: | Line 65: | ||
end | end | ||
end | end | ||
if colour | 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 | 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 | end | ||
Line 82: | Line 98: | ||
|ggparent_authority = taxonomic authority for TAXON's greatgreatgrandparent | |ggparent_authority = taxonomic authority for TAXON's greatgreatgrandparent | ||
|bold_first = 'bold' to bold TAXON in its row | |bold_first = 'bold' to bold TAXON in its row | ||
|virus = 'yes' to apply virus taxa italicization standards | |||
}} | }} | ||
=============================================================================]] | =============================================================================]] | ||
function p.taxoboxList(frame) | function p.taxoboxList(frame) | ||
local currTaxon = frame.args[1] or '' | local currTaxon = frame.args[1] or '' | ||
if currTaxon == '' then return '' end | |||
local displayN = (tonumber(frame.args['display_taxa']) or 1) + 1 | local displayN = (tonumber(frame.args['display_taxa']) or 1) + 1 | ||
local | local authTable = {} | ||
authTable[1] = frame.args['authority'] or '' | |||
authTable[2] = frame.args['parent_authority'] or '' | |||
authTable[3] = frame.args['gparent_authority'] or '' | |||
authTable[4] = frame.args['ggparent_authority'] or '' | |||
authTable[5] = frame.args['gggparent_authority'] or '' | |||
local boldFirst = frame.args['bold_first'] or 'link' -- values 'link' or 'bold' | local boldFirst = frame.args['bold_first'] or 'link' -- values 'link' or 'bold' | ||
local taxonTable = | local virus = frame.args['virus'] or 'no' -- values 'yes' or 'no' | ||
local offset = tonumber(frame.args['offset'] or 0) | |||
-- adjust the authority table if 'authority' refers to a rank lower than the target taxon | |||
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 taxonTable, taxonRankTable = l.makeTable(frame, currTaxon) | |||
local res = '' | local res = '' | ||
-- display all taxa above possible greatgreatgrandparent | local topTaxonN = taxonTable.n | ||
for i = | -- display all taxa above possible greatgreatgrandparent, without authority | ||
res = res .. frame | for i = topTaxonN, 6, -1 do | ||
res = res .. l.showTaxon(frame, taxonTable[i], taxonRankTable[i], topTaxonN==i, '', displayN >= i, '', virus) | |||
end | end | ||
-- display | -- display all taxa above possible parent, with authority if given | ||
for i = math.min(topTaxonN, 5), 2, -1 do | |||
res = res .. frame | res = res .. l.showTaxon(frame, taxonTable[i], taxonRankTable[i], topTaxonN==i, authTable[i], displayN >= i, '', virus) | ||
end | end | ||
-- display | -- display target taxon, always displayed and emboldened | ||
if | res = res .. l.showTaxon(frame, taxonTable[1], taxonRankTable[1], topTaxonN==1, authTable[1], true, boldFirst, virus) | ||
return res | |||
end | |||
res = | --[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = | ||
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 .. '<br><small>' .. auth .. '</small>' | |||
end | |||
return res .. '\n|-\n' | |||
else | |||
return '' | |||
end | |||
end | end | ||
end | end | ||
Line 133: | Line 188: | ||
local currTaxon = frame.args[1] or '' | local currTaxon = frame.args[1] or '' | ||
if currTaxon == '' then return '| ||ERROR: no taxon supplied\n|-' end | if currTaxon == '' then return '| ||ERROR: no taxon supplied\n|-' end | ||
local taxonTable = | local taxonTable, taxonRankTable = l.makeTable(frame, currTaxon) | ||
local rankTable = | local rankTable = l.getRankTable() | ||
local lastRankVal = 1000000 | local lastRankVal = 1000000 | ||
local orderOk | local orderOk = true | ||
local res = '' | local res = '' | ||
for i = taxonTable.n, 1, -1 do | -- 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 | -- check ranks are in right order in the hierarchy | ||
local | taxon = taxonTable[i] | ||
local rank = taxonRankTable[i] | |||
local currRankVal = rankTable[string.lower(rank)] | local currRankVal = rankTable[string.lower(rank)] | ||
if currRankVal then | if currRankVal then | ||
Line 150: | Line 226: | ||
-- now return a row of the taxonomy table with anomalous ranks marked | -- now return a row of the taxonomy table with anomalous ranks marked | ||
local errorStr = '' | local errorStr = '' | ||
if not orderOk then errorStr = ' | if not orderOk then errorStr = 'yes' end | ||
res = res .. | local link = l.getTaxonLink(frame, taxon, rank, 'no', '', virus) | ||
res = res .. '\n' .. l.taxonTableRow(frame, taxon, rank, link, errorStr) | |||
end | end | ||
-- if the last row has an anomalous rank, put the page in the error-tracking category; category statements don't work | -- if the last row has an anomalous rank, put the page in the error-tracking category; category statements don't work | ||
Line 158: | Line 235: | ||
res = res .. '\n|}\n[[Category:Taxonomy templates showing anomalous ranks]]\n{|\n' | res = res .. '\n|}\n[[Category:Taxonomy templates showing anomalous ranks]]\n{|\n' | ||
end | end | ||
return res | |||
end | |||
--[[= = = = = = = = = = = = = = taxonTableRow = = = = = = = = = = = = = = = = | |||
Returns a single row of the taxonomy table displayed on the right hand side | |||
of "Template:Taxonomy...." pages. | |||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | |||
function l.taxonTableRow(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 .. '<span style="background-color:#FDD">' | |||
end | |||
local anglicizedRank = frame:expandTemplate{ title = 'Template:Anglicise rank', args = { rank } } | |||
res = res .. anglicizedRank | |||
if error == 'yes' then | |||
res = res .. '</span>' | |||
end | |||
res = res .. ':||<span class="' .. string.lower(anglicizedRank) .. '" style="white-space:nowrap;">' .. link .. '</span>' .. frame:expandTemplate{ title = 'Template:Edit a taxon', args = { taxon } } .. '\n|-' | |||
return res | return res | ||
end | end | ||
Line 176: | Line 278: | ||
}} | }} | ||
=============================================================================]] | =============================================================================]] | ||
local PARENT = 1 | local PARENT = 1 | ||
local RANK = 2 | local RANK = 2 | ||
Line 183: | Line 284: | ||
local ALWAYS_DISPLAY = 5 | local ALWAYS_DISPLAY = 5 | ||
local EXTINCT = 6 | local EXTINCT = 6 | ||
local SAME_AS = 7 | |||
local REFS = 8 | local REFS = 8 | ||
function p.callTaxonomyKey(frame) | function p.callTaxonomyKey(frame) | ||
local taxon = frame.args['taxon'] or '' | |||
local parent = frame.args['parent'] or '' | local parent = frame.args['parent'] or '' | ||
local rank = frame.args['rank'] or '' | local rank = frame.args['rank'] or '' | ||
Line 218: | Line 321: | ||
if linkText ~= '' and linkText ~= linkTarget then link = link .. "|" .. linkText end | if linkText ~= '' and linkText ~= linkTarget then link = link .. "|" .. linkText end | ||
return frame:expandTemplate{ title = 'Template:Taxonomy key', | return frame:expandTemplate{ title = 'Template:Taxonomy key', | ||
args = {parent=parent, rank=rank, extinct=extinct, always_display=alwaysDisplay, link_target=linkTarget, link=link, refs=refs, same_as=sameAsTaxon} } | args = {taxon=taxon, parent=parent, rank=rank, extinct=extinct, always_display=alwaysDisplay, link_target=linkTarget, link=link, refs=refs, same_as=sameAsTaxon} } | ||
end | |||
--[[============================= showRefs ================================== | |||
Shows the refs field in a taxonomy template, handing incertae sedis taxa and | |||
using '–' for absent refs. | |||
Usage: {{#invoke:Autotaxobox|showRefs|TAXON|REFS}} | |||
=============================================================================]] | |||
function p.showRefs(frame) | |||
local taxonName = frame.args[1] or '' | |||
local refs = frame.args[2] or '' | |||
return l.doShowRefs(taxonName, refs) | |||
end | |||
--[[= = = = = = = = = = = = = = doShowRefs = = = = = = = = = = = = = = = = = | |||
Show the refs field in a taxonomy template. | |||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | |||
function l.doShowRefs(taxonName, refs) | |||
if mw.text.split(taxonName, '/', true)[1] == 'Incertae sedis' then | |||
refs = 'not applicable (<i>incertae sedis</i>)' | |||
elseif refs == '' then | |||
refs = '–' | |||
end | |||
return refs | |||
end | end | ||
Line 225: | Line 351: | ||
one 'same as' link if required. | one 'same as' link if required. | ||
Usage: {{#invoke:Autotaxobox|taxonInfo|TAXON|ITEM}} | Usage: {{#invoke:Autotaxobox|taxonInfo|TAXON|ITEM}} | ||
ITEM is one of: 'parent', 'rank', 'link target', 'link text | ITEM is one of: 'parent', 'rank', 'link target', 'link text', 'extinct', | ||
'always display', 'refs', 'same as' or 'all'. | 'always display', 'refs', 'same as' or 'all'. | ||
If ITEM is not specified, the default is 'all' – all values in a single string | If ITEM is not specified, the default is 'all' – all values in a single string | ||
Line 234: | Line 360: | ||
local item = frame.args[2] or '' | local item = frame.args[2] or '' | ||
if item == '' then item = 'all' end | if item == '' then item = 'all' end | ||
local ok, info = | local ok, info = l.getTaxonInfoItem(frame, taxon, item) | ||
return info | return info | ||
end | |||
--[[= = = = = = = = = = = getTaxonInfoItem = = = = = = = = = = = = = = = = = | |||
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 .. '<span style="font-style:normal;font-weight:normal;"> (?)</span>' | |||
end | |||
end | |||
else | |||
info = '[[Template:Taxonomy/' .. taxon .. ']]' --error indicator in code before conversion to Lua | |||
end | |||
return ok, info | |||
end | end | ||
Line 248: | Line 418: | ||
|italic= : 'yes' makes the core output italic | |italic= : 'yes' makes the core output italic | ||
|link_target= : target for the wikilink | |link_target= : target for the wikilink | ||
link_text= : text of the wikilink (may be same as link_target), without †, italics, etc. | |link_text= : text of the wikilink (may be same as link_target), without †, italics, etc. | ||
}} | }} | ||
=============================================================================]] | =============================================================================]] | ||
Line 258: | Line 428: | ||
local linkTarget = frame.args['link_target'] 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 | 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 | |||
--[[= = = = = = = = = = = = = = getTaxonLink = = = = = = = = = = = = = = = = | |||
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 | |||
--[[= = = = = = = = = = = = = = makeLink = = = = = = = = = = = = = = = = = = | |||
Actually make the link. | |||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | |||
function l.makeLink(taxon, extinct, bold, italic, linkTarget, linkText) | |||
-- if link text is missing, try to find a replacement | -- if link text is missing, try to find a replacement | ||
if linkText == '' then | if linkText == '' then | ||
Line 264: | Line 454: | ||
linkTarget = 'Incertae sedis' | linkTarget = 'Incertae sedis' | ||
else | else | ||
linkText = | linkText = l.stripExtra(taxon) | ||
end | end | ||
end | end | ||
if linkTarget == '' then linkTarget = linkText end | |||
if italic == 'yes' then linkText = TaxonItalics.italicizeTaxonName(linkText, false) end | |||
local link = '' | local link = '' | ||
if bold == 'yes' then link = '<b>' .. linkText .. '</b>' | if bold == 'yes' then link = '<b>' .. linkText .. '</b>' | ||
else | else | ||
if linkTarget == linkText | if linkTarget == linkText then link = linkText | ||
else link = linkTarget .. '|' .. linkText | else link = linkTarget .. '|' .. linkText | ||
end | end | ||
link = '[[' .. link .. ']]' | link = '[[' .. link .. ']]' | ||
end | end | ||
if (extinct == 'yes' or extinct == 'true') and not string.find(link, '†', 1, true) then | if (extinct == 'yes' or extinct == 'true') and not string.find(link, '†', 1, true) then | ||
link = '<span style="font-style:normal;font-weight:normal;">†</span>' .. link | link = '<span style="font-style:normal;font-weight:normal;">†</span>' .. link | ||
Line 290: | Line 481: | ||
Usage: {{#invoke:Autotaxobox|showRankTable}} | Usage: {{#invoke:Autotaxobox|showRankTable}} | ||
=============================================================================]] | =============================================================================]] | ||
function p.showRankTable(frame) | function p.showRankTable(frame) | ||
local rankTable = | local rankTable = l.getRankTable() | ||
local res = '{| class="wikitable sortable"\n|+ Ranks checked in taxonomy templates\n! Rank !! Shown as !! Value\n' | local res = '{| class="wikitable sortable"\n|+ Ranks checked in taxonomy templates\n! Rank !! Shown as !! Value\n' | ||
for k, v in pairs(rankTable) do | for k, v in pairs(rankTable) do | ||
Line 299: | Line 489: | ||
end | end | ||
return res .. '|}\n' | return res .. '|}\n' | ||
end | |||
--[[============================== find ===================================== | |||
Returns the taxon above the specified taxon with a given rank. | |||
Usage: {{#invoke:Autotaxobox|find|TAXON|RANK}} | |||
=============================================================================]] | |||
function p.find(frame) | |||
local currTaxon = frame.args[1] or '' | |||
if currTaxon == '' then return '<span class="error">no taxon supplied</span>' end | |||
local rank = frame.args[2] or '' | |||
if rank == '' then return '<span class="error">no rank supplied</span>' 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 '<span class="error">rank not found</span>' | |||
end | |||
end | end | ||
Line 317: | Line 535: | ||
local inHierarchy = true -- still in the taxonomic hierarchy or off the top? | local inHierarchy = true -- still in the taxonomic hierarchy or off the top? | ||
while i < n and inHierarchy do | while i < n and inHierarchy do | ||
local ok, parent = | local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') | ||
if ok and parent ~= '' then | if ok and parent ~= '' then | ||
currTaxon = parent | currTaxon = parent | ||
Line 342: | Line 560: | ||
local inHierarchy = true -- still in the taxonomic hierarchy or off the top? | local inHierarchy = true -- still in the taxonomic hierarchy or off the top? | ||
while inHierarchy and i < MaxSearchLevels do | while inHierarchy and i < MaxSearchLevels do | ||
local ok, parent = | local ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') | ||
if ok and parent ~= '' then | if ok and parent ~= '' then | ||
currTaxon = parent | currTaxon = parent | ||
Line 364: | Line 582: | ||
local currTaxon = frame.args[1] or '' | local currTaxon = frame.args[1] or '' | ||
if currTaxon == '' then return 'ERROR: no taxon supplied' end | if currTaxon == '' then return 'ERROR: no taxon supplied' end | ||
return | 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 | end | ||
Line 371: | Line 597: | ||
=============================================================================]] | =============================================================================]] | ||
--[[= = = = = = = = = = = = | --[[= = = = = = = = = = = = stripExtra = = = = = = = = = = = = = = = = = = = | ||
Internal utility function to strip off any extra parts of a taxon name, i.e. | 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". | anything after a '/'. Thus "Felidae/?" would be reduced to "Felidae". | ||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | ||
function | function l.stripExtra(taxonName) | ||
local i = string.find(taxonName,'/') | local i = string.find(taxonName,'/') | ||
if i then | if i then | ||
Line 384: | Line 610: | ||
end | end | ||
--[[= = = = = = = = = = = = = | --[[= = = = = = = = = = = = = makeTable = = = = = = = = = = = = = = = = = = = | ||
Internal utility function to return a table (array) constructed from a | Internal utility function to return a table (array) constructed from a | ||
taxonomic hierarchy stored in "Template:Taxonomy/..." templates. | taxonomic hierarchy stored in "Template:Taxonomy/..." templates. | ||
TABLE.n holds the total number of taxa; TABLE[1]..TABLE[TABLE.n] the taxon | TABLE.n holds the total number of taxa; TABLE[1]..TABLE[TABLE.n] the taxon | ||
names. | 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 | function l.makeTable(frame, currTaxon) | ||
local taxonTable = {} | |||
local taxonRankTable = {} | |||
local ok, rank, parent | |||
local i = 1 | local i = 1 | ||
local | local topReached = false -- reached the top of the taxonomic hierarchy? | ||
repeat | |||
taxonTable[i] = currTaxon | |||
ok, rank = l.getTaxonInfoItem(frame, currTaxon, 'rank') | |||
if ok then taxonRankTable[i] = rank else taxonRankTable[i] = '' end | |||
ok, parent = l.getTaxonInfoItem(frame, currTaxon, 'parent') | |||
if ok and parent ~= '' then | if ok and parent ~= '' then | ||
currTaxon = parent | currTaxon = parent | ||
i = i + 1 | i = i + 1 | ||
else | else | ||
topReached = true -- reached the top of the hierarchy or tried to use a non-existent taxonomy template | |||
end | end | ||
until topReached or i > MaxSearchLevels | |||
taxonTable.n = i | taxonTable.n = math.min(i, MaxSearchLevels) | ||
return taxonTable | return taxonTable, taxonRankTable | ||
end | end | ||
--[[= = = = = = = = = = = = | --[[= = = = = = = = = = = = getRankTable = = = = = = = = = = = = = = = = = = | ||
Internal utility function to set up a table of numerical values corresponding | Internal utility function to set up a table of numerical values corresponding | ||
to 'Linnaean' ranks, with upper ranks having higher values. In a valid | to 'Linnaean' ranks, with upper ranks having higher values. In a valid | ||
Line 474: | Line 648: | ||
The ranks should correspond to those in Template:Anglicise ranks. | The ranks should correspond to those in Template:Anglicise ranks. | ||
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]] | ||
function | function l.getRankTable() | ||
return { | return { | ||
classis = 1400, | classis = 1400, | ||
Line 501: | Line 675: | ||
ordo = 1000, | ordo = 1000, | ||
parafamilia = 800, | parafamilia = 800, | ||
parvclassis = 1396; -- same as subterclassis | |||
parvordo = 996, | parvordo = 996, | ||
phylum = 1500, | phylum = 1500, | ||
Line 518: | Line 693: | ||
subsectio = 498, | subsectio = 498, | ||
subspecies = 298, | subspecies = 298, | ||
subterclassis = 1396; -- same as parvclassis | |||
subtribus = 698, | subtribus = 698, | ||
superclassis = 1403, | superclassis = 1403, |