Module:Autotaxobox: Difference between revisions

From Chalo Chatu, Zambia online encyclopedia
m
1 revision imported
(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
local colour = '' -- default is no colour
while searching and i <= MaxSearchLevels do
while searching and i <= MaxSearchLevels do
local plainCurrTaxon = p.stripExtra(currTaxon) -- remove trailing text after /
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 = p.getTaxonInfoItem(frame, currTaxon, '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 ~= '' then
if colour == '' then
return colour
if foundICTaxon then
elseif foundICTaxon then
colour = frame:expandTemplate{ title = 'Template:Taxobox colour', args = { 'incertae sedis' } }
return frame:expandTemplate{ title = 'Template:Taxobox colour', args = { 'incertae sedis' } }
elseif searching then
elseif searching then
-- hierarchy exceeds MaxSearchLevels levels
-- hierarchy exceeds MaxSearchLevels levels
colour = frame:expandTemplate{ title = 'Template:Taxobox/Error colour', args = { } }
return frame:expandTemplate{ title = 'Template:Taxobox/Error colour', args = { } }
else
else
colour = 'transparent'
return '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 auth = frame.args['authority'] or ''
local authTable = {}
local parentAuth = frame.args['parent_authority'] or ''
authTable[1] = frame.args['authority'] or ''
local gParentAuth = frame.args['gparent_authority'] or ''
authTable[2] = frame.args['parent_authority'] or ''
local ggParentAuth = frame.args['ggparent_authority'] or ''
authTable[3] = frame.args['gparent_authority'] or ''
local gggParentAuth = frame.args['gggparent_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 = p.makeTable(frame, currTaxon)
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 = taxonTable.n, 6, -1 do
-- display all taxa above possible greatgreatgrandparent, without authority
res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[i], fc = tostring(displayN >= i) } }
for i = topTaxonN, 6, -1 do
res = res .. l.showTaxon(frame, taxonTable[i], taxonRankTable[i], topTaxonN==i, '', displayN >= i, '', virus)
end
end
-- display greatgreatgrandparent, if it exists
-- display all taxa above possible parent, with authority if given
if taxonTable.n >= 5 then
for i = math.min(topTaxonN, 5), 2, -1 do
res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[5], authority = gggParentAuth, fc = tostring(displayN >= 5) } }
res = res .. l.showTaxon(frame, taxonTable[i], taxonRankTable[i], topTaxonN==i, authTable[i], displayN >= i, '', virus)
end
end
-- display greatgrandparent, if it exists; force the display if an infrataxon is below
-- display target taxon, always displayed and emboldened
if taxonTable.n >= 4 then
res = res .. l.showTaxon(frame, taxonTable[1], taxonRankTable[1], topTaxonN==1, authTable[1], true, boldFirst, virus)
local force = tostring(displayN >= 4) or
return res
              frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable[3] } } == 'true' or
end
              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) } }
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
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
-- 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
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 = p.makeTable(frame, currTaxon)
local taxonTable, taxonRankTable = l.makeTable(frame, currTaxon)
local rankTable = p.getRankTable()
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 ok, rank = p.getTaxonInfoItem(frame, taxonTable[i], 'rank')
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 = 'true' end
if not orderOk then errorStr = 'yes' end
res = res .. frame:expandTemplate{ title = 'Template:Taxonomy links', args = { taxonTable[i], error = errorStr } }
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 SAME_AS = 7
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', 'link', 'extinct',
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 = p.getTaxonInfoItem(frame, taxon, item)
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 = '&dagger;'
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 = p.stripExtra(taxon)
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 or linkTarget == '' then link = linkText
if linkTarget == linkText then link = linkText
else link = linkTarget .. '|' .. linkText
else link = linkTarget .. '|' .. linkText
end
end
link = '[[' .. link .. ']]'
link = '[[' .. link .. ']]'
end
end
if italic == 'yes' and not string.find(link, "''", 1, true) then link = '<i>' .. link .. '</i>' 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 = p.getRankTable()
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 = p.getTaxonInfoItem(frame, currTaxon, '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 = p.getTaxonInfoItem(frame, currTaxon, '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 p.listTaxa(p.makeTable(frame, currTaxon))
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 p.stripExtra(taxonName)
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 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
 
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
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)
-- item == 'link' is a special case
if item == 'link' then
return p.getTaxonInfoLink(frame, taxon)
end
-- item ~= 'link'
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 } })
end
end
end
if ok then
-- if item is 'link_text' check whether '(?)' needs to be added
if item == 'link_text' and string.sub(taxon, -2) == '/?' and not string.find(info, '?', 1, true) then
info = info .. '<span style="font-style:normal;font-weight:normal;"> (?)</span>'
end
else
info = '[[Template:Taxonomy/' .. taxon .. ']]' --error indicator in code before conversion to Lua
end
return ok, info
end
 
function p.getTaxonInfoLink(frame, taxon)
local ok, linkText, linkTarget
local link = ''
ok, linkText = p.getTaxonInfoItem(frame, taxon, 'link_text')
if ok then
ok, linkTarget = p.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
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 p.makeTable(frame, currTaxon)
function l.makeTable(frame, currTaxon)
local taxonTable = {}
local taxonRankTable = {}
local ok, rank, parent
local i = 1
local i = 1
local inHierarchy = true -- still in the taxonomic hierarchy or off the top?
local topReached = false -- reached the top of the taxonomic hierarchy?
local taxonTable = {}
repeat
taxonTable[1] = currTaxon;
taxonTable[i] = currTaxon
while i < MaxSearchLevels and inHierarchy do
ok, rank = l.getTaxonInfoItem(frame, currTaxon, 'rank')
local ok, parent = p.getTaxonInfoItem(frame, currTaxon, 'parent')
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
taxonTable[i] = currTaxon
else
else
inHierarchy = false -- run off the top of the hierarchy or tried to use non-existent taxonomy template
topReached = true -- reached the top of the hierarchy or tried to use a non-existent taxonomy template
end
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 p.getRankTable()
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,
Administrators, upwizcampeditors
0

edits