Module:Sandbox/Jts1882/Biota infobox/auto
Module documentation[] [purge]
local p = {} --
local g = {} -- these are variables with global scope in this sub-module
g.info = {}
--[[ testing function to show automatic taxonomy within a table ]]
function p.showTaxonomyTable(frame)
g.templateArgs = {}
g.info.auto= false
g.taxonTable = p.loadTaxonomyTable(frame)
local output = '\n{| class="wikitable" \n|- style="vertical-align:top;" '
--output = output .. '\n! Rank !! Taxon \n|-' -- oldversion starting new row
output = output .. '\n! Rank !! Taxon' -- don't start a new row here
g.htmlTable = mw.html.create('table')
:addClass('infobox'):addClass('biota')
:cssText("text-align: left; width: 200px; font-size: 100%")
output = output .. p.taxoboxList(frame)
output = output .. '\n|}'
return tostring(g.htmlTable) .. output
--return '\n' ..p.showTaxonomyHierarchyRaw(frame, g.taxonTable) --output
--return output
end
--[[ function to add rows for an automatic taxonomy to an taxobox-style infobox
-- called from parent to this submodule
-- uses a modification of p.taxoboxList() form Module:Autotaxobox
-- uses a function to emulate
]]
function p.getTaxonomyTableRows(frame, htmlTable, templateArgs, info)
g.htmlTable = htmlTable
g.templateArgs = templateArgs
g.info = info
g.taxonTable = p.loadTaxonomyTable(frame)
return p.taxoboxList(frame)
end
--[[ testing function to output the heirarchy table from the automatic taxonomy as a wikitable
]]
function p.showTaxonomyHierarchyRaw(frame, taxonTable)
local output = '{| class="wikitable sortable" '
for k,v in pairs(taxonTable[1]) do
output = output .. '\n!' .. k
end
for i=1, #taxonTable, 1 do
output = output .. '\n|-'
for k,v in pairs(taxonTable[i]) do
output = output .. '\n|' .. v
end
end
output = output .. '\n|}'
--return mw.dumpObject(taxonTable)
return output
end
--[[ function p.loadTaxonomyTable(frame) - loads a 2-D table of taxon information from automatic taxonomy system
each row is the informaiton for a taxon
- this obtained useing Template:Taxonomy/TAXON with argument ['machine code'] = "all"
- additionally adds blank taxon and authority columns
row ={ parent, rank, link_target, link_text, always_display, extinct, same_as, refs, taxon, authority }
]]
function p.loadTaxonomyTable(frame)
local ok, taxonInfo
local taxonTable= {}
local i = 1
-- load authorities from template parameters
local authorities = { g.templateArgs['authority'] or "",
g.templateArgs['parent_authority'] or "",
g.templateArgs['grandparent_authority'] or "",
g.templateArgs['greatgrandparent_authority'] or "",
g.templateArgs['greatgreatgrandparent_authority'] or "",
g.templateArgs['greatgreatgreatgrandparent_authority'] or "",
g.templateArgs['greatgreatgreatgreatgrandparent_authority'] or "",
}
-- get the name of the first taxon
local taxon = g.templateArgs['taxon'] or g.templateArgs['parent'] or "Felis"
--taxon= 'Felis'
--taxon= 'Worthenella'
--taxon= 'Fereuungulata'
--local authority = 'authority'
-- the following section is an alternative method for adding rows for species, subspecies, etc
--[[START: insert rows for variety, subspecies, species and subgenus at base of automatic taxonomy]]
if g.templateArgs['species_name'] then
if g.templateArgs['variety_name'] then
taxonTable[i]= { taxon = g.templateArgs['variety_name'],
rank = 'variety',
authority = authorities[i] --g.templateArgs[authority],
}
i=i+1
end
if g.templateArgs['subspecies_name'] then
taxonTable[i]= { taxon = g.templateArgs['subspecies_name'],
rank = 'subspecies',
authority = authorities[i] -- g.templateArgs[authority],
}
i=i+1
end
-- TODO if subgenus
taxonTable[i]= { taxon = g.templateArgs['species_name'],
rank = 'species',
authority = authorities[i] -- g.templateArgs[authority],
}
i=i+1
taxon = g.templateArgs['parent']
end
--[[END: insert rows for variety, subspecies species and subgenus at base of automatic taxonomy]]
--[[ load the heirarchy of the automatic taxonomy
each row has the contents for a taxon returned by g.getTaxonInfo()
which uses Template:Taxonomy/TAXON with argument machine code ="all"
]]
while i<100 do
ok, taxonTable[i] = g.getTaxonInfo(frame, taxon)
--if ok and taxonTable[i]['parent'] ~= "" then
if ok then
if taxonTable[i]['same_as'] and taxonTable[i]['same_as'] ~= "" then
taxon = taxonTable[i]['same_as']
local ok, sameAsTable = g.getTaxonInfo(frame, taxon)
if ok then
for k,v in pairs(taxonTable[i]) do
if v == "" then
taxonTable[i][k] = sameAsTable[k] -- use same_as values if none set
end
end
else break;
end
else -- we have what data for the taxon directly
-- TODO do something
end
-- add taxon to the table row
if taxonTable[i]['link_text'] and taxonTable[i]['link_text'] ~= "" then
taxonTable[i]['taxon'] = taxonTable[i]['link_text']
else
taxonTable[i]['taxon'] = taxonTable[i]['link_target']
end
-- authority from parent authroity sequence
taxonTable[i]['authority'] = (authorities[i] or "")
if taxonTable[i]['parent'] == "" then -- have we reached the top of the heirarchy?
break
else
taxon = taxonTable[i]['parent'] -- set the taxon for the next loop
end
else break
end
i = i + 1
end
--we have a complete table
taxonTable.n = #taxonTable - 1 -- minus one as last one has parent=life and displays as Genus: Ursus
return taxonTable
end
--[[ loads a row of taxon information
uses Template:Taxonomy/TAXON with argument ['machine code'] = "all"
additionally adds blank taxon and authority columns
row ={ parent, rank, link_target, link_text, always_display, extinct, same_as, refs, taxon, authority }
]]
function g.getTaxonInfo(frame, taxon)
local ok, taxonInfo = pcall(frame.expandTemplate, frame, { title = 'Template:Taxonomy/' .. taxon,
args = {['machine code'] = "all" } })
if ok then
local split= mw.text.split(taxonInfo, "$", true)
-- all: returns "parent$rank$link_target$unnamed parameter$always_display$extinct$same_as$refs"
local taxonRow ={
parent = split[1] or "",
rank = split[2] or "",
-- if link containing pipe, e.g. |link=Fereuungulata|Ferungulata =LINK_TARGET|LINK_TEXT
link_target = split[3] or "", -- link_target = link or first part of link before pipe
link_text = split[4] or "", -- then produces unnamed parameter 'link_text'
always_display = split[5] or "",
extinct = split[6] or "",
same_as = split[7] or "",
refs = split[8] or "",
taxon = "", -- create blank now to stop table reordering
authority = "", -- create blank now to stop table reordering
}
return ok, taxonRow
end
end
--[[=========================== taxoboxList (old version) =================================
-- Copied from Module:Autotaxobox on 19 December 2018
-- modified to use full table of taxaonomy template parameters
-- reason: to reduce template calls, especially in replacement for Template:Taxobox/showtaxon
Returns the rows of taxa in an automated taxobox, based on the taxonomic
hierarchy for the supplied taxon.
Usage:
{{#invoke:Autotaxobox|taxoboxList|TAXON
|display_taxa = the number of taxa *above* TAXON to force to be displayed
|authority = taxonomic authority for TAXON
|parent_authority = taxonomic authority for TAXON's parent
|gparent_authority = taxonomic authority for TAXON's grandparent
|ggparent_authority = taxonomic authority for TAXON's greatgrandparent
|ggparent_authority = taxonomic authority for TAXON's greatgreatgrandparent
|bold_first = 'bold' to bold TAXON in its row
|virus = 'yes' to apply virus taxa italicization standards
}}
=============================================================================]]
function p.taxoboxList(frame)
--local currTaxon = frame.args[1] or ''
local displayN = (tonumber(g.templateArgs['display_taxa']) or 1) + 1
--local displayN = (tonumber(frame.args['display_taxa']) or 1) + 1
--local auth = frame.args['authority'] or ''
--local parentAuth = frame.args['parent_authority'] or ''
--local gParentAuth = frame.args['gparent_authority'] or ''
--local ggParentAuth = frame.args['ggparent_authority'] or ''
--local gggParentAuth = frame.args['gggparent_authority'] or ''
local boldFirst = frame.args['bold_first'] or 'link' -- values 'link' or 'bold'
local virus = frame.args['virus'] or 'no' -- values 'yes' or 'no'
-- local taxonTable = l.makeTable(frame, currTaxon)
local taxonTable = g.taxonTable -- modifications using full table
--taxonTable.n = #taxonTable
--displayN = 10 -- force display
--[[]
taxonTable[1]['authority'] = frame.args['authority'] or 'authority'
taxonTable[2]['authority'] = frame.args['parent_authority'] or 'parent auth'
taxonTable[3]['authority'] = frame.args['gparent_authority'] or 'gp auth'
taxonTable[4]['authority'] = frame.args['ggparent_authority'] or 'ggp auth'
taxonTable[5]['authority'] = frame.args['gggparent_authority'] or 'gggp auth' ]]
local test = g.templateArgs['authority'] or 'authority'
--[[ TODO check that taxonTable[i] exists
taxonTable[1]['authority'] = g.templateArgs['authority'] or ''
taxonTable[2]['authority'] = g.templateArgs['parent_authority'] or ''
taxonTable[3]['authority'] = g.templateArgs['grandparent_authority'] or ''
taxonTable[4]['authority'] = g.templateArgs['greatgrandparent_authority'] or ''
taxonTable[5]['authority'] = g.templateArgs['greatgreatgrandparent_authority'] or '' ]]
-- determine when to force: when i<displayN and when infrataxons in i=2 and i=3 (why?)
for i= 1, displayN, 1 do -- use 'always_display' to flag a force
taxonTable[i]['always_display'] = "yes"
end
--[[check for lower infrataxons for i=4 and i=3 TODO verify this works
if g.isInfraTaxon(taxonTable[3]['rank']) then -- if i=3 an infrataxon
taxonTable[4]['always_display'] = "yes" -- then always display i=4
end
if g.isInfraTaxon(taxonTable[2]['rank']) then -- if i=2 an infrataxon
taxonTable[4]['always_display'] = "yes" -- then always display i=3 and i=4
taxonTable[3]['always_display'] = "yes"
end]]
local res = ''
-- generic display to replace >6, 5,4,3,2,1 sections
for i = taxonTable.n, 1, -1 do
if i==1 then boldFirst = "bold" end
res = res .. g.showTaxonRow(frame, i, boldFirst, virus)
--res = res .. g.showTaxonRow(frame, i, taxonTable[i]['taxon'], taxonTable[i]['authority'], taxonTable[i]['always_display'], boldFirst, virus)
end
return res
end
--[[ function to check if an infrarank (not major rank) that should be displayed
- emulates template Template:Infrataxon(), which uses Template:Principal rank
]]
function g.isPrincipalRank(rank)
-- Remove "ichno" and "oo" and then check for a major taxon ("oordo" becomes "rdo"):
rank = string.gsub(rank, "ichno", "")
rank = string.gsub(rank, "oo", "")
if rank == "regnum" or rank=="phylum" or rank=="divisio" or rank=="classis" or rank=="ordo" or rank=="rdo"
or rank=="familia" or rank=="genus" or rank=="species" or rank=="subspecies" or rank=="variety" then
return true
else
return false -- rank is an infrarank
end
--return not g.isInfraTaxon(rank)
end
function g.isInfraTaxon(rank)
--Remove "ichno" and "oo" and then check for a major taxon ("oordo" becomes "rdo"):
rank = string.gsub(rank, "ichno", "")
rank = string.gsub(rank, "oo", "")
if rank == "regnum" or rank=="phylum" or rank=="divisio" or rank=="classis" or rank=="ordo" or rank=="rdo"
or rank=="familia" or rank=="genus" or rank=="species" or rank=="subspecies" or rank=="variety" then
return false
else
return true -- rank is an infrarank
end
end
--[[ function g.showTaxonRow () - show a row of the taxonomy table
- emulates Template:Taxobox/showtaxon
- uses Template:Taxon link and Template:anglicise rank
]]
function g.showTaxonRow (frame, i, boldFirst, virus)
--[[ return frame:expandTemplate{ title = 'Template:Taxobox/showtaxon',
args = { g.taxonTable[i]['taxon'],
authority=g.taxonTable[i]['authority'],
fc = g.taxonTable[i]['always_display'],
format = boldFirst,
virus = virus } }
]]
-- do we want to display the taxon?
if g.taxonTable[i]['always_display'] == "yes" -- the flag for whether to force display a taxon
or g.taxonTable[i]['always_display'] == "true"
or g.isPrincipalRank(g.taxonTable[i]['rank']) then -- or major ranks
-- continue
else --if g.isInfraTaxon(g.taxonTable[i]['rank']) then -- or a major rank (=not a minor rank)
return ""
end
--{{Taxon link|{{{1|Ursa}}}|bold={{#ifeq:{{{format|link}}}|bold|yes|no}}|virus={{{virus|no}}}}}
local bold = "no"
if boldFirst == "bold" then bold = "yes" end
--taxon name
local taxonName = g.taxonTable[i]['taxon'] -- plain name
local rank = g.taxonTable[i]['rank']
if rank == "species" or rank == "subspecies" or rank == "variety" then
-- no processing of name necessary (already set to species_name, subspecies_name, etc)
else
taxonName = frame:expandTemplate{ title = "Taxon link",
args = { taxonName, bold=bold, virus=virus } }
end
--rank
local taxonRank = g.taxonTable[i]['rank']
taxonRank = frame:expandTemplate{ title = "anglicise rank", args = { g.taxonTable[i]['rank'] } }
if g.taxonTable[i]['rank'] == "virus_group" then
taxonName = frame:expandTemplate{ title = "Virus group", args = { g.taxonTable[i]['taxon'] } }
-- taxonRank = "Group" -- handled by anglicise rank template
end
local authorityString = ''
if g.taxonTable[i]['authority'] and g.taxonTable[i]['authority'] ~= "" then
authorityString = '<br /><small>'.. g.taxonTable[i]['authority'] ..'</small>'
end
--[[ now output the html
the autotaxobox templates had already started a new row and ended with new row
this was the stumbling block for the nodal approach uing the Lua html library (mw.html)
which required the embedded table
]]
-- new method append row to the table structure using mw:html library
local row =g.htmlTable:tag('tr')
local cell = row:tag('td'):wikitext(taxonRank .. ":"..i)
cell = row:tag('td'):wikitext(taxonName .. authorityString)
-- old method: return wikitext for table row
local rowWiki = '\n|-\n|'..taxonRank .. ':' .. i .. '||' .. taxonName .. authorityString
--return row .. '\n|-' -- return with new row started
return rowWiki -- so don't start the new row
end
return p