Module:Sandbox/Jts1882/CladeN: Difference between revisions

Content deleted Content added
style nested leaf/image table (add notes on importance of newline
Replace Module:No globals with require( "strict" )
 
(27 intermediate revisions by one other user not shown)
Line 8:
now uses templatestyles
]]
require('Module:No globalsstrict')
local p = {}
local pargs = {} -- parent arguments
Line 18:
local infoOutput
local reverseClade = false
local nodeColor
local nodeThickness
local nodeState
 
 
--[[============================== main function ===========================
Line 61 ⟶ 57:
cladeString = cladeString .. p.templateStyle( frame, src ) .. '\n'
--end
local tableStyle = frame.args.style or ""
 
--if tableStyle == '{{{style}}}' then tableStyle = "" end -- no longer needed as pipe added to template to suppress passing of {{{style}} when no value
if tableStyle ~= "" then
tableStyle = ' style="' .. tableStyle .. '"' -- include style= in string to suppress empty style elements
Line 74 ⟶ 68:
--reverseClade = true
 
local captionName =mw.getCurrentFrame():getParent().args pargs['caption'] or ""
local captionStyle = mw.getCurrentFrame():getParent().argspargs['captionstyle'] or ""
 
-- add an element to mimick nowiki WORKS BUT DISABLE FOR DEMO PURPOSES
Line 90 ⟶ 84:
end
-- global nodeParameters (unnumber, i.e. color, thickness, state) apply to whole node bracket,
-- but can be overrriden by branchParameters (numbered, e.g. color2, thickness2, state2)
nodeColor = mw.getCurrentFrame():getParent().args['color'] or ""
nodeThickness = tonumber(mw.getCurrentFrame():getParent().args['thickness']) or 1
nodeState = mw.getCurrentFrame():getParent().args['state'] or "solid"
local moreNeeded = true
Line 111 ⟶ 100:
 
childNumber = childNumber + 1 -- so we start with 1
local nodeLeaf = mw.getCurrentFrame():getParent().argspargs[tostring(childNumber)] or "" -- get data from |N=
local nodeLabel = mw.getCurrentFrame():getParent().argspargs['label'..tostring(childNumber)] or "" -- get data from |labelN=
local newickString = mw.getCurrentFrame():getParent().argspargs['newick'..tostring(childNumber)] or "" -- get data from |labelN=
local listString = mw.getCurrentFrame():getParent().argspargs['list'..tostring(childNumber)] or ""
if listString ~= "" then
Line 136 ⟶ 125:
end
 
local footerText = mw.getCurrentFrame():getParent().argspargs['footer'] or ""
local footerStyle = mw.getCurrentFrame():getParent().argspargs['footerstyle'] or ""
 
if footerText ~= "" then
Line 162 ⟶ 151:
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",
Line 190 ⟶ 179:
function p.addTaxon(childNumber, nodeLeaf, nodeLabel, lastNode)
 
--[[ get border formating parameters (i.e. color, thickness, state)
nodeParameters for whole bracket (unnumbered, i.e. color, thickness, state) apply to whole node bracket,
branchParameters apply to individual branches
the branch parameters have a number, e.g. |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 border formating parameters for branch (default to global nodeParameters)
local branchColor = pargs['color'..tostring(childNumber)] or nodeColor
-- - the branch parameters have a number, e.g. |colorN, |thicknessN, |stateN
local branchThickness = tonumber(pargs['thickness'..tostring(childNumber)]) or nodeThickness
-- - the node parameters have no number, e.g. |color, |thickness, |state
local branchThicknessbranchState = tonumber(mw.getCurrentFrame():getParent().argspargs['thicknessstate'..tostring(childNumber)]) or nodeThicknessnodeState
if branchState == 'double' then
local branchColor = mw.getCurrentFrame():getParent().args['color'..tostring(childNumber)] or nodeColor
if branchThickness < 2 then branchThickness = 3 end -- need thick line for double
local branchStyle = mw.getCurrentFrame():getParent().args['style'..tostring(childNumber)] or ""
end
local branchLabelStyle = mw.getCurrentFrame():getParent().args['branch'..tostring(childNumber)] or ""
local branchState = mw.getCurrentFrame():getParent().args['state'..tostring(childNumber)] or nodeState -- "solid"
local branchStyle = pargs['style'..tostring(childNumber)] or ""
if branchState == 'double' then if branchThickness < 2 then branchThickness = 3 end end -- need thick line for double
local branchLength = pargs['length'] or pargs['length'..tostring(childNumber)] or ""
 
-- the left border takes node parameters, the bottom border takes branch parameters
Line 217 ⟶ 216:
-- variables for right hand bar or bracket
--local barColor = ""
local barRight = mw.getCurrentFrame():getParent().argspargs['bar'..tostring(childNumber)] or "0"
local barBottom = mw.getCurrentFrame():getParent().argspargs['barend'..tostring(childNumber)] or "0"
local barTop = mw.getCurrentFrame():getParent().argspargs['barbegin'..tostring(childNumber)] or "0"
local barLabel = mw.getCurrentFrame():getParent().argspargs['barlabel'..tostring(childNumber)] or ""
local groupLabel = mw.getCurrentFrame():getParent().argspargs['grouplabel'..tostring(childNumber)] or ""
local groupLabelStyle = mw.getCurrentFrame():getParent().argspargs['grouplabelstyle'..tostring(childNumber)] or ""
local labelStyle = mw.getCurrentFrame():getParent().argspargs['labelstyle'..tostring(childNumber)] or ""
local sublabelStyle = pargs['sublabelstyle'..tostring(childNumber)] or ""
 
--replace colours with format string; need right bar for all three options
Line 239:
local classString = ''
local reverseClass = ''
local widthClass = ''
-- class to add if using reverse (rtl) cladogram;
Line 260 ⟶ 261:
end
end
 
if useInlineStyle or (branchStyle ~= '') or (branchLabelStylebranchLength ~= '')"" or labelStyle ~= "" then
local branchLengthStyle = ""
styleString = 'style="' .. borderStyle .. branchStyle .. branchLabelStyle .. '"'
if branchLength ~= "" then
if childNumber == 1 then
branchLengthStyle = 'width:' .. branchLength .. ';' -- add width to first element
end
--if childNumber > 1 then prefix = 'max-' end
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
.. 'max-width:' .. branchLength ..';'
.. 'padding:0em;' -- remove padding to make calculation easier
-- following moved to styles.css
-- .. 'white-space:nowrap'
-- .. 'overflow:hidden;' -- clip labels longer than the max-width
-- .. 'text-overflow:clip;' -- ellipsis;'
--if pargs['noclip'] then
if string.find(nodeLabel, '<div style="position:absolute;') then
branchLengthStyle = branchLengthStyle .. 'overflow:visible;'
end
widthClass = " clade-fixed-width"
end
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. labelStyle .. '"'
end
 
if childNumber == 1 then
classString= 'class="clade-label first'.. widthClass .. '" ' -- add class "first" for top row
else
classString = 'class="clade-label' .. reverseClass .. widthClass .. '" ' -- add "reverse" class if ltr cladogram
end
 
Line 292 ⟶ 313:
end
end
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;"
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)
]]
local content = '\n' .. nodeLeaf -- the newline is not necessary, but keep for backward compatibility
 
-- test using image parameter
local image = pargs['image'..tostring(childNumber)] or ""
 
if image ~= "" then
local content = nodeLeaf
if --content = content .. image ~=-- ""basic thenversion
content = '\n{| class="clade" style="width:auto;"' --defaults to width:100% because of class "clade"
content = content .. image -- simple version
.. '\n| class="clade-leaf" ' .. '|\n' .. nodeLeaf
--[[note: plain leaf elements get wrapped in <p>.. with'\n| styleclass="margin:0clade-leaf" ' ..4em 0'|\n' 0.5em. 0;"image
this adds spacing to rows, but is set by defaults rather than the clade template
]]
 
--content = '\n{| class="clade-image" style="border-collapse:separate;border-spacing:0;margin:0;" '
content = '\n{| class="clade" style="width:auto;" '
.. '\n| class="clade-leaf" style=background-color:#ddffdd;' .. '|' .. nodeLeaf
.. '\n| class="clade-leaf" style=background-color:#ffffdd;' .. '|' .. image
.. '\n|}'
-- 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
.. '\n| style="border:0;padding:0;" ' .. '|\n' .. nodeLeaf
.. '\n| style="border:0;padding:0;" ' .. '|\n' .. image
.. '\n|}'
end
 
content = '\n{| style="border-collapse:collapse;border-spacing:0;margin:0;" \n|' .. nodeLeaf .. '||' .. image .. '\n|}'
 
end
-- 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)
-- the newline wraps plain leaf terminals in <P> with vertical paddingtpadding (see above)
 
classString = 'class="clade-leaf' .. reverseClass .. '"'
 
--local leafCellString = '\n|rowspan=2 ' .. classString .. styleString .. ' |\n' .. content -- the new line causes <p> wrapping for plain leaf terminals
Line 355 ⟶ 379:
-- (6) add cell containing sublabel
local subLabel = mw.getCurrentFrame():getParent().argspargs['sublabel'..tostring(childNumber)] or "" -- request in addLabel
-- FOR TESTING: use subLabel for annotating the clade structues to use structure information (DEBUGGIING ONLY)
Line 374 ⟶ 398:
end
end
if borderStyle ~= '' or branchStyle ~= '' or branchLength ~= '' or sublabelStyle ~= "" then
local branchLengthStyle = ""
styleString = ' style="' .. borderStyle .. branchStyle .. '"'
if branchLength ~= "" then
if childNumber == 1 then
--only set for label branchLengthStyle = 'width:' .. branchLength .. ';' -- add width to first element
end
--if childNumber > 1 then prefix = 'max-' end
branchLengthStyle = branchLengthStyle --= prefix .. 'width:' .. branchLength .. ';'
.. 'max-width:' .. branchLength ..';'
.. 'padding:0em;' -- remove padding to make calculation easier
--if pargs['noclip'] then
if string.find(subLabel, '<div style="position:absolute;') then
branchLengthStyle = branchLengthStyle .. 'overflow:visible;'
end
end
styleString = 'style="' .. borderStyle .. branchLengthStyle .. branchStyle .. sublabelStyle .. '"'
--styleString = ' style="' .. borderStyle .. branchStyle .. sublabelStyle .. '"'
end
 
Line 381 ⟶ 420:
 
if childNumber == lastNode then
classString = 'class="clade-slabel last' .. widthClass .. '" '
else
classString = 'class="clade-slabel' .. reverseClass .. widthClass .. '" '
end
local sublabelCellString = '\n|' .. classString .. styleString .. '|' .. p.addLabel(childNumber,subLabel)
Line 415 ⟶ 454:
function p.addLabel(childNumber,nodeLabel)
--local nodeLabel = mw.getCurrentFrame():getParent().args['label'..tostring(childNumber)] or ""
 
--local firstChars = string.sub(nodeLabel, 1,2) -- get first two characters; will be {{ if no parameter (for Old method?)
--if firstChars == "{{{" or nodeLabel == "" then
if nodeLabel == "" then
--return '<br/>' --'&nbsp;<br/>' -- remove space to reduce post-expand include size (the width=1.5em handles spacing)
--return '<br/>' -- must return something; this is critical for clade structure
--return '&#8239;' -- &nbsp; &thinsp; &#8239;(thin nbsp)
else
-- spaces can cause wrapping and can break tree structure, hence use span with nowrap class
Line 434 ⟶ 469:
--TODO test following alternative
--if nodeLabel:find( "%b<>") then stylingElementDetected = true end
-- we know the no break is handled when using {{clade label}}
if string.find(nodeLabel, '<div style="position:absolute;') then stylingElementDetected = false end
if stylingElementDetected == true then
return '<span class="nowrap">' .. nodeLabel .. '</span>'
else
--local nowrapString = string.gsub(nodeLabel," ", "&nbsp;") -- replace spaces with non-breaking space
local nowrapString = nodeLabel -- spaces are now handled by CSS "white-space:nowrap;""
if not nowrapString:find("UNIQ.-QINU") then -- unless a strip marker
nowrapString = string.gsub(nowrapString,"-", "&#8209;") -- replace hyphen with non-breaking hyphen (&#8209;)
Line 527 ⟶ 566:
function p.newickConverter(frame)
local newickString = frame.args['newickstring'] or mw.getCurrentFrame():getParent().argspargs['newick']
--if newickString == '{{{newickstring}}}' then return newickString end
Line 545 ⟶ 584:
 
local resultString = ''
local option = mw.getCurrentFrame():getParent().argspargs['option'] or ''
if option == 'tree' then
--show the transcluded clade diagram
Line 635 ⟶ 674:
local maxPatterns = 5
local i = 0
local pargs = mw.getCurrentFrame():getParent().argspargs
local pattern = pargs['newick'..tostring(childNumber)..'-pattern'] -- unnumbered option for i=1
local replace = pargs['newick'..tostring(childNumber)..'-replace']
Line 683 ⟶ 722:
while childNumber < maxChildren do -- preprocessing loop
childNumber = childNumber + 1 -- so we start with 1
local nodeLeaf,data = mw.getCurrentFrame():getParent().argspargs[tostring(childNumber)] or "" -- get data from |N=
local newickString = mw.getCurrentFrame():getParent().argspargs['newick'..tostring(childNumber)] or "" -- get data from |labelN=
local listString = mw.getCurrentFrame():getParent().argspargs['list'..tostring(childNumber)] or "" -- get data from |labelN=
if newickString ~= "" or nodeLeaf ~= "" or listString ~= "" then
--if nodeLeaf ~= "" then
Line 819 ⟶ 858:
function p.listConverter(frame)
local listString = frame.args['list'] or mw.getCurrentFrame():getParent().argspargs['list']
 
-- show the list string
Line 832 ⟶ 871:
 
local resultString = ''
local option = mw.getCurrentFrame():getParent().argspargs['option'] or ''
if option == 'tree' then
--show the transcluded clade diagram