Jump to content

Module:Clade and Module:Clade/sandbox: Difference between pages

(Difference between pages)
Page 1
Page 2
Content deleted Content added
add div to allow overflow: '<div class="clade"> ... </div>'
 
Simplifications and some formatting improvements
 
Line 2: Line 2:


The main function is called by the template using the {{invoke}} instruction; the three main functions are:
The main function is called by the template using the {{invoke}} instruction; the three main functions are:
p.main(frame) - opens and closes table, loops through the children of node, main is invoked once and controls the rest, calling ...
p.main(frame) - 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.addTaxon(childNumber, nodeLeaf) - the nuts and bolts; code dealing with each child node
p.addLabel(childNumber) - adds the label text
p.addLabel(childNumber) - adds the label text
now uses templatestyles
now uses templatestyles
]]
]]
require('strict')
require('strict')
local getArgs = require('Module:Arguments').getArgs
local p = {}
local p = {}
local pargs = {} -- parent arguments
local pargs = {} -- parent arguments
Line 40: Line 39:
local totalCount = 0
local totalCount = 0
pargs = getArgs(frame) -- parent arguments
pargs = frame:getParent().args -- parent arguments
infoOutput = p.getCladeTreeInfo() -- get info about clade structure, e.g. lastNode (last |N= child number)
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)
--[[ add the templatestyles tag conditionally to reduce expansion size (currently diabled)
when added to every clade table, it increases post‐expand include size significantly
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)
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
if template styles added to all pages there are 133 stripmarkers
with cladeCount==1 condition, this is reduced to 34
with cladeCount==1 condition, this is reduced to 34
however cladeCount==1 condition interfers with fix for additional line due to parser bug T18700
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
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.killMarkers( cladeString ) -- also kills off strip markers using citation templates
--cladeString = mw.text.unstrip(cladeString)
--cladeString = mw.text.unstrip(cladeString)
--if cladeCount==1 then
--if cladeCount==1 then
cladeString = cladeString .. frame:extensionTag('templatestyles', '',
cladeString = cladeString .. frame:extensionTag('templatestyles', '',
{ src="Template:Clade/styles.css" }) .. '\n'
{ src="Template:Clade/sandbox/styles.css" }) .. '\n'
--end
--end
local tableStyle = frame.args.style or pargs.style or ""
local tableStyle = frame.args.style or ""


if tableStyle ~= "" then
if tableStyle ~= "" then
tableStyle = ' style="' .. tableStyle .. '"' -- include style= in string to suppress empty style elements
tableStyle = ' style="' .. tableStyle .. '"' -- include style= in string to suppress empty style elements
end
end
reverseClade =frame.args.reverse or pargs.reverse or false -- a global
reverseClade =frame.args.reverse or pargs.reverse or false -- a global
--ENFORCE GLOBAL FOR DEVELOPMENT
--ENFORCE GLOBAL FOR DEVELOPMENT
--reverseClade = true
--reverseClade = true


local captionName = pargs['caption'] or ""
local captionName = pargs['caption'] or ""
local captionStyle = pargs['captionstyle'] or ""
local captionStyle = pargs['captionstyle'] or ""


-- add an element to mimick nowiki WORKS BUT DISABLE FOR DEMO PURPOSES
-- add an element to mimick nowiki WORKS BUT DISABLE FOR DEMO PURPOSES
--cladeString = '<p class="mw-empty-elt"></p>\n'
--cladeString = '<p class="mw-empty-elt"></p>\n'
-- open table
-- open table
-- (border-collapse causes problems (see talk) -- cladeString = cladeString .. '{| style="border-collapse:collapse;border-spacing:0;margin:0;' .. tableStyle .. '"'
-- (border-collapse causes problems (see talk) -- cladeString = cladeString .. '{| style="border-collapse:collapse;border-spacing:0;margin:0;' .. tableStyle .. '"'
-- (before CSS styling) -- cladeString = cladeString .. '{| style="border-spacing:0;margin:0;' .. tableStyle .. '"'
-- (before CSS styling) -- cladeString = cladeString .. '{| style="border-spacing:0;margin:0;' .. tableStyle .. '"'
cladeString = cladeString .. '{|class="clade"' .. tableStyle
cladeString = cladeString .. '{|class="clade"' .. tableStyle


-- add caption
-- add caption
if captionName ~= "" then
if captionName ~= "" then
cladeString = cladeString .. '\n|+ style="' .. captionStyle .. '"|' .. captionName
cladeString = cladeString .. '\n|+ style="' .. captionStyle .. '"|' .. captionName
Line 91: Line 90:


--[[get child elements (add more rows for each child of node; each child is two rows)
--[[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;
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;
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
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 right
a third cell on the top row is sometimes added to contain a group to the right
]]
]]
Line 120: Line 119:
--if reverseClade2 then
--if reverseClade2 then
-- cladeString = cladeString .. '\n' .. p.addTaxonReverse(childNumber, nodeLeaf, nodeLabel, lastNode)
-- cladeString = cladeString .. '\n' .. p.addTaxonReverse(childNumber, nodeLeaf, nodeLabel, lastNode)
--else
--else
cladeString = cladeString .. '\n' .. p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)
cladeString = cladeString .. '\n' .. p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)
--end
--end
Line 133: Line 132:
-- note the footer causes a problem with tr:last-child so need either
-- note the footer causes a problem with tr:last-child so need either
-- (1) use <tfoot> but it is not allowed or incompatable
-- (1) use <tfoot> but it is not allowed or incompatable
-- cladeString = cladeString .. '<tfoot><tr style="' .. footerStyle .. '"><td colspan="2"><p>' .. footerText .. '</p></td></tr></tfoot>'
-- cladeString = cladeString .. '<tfoot><tr style="' .. footerStyle .. '"><td colspan="2"><p>' .. footerText .. '</p></td></tr></tfoot>'
-- (2) always add footer and use nth:last-child(2) but is this backwards compatible
-- (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)
-- (3) if footer= set the style inline for the last sublabel row (more a temp fix)
Line 144: Line 143:
cladeString = p.addSubTrees(cladeString) -- add subtrees
cladeString = p.addSubTrees(cladeString) -- add subtrees
return cladeString
--wrap in div to allow overflow display; new vector skin for mobile has issues (see talk page)
if pargs['overflow'] == 'yes' or 1==1 then -- force for all cases
local divCSS = ' class="clade"' -- ' style="overflow:auto;"'
if string.find(cladeString, divCSS) then
cladeString = string.gsub(cladeString, divCSS, "") -- delete CSS styling of inner clades (only want on outer)
end
return '<div' .. divCSS .. '>' .. cladeString .. '</div>'
else
return cladeString
end
--return '<div style="width:auto;">\n' .. cladeString .. '</div>'
--return '<div style="width:auto;">\n' .. cladeString .. '</div>'
end
end
Line 164: Line 154:
local suffix = { [1]="A", [2]="B", [3]="C", [4]="D", [5]="E", [6]="F", [7]="G", [8]="H", [9]="I", [10]="J",
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",
[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"}
[21]="U", [22]="V", [23]="W", [24]="X", [25]="Y", [26]="Z"}
for i=1, 26, 1 do
for i = 1, 26, 1 do
local subclade = pargs['subclade'..suffix[i]]
local subclade = pargs['subclade'..suffix[i]]
local target = pargs['target'..suffix[i]] or "SUBCLADE_" .. suffix[i]
local target = pargs['target'..suffix[i]] or "SUBCLADE_" .. suffix[i]
Line 174: Line 164:
end
end
end
end
end
end
return cladeString
return cladeString
end
end
--[[ -------------------------------------- p.addTaxon() ------------------------------------------
--[[ -------------------------------------- p.addTaxon() ------------------------------------------
function to add child elements
function to add child elements
adds wikitext for two rows of the table for each child node,
adds wikitext for two rows of the table for each child node,
the first cell in each is used for the label and sublabel; the bottom border forms the horizonal branch of the bracket
the first cell in each is used for the label and sublabel; the bottom border forms the horizonal branch of the bracket
the second cell is used for the leafname or a transcluded clade structure and spans both rows
the second cell is used for the leafname or a transcluded clade structure and spans both rows
note that the first and last child nodes need to be handled differently from the middle elements
note that the first and last child nodes need to be handled differently from the middle elements
the middle elements (|2, |3 ...) use a left border to create the vertical line of the bracket
the middle elements (|2, |3 ...) use a left border to create the vertical line of the bracket
the first child element doesn't use a left border for the first cell in the top row (as it is above the bracket)
the first child element doesn't use a left border for the first cell in the top row (as it is above the bracket)
the last child doesn't use a left border for the first cell in the second row (as it is below the bracket)
the last child doesn't use a left border for the first cell in the second row (as it is below the bracket)
]]
]]
function p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)
function p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)


--[[ get border formating parameters (i.e. color, thickness, state)
--[[ get border formating parameters (i.e. color, thickness, state)
nodeParameters for whole bracket (unnumbered, i.e. color, thickness, state) apply to whole node bracket,
nodeParameters for whole bracket (unnumbered, i.e. color, thickness, state) apply to whole node bracket,
branchParameters apply to individual branches
branchParameters apply to individual branches
the branch parameters have a number, e.g. |colorN, |thicknessN, |stateN
the branch parameters have a number, e.g. |colorN, |thicknessN, |stateN
the node parameters have no number, e.g. |color, |thickness, |state
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 nodeColor = pargs['color'] or "" -- don't set default to allow green on black gadget
local nodeThickness = tonumber(pargs['thickness']) or 1
local nodeThickness = tonumber(pargs['thickness']) or 1
local nodeState = pargs['state'] or "solid"
local nodeState = pargs['state'] or "solid"
Line 209: Line 199:
local branchLength = pargs['length'] or pargs['length'..tostring(childNumber)] or ""
local branchLength = pargs['length'] or pargs['length'..tostring(childNumber)] or ""


-- the left border takes node parameters, the bottom border takes branch parameters
-- the left border takes node parameters, the bottom border takes branch parameters
-- this has coding on the colours for green on black
-- this has coding on the colours for green on black
local bottomBorder = tostring(branchThickness) ..'px ' .. branchState .. (branchColor~="" and ' ' .. branchColor or '')
local bottomBorder = tostring(branchThickness) ..'px ' .. branchState .. (branchColor~="" and ' ' .. branchColor or '')
local leftBorder = tostring(nodeThickness) ..'px ' .. nodeState .. (nodeColor~="" and ' ' .. nodeColor or '')
local leftBorder = tostring(nodeThickness) ..'px ' .. nodeState .. (nodeColor~="" and ' ' .. nodeColor or '')
--The default border styles are in the CSS (styles.css)
--The default border styles are in the CSS (styles.css)
-- the inline styling is applied when thickness, color or state are change
-- the inline styling is applied when thickness, color or state are change
local useInlineStyle = false
local useInlineStyle = false
Line 228: Line 218:
local barRight = pargs['bar'..tostring(childNumber)] or "0"
local barRight = pargs['bar'..tostring(childNumber)] or "0"
local barBottom = pargs['barend'..tostring(childNumber)] or "0"
local barBottom = pargs['barend'..tostring(childNumber)] or "0"
local barTop = pargs['barbegin'..tostring(childNumber)] or "0"
local barTop = pargs['barbegin'..tostring(childNumber)] or "0"
local barLabel = pargs['barlabel'..tostring(childNumber)] or ""
local barLabel = pargs['barlabel'..tostring(childNumber)] or ""
local groupLabel = pargs['grouplabel'..tostring(childNumber)] or ""
local groupLabel = pargs['grouplabel'..tostring(childNumber)] or ""
local groupLabelStyle = pargs['grouplabelstyle'..tostring(childNumber)] or ""
local groupLabelStyle = pargs['grouplabelstyle'..tostring(childNumber)] or ""
local labelStyle = pargs['labelstyle'..tostring(childNumber)] or ""
local labelStyle = pargs['labelstyle'..tostring(childNumber)] or ""
local sublabelStyle = pargs['sublabelstyle'..tostring(childNumber)] or ""
local sublabelStyle = pargs['sublabelstyle'..tostring(childNumber)] or ""


--replace colours with format string; need right bar for all three options
--replace colours with format string; need right bar for all three options
if barRight ~= "0" then barRight = "2px solid " .. barRight end
if barRight ~= "0" then barRight = "2px solid " .. barRight end
if barTop ~= "0" then barRight = "2px solid " .. barTop end
if barTop ~= "0" then barRight = "2px solid " .. barTop end
if barBottom ~= "0" then barRight = "2px solid " .. barBottom end
if barBottom ~= "0" then barRight = "2px solid " .. barBottom end
if barTop ~= "0" then barTop = "2px solid " .. barTop end
if barTop ~= "0" then barTop = "2px solid " .. barTop end
if barBottom ~= "0" then barBottom = "2px solid " .. barBottom end
if barBottom ~= "0" then barBottom = "2px solid " .. barBottom end
Line 246: Line 236:
local cladeString = ''
local cladeString = ''
local styleString = ''
local styleString = ''
local borderStyle = '' -- will be used if border color, thickness or state is to be changed
local borderStyle = '' -- will be used if border color, thickness or state is to be changed
local classString = ''
local classString = ''
local reverseClass = ''
local reverseClass = ''
local widthClass = ''
local widthClass = ''
-- class to add if using reverse (rtl) cladogram;
-- class to add if using reverse (rtl) cladogram;
if reverseClade then reverseClass = ' reverse' end
if reverseClade then reverseClass = ' reverse' end
-- (1) wikitext for new row
-- (1) wikitext for new row
--cladeString = cladeString .. '\n|-'
--cladeString = cladeString .. '\n|-'


-- (2) now add cell with label
-- (2) now add cell with label
if useInlineStyle then
if useInlineStyle then
if childNumber == 1 then
if childNumber == 1 then
borderStyle = 'border-left:none;border-right:none;border-bottom:' .. bottomBorder .. ';'
borderStyle = 'border-left:none;border-right:none;border-bottom:' .. bottomBorder .. ';'
--borderStyle = 'border-bottom:' .. bottomBorder .. ';'
--borderStyle = 'border-bottom:' .. bottomBorder .. ';'
else -- for 2-17
else -- for 2-17
if reverseClade then
if reverseClade then
borderStyle = 'border-left:none;border-right:' .. leftBorder .. ';border-bottom:' .. bottomBorder .. ';'
borderStyle = 'border-left:none;border-right:' .. leftBorder .. ';border-bottom:' .. bottomBorder .. ';'
else
else
borderStyle = 'border-left:' .. leftBorder .. ';border-bottom:' .. bottomBorder .. ';'
borderStyle = 'border-left:' .. leftBorder .. ';border-bottom:' .. bottomBorder .. ';'
end
end
end
end
end
end
Line 281: Line 271:
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
.. 'max-width:' .. branchLength ..';'
.. 'max-width:' .. branchLength ..';'
.. 'padding:0em;' -- remove padding to make calculation easier
.. 'padding:0em;' -- remove padding to make calculation easier
-- following moved to styles.css
-- following moved to styles.css
-- .. 'white-space:nowrap'
-- .. 'white-space:nowrap'
-- .. 'overflow:hidden;' -- clip labels longer than the max-width
-- .. 'overflow:hidden;' -- clip labels longer than the max-width
-- .. 'text-overflow:clip;' -- ellipsis;'
-- .. 'text-overflow:clip;' -- ellipsis;'
widthClass = " clade-fixed-width"
widthClass = " clade-fixed-width"
end
end
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. labelStyle .. '"'
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. labelStyle .. '"'
end
end


if childNumber == 1 then
if childNumber == 1 then
classString= 'class="clade-label first'.. widthClass .. '" ' -- add class "first" for top row
classString= 'class="clade-label first'.. widthClass .. '" ' -- add class "first" for top row
else
else
classString = 'class="clade-label' .. reverseClass .. widthClass .. '" ' -- add "reverse" class if ltr cladogram
classString = 'class="clade-label' .. reverseClass .. widthClass .. '" ' -- add "reverse" class if ltr cladogram
end
end


-- wikitext for cell with label
-- wikitext for cell with label
local labelCellString = '\n|' .. classString .. styleString .. '|' .. p.addLabel(childNumber,nodeLabel) -- p.addLabel(nodeLabel)
local labelCellString = '\n|' .. classString .. styleString .. '|' .. p.addLabel(childNumber,nodeLabel) -- p.addLabel(nodeLabel)
--cladeString = cladeString .. labelCellString
--cladeString = cladeString .. labelCellString


---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
-- (3) add cell with leaf (which may be a table with transluded clade content)
-- (3) add cell with leaf (which may be a table with transluded clade content)
if barRight ~= "0" then
if barRight ~= "0" then
if reverseClade then -- we want the bar on the left
if reverseClade then -- we want the bar on the left
styleString = ' style="border-left:' .. barRight .. ';border-bottom:' .. barBottom .. ';border-top:' .. barTop .. ';' .. branchStyle .. '"'
styleString = ' style="border-left:' .. barRight .. ';border-bottom:' .. barBottom .. ';border-top:' .. barTop .. ';' .. branchStyle .. '"'
else
else
styleString = ' style="border-right:' .. barRight .. ';border-bottom:' .. barBottom .. ';border-top:' .. barTop .. ';' .. branchStyle .. '"'
styleString = ' style="border-right:' .. barRight .. ';border-bottom:' .. barBottom .. ';border-top:' .. barTop .. ';' .. branchStyle .. '"'
end
end
elseif (branchStyle ~= '') then
else
if (branchStyle ~= '') then
styleString = ' style="' .. branchStyle .. '"'
else
styleString = ' style="' .. branchStyle .. '"'
styleString = '' -- use defaults in styles.css
else
end
styleString = '' -- use defaults in styles.css
end
end
classString = 'class="clade-leaf' .. reverseClass .. '"'
classString = 'class="clade-leaf' .. reverseClass .. '"'


--[[note: the \n causes plain leaf elements get wrapped in <p> with style="margin:0.4em 0 0.5em 0;"
--[[note: the \n causes plain leaf elements get wrapped in <p> with style="margin:0.4em 0 0.5em 0;"
this adds spacing to rows, but is set by defaults rather than the clade template
this adds spacing to rows, but is set by defaults rather than the clade template
it also means there are two newlines when it is a clade structure (which might explain some past issues)
it also means there are two newlines when it is a clade structure (which might explain some past issues)
]]
]]
local content = '\n' .. nodeLeaf -- the newline is not necessary, but keep for backward compatibility
local content = '\n' .. nodeLeaf -- the newline is not necessary, but keep for backward compatibility


-- test using image parameter
-- test using image parameter
local image = pargs['image'..tostring(childNumber)] or ""
local image = pargs['image'..tostring(childNumber)] or ""


if image ~= "" then
if image ~= "" then
--content = content .. image -- basic version
--content = content .. image -- basic version
content = '\n{|class=clade style=width:auto' --defaults to width:100% because of class "clade"
content = '\n{|class=clade style=width:auto' --defaults to width:100% because of class "clade"
.. '\n|class=clade-leaf|\n' .. nodeLeaf
.. '\n|class=clade-leaf|\n' .. nodeLeaf
.. '\n|class=clade-leaf|\n' .. image
.. '\n|class=clade-leaf|\n' .. image
.. '\n|}'
.. '\n|}'
-- note: the classes interfere with the node counter, so try simpler version with style
-- note: the classes interfere with the node counter, so try simpler version with style
content = '\n{|style=width:100%;border-spacing:0' --width:auto is "tight"; 100% needed for image alignment
content = '\n{|style=width:100%;border-spacing:0' --width:auto is "tight"; 100% needed for image alignment
.. '\n|style=border:0;padding:0|\n' .. nodeLeaf
.. '\n|style=border:0;padding:0|\n' .. nodeLeaf
.. '\n|style=border:0;padding:0|\n' .. image
.. '\n|style=border:0;padding:0|\n' .. image
.. '\n|}'
.. '\n|}'
end
end




-- wikitext for leaf cell (note: nodeLeaf needs to be on newline if new wikitable)
-- wikitext for leaf cell (note: nodeLeaf needs to be on newline if new wikitable)
-- but that is no longer the case (newline is now forced)
-- but that is no longer the case (newline is now forced)
-- the newline wraps plain leaf terminals in <P> with vertical padding (see above)
-- the newline wraps plain leaf terminals in <P> with vertical padding (see above)


--local leafCellString = '\n|rowspan=2 ' .. classString .. styleString .. ' |\n' .. content -- the new line causes <p> wrapping for plain leaf terminals
--local leafCellString = '\n|rowspan=2 ' .. classString .. styleString .. ' |\n' .. content -- the new line causes <p> wrapping for plain leaf terminals
local leafCellString = '\n|rowspan=2 ' .. classString .. styleString .. ' |' .. content
local leafCellString = '\n|rowspan=2 ' .. classString .. styleString .. ' |' .. content
--cladeString = cladeString .. leafCellString
--cladeString = cladeString .. leafCellString


-------------------------------------------
-------------------------------------------
-- (4) stuff for right-hand bracket labels
-- (4) stuff for right-hand bracket labels


classString='class="clade-bar' .. reverseClass .. '"'
classString='class="clade-bar' .. reverseClass .. '"'
local barLabelCellString = ''
local barLabelCellString = ''
if barRight ~= "0" and barLabel ~= "" then
if barRight ~= "0" and barLabel ~= "" then
barLabelCellString = '\n|rowspan=2 ' .. classString .. ' |' .. barLabel
barLabelCellString = '\n|rowspan=2 ' .. classString .. ' |' .. barLabel
Line 369: Line 357:
barLabelCellString = barLabelCellString .. '\n|rowspan=2 ' .. classString .. ' style="'.. groupLabelStyle .. '" |' .. groupLabel
barLabelCellString = barLabelCellString .. '\n|rowspan=2 ' .. classString .. ' style="'.. groupLabelStyle .. '" |' .. groupLabel
else -- uncomment following line to see the cell structure
else -- uncomment following line to see the cell structure
--barLabelCellString = barLabelCellString .. '\n|rowspan=2 ' .. classString .. '" |' .. 'GL'
--barLabelCellString = barLabelCellString .. '\n|rowspan=2 ' .. classString .. '" |' .. 'GL'
end
end


--cladeString = cladeString .. barLabelCellString
--cladeString = cladeString .. barLabelCellString
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
-- (5) add second row (only one cell needed for sublabel because of rowspan=2);
-- (5) add second row (only one cell needed for sublabel because of rowspan=2);
-- note: earlier versions applied branch style to row rather than cell
-- note: earlier versions applied branch style to row rather than cell
-- for consistency, it is applied to the sublabel cell as with the label cell
-- for consistency, it is applied to the sublabel cell as with the label cell
--cladeString = cladeString .. '\n|-'
--cladeString = cladeString .. '\n|-'
Line 395: Line 383:
if childNumber==lastNode then -- if childNumber==lastNode we don't want left border, otherwise we do
if childNumber==lastNode then -- if childNumber==lastNode we don't want left border, otherwise we do
borderStyle = 'border-right:none;border-left:none;'
borderStyle = 'border-right:none;border-left:none;'
elseif reverseClade then
else
borderStyle = 'border-left:none;border-right:' .. leftBorder .. ';'
if reverseClade then
else
borderStyle = 'border-left:none;border-right:' .. leftBorder .. ';'
borderStyle = 'border-right:none;border-left:' .. leftBorder .. ';'
else
end
borderStyle = 'border-right:none;border-left:' .. leftBorder .. ';'
end
end
if borderStyle ~= '' or branchStyle ~= '' or branchLength ~= '' or sublabelStyle ~= "" then
end
end
if borderStyle ~= '' or branchStyle ~= '' or branchLength ~= '' or sublabelStyle ~= "" then
local branchLengthStyle = ""
local branchLengthStyle = ""
if branchLength ~= "" then
if branchLength ~= "" then
Line 412: Line 398:
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
.. 'max-width:' .. branchLength ..';'
.. 'max-width:' .. branchLength ..';'
.. 'padding:0em;' -- remove padding to make calculation easier
.. 'padding:0em;' -- remove padding to make calculation easier
end
end
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. sublabelStyle .. '"'
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. sublabelStyle .. '"'
--styleString = ' style="' .. borderStyle .. branchStyle .. sublabelStyle .. '"'
--styleString = ' style="' .. borderStyle .. branchStyle .. sublabelStyle .. '"'
end
end


--local sublabel = p.addLabel(childNumber,subLabel)
--local sublabel = p.addLabel(childNumber,subLabel)


if childNumber == lastNode then
if childNumber == lastNode then
classString = 'class="clade-slabel last' .. widthClass .. '" '
classString = 'class="clade-slabel last' .. widthClass .. '" '
else
else
classString = 'class="clade-slabel' .. reverseClass .. widthClass .. '" '
classString = 'class="clade-slabel' .. reverseClass .. widthClass .. '" '
end
end
local sublabelCellString = '\n|' .. classString .. styleString .. '|' .. p.addLabel(childNumber,subLabel)
local sublabelCellString = '\n|' .. classString .. styleString .. '|' .. p.addLabel(childNumber,subLabel)
--cladeString = cladeString .. sublabelCellString
--cladeString = cladeString .. sublabelCellString


-- constuct child element wikitext
-- constuct child element wikitext
if reverseClade then
if reverseClade then
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. barLabelCellString
cladeString = cladeString .. barLabelCellString
cladeString = cladeString .. leafCellString
cladeString = cladeString .. leafCellString
cladeString = cladeString .. labelCellString
cladeString = cladeString .. labelCellString
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. sublabelCellString
cladeString = cladeString .. sublabelCellString
else
else
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. '\n|-'
cladeString = cladeString .. labelCellString
cladeString = cladeString .. labelCellString
cladeString = cladeString .. leafCellString
cladeString = cladeString .. leafCellString
cladeString = cladeString .. barLabelCellString
cladeString = cladeString .. barLabelCellString
cladeString = cladeString .. '\n|-' -- add second row (only one cell needed for sublabel because of rowspan=2);
cladeString = cladeString .. '\n|-' -- add second row (only one cell needed for sublabel because of rowspan=2);
cladeString = cladeString .. sublabelCellString
cladeString = cladeString .. sublabelCellString
end
end
return cladeString
return cladeString
end
end
Line 469: Line 455:
-- however, there is a problem if labels have a styling element (e.g. <span style= ..., <span title= ...)
-- however, there is a problem if labels have a styling element (e.g. <span style= ..., <span title= ...)
local stylingElementDetected = false
local stylingElementDetected = false
if string.find(nodeLabel, "span ") ~= nil then stylingElementDetected = true end
if nodeLabel:find("span ") or nodeLabel:find(" style") then
if string.find(nodeLabel, " style") ~= nil then stylingElementDetected = true end
stylingElementDetected = true
end
--TODO test following alternative
--TODO test following alternative
--if nodeLabel:find( "%b<>") then stylingElementDetected = true end
--if nodeLabel:find( "%b<>") then stylingElementDetected = true end
Line 476: Line 463:
if stylingElementDetected == true then
if stylingElementDetected == true then
return '<div style=display:inline class=nowrap>' .. nodeLabel .. '</div>'
return '<div style=display:inline class=nowrap>' .. nodeLabel .. '</div>'
else
else
local nowrapString = string.gsub(nodeLabel, " ", "&nbsp;") -- replace spaces with non-breaking space
local nowrapString = string.gsub(nodeLabel, " ", "&nbsp;") -- replace spaces with non-breaking space
if not nowrapString:find("UNIQ.-QINU") and not nowrapString:find("%[%[.-%]%]") then -- unless a strip marker
if not nowrapString:find("UNIQ.-QINU") and not nowrapString:find("%[%[.-%]%]") then -- unless a strip marker
nowrapString = string.gsub(nowrapString, "-", "&#8209;") -- replace hyphen with non-breaking hyphen (&#8209;)
nowrapString = string.gsub(nowrapString, "-", "&#8209;") -- replace hyphen with non-breaking hyphen (&#8209;)
end
end
return nowrapString
return nowrapString
end
end
Line 501: Line 488:


local j,k
local j,k
j,k = string.find(newickString, '%(.*%)') -- find location of outer parenthesised term
j,k = string.find(newickString, '%(.*%)') -- find location of outer parenthesised term
local innerTerm = string.sub(newickString, j+1, k-1) -- select content in parenthesis
local innerTerm = string.sub(newickString, j+1, k-1) -- select content in parenthesis
local outerTerm = string.gsub(newickString, "%b()", "") -- delete parenthetic term
local outerTerm = string.gsub(newickString, "%b()", "") -- delete parenthetic term
if outerTerm == 'panthera' then outerTerm = "x" end -- how is this set in local variable for inner nodes?
if outerTerm == 'panthera' then outerTerm = "x" end -- how is this set in local variable for inner nodes?
outerTerm = tostring(count)
outerTerm = tostring(count)
-- need to remove commas in bracket terms before split, so temporarily replace commas between brackets
-- need to remove commas in bracket terms before split, so temporarily replace commas between brackets
local innerTerm2 = string.gsub(innerTerm, "%b()", function (n)
local innerTerm2 = string.gsub(innerTerm, "%b()", function (n)
return string.gsub(n, ",%s*", "XXX") -- also strip spaces after commas here
return string.gsub(n, ",%s*", "XXX") -- also strip spaces after commas here
end)
end)
--cladeString = cladeString .. '\n' .. p.addTaxon(1, innerTerm2, "")
--cladeString = cladeString .. '\n' .. p.addTaxon(1, innerTerm2, "")


-- this needs a lastNode variable
-- this needs a lastNode variable
local s = p.strsplit(innerTerm2, ",")
local s = p.strsplit(innerTerm2, ",")
--oldLastNode=lastNode
--oldLastNode=lastNode
local lastNode=table.getn(s) -- number of child branches
local lastNode=table.getn(s) -- number of child branches
local i=1
local i = 1
while s[i] do
while s[i] do
local restoredString = string.gsub(s[i],"XXX", ",") -- convert back to commas
local restoredString = string.gsub(s[i],"XXX", ",") -- convert back to commas
Line 530: Line 517:
cladeString = cladeString .. '\n' .. p.addTaxon(i, restoredString, "", lastNode) --count)
cladeString = cladeString .. '\n' .. p.addTaxon(i, restoredString, "", lastNode) --count)
end
end
i=i+1
i = i + 1
end
end
-- lastNode=oldLastNode
-- lastNode=oldLastNode
-- close table
-- close table
--cladeString = cladeString .. '\n' .. '| style="border: 0; padding: 0; vertical-align: top;" | <br/> \n|}'
--cladeString = cladeString .. '\n' .. '| style="border: 0; padding: 0; vertical-align: top;" | <br/> \n|}'
Line 543: Line 530:
-- why not use mw.text.split(s, sep)?
-- why not use mw.text.split(s, sep)?
function p.strsplit(inputstr, sep)
function p.strsplit(inputstr, sep)
if sep == nil then
if sep == nil then
sep = "%s"
sep = "%s"
end
end
local t={}
local t={}
local i=1
local i = 1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
t[i] = str
i = i + 1
i = i + 1
end
end
return t
return t
end
end


Line 568: Line 555:
--if newickString == '{{{newickstring}}}' then return newickString end
--if newickString == '{{{newickstring}}}' then return newickString end


newickString = p.processNewickString(newickString,"") -- "childNumber")
newickString = p.processNewickString(newickString,"") -- "childNumber")
-- show the Newick string
-- show the Newick string
local cladeString = ''
local cladeString = ''
local levelNumber = 1 -- for depth of iteration
local levelNumber = 1 -- for depth of iteration
local childNumber = 1 -- number of sister elements on node (always one for root)
local childNumber = 1 -- number of sister elements on node (always one for root)
-- converted the newick string to the clade structure
-- converted the newick string to the clade structure
Line 582: Line 569:


local resultString = ''
local resultString = ''
local option = pargs['option'] or ''
local option = pargs['option'] or ''
if option == 'tree' then
if option == 'tree' then
--show the transcluded clade diagram
--show the transcluded clade diagram
resultString = cladeString
resultString = cladeString
else
else
-- show the Newick string
-- show the Newick string
resultString = '<pre>'..newickString..'</pre>'
resultString = '<pre>'..newickString..'</pre>'
-- show the converted clade structure
-- show the converted clade structure
resultString = resultString .. '<pre>'.. cladeString ..'</pre>'
resultString = resultString .. '<pre>'.. cladeString ..'</pre>'
end
end
--resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) }
--resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) }


return resultString
return resultString
end
end


--[[ Parse one level of Newick string
--[[ Parse one level of Newick string
This function receives a Newick string, which has two components
This function receives a Newick string, which has two components
1. the right hand term is a clade label: |labelN=labelname
1. the right hand term is a clade label: |labelN=labelname
2. the left hand term in parenthesis has common delimited child nodes, each of which can be
2. the left hand term in parenthesis has common delimited child nodes, each of which can be
i. a taxon name which just needs: |N=leafname
i. a taxon name which just needs: |N=leafname
ii. a Newick string which needs further processing through reiteration
ii. a Newick string which needs further processing through reiteration
]]
]]
function p.newickParseLevel(newickString,levelNumber,childNumber)
function p.newickParseLevel(newickString,levelNumber,childNumber)


local cladeString = ""
local cladeString = ""
local indent = p.getIndent(levelNumber)
local indent = p.getIndent(levelNumber)
Line 613: Line 600:
local j=0
local j=0
local k=0
local k=0
j,k = string.find(newickString, '%(.*%)') -- find location of outer parenthesised term
j,k = string.find(newickString, '%(.*%)') -- find location of outer parenthesised term
local innerTerm = string.sub(newickString, j+1, k-1) -- select content in parenthesis
local innerTerm = string.sub(newickString, j+1, k-1) -- select content in parenthesis
local outerTerm = string.gsub(newickString, "%b()", "") -- delete parenthetic term
local outerTerm = string.gsub(newickString, "%b()", "") -- delete parenthetic term


Line 624: Line 611:
-- protect commas in inner parentheses from split; temporarily replace commas between parentheses
-- protect commas in inner parentheses from split; temporarily replace commas between parentheses
local innerTerm2 = string.gsub(innerTerm, "%b()", function (n)
local innerTerm2 = string.gsub(innerTerm, "%b()", function (n)
return string.gsub(n, ",%s*", "XXX") -- also strip spaces after commas here
return string.gsub(n, ",%s*", "XXX") -- also strip spaces after commas here
end)
end)
local s = p.strsplit(innerTerm2, ",")
local s = p.strsplit(innerTerm2, ",")
local i=1
local i = 1
while s[i] do
while s[i] do
local restoredString = string.gsub(s[i],"XXX", ",") -- convert back to commas
local restoredString = string.gsub(s[i],"XXX", ",") -- convert back to commas
Line 640: Line 627:
cladeString = cladeString .. indent .. '|' .. i .. '=' .. restoredString --.. '(level=' .. levelNumber .. ')'
cladeString = cladeString .. indent .. '|' .. i .. '=' .. restoredString --.. '(level=' .. levelNumber .. ')'
end
end
i=i+1
i = i + 1
end
end
-- end -- end splitting of strings
-- end -- end splitting of strings


cladeString = cladeString .. indent .. '}}'
cladeString = cladeString .. indent .. '}}'
return cladeString
return cladeString
end
end


Line 652: Line 639:
local extraIndent = pargs['indent'] or mw.getCurrentFrame().args['indent'] or 0
local extraIndent = pargs['indent'] or mw.getCurrentFrame().args['indent'] or 0
indent = indent .. string.rep(" ", extraIndent) .. string.rep(" ", levelNumber - 1) -- extra indent to make aligning compound trees easier
while tonumber(extraIndent) > 0 do
indent = indent .. " " -- an extra indent to make aligining compound trees easier
extraIndent = extraIndent - 1
end
while levelNumber > 1 do
indent = indent .. " "
levelNumber = levelNumber-1
end
return indent
return indent
end
end
Line 673: Line 653:
local i = 0
local i = 0
local pargs = pargs
local pargs = pargs
local pattern = pargs['newick'..tostring(childNumber)..'-pattern'] -- unnumbered option for i=1
local pattern = pargs['newick'..tostring(childNumber)..'-pattern'] -- unnumbered option for i = 1
local replace = pargs['newick'..tostring(childNumber)..'-replace']
local replace = pargs['newick'..tostring(childNumber)..'-replace']
while i < maxPatterns do
while i < maxPatterns do
i=i+1
i = i + 1
pattern = pattern or pargs['newick'..tostring(childNumber)..'-pattern'..tostring(i)]
pattern = pattern or pargs['newick'..tostring(childNumber)..'-pattern'..tostring(i)]
replace = replace or pargs['newick'..tostring(childNumber)..'-replace'..tostring(i)] or ""
replace = replace or pargs['newick'..tostring(childNumber)..'-replace'..tostring(i)] or ""
if pattern then
if pattern then
newickString = string.gsub (newickString, pattern, replace)
newickString = string.gsub(newickString, pattern, replace)
end
end
pattern = nil; replace = nil
pattern = nil; replace = nil
end
end
newickString = string.gsub (newickString, "_", " ") -- replace underscore with space
newickString = string.gsub(newickString, "_", " ") -- replace underscore with space
return newickString
return newickString
end
end
Line 702: Line 682:


--[[function getCladeTreeInfo()
--[[function getCladeTreeInfo()
this preprocessing loop gets information about the whole structure (number of nodes, leaves etc)
this preprocessing loop gets information about the whole structure (number of nodes, leaves etc)
it makes a redundant calls to the templates through transclusion, but doen't affect the template depths;
it makes a redundant calls to the templates through transclusion, but doen't affect the template depths;
it provides the global lastNode that is used to limit the main while loop
it provides the global lastNode that is used to limit the main while loop
Line 708: Line 688:
function p.getCladeTreeInfo()
function p.getCladeTreeInfo()


-- enable proprocessing loop
-- enable proprocessing loop
local childNumber = 0
local childNumber = 0
local childCount =0
local childCount = 0
local maxChildren =20
local maxChildren = 20
--info veriables (these are global for now)
--info veriables (these are global for now)
nodeCount = 0
nodeCount=0
cladeCount = 0
cladeCount=0
leafCount = 0
leafCount=0
while childNumber < maxChildren do -- preprocessing loop
while childNumber < maxChildren do -- preprocessing loop
childNumber = childNumber + 1 -- so we start with 1
childNumber = childNumber + 1 -- so we start with 1
local nodeLeaf,data = pargs[tostring(childNumber)] or "" -- get data from |N=
local nodeLeaf,data = pargs[tostring(childNumber)] or "" -- get data from |N=
local newickString = pargs['newick'..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 "" -- get data from |labelN=
local listString = pargs['list'..tostring(childNumber)] or "" -- get data from |labelN=
if newickString ~= "" or nodeLeaf ~= "" or listString ~= "" then
if newickString ~= "" or nodeLeaf ~= "" or listString ~= "" then
--if nodeLeaf ~= "" then
--if nodeLeaf ~= "" then
childCount = childCount + 1 -- this counts child elements in this clade
childCount = childCount + 1 -- this counts child elements in this clade
--[[]
--[[]
for i in string.gmatch(nodeLeaf, "||rowspan") do -- count number of rows started (transclusion)
for i in string.gmatch(nodeLeaf, "||rowspan") do -- count number of rows started (transclusion)
nodeCount = nodeCount + 1
nodeCount = nodeCount + 1
end
end
for i in string.gmatch(nodeLeaf, '{|class="clade"') do -- count number of tables started (transclusion)
for i in string.gmatch(nodeLeaf, '{|class="clade"') do -- count number of tables started (transclusion)
cladeCount = cladeCount + 1
cladeCount = cladeCount + 1
end
end
]]
]]
-- count occurences of clade structure using number of classes used and add to counters
-- count occurences of clade structure using number of classes used and add to counters
local _, nClades = string.gsub(nodeLeaf, 'class="clade"', "")
local _, nClades = string.gsub(nodeLeaf, 'class="clade"', "")
local _, nNodes = string.gsub(nodeLeaf, 'class="clade%-leaf"', "")
local _, nNodes = string.gsub(nodeLeaf, 'class="clade%-leaf"', "")
cladeCount = cladeCount + nClades
cladeCount = cladeCount + nClades
nodeCount = nodeCount + nNodes
nodeCount = nodeCount + nNodes
lastNode = childNumber -- this gets the last node with a valid entry, even when missing numbers
lastNode = childNumber -- this gets the last node with a valid entry, even when missing numbers
end
end
end
end
--]]
--]]
-- nodes can be either terminal leaves or a clade structure (table)
-- nodes can be either terminal leaves or a clade structure (table)
-- note: should change class clade-leaf to clade-node to reflect this
-- note: should change class clade-leaf to clade-node to reflect this
nodeCount = nodeCount -- number of nodes (class clade-leaf) passed down by transduction
nodeCount = nodeCount -- number of nodes (class clade-leaf) passed down by transduction
+ childCount + 1 -- plus one for current clade and one for each of its child element
+ childCount + 1 -- plus one for current clade and one for each of its child element
cladeCount = cladeCount + 1 -- number of clade structure tables passed down by transduction (plus one for current clade)
cladeCount = cladeCount + 1 -- number of clade structure tables passed down by transduction (plus one for current clade)
leafCount = nodeCount-cladeCount -- number of terminal leaves (equals height of cladogram)
leafCount = nodeCount-cladeCount -- number of terminal leaves (equals height of cladogram)
-- output for testing: number of clades / total nodes / terminal nodes (=leaves)
-- output for testing: number of clades / total nodes / terminal nodes (=leaves)
-- (internal nodes) (cladogram height)
-- (internal nodes) (cladogram height)
infoOutput = '<small>[' .. cladeCount .. '/' .. nodeCount .. '/' .. leafCount .. ']</small>'
infoOutput = '<small>[' .. cladeCount .. '/' .. nodeCount .. '/' .. leafCount .. ']</small>'
Line 761: Line 741:
function p.showClade(frame)
function p.showClade(frame)
--local code = frame.args.code or ""
--local code = frame.args.code or ""
local code = frame:getParent().args['code2'] or frame.args['code2'] or ""
local code = frame:getParent().args['code2'] or ""
--return code
--return code
Line 769: Line 749:
--return string.sub(test,6,-7)
--return string.sub(test,6,-7)
local o1 =frame:getParent():getArgument('code2') or frame:getArgument('code2')
local o1 =frame:getParent():getArgument('code2')
return o1:expand()
return o1:expand()
--return string.sub(code,2,-1) -- strip marker \127'"`UNIQ--tagname-8 hex digits-QINU`"'\127
--return string.sub(code,2,-1) -- strip marker \127'"`UNIQ--tagname-8 hex digits-QINU`"'\127
--return frame:preprocess(string.sub(code,3))
--return frame:preprocess(string.sub(code,3))
end
end
Line 778: Line 758:


function p.firstToUpper(str)
function p.firstToUpper(str)
return (str:gsub("^%l", string.upper))
return (str:gsub("^%l", string.upper))
end
end
--[[ function to generate cladogram from a wikitext-like list
--[[ function to generate cladogram from a wikitext-like list
- uses @ instead of * because we don't want wikitext processed and nowiki elements are passed as stripmarkers (?)
- uses @ instead of * because we don't want wikitext processed and nowiki elements are passed as stripmarkers (?)
]]
]]
function p.list(count,listString)
function p.list(count,listString)
Line 787: Line 767:
local cladeString = ""
local cladeString = ""
--count = count+1
--count = count+1
local i=1
local i = 1
local child=1
local child = 1
local lastNode=0--table.getn(list) -- number of child branches (potential)
local lastNode=0--table.getn(list) -- number of child branches (potential)
local listChar = "@"
local listChar = "@"
if listString:find("UNIQ.-QINU") then -- if wrapped in nowiki
if listString:find("UNIQ.-QINU") then -- if wrapped in nowiki
mw.addWarning("Stripping content in nowiki tags")
mw.addWarning("Stripping content in nowiki tags")
listString = mw.text.trim( mw.text.unstripNoWiki( listString ) )
listString = mw.text.trim( mw.text.unstripNoWiki( listString ) )
end
end
if string.match( listString, "^*", 1 ) then
if string.match( listString, "^*", 1 ) then
listChar = "*"
listChar = "*"
end
end
local list = mw.text.split(listString, "\n")
local list = mw.text.split(listString, "\n")
cladeString = cladeString .. '{| class="clade" '
cladeString = cladeString .. '{| class="clade" '
while list[i] do
while list[i] do
list[i]=list[i]:gsub("^"..listChar, "") -- strip the first @ or *
list[i] = list[i]:gsub("^"..listChar, "") -- strip the first @ or *
list[i]=mw.text.trim(list[i]) -- trim
list[i] = mw.text.trim(list[i]) -- trim
if not string.match( list[i], "^"..listChar, 1 ) then -- count children at this level (not beginning wiht @/*)
if not string.match( list[i], "^"..listChar, 1 ) then -- count children at this level (not beginning wiht @/*)
lastNode = lastNode+1
lastNode = lastNode+1
end
end
i=i+1
i = i + 1
end
end
i=1
i = 1
while list[i] do
while list[i] do


--[[ pseudocode:
--[[ pseudocode:
if next value begins with @ we have a subtree,
if next value begins with @ we have a subtree,
which must be recombined and past iteratively
which must be recombined and past iteratively
else we have a simple leaf
else we have a simple leaf
]]
]]


-- if the next value begins with @, we have a subtree which should be recombined
-- if the next value begins with @, we have a subtree which should be recombined
if list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) then
if list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) then
local label=list[i]
local label=list[i]
i=i+1
i = i + 1
local recombined = list[i]
local recombined = list[i]
while list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) do
while list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) do
recombined = recombined .. "\n" .. list[i+1]
recombined = recombined .. "\n" .. list[i+1]
i=i+1
i = i + 1
end
end
--cladeString = cladeString .. '\n' .. p.addTaxon(child, recombined, label, lastNode)
--cladeString = cladeString .. '\n' .. p.addTaxon(child, recombined, label, lastNode)
cladeString = cladeString .. '\n' .. p.addTaxon(child, p.list(count,recombined), label, lastNode)
cladeString = cladeString .. '\n' .. p.addTaxon(child, p.list(count,recombined), label, lastNode)
else
else
cladeString = cladeString .. '\n' .. p.addTaxon(child, list[i], "", lastNode)
cladeString = cladeString .. '\n' .. p.addTaxon(child, list[i], "", lastNode)
end
end
i=i+1
i = i + 1
child=child+1
child = child + 1
end
end


Line 855: Line 835:
]]
]]
function p.cladeConverter(frame)
function p.cladeConverter(frame)
pargs = getArgs(frame)
pargs = frame:getParent().args
if frame.args['list'] or pargs['list'] then
if frame.args['list'] or pargs['list'] then
return p.listConverter(frame)
return p.listConverter(frame)
elseif frame.args['newickstring'] or frame.args['newick'] or pargs['newickstring'] or pargs['newick'] then
elseif frame.args['newickstring'] or frame.args['newick'] or pargs['newickstring'] or pargs['newick'] then
return p.newickConverter(frame)
return p.newickConverter(frame)
else
else
local message = "Conversion needs wikitext list or newick string in parameters ''list'' or ''newick'' respectively"
local message = "Conversion needs wikitext list or newick string in parameters ''list'' or ''newick'' respectively"
Line 873: Line 853:
-- show the list string
-- show the list string
local cladeString = ''
local cladeString = ''
local levelNumber = 1 -- for depth of iteration
local levelNumber = 1 -- for depth of iteration
local childNumber = 1 -- number of sister elements on node (always one for root)
local childNumber = 1 -- number of sister elements on node (always one for root)
local indent = p.getIndent(levelNumber)
local indent = p.getIndent(levelNumber)
-- converted the newick string to the clade structure
-- converted the newick string to the clade structure
Line 882: Line 862:


local resultString = ''
local resultString = ''
local option = pargs['option'] or ''
local option = pargs['option'] or ''
if option == 'tree' then
if option == 'tree' then
--show the transcluded clade diagram
--show the transcluded clade diagram
resultString = cladeString
resultString = cladeString
else
else
-- show the wikitext list string
-- show the wikitext list string
resultString = '<pre>'..listString..'</pre>'
resultString = '<pre>'..listString..'</pre>'
-- show the converted clade structure
-- show the converted clade structure
resultString = resultString .. '<pre>'.. cladeString ..'</pre>'
resultString = resultString .. '<pre>'.. cladeString ..'</pre>'
end
end
--resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) }
--resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) }


return resultString
return resultString
end
end


Line 901: Line 881:
local cladeString = ""
local cladeString = ""
local indent = p.getIndent(levelNumber)
local indent = p.getIndent(levelNumber)
levelNumber=levelNumber+1
levelNumber=levelNumber+1
local nowiki = false
local nowiki = false
if listString:find("UNIQ.-QINU") then -- if wrapped in nowiki
if listString:find("UNIQ.-QINU") then -- if wrapped in nowiki
mw.addWarning("Stripping content in nowiki tags")
mw.addWarning("Stripping content in nowiki tags")
listString = mw.text.trim( mw.text.unstripNoWiki( listString ) )
listString = mw.text.trim( mw.text.unstripNoWiki( listString ) )
nowiki = true
nowiki = true
end
end
local listChar = "@"
local listChar = "@"
if string.match( listString, "^*", 1 ) then
if string.match( listString, "^*", 1 ) then
listChar = "*"
listChar = "*"
end
end


local list = mw.text.split(listString, "\n")
local list = mw.text.split(listString, "\n")
local i=1
local i = 1
local child=1
local child = 1
local lastNode=0
local lastNode = 0
while list[i] do
while list[i] do
list[i]=list[i]:gsub("^"..listChar, "") -- strip the first @
list[i] = list[i]:gsub("^"..listChar, "") -- strip the first @
if not string.match( list[i], "^"..listChar, 1 ) then -- count children at this level (not beginning wiht @)
if not string.match(list[i], "^"..listChar, 1) then -- count children at this level (not beginning wiht @)
lastNode = lastNode+1
lastNode = lastNode +1
end
end
i=i+1
i = i + 1
end
end
i=1
i = 1


while list[i] do
while list[i] do


--[[ pseudocode:
--[[ pseudocode:
if next value begins with @ we have a subtree,
if next value begins with @ we have a subtree,
which must be recombined and past iteratively
which must be recombined and past iteratively
else we have a simple leaf
else we have a simple leaf
]]
]]


-- if the next value begins with @, we have a subtree which should be recombined
-- if the next value begins with @, we have a subtree which should be recombined
if list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) then
if list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) then
local label=list[i]
local label = list[i]
i=i+1
i = i + 1
local recombined = list[i]
local recombined = list[i]
while list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) do
while list[i+1] and string.match( list[i+1], "^"..listChar, 1 ) do
recombined = recombined .. "\n" .. list[i+1]
recombined = recombined .. "\n" .. list[i+1]
i=i+1
i = i + 1
end
end
cladeString = cladeString .. indent .. '|label' .. child ..'=' .. label
cladeString = cladeString .. indent .. '|label' .. child ..'=' .. label
cladeString = cladeString .. indent .. '|' .. child ..'=' .. '{{clade'
cladeString = cladeString .. indent .. '|' .. child ..'=' .. '{{clade'
.. p.listParseLevel(recombined,levelNumber,i)
.. p.listParseLevel(recombined,levelNumber,i)
else
else
cladeString = cladeString .. indent .. '|' .. child ..'=' .. list[i]
cladeString = cladeString .. indent .. '|' .. child ..'=' .. list[i]
end
end
i=i+1
i = i + 1
child=child+1
child=child+1
end
end