Module:Clade/converter
Appearance
From Wikipedia, the free encyclopedia
You might want to create a documentation page for this Scribunto module.
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module's sandbox (create | mirror) and testcases (create) pages.
Add categories to the /doc subpage. Subpages of this module.
--require('strict') -- comment out until clade also uses noglobals localp={} localpargs=mw.getCurrentFrame():getParent().args --[[ =================== parser for conversion to clade structure ============================= Function p.newickConverter() convert Newick strings to clade format Usage: {{#invoke:Module:Sandbox/Jts1882/CladeN|newickConverter|newickstring={{{NEWICK_STRING}}} }} Function p.listConverter() convert wikitext-like lists to clade format use @ instead of * in wikitext to avoid processing Usage: {{#invoke:Module:Clade/converter|listConverter|list={{{LIST_STRING}}} }} ]] functionp.cladeConverter(frame) ifframe.args['newickstring']orpargs['newick']orpargs['newickstring']then returnp.newickConverter(frame) elseifframe.args['list']orpargs['list']then returnp.listConverter(frame) end end --[[ =================== Newick to clade parser function ============================= Function of convert Newick strings to clade format Usage: {{#invoke:Module:Sandbox/Jts1882/CladeN|newickConverter|newickstring={{{NEWICK_STRING}}} }} ]] functionp.newickConverter(frame) localnewickString=frame.args['newickstring']orpargs['newick']orpargs['newickstring'] --if newickString == '{{{newickstring}}}' then return newickString end newickString=require('Module:Clade').processNewickString(newickString,"")-- "childNumber") -- show the Newick string localcladeString='' locallevelNumber=1-- for depth of iteration localchildNumber=1-- number of sister elements on node (always one for root) -- converted the newick string to the clade structure cladeString=cladeString..'{{clade' cladeString=cladeString..p.newickParseLevel(newickString,levelNumber,childNumber) cladeString=cladeString..'\r}}' localresultString='' localoption=mw.getCurrentFrame():getParent().args['option']or'' ifoption=='tree'then --show the transcluded clade diagram resultString=cladeString else -- show the Newick string resultString='<div>Modified Newick string:' ..'<pre>'..newickString..'</pre>' -- show the converted clade structure resultString=resultString..'Output of clade template structure:' ..'<pre>'..cladeString..'</pre></div>' end --resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) } returnresultString end --[[ Parse one level of Newick string This function receives a Newick string, which has two components 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 i. a taxon name which just needs: |N=leafname ii. a Newick string which needs further processing through reiteration ]] functionp.newickParseLevel(newickString,levelNumber,childNumber) localcladeString="" localindent=p.getIndent(levelNumber) --levelNumber=levelNumber+1 localj=0 localk=0 j,k=string.find(newickString,'%(.*%)')-- find location of outer parenthesised term localinnerTerm=string.sub(newickString,j+1,k-1)-- select content in parenthesis localouterTerm=string.gsub(newickString,"%b()","")-- delete parenthetic term cladeString=cladeString..indent..'|label'..childNumber..'='..outerTerm cladeString=cladeString..indent..'|'..childNumber..'='..'{{clade' levelNumber=levelNumber+1 indent=p.getIndent(levelNumber) -- protect commas in inner parentheses from split; temporarily replace commas between parentheses localinnerTerm2=string.gsub(innerTerm,"%b()",function(n) returnstring.gsub(n,",%s*","XXX")-- also strip spaces after commas here end) --local s = p.strsplit(innerTerm2, ",") locals=mw.text.split(innerTerm2,",") locali=1 whiles[i]do localrestoredString=string.gsub(s[i],"XXX",",")-- convert back to commas localouterTerm=string.gsub(restoredString,"%b()","") ifstring.find(restoredString,'%(.*%)')then --cladeString = cladeString .. indent .. '|y' .. i .. '=' .. p.newickParseLevel(restoredString,levelNumber+1,i) cladeString=cladeString..p.newickParseLevel(restoredString,levelNumber,i) else cladeString=cladeString..indent..'|'..i..'='..restoredString--.. '(level=' .. levelNumber .. ')' end i=i+1 end -- end -- end splitting of strings cladeString=cladeString..indent..'}}' returncladeString end functionp.getIndent(levelNumber) localindent="\r" localextraIndent=pargs['indent']ormw.getCurrentFrame().args['indent']or0 whiletonumber(extraIndent)>0do indent=indent.." "-- an extra indent to make aligining compound trees easier extraIndent=extraIndent-1 end whilelevelNumber>1do indent=indent.." " levelNumber=levelNumber-1 end returnindent end --[[ =================== experimental list to clade parser function ============================= Function of convert wikitext-like listss to clade format - use @ instead of * in wikitext to avoid processing Usage: {{#invoke:Module:Clade/converter|listConverter|list={{{LIST_STRING}}} }} ]] functionp.listConverter(frame) locallistString=frame.args['list']ormw.getCurrentFrame():getParent().args['list'] -- show the list string localcladeString='' locallevelNumber=1-- for depth of iteration localchildNumber=1-- number of sister elements on node (always one for root) localindent=p.getIndent(levelNumber) -- converted the newick string to the clade structure cladeString=cladeString..indent..'{{clade' cladeString=cladeString..p.listParseLevel(listString,levelNumber,childNumber) --cladeString = cladeString .. '\r}}' localresultString='' localoption=mw.getCurrentFrame():getParent().args['option']or'' ifoption=='tree'then --show the transcluded clade diagram resultString=cladeString else -- show the list string --resultString = '<pre>'..listString..'</pre>' -- show the converted clade structure resultString=resultString..'<pre>'..cladeString..'</pre>' end --resultString = frame:expandTemplate{ title = 'clade', frame:preprocess(cladeString) } returnresultString end functionp.listParseLevel(listString,levelNumber,childNumber) localcladeString="" localindent=p.getIndent(levelNumber) levelNumber=levelNumber+1 locallist=mw.text.split(listString,"\n") locali=1 localchild=1 locallastNode=0 whilelist[i]do list[i]=list[i]:gsub("^@","")-- strip the first @ ifnotstring.match(list[i],"^@",1)then-- count children at this level (not beginning wiht @) lastNode=lastNode+1 end i=i+1 end i=1 whilelist[i]do --[[ pseudocode: if next value begins with @ we have a subtree, which must be recombined and past iteratively else we have a simple leaf ]] -- if the next value begins with @, we have a subtree which should be recombined iflist[i+1]andstring.match(list[i+1],"^@",1)then locallabel=list[i] i=i+1 localrecombined=list[i] whilelist[i+1]andstring.match(list[i+1],"^@",1)do recombined=recombined.."\n"..list[i+1] i=i+1 end cladeString=cladeString..indent..'|label'..child..'='..label cladeString=cladeString..indent..'|'..child..'='..'{{clade' ..p.listParseLevel(recombined,levelNumber,i) else cladeString=cladeString..indent..'|'..child..'='..list[i] end i=i+1 child=child+1 end cladeString=cladeString..indent..'}}' returncladeString end returnp