--NOTE: this module contains functions for generating the table structure of the clade tree:  
The main function is called by the template using the instruction; the three main functions are:
p.main - opens and closes table, loops through the children of node, main is invoked once and controls the rest, calling ...
p.addTaxon(childNumber, nodeLeaf) - the nuts and bolts; code dealing with each child node
p.addLabel(childNumber) - adds the label text  
now uses templatestyles  
require('strict')
local p = {}
local pargs = {} -- parent arguments
local lastNode=0
local nodeCount=0
local cladeCount=0
local leafCount=0
local templateStylesCount=0
local infoOutput
local reverseClade = false  
--============================== main function ===========================
-- main function, which will generate the table structure of the tree  
Test version:
Usage:
Template:CladeN  
Release version:
Usage:
Template:Clade  
function p.main  
local cladeString = ""
local maxChildren = 20 -- was 17 in the clade/cladex templates
local childNumber = 0
local childCount = 0 -- number of leaves in the clade (can use to set bottom of bracket in addTaxon
local totalCount = 0  
pargs = :getParent.args -- parent arguments  
infoOutput = p.getCladeTreeInfo -- get info about clade structure, e.g. lastNode (last |N= child number)  
-- add the templatestyles tag conditionally to reduce expansion size (currently diabled)
when added to every clade table, it increases post‐expand include size significantly
e.g. the Neosuchia page (or test version) is increase by about 8% (672 bytes each)
if template styles added to all pages there are 133 stripmarkers
with cladeCount==1 condition, this is reduced to 34
however cladeCount==1 condition interfers with fix for additional line due to parser bug T18700
killing the strip markers also removes backlinks to references using citation templates
---
--cladeString =mw.text.killMarkers( cladeString ) -- also kills off strip markers using citation templates
--cladeString = mw.text.unstrip(cladeString)
--if cladeCount==1 then
cladeString = cladeString .. :extensionTag('templatestyles', '',
{ src="Template:Clade/styles.css" }) .. '\n'
--end  
local tableStyle = .args.style or ""  
if tableStyle ~= "" then
table -- include style= in string to suppress empty style elements
end  
reverseClade =.args.reverse or pargs.reverse or false -- a global
--ENFORCE GLOBAL FOR DEVELOPMENT
--reverseClade = true  
local captionName = pargs['caption'] or ""
local captionStyle = pargs['captionstyle'] or ""  
-- add an element to mimick nowiki WORKS BUT DISABLE FOR DEMO PURPOSES
--cladeString = '<p></p>\n'  
-- open table
-- (-collapse causes problems (see talk) -- cladeString = cladeString .. '{|'
-- (before CSS styling) -- cladeString = cladeString .. '{|'
cladeString = cladeString .. '{|' .. tableStyle  
-- add caption
if captionName ~= "" then
cladeString = cladeString .. '\n|+|' .. captionName
end  
local moreNeeded = true
childNumber = 0
--lastNode = 0  
--get child elements (add more rows for each child of node; each child is two rows)
the function addTaxon is called to add the rows for each child element;
each child add two rows: the first cell of each row contains the label or sublabel (below the line label), respectively;
the second cell spans both rows and contains the leaf name or a new clade structure
a third cell on the top row is sometimes added to contain a group to the  
-- main loop
while childNumber < lastNode do -- use the last number determined in the preprocessing  
childNumber = childNumber + 1 -- so we start with 1
local nodeLeaf = pargs[tostring(childNumber)] or "" -- get data from |N=
local nodeLabel = pargs['label'..tostring(childNumber)] or "" -- get data from |labelN=  
local newickString = pargs['newick'..tostring(childNumber)] or "" -- get data from |labelN=
local listString = pargs['list'..tostring(childNumber)] or ""  
if listString ~= "" then
cladeString = cladeString .. '\n' .. p.addTaxon(childNumber, p.list(0, listString), nodeLabel, lastNode)
elseif newickString ~= "" then -- if using a newick string instead of a clade structure
newickString = p.processNewickString(newickString,childNumber)
if nodeLabel == "" then -- use labelN by default, otherwise use root name from Newick string
nodeLabel = p.getNewickOuterterm(newickString) -- need to use terminal part of newick string for label
end
cladeString = cladeString .. '\n' .. p.addTaxon(childNumber, p.newick(0, newickString), nodeLabel, lastNode)
--lastNode=lastNode+1 -- there is a counting problem with the newickstring
elseif nodeLeaf ~= "" then -- if the node contains a leaf name or clade structue
--if reverseClade2 then
-- cladeString = cladeString .. '\n' .. p.addTaxonReverse(childNumber, nodeLeaf, nodeLabel, lastNode)
--else
cladeString = cladeString .. '\n' .. p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)
--end
end
end  
local footerText = pargs['footer'] or ""
local footerStyle = pargs['footerstyle'] or ""  
if footerText ~= "" then
cladeString = cladeString .. '\n|-\n||<p>' .. footerText .. '</p>||'
-- note the footer causes a problem with tr:last-child so need either
-- (1) use <tfoot> but it is not allowed or incompatable
-- cladeString = cladeString .. '<tfoot><tr><td><p>' .. footerText .. '</p></td></tr></tfoot>'
-- (2) always add footer and use nth:last-child(2) but is this backwards compatible
-- (3) if footer= set the style inline for the last sublabel row (more a temp fix)
-- (4) set class for first and last element (DONE. Also works well with reverse class)
end  
-- close table (wikitext to close table)
cladeString = cladeString .. '\n|}'  
cladeString = p.addSubTrees(cladeString) -- add subtrees  
return cladeString
--return '<div>\n' .. cladeString .. '</div>'
end  
-- =============================function to add subtrees ==========================================  
function p.addSubTrees(cladeString)  
--local pargs = mw.getCurrentFrame:getParent.args  
local suffix = { [1]="A", [2]="B", [3]="C", [4]="D", [5]="E", [6]="F", [7]="G", [8]="H", [9]="I", [10]="J",
[11]="K", [12]="L", [13]="M", [14]="N", [15]="O", [16]="P", [17]="Q", [18]="R", [19]="S", [20]="T",
[21]="U", [22]="V", [23]="W", [24]="X", [25]="Y", [26]="Z"}
for i=1, 26, 1 do
local subclade = pargs['subclade'..suffix[i]]
local target = pargs['target'..suffix[i]] or "SUBCLADE_" .. suffix[i]
if subclade then
if string.find(cladeString, target) then
cladeString = string.gsub(cladeString,target,subclade)
end
end
end
return cladeString
end
--2, |3 ...) use a to create the vertical line of the bracket
the first child element doesn't use a for the first cell in the top row (as it is above the bracket)
the last child doesn't use a for the first cell in the second row (as it is below the bracket)  
function p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)  
--colorN, |thicknessN, |stateN
the node parameters have no number, e.g. |color, |thickness, |state  
local nodeColor = pargs['color'] or "" -- don't set default to allow green on black gadget
local nodeThickness = tonumber(pargs['thickness']) or 1
local nodeState = pargs['state'] or "solid"
-- get formating parameters for branch (default to global nodeParameters)
local branchColor = pargs['color'..tostring(childNumber)] or nodeColor
local branchThickness = tonumber(pargs['thickness'..tostring(childNumber)]) or nodeThickness
local branchState = pargs['state'..tostring(childNumber)] or nodeState
if branchState == 'double' then
if branchThickness < 2 then branchThickness = 3 end -- need thick line for double
end  
local branchStyle = pargs['style'..tostring(childNumber)] or ""
local branchLength = pargs['length'] or pargs['length'..tostring(childNumber)] or ""  
-- the takes node parameters, the bottom takes branch parameters
-- this has coding on the colours for green on black
local bottomBorder = tostring(branchThickness) ..'px ' .. branchState .. (branchColor~="" and ' ' .. branchColor or '')