Gaan na inhoud

Module:Autotaxobox

in Wikipedia, die vrye ensiklopedie

Dokumentasie vir hierdie module kan geskep word by:Module:Autotaxobox/doc

--[[*************************************************************************
This module provides support to the automated taxobox system – the templates
Automatic taxobox, Speciesbox, Subspeciesbox, Infraspeciesbox, etc.

In particular it provides a way of traversing the taxonomic hierarchy encoded
in taxonomy templates (templates with names of the form
"Template:Taxonomy/TAXON_NAME" ) without causing template expansion depth
errors.
*****************************************************************************]]

require('strict')
localTaxonItalics=require('Module:TaxonItalics')-- use a function from Module:TaxonItalics to italicize a taxon name
localTableRow='|-\n'
localTableEnd='|}\n'
localp={}-- functions made public
locall={}-- internal functions, kept separate
localcolour=''-- colour for taxobox and taxonomy listings

--[[=========================================================================
Limit the maximum depth of a taxonomic hierarchy that can be traversed;
avoids excessive processing time and protects against incorrectly set up
hierarchies, e.g. loops.
The value can be obtained externally via
{{#invoke:Autotaxobox|getMaxSearchLevels}}
=============================================================================]]
localMaxSearchLevels=100

functionp.getMaxSearchLevels()
returnMaxSearchLevels
end

--[[========================== taxoboxColour ================================
Determines the correct colour for a taxobox, by searching up the taxonomic
hierarchy from the supplied taxon for the first taxon (other than
'incertae sedis') that sets a taxobox colour. It is assumed that a valid
taxobox colour is defined using CSS rgb() syntax.
If no taxon that sets a taxobox colour is found, then 'transparent' is
returned unless the taxonomic hierarchy is too deep, when the error colour is
returned.
Usage: {{#invoke:Autotaxobox|taxoboxColour|TAXON}}
=============================================================================]]
functionp.taxoboxColour(frame)
returnp.getTaxoboxColour(frame,frame.args[1]or'')
end

functionp.getTaxoboxColour(frame,currTaxon)
-- note that colour is global to this function; default is empty string
locali=1-- count levels processed
localsearching=currTaxon~=''-- still searching for a colour?
localfoundICTaxon=false-- record whether 'incertae sedis' found
whilesearchingandi<=MaxSearchLevelsdo
localplainCurrTaxon,dummy=l.stripExtra(currTaxon)-- remove trailing text after /
ifstring.lower(plainCurrTaxon)=='incertae sedis'then
foundICTaxon=true
else
localpossibleColour=frame:expandTemplate{title='Sjabloon:Taksobokskleur',args={plainCurrTaxon}}
ifstring.sub(possibleColour,1,3)=='rgb'then
colour=possibleColour
searching=false
end
end
ifsearchingthen
localok,parent=p.getTaxonInfoItem(frame,currTaxon,'parent')
ifokandparent~=''then
currTaxon=parent
i=i+1
else
searching=false-- run off the top of the hierarchy or tried to use non-existent taxonomy template
end
end
end
ifcolour==''then
iffoundICTaxonthen
colour=frame:expandTemplate{title='Sjabloon:Taksobokskleur',args={'incertae sedis'}}
elseifsearchingthen
-- hierarchy exceeds MaxSearchLevels levels
colour=frame:expandTemplate{title='Sjabloon:Taksoboks/Foutkleur',args={}}
else
colour='transparent'
end
end
returncolour
end

--[[= = = = = = = = = = = = = topLevelTaxon = = = = = = = = = = = = = = = =
Defines the correct top level taxa, one of which should terminate every
taxonomic hierarchy encoded in taxonomy templates.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.topLevelTaxon(taxon)
returntaxon=='Life'ortaxon=='Veterovata'ortaxon=='Ichnos'ortaxon=='Lewe'
end

--[[=========================== taxoboxList =================================
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
}}
=============================================================================]]
functionp.taxoboxList(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''thenreturn''end
localdisplayN=(tonumber(frame.args['display_taxa'])or1)+1
localauthTable={}
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''
localboldFirst=frame.args['bold_first']or'link'-- values 'link' or 'bold'
localvirus=frame.args['virus']or'no'-- values 'yes' or 'no'
localoffset=tonumber(frame.args['offset']or0)
-- adjust the authority table if 'authority' refers to a rank lower than the target taxon
ifoffset~=0then
fori=1,5do
localj=i+offset
ifj<=5then
authTable[i]=authTable[j]
else
authTable[i]=''
end
end
end
localtaxonTable,taxonRankTable=l.makeTable(frame,currTaxon)
localres=''
localtopTaxonN=taxonTable.n
-- display all taxa above possible greatgreatgrandparent, without authority
fori=topTaxonN,6,-1do
res=res..l.showTaxon(frame,taxonTable[i],taxonRankTable[i],topTaxonN==i,'',displayN>=i,'',virus)
end
-- display all taxa above possible parent, with authority if given
fori=math.min(topTaxonN,5),2,-1do
res=res..l.showTaxon(frame,taxonTable[i],taxonRankTable[i],topTaxonN==i,authTable[i],displayN>=i,'',virus)
end
-- display target taxon, always displayed and emboldened
res=res..l.showTaxon(frame,taxonTable[1],taxonRankTable[1],topTaxonN==1,authTable[1],true,boldFirst,virus)
returnres
end

--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Show one taxon row in a taxobox.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.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" )
ifisTopTaxonthen
ifl.topLevelTaxon(taxon)then
return''-- don't display a top level taxon
elseifmw.title.new('Taksonomie/'..taxon,'Sjabloon').existsthen
-- taxonomy template for this taxon has no parent specified
returnframe:expandTemplate{title='Sjabloon:Create taxonomy',args={taxon,msg='Taxonomy template does not specify a parent'}}..'\n'..TableRow
else
-- no taxonomy template for this taxon
returnframe:expandTemplate{title='Sjabloon:Create taxonomy',args={taxon,msg='Taksonomiesjabloon ontbreek'}}..'\n'..TableRow
end
else
-- if showing is not already forced, force if it's a principal rank or an authority is specified
force=forceorframe:expandTemplate{title='Sjabloon:Principal rank',args={rank}}=='yes'or
auth~=''
ifnotforcethen
-- if showing is still not already forced, force if the taxonomy template has 'always_display' set
localok,alwaysDisplay=p.getTaxonInfoItem(frame,taxon,'always_display')
force=alwaysDisplay=='yes'oralwaysDisplay=='true'
end
ifforcethen
localres=l.tableCell(frame:expandTemplate{title='Sjabloon:Anglicise rank',args={rank}}..':')
localbold='no'
ifboldFirst=='bold'thenbold='yes'end
ifauth~=''then
auth='<br><small>'..auth..'</small>'
end
localres=res..l.tableCell(l.getTaxonLink(frame,taxon,rank,bold,'','',virus)..auth)-- italic, abbreviated
returnres..TableRow
else
return''
end
end
end

--[[========================== taxonomyList =================================
Returns the cells of the taxonomy table displayed on the right hand side of
"Template:Taxonomy...." pages.
Usage: {{#invoke:Autotaxobox|taxonomyList|TAXON}}
=============================================================================]]
functionp.taxonomyList(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''then
return'{|class= "infobox biota"\n'..TableRow..l.tableCell('')..l.tableCell('ERROR: no taxon supplied')..TableEnd
end
localtaxonTable,taxonRankTable=l.makeTable(frame,currTaxon)
localrankValTable=l.getRankTable()
locallastRankVal=1000000
localorderOk=true
-- check whether the taxonomy is for viruses; use already determined taxon colour if possible
localvirus='no'
localtaxoColour=colour
iftaxoColour==''then
iftaxonTable[taxonTable.n]=='Ichnos'ortaxonTable[taxonTable.n]=='Veterovata'then
taxoColour=frame:expandTemplate{title='Sjabloon:Taksobokskleur',args={taxonTable[taxonTable.n]}}
else
taxoColour=frame:expandTemplate{title='Sjabloon:Taksobokskleur',args={taxonTable[taxonTable.n-1]}}
end
end
iftaxoColour==frame:expandTemplate{title='Sjabloon:Taksobokskleur',args={'virus'}}then
virus='yes'
end
-- add information message
localres='<p style= "float:right" >Bold ranks show taxa that will be shown in taxoboxes<br>because rank is principal or <code>always_display=yes</code>.</p>\n'

-- start table
res=res..'{| class= "infobox biota" style= "text-align: left; font-size:100%"\n'..TableRow..'! colspan=4 style= "text-align: center; background-color: '
..taxoColour..' "|Voorvaderlike taksa\n'
-- deal first with the top level taxon; if there are no errors, it should be Life/Veterovata/Ichnos, which are
-- not displayed
localtaxon=taxonTable[taxonTable.n]
ifnotl.topLevelTaxon(taxon)then
localmsg='Taxonomy template missing'
ifmw.title.new('Taksonomie/'..taxon,'Sjabloon').existsthen
msg='Parent taxon needed'
end
res=res..TableRow..l.tableCell('colspan=2',frame:expandTemplate{title='Sjabloon:Create taxonomy',args={taxon,msg=msg}})
end
-- now output the rest of the table
localcurrRankVal
fori=taxonTable.n-1,1,-1do
-- check ranks are in right order in the hierarchy
taxon=taxonTable[i]
localrank=taxonRankTable[i]
currRankVal=l.lookupRankVal(rankValTable,rank)
ifcurrRankValthen
orderOk=currRankVal<lastRankVal
iforderOkthenlastRankVal=currRankValend
else
orderOk=true
end
-- see if the row will be displayed in a taxobox; bold the rank if so
localboldRank=false
localok,alwaysDisplay=p.getTaxonInfoItem(frame,taxon,'always_display')
ifokand(alwaysDisplay=='yes'oralwaysDisplay=='true')then
boldRank=true
else
boldRank=frame:expandTemplate{title='Sjabloon:Principal rank',args={rank}}=='yes'
end
-- now return a row of the taxonomy table with anomalous ranks marked
localerrorStr=''
ifnotorderOkthenerrorStr='yes'end
locallink=l.getTaxonLink(frame,taxon,rank,'','','',virus)-- bold, italic, abbreviated
res=res..l.taxonomyListRow(frame,taxon,rank,link,boldRank,errorStr)
end
-- close table
res=res..TableEnd
-- error-tracking for taxonomy templates
-- if the last row has an anomalous rank, put the page in an error-tracking category
localerrCat1=''
ifnotorderOkthen
errCat1='[[Category:Taxonomy templates showing anomalous ranks]]\n'
end
-- if the last row has a taxon name in the page name that does not match the link text,
-- put the taxonomy template in a tracking category
localdummy,linkText=p.getTaxonInfoItem(frame,taxon,'link_text')
localmatch=l.matchTaxonLink(taxon,linkText,currRankValandcurrRankVal<rankValTable['genus'])
localerrCat2=''
ifnotmatchthen
errCat2='[[Category:Taxonomy templates with name and link text not matching|'..taxon..']]\n'
end
iferrCat1..errCat2~=''then
res=res..frame:expandTemplate{title='Template other',args={errCat1..errCat2}}
end
returnres
end

--[[ = = = = = = = = = = = = = = taxonomyListRow = = = = = = = = = = = = = =
Returns a single row of the taxonomy table displayed on the right hand side
of "Template:Taxonomy...." pages.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.taxonomyListRow(frame,taxon,rank,link,boldRank,error)
localres=''
iftaxon==''orrank==''thenreturnresend
localbaseTaxon,qualifier=l.stripExtra(taxon)
-- if appropriate, make it clear that some taxa have been skipped via a... row
ifqualifier=='/skip'then
res=res..TableRow..l.tableCell('.....')..l.tableCell('.....')
end
-- now generate a row of the table
res=res..TableRow
localcellContent=''
localanglicizedRank=frame:expandTemplate{title='Sjabloon:Vulgêre rang',args={rank}}
ifboldRankthen
cellContent=cellContent..'<b>'..anglicizedRank..'</b>:'
else
cellContent=cellContent..anglicizedRank..':'
end
iferror=='yes'then
cellContent='<span style= "background-color:#FDD" >'..cellContent..'</span>'
end
res=res..l.tableCell(cellContent)
..l.tableCell('<span style= "white-space:nowrap;" >'..link..'</span>')
..l.tableCell('<span style= "font-size:smaller;" >'..qualifier..'</span>')
..l.tableCell('<span style= "white-space:nowrap;" >'..frame:expandTemplate{title='Sjabloon:Edit a taxon',args={taxon}}..'</span>')
returnres
end

--[[========================= callTaxonomyKey ===============================
Prepares for, and then calls, Template:Taxonomy key to display a taxonomy
template page. It does this by building up the information the template
requires, following one 'same as' link, if required.
Usage:
{{#invoke:Autotaxobox|callTaxonomyKey
|parent=
|rank=
|extinct=
|always_display=
|link_target=value of 'link' parameter in taxonomy template
|link_text=value of parameter 2 in taxonomy template
|same_as=
}}
=============================================================================]]
localPARENT=1
localRANK=2
localLINK_TARGET=3
localLINK_TEXT=4
localALWAYS_DISPLAY=5
localEXTINCT=6
localSAME_AS=7
localREFS=8

functionp.callTaxonomyKey(frame)
localtaxon=frame.args['taxon']or''
localparent=frame.args['parent']or''
localrank=frame.args['rank']or''
localextinct=string.lower(frame.args['extinct'])or''
localalwaysDisplay=string.lower(frame.args['always_display'])or''
locallinkTarget=frame.args['link_target']or''
locallinkText=frame.args['link_text']or''-- this is the "raw" link text, and can be ''
localrefs=frame.args['refs']or''
localsameAsTaxon=frame.args['same_as']or''
ifsameAsTaxon~=''then
-- try using the 'same as' taxon; it's an error if it doesn't exist
localok,sameAsInfoStr=pcall(frame.expandTemplate,frame,{title='Sjabloon:Taksonomie/'..sameAsTaxon,args={['machine code']='all'}})
ifokthen
localsameAsInfo=mw.text.split(sameAsInfoStr,'$',true)
--'same as' taxon's taxonomy template must not have a 'same as' link
ifsameAsInfo[SAME_AS]==''then
ifparent==''thenparent=sameAsInfo[PARENT]end
ifrank==''thenrank=sameAsInfo[RANK]end
ifextinct==''thenextinct=string.lower(sameAsInfo[EXTINCT])end
ifalwaysDisplay==''thenalwaysDisplay=string.lower(sameAsInfo[ALWAYS_DISPLAY])end
iflinkTarget==''thenlinkTarget=sameAsInfo[LINK_TARGET]end
iflinkText==''thenlinkText=sameAsInfo[LINK_TEXT]end
ifrefs==''andparent==sameAsInfo[PARENT]thenrefs=sameAsInfo[REFS]end
else
return'<span style= "color:red; font-size:1.1em" >Error: attempt to follow two "same as" links</span>: <code>same_as = '..sameAsTaxon..'</code>, but [[Sjabloon:Taksonomie/'..sameAsTaxon..']] also has a<code>same_as</code> parameter.'
end
else
returnframe:expandTemplate{title='Sjabloon:Taxonomy key/missing template',args={taxon=sameAsTaxon,msg='given as the value of <code>same as</code>'}}
end
end
locallink=linkTarget
iflinkText~=''andlinkText~=linkTargetthenlink=link.."|"..linkTextend
-- check consistency of extinct status; if this taxon is not extinct, parent must not be either
localextinctError='no'
ifparent~=''and(extinct==''orextinct=='no'orextinct=='false')then
localok,parentExtinct=p.getTaxonInfoItem(frame,parent,'extinct')
ifokand(parentExtinct=='yes'orparentExtinct=='true')thenextinctError='yes'end
end
returnframe:expandTemplate{title='Sjabloon:Taxonomy key',
args={taxon=taxon,parent=parent,rank=rank,extinct=extinct,always_display=alwaysDisplay,link_target=linkTarget,link=link,refs=refs,same_as=sameAsTaxon,extinct_error=extinctError}}
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}}
=============================================================================]]
functionp.showRefs(frame)
localtaxonName=frame.args[1]or''
localrefs=frame.args[2]or''
returnl.doShowRefs(taxonName,refs)
end

--[[= = = = = = = = = = = = = = doShowRefs = = = = = = = = = = = = = = = = =
Show the refs field in a taxonomy template.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.doShowRefs(taxonName,refs)
ifmw.text.split(taxonName,'/',true)[1]=='Incertae sedis'then
refs='not applicable (<i>incertae sedis</i>)'
elseifrefs==''then
refs='–'
end
returnrefs
end

--[[============================ taxonInfo ==================================
Extracts and returns information from Template:Taxonomy/TAXON, following
one 'same as' link if required.
Usage: {{#invoke:Autotaxobox|taxonInfo|TAXON|ITEM}}
ITEM is one of: 'parent', 'rank', 'link target', 'link text', 'extinct',
'always display', 'refs', 'same as' or 'all'.
If ITEM is not specified, the default is 'all' – all values in a single string
separated by '$'.
=============================================================================]]
functionp.taxonInfo(frame)
localtaxon=frame.args[1]or''
localitem=frame.args[2]or''
ifitem==''thenitem='all'end
localok,info=p.getTaxonInfoItem(frame,taxon,item)
returninfo
end

--[[= = = = = = = = = = = getTaxonInfoItem = = = = = = = = = = = = = = = = =
Utility function to extract an item of information from a
taxonomy template, following one 'same as' link if required.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionp.getTaxonInfoItem(frame,taxon,item)
localok,info
-- item == 'dagger' is a special case
ifitem=='dagger'then
ok,info=p.getTaxonInfoItem(frame,taxon,'extinct')
ifokthen
ifinfo=='yes'orinfo=='true'then
info='&dagger;'
else
info=''
end
end
-- item ~= 'dagger'
else
ok,info=pcall(frame.expandTemplate,frame,{title='Sjabloon:Taksonomie/'..taxon,args={['machine code']=item}})
ifokthen
ifinfo==''then
-- try 'same as'
localsameAsTaxon=frame:expandTemplate{title='Sjabloon:Taksonomie/'..taxon,args={['machine code']='same as'}}
ifsameAsTaxon~=''then
ok,info=pcall(frame.expandTemplate,frame,{title='Sjabloon:Taksonomie/'..sameAsTaxon,args={['machine code']=item}})
end
end
end
end
ifokthen
-- if item is 'link_text', trim info and check whether '(?)' needs to be added
ifitem=='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)
ifstring.sub(taxon,-2)=='/?'andnotstring.find(info,'?',1,true)then
info=info..'<span style= "font-style:normal;font-weight:normal;" > (?)</span>'
end
end
else
info='[[Sjabloon:Taksonomie/'..taxon..']]'--error indicator in code before conversion to Lua
end
returnok,info
end

--[[============================ taxonLink ==================================
Returns a wikilink to a taxon, if required including '†' before it and
' (?)' after it, and optionally italicized or bolded without a wikilink.
Usage:
{{#invoke:Autotaxobox|taxonLink
|taxon=: having '/?' at the end triggers the output of ' (?)'
|extinct=: 'yes' or 'true' trigger the output of '†'
|bold=: 'yes' makes the core output bold and not wikilinked
|italic=: 'yes' makes the core output italic
|link_target=: target for the wikilink
|link_text=: text of the wikilink (may be same as link_target), without †, italics, etc.
}}
=============================================================================]]
functionp.taxonLink(frame)
localtaxon=frame.args['taxon']or''
localextinct=string.lower(frame.args['extinct']or'')
localbold=frame.args['bold']or''
localitalic=frame.args['italic']or''
localabbreviated=frame.args['abbreviated']or''
locallinkTarget=frame.args['link_target']or''
locallinkText=frame.args['link_text']orframe.args['plain_link_text']or''--temporarily allow alternative args
returnl.makeLink(taxon,extinct,bold,italic,abbreviated,linkTarget,linkText)
end

--[[= = = = = = = = = = = = = = getTaxonLink = = = = = = = = = = = = = = = =
Internal function to drive l.makeLink().
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.getTaxonLink(frame,taxon,rank,bold,italic,abbreviated,virus)
localok,extinct=p.getTaxonInfoItem(frame,taxon,'extinct')
ifitalic==''then
italic=frame:expandTemplate{title='Sjabloon:Is italic taxon',args={rank,virus=virus}}
end
localok,linkTarget=p.getTaxonInfoItem(frame,taxon,'link_target')
localok,linkText=p.getTaxonInfoItem(frame,taxon,'link_text')
returnl.makeLink(taxon,extinct,bold,italic,abbreviated,linkTarget,linkText)
end

--[[= = = = = = = = = = = = = = makeLink = = = = = = = = = = = = = = = = = =
Actually make the link.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.makeLink(taxon,extinct,bold,italic,abbreviated,linkTarget,linkText)
localdummy
-- if link text is missing, try to find a replacement
iflinkText==''then
ifstring.find(taxon,'Incertae sedis',1,true)then
linkText="''incertae sedis''"
linkTarget='Incertae sedis'
else
linkText,dummy=l.stripExtra(taxon)
end
end
iflinkTarget==''thenlinkTarget=linkTextend
ifitalic=='yes'thenlinkText=TaxonItalics.italicizeTaxonName(linkText,false,abbreviated=='yes')end
locallink=''
ifbold=='yes'thenlink='<b>'..linkText..'</b>'
else
iflinkTarget==linkTextthenlink=linkText
elselink=linkTarget..'|'..linkText
end
link='[['..link..']]'
end
if(extinct=='yes'orextinct=='true')andnotstring.find(link,'†',1,true)then
link='<span style= "font-style:normal;font-weight:normal;" >†</span>'..link
end
ifstring.sub(taxon,-2)=='/?'andnotstring.find(link,'?',1,true)then
link=link..'<span style= "font-style:normal;font-weight:normal;" > (?)</span>'
end
returnlink
end

--[[========================== showRankTable ================================
Returns a wikitable showing the ranks and their values as set up by
getRankTable().
Usage: {{#invoke:Autotaxobox|showRankTable}}
=============================================================================]]
functionp.showRankTable(frame)
localrankTable=l.getRankTable()
localres='{| class= "wikitable sortable"\n|+ Ranks checked in taxonomy templates\n!Rank!! Shown as!! Value\n'
fork,vinpairs(rankTable)do
localrankShown=frame:expandTemplate{title='Sjabloon:Anglicise rank',args={k}}
res=res..TableRow..l.tableCell(k)..l.tableCell(rankShown)..l.tableCell(v)
end
returnres..TableEnd
end

--[[============================== find =====================================
Returns the taxon above the specified taxon with a given rank.
Usage: {{#invoke:Autotaxobox|find|TAXON|RANK}}
=============================================================================]]
functionp.find(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''thenreturn'<span class= "error" >no taxon supplied</span>'end
localrank=frame.args[2]or''
ifrank==''thenreturn'<span class= "error" >no rank supplied</span>'end
localinHierarchy=true-- still in the taxonomic hierarchy or off the top?
localsearching=true-- still searching
whileinHierarchyandsearchingdo
localok,parent=p.getTaxonInfoItem(frame,currTaxon,'parent')
ifokandparent~=''then
currTaxon=parent
localok,currRank=p.getTaxonInfoItem(frame,currTaxon,'rank')
ifcurrRank==rankthen
searching=false
end
else
inHierarchy=false
end
end
ifinHierarchyandnotsearchingthenreturncurrTaxon
elsereturn'<span class= "error" >rank not found</span>'
end
end

--[[=============================== nth =====================================
External utility function primarily intended for use in checking and debugging.
Returns the nth level above a taxon in a taxonomic hierarchy, where the taxon
itself is counted as the first level.
Usage: {{#invoke:Autotaxobox|nth|TAXON|n=N}}
=============================================================================]]
functionp.nth(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''thenreturn'ERROR: no taxon supplied'end
localn=tonumber(frame.args['n']or1)
ifn>MaxSearchLevelsthen
return'Exceeded maximum number of levels allowed ('..MaxSearchLevels..')'
end
locali=1
localinHierarchy=true-- still in the taxonomic hierarchy or off the top?
whilei<nandinHierarchydo
localok,parent=p.getTaxonInfoItem(frame,currTaxon,'parent')
ifokandparent~=''then
currTaxon=parent
i=i+1
else
inHierarchy=false
end
end
ifinHierarchythenreturncurrTaxon
elsereturn'Level '..n..' is past the top of the taxonomic hierarchy'
end
end

--[[============================= nLevels ===================================
External utility function primarily intended for use in checking and debugging.
Returns number of levels in a taxonomic hierarchy, starting from
the supplied taxon as level 1.
Usage: {{#invoke:Autotaxobox|nLevels|TAXON}}
=============================================================================]]
functionp.nLevels(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''thenreturn'ERROR: no taxon supplied'end
locali=1
localinHierarchy=true-- still in the taxonomic hierarchy or off the top?
whileinHierarchyandi<MaxSearchLevelsdo
localok,parent=p.getTaxonInfoItem(frame,currTaxon,'parent')
ifokandparent~=''then
currTaxon=parent
i=i+1
else
inHierarchy=false
end
end
ifinHierarchythenreturnMaxSearchLevels..'+'
elsereturni
end
end

--[[============================= listAll ===================================
External utility function primarily intended for use in checking and debugging.
Returns a comma separated list of a taxonomic hierarchy, starting from
the supplied taxon.
Usage: {{#invoke:Autotaxobox|listAll|TAXON}}
=============================================================================]]
functionp.listAll(frame)
localcurrTaxon=frame.args[1]or''
ifcurrTaxon==''thenreturn'ERROR: no taxon supplied'end
returnl.doListAll(l.makeTable(frame,currTaxon))
end

functionl.doListAll(taxonTable,taxonRankTable)
locallst=taxonTable[1]..'-'..tostring(taxonRankTable[1])
fori=2,taxonTable.n,1do
lst=lst..', '..taxonTable[i]..'-'..taxonRankTable[i]
end
returnlst
end

--[[=========================== removeQualifier ================================
External utility function to remove a qualifier (any part after a "/" ) from a
taxon name.
Usage: {{#invoke:Autotaxobox|removeQualifier|TAXON}}
=============================================================================]]
functionp.removeQualifier(frame)
localbaseName,qualifier=l.stripExtra(frame.args[1])
returnbaseName
end

--[[=========================================================================
Internal functions
=============================================================================]]

--[[= = = = = = = = = = = = stripExtra = = = = = = = = = = = = = = = = = = =
Internal utility function to strip off any extra parts of a taxon name, i.e.
anything after a '/'. Thus 'Felidae/?' would be split into 'Felidae' and '?'.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.stripExtra(taxonName)
locali=mw.ustring.find(taxonName,'/',1,true)
ifithen
returnmw.ustring.sub(taxonName,1,i-1),mw.ustring.sub(taxonName,i,-1)
else
returntaxonName,''
end
end

--[[= = = = = = = = = = = = splitTaxonName = = = = = = = = = = = = = = = = =
Internal utility function to split a taxon name into its parts and return
them. Possible formats include:
* taxon
* taxon (disambig)
* taxon (Subgenus)
* taxon/qualifier
* combinations, e.g. taxon (disambig)/qualifier
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.splitTaxonName(taxon)
-- get any qualifier present
localqualifier=''
locali=mw.ustring.find(taxon,'/',1,true)
ifithen
qualifier=mw.ustring.sub(taxon,i+1,-1)
taxon=mw.ustring.sub(taxon,1,i-1)
end
-- get any disambiguator or subgenus
localdisambig=''
localsubgenus=''
i=mw.ustring.find(taxon,' (',1,true)
ifithen
localparenTerm=mw.ustring.sub(taxon,i+2,-2)
taxon=mw.ustring.sub(taxon,1,i-1)
localchar1=mw.ustring.sub(parenTerm,1,1)
ifchar1==mw.ustring.lower(char1)then
disambig=parenTerm
else
subgenus=parenTerm
end
end
returntaxon,disambig,subgenus,qualifier
end

--[[= = = = = = = = = = = = matchTaxonLink = = = = = = = = = = = = = = = = =
Function to determine whether the taxon name derived from the name of the
taxonomy template (passed in the parameter taxon) matches the link text
(passed in the parameter linkText).
The taxon name may have any of the formats:
* baseTaxon/qualifier
* baseTaxon (disambig)
* baseTaxon (Subgenus) [distinguished by the capital letter]
* a qualifier may be present after the previous two formats.

Examples of matches (baseTaxon ~ linkText):
* Pinus ~ Pinus
* Pinus sect. Trifoliae ~ Pinus sect. Trifoliae
* Pinus sect. Trifoliae ~ ''Pinus'' sect. ''Trifoliae'' [italic markers ignored]
* Pinus sect. Trifoliae ~ P. sect. Trifoliae [abbreviated genus name matches]
* Bombus (Pyrobombus) ~ Bombus (Pyrobombus)
* Bombus (Pyrobombus) ~ B. (Pyrobombus)
* Bombus (Pyrobombus) ~ Pyrobombus [link text may just be the subgenus]
* Heteractinida ~ "Heteractinida" [double-quotes are ignored in link text]
* "Heteractinida" ~ Heteractinida [double-quotes are ignored in base taxon name]
* Incertae sedis ~ anything [link text is ignored for matching in this case]
* Cetotheriidae with qualifier=? ~ Cetotheriidae (?)
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.matchTaxonLink(taxon,linkText,rankBelowGenus)
localdummy
linkText,dummy=mw.ustring.gsub(linkText,"''",'')-- remove any italic wikitext in the link text
linkText,dummy=mw.ustring.gsub(linkText,'<.->','')-- strip all tags used to format the link text
linkText,dummy=mw.ustring.gsub(linkText,' "','')-- remove any occurrences of "in the link text
localbaseTaxon,disambig,subgenus,qualifier=l.splitTaxonName(taxon)-- split up the taxon name
baseTaxon,dummy=mw.ustring.gsub(linkText,' "','')-- remove any occurrences of "in the base taxon name
localmatch=linkText==baseTaxonor
linkText==subgenusor
linkText==baseTaxon..' ('..subgenus..')'or
linkText==mw.ustring.sub(baseTaxon,1,1)..'. ('..subgenus..')'or
baseTaxon=='Incertae sedis'or
rankBelowGenusandlinkText==mw.ustring.gsub(baseTaxon,'([A-Z]).- (.*)','%1. %2')or
mw.ustring.find(qualifier,'?',1,true)andmw.ustring.find(linkText,baseTaxon,1,true)==1
returnmatch
end

--[[= = = = = = = = = = = = = makeTable = = = = = = = = = = = = = = = = = = =
Internal utility function to return a table (array) constructed from a
taxonomic hierarchy stored in "Template:Taxonomy/..." templates.
TABLE.n holds the total number of taxa; TABLE[1]..TABLE[TABLE.n] the taxon
names.
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.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.makeTable(frame,currTaxon)
localtaxonTable={}
localtaxonRankTable={}
localok,rank,parent
locali=1
localtopReached=false-- reached the top of the taxonomic hierarchy?
repeat
taxonTable[i]=currTaxon
ok,rank=p.getTaxonInfoItem(frame,currTaxon,'rank')
ifokthentaxonRankTable[i]=string.lower(rank)elsetaxonRankTable[i]=''end
ok,parent=p.getTaxonInfoItem(frame,currTaxon,'parent')
ifokandparent~=''then
currTaxon=parent
i=i+1
else
topReached=true-- reached the top of the hierarchy or tried to use a non-existent taxonomy template
end
untiltopReachedori>MaxSearchLevels
taxonTable.n=math.min(i,MaxSearchLevels)
returntaxonTable,taxonRankTable
end

--[[= = = = = = = = = = = = getRankTable = = = = = = = = = = = = = = = = = =
Internal utility function to set up a table of numerical values corresponding
to 'Linnaean' ranks, with upper ranks having higher values. In a valid
taxonomic hierarchy, a lower rank should never have a higher value than a
higher rank. The actual numerical values are arbitrary so long as they are
ordered.
The ranks should correspond to those in Template:Anglicise ranks.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.getRankTable()
return{
classis=1400,
cohort=1100,
divisio=1500,
domain=1700,
familia=800,
forma=100,
genus=600,
grandordo=1005,
['grandordo-mb']=1002,
hyperfamilia=805;
infraclassis=1397,
infralegio=1197,
infraordo=997,
infraphylum=1497,
infraregnum=1597,
infratribus=697,
legio=1200,
magnordo=1006,
microphylum=1495,
micrordo=995,
mirordo=1004,
['mirordo-mb']=1001,
nanophylum=1494,
nanordo=994,
ordo=1000,
parafamilia=800,
parvclassis=1396;-- same as subterclassis
parvordo=996,
phylum=1500,
regnum=1600,
sectio=500,
--series = 400, used too inconsistently to check
species=300,
subclassis=1398,
subcohort=1098,
subdivisio=1498,
subfamilia=798,
subgenus=598,
sublegio=1198,
subordo=998,
subphylum=1498,
subregnum=1598,
subsectio=498,
subspecies=298,
subterclassis=1396;-- same as parvclassis
subtribus=698,
superclassis=1403,
supercohort=1103,
superdivisio=1503,
superdomain=1703,
superfamilia=803,
superlegio=1203,
superordo=1003,
superphylum=1503,
superregnum=1603,
supertribus=703,
tribus=700,
varietas=200,
zoodivisio=1300,
zoosectio=900,
zoosubdivisio=1298,
zoosubsectio=898,
}
end

--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Function to look up the arbitrary numerical value of a rank in a rank value
table. "Ichno" and "oo" ranks are not stored separately, so if present the
prefix is removed.
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.lookupRankVal(rankValTable,rank)
localrankVal=rankValTable[rank]
ifnotrankValthen
-- may be an "ichno" or "oo" rank; try removing "ichno-" or "oo-"
localbaseRank=mw.ustring.gsub(mw.ustring.gsub(rank,'^ichno',''),'^oo','')
ifbaseRank=='rdo'thenbaseRank='ordo'end
-- if an "ichno" or "oo" rank, lower rank value slightly so it is ok below the base rank
rankVal=rankValTable[baseRank]
ifrankValthen
rankVal=rankVal-0.1
end
end
returnrankVal
end

--[[= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =]]
functionl.tableCell(arg1,arg2)
localtext,style
ifarg2then
style=arg1
text=arg2
else
style=''
text=arg1
end
localres='|'
ifstyle~=''then
res=res..style..'|'
end
returnres..text..'\n'
end

returnp