Module:Autotaxobox: Difference between revisions

From Chalo Chatu, Zambia online encyclopedia
m
1 revision imported
m (1 revision imported)
 
m (1 revision imported)
 
(One intermediate revision 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.
*****************************************************************************]]


require('Module:No globals')
local TaxonItalics = require('Module:TaxonItalics') -- use a function from Module:TaxonItalics to italicize a taxon name
local TaxonItalics = require('Module:TaxonItalics') -- use a function from Module:TaxonItalics to italicize a taxon name
local p = {}
local p = {} -- functions made public
local l = {} -- internal functions, kept separate
local colour = '' -- colour for taxobox and taxonomy listings


--[[=========================================================================
--[[=========================================================================
Line 15: 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 33: 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 50: 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 59: 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 83: 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) } }
--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
end
Show one taxon row in a taxobox.
-- display grandparent, if it exists; force the display if an infrataxon is below
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
if taxonTable.n >= 3 then
function l.showTaxon(frame, taxon, rank, isTopTaxon, auth, force, boldFirst, virus)
local force = tostring(displayN >= 3) or
-- it's an error if this is the top taxon and it's not a top level taxon (e.g. "Life")
                      frame.expandTemplate{ title = 'Template:Infrataxon()', args = { taxonTable[2] } } == 'true'
if isTopTaxon then
        res = res .. frame:expandTemplate{ title = 'Template:Taxobox/showtaxon', args = { taxonTable[3], authority = gParentAuth, fc = tostring(force) } }
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 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 134: 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 151: 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 159: 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 177: Line 278:
}}
}}
=============================================================================]]
=============================================================================]]
local SAME_AS = 7
local PARENT = 1
local PARENT = 1
local RANK = 2
local RANK = 2
Line 184: 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 219: 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 226: 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 235: 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 249: 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 259: 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 265: Line 454:
linkTarget = 'Incertae sedis'
linkTarget = 'Incertae sedis'
else
else
linkText = p.stripExtra(taxon)
linkText = l.stripExtra(taxon)
end
end
end
end
Line 292: 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 307: Line 495:
Usage: {{#invoke:Autotaxobox|find|TAXON|RANK}}
Usage: {{#invoke:Autotaxobox|find|TAXON|RANK}}
=============================================================================]]
=============================================================================]]
function p.find(frame)
function p.find(frame)
local currTaxon = frame.args[1] or ''
local currTaxon = frame.args[1] or ''
Line 316: Line 503:
local searching = true -- still searching
local searching = true -- still searching
while inHierarchy and searching do
while inHierarchy and searching 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
local ok, currRank = p.getTaxonInfoItem(frame, currTaxon, 'rank')
local ok, currRank = l.getTaxonInfoItem(frame, currTaxon, 'rank')
if currRank == rank then
if currRank == rank then
searching = false
searching = false
Line 348: 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 373: 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 395: 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 402: 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 415: 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 505: 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 532: Line 675:
ordo = 1000,
ordo = 1000,
parafamilia = 800,
parafamilia = 800,
parvclassis = 1396; -- same as subterclassis
parvordo = 996,
parvordo = 996,
phylum = 1500,
phylum = 1500,
Line 549: 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