<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mywikibiz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AClade%2Fconverter</id>
	<title>Module:Clade/converter - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mywikibiz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AClade%2Fconverter"/>
	<link rel="alternate" type="text/html" href="https://mywikibiz.com/index.php?title=Module:Clade/converter&amp;action=history"/>
	<updated>2026-06-14T06:58:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.3</generator>
	<entry>
		<id>https://mywikibiz.com/index.php?title=Module:Clade/converter&amp;diff=471287&amp;oldid=prev</id>
		<title>Zoran: Pywikibot 6.4.0</title>
		<link rel="alternate" type="text/html" href="https://mywikibiz.com/index.php?title=Module:Clade/converter&amp;diff=471287&amp;oldid=prev"/>
		<updated>2021-07-15T21:02:23Z</updated>

		<summary type="html">&lt;p&gt;Pywikibot 6.4.0&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--require('Module:No globals')   -- comment out until clade also uses noglobals&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local pargs = mw.getCurrentFrame():getParent().args&lt;br /&gt;
&lt;br /&gt;
--[[ =================== parser for conversion to clade structure =============================&lt;br /&gt;
    &lt;br /&gt;
    Function p.newickConverter()&lt;br /&gt;
        convert Newick strings to clade format&lt;br /&gt;
		Usage: {{#invoke:Module:Sandbox/Jts1882/CladeN|newickConverter|newickstring={{{NEWICK_STRING}}} }}&lt;br /&gt;
&lt;br /&gt;
    Function p.listConverter()&lt;br /&gt;
        convert wikitext-like lists to clade format&lt;br /&gt;
        use @ instead of * in wikitext to avoid processing&lt;br /&gt;
    	Usage: {{#invoke:Module:Clade/converter|listConverter|list={{{LIST_STRING}}} }}&lt;br /&gt;
]]&lt;br /&gt;
function p.cladeConverter(frame)&lt;br /&gt;
	if frame.args['newickstring'] or pargs['newick'] or pargs['newickstring'] then&lt;br /&gt;
		return p.newickConverter(frame)&lt;br /&gt;
	elseif frame.args['list'] or pargs['list'] then&lt;br /&gt;
		return p.listConverter(frame)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ =================== Newick to clade parser function =============================&lt;br /&gt;
&lt;br /&gt;
	Function of convert Newick strings to clade format&lt;br /&gt;
&lt;br /&gt;
	Usage: {{#invoke:Module:Sandbox/Jts1882/CladeN|newickConverter|newickstring={{{NEWICK_STRING}}} }}&lt;br /&gt;
]]&lt;br /&gt;
function p.newickConverter(frame)&lt;br /&gt;
	&lt;br /&gt;
	local newickString = frame.args['newickstring'] or pargs['newick'] or pargs['newickstring']&lt;br /&gt;
	&lt;br /&gt;
	--if newickString == '{{{newickstring}}}' then return newickString  end&lt;br /&gt;
&lt;br /&gt;
    newickString = require('Module:Clade').processNewickString(newickString,&amp;quot;&amp;quot;) -- &amp;quot;childNumber&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
	-- show the Newick string&lt;br /&gt;
	local cladeString = ''&lt;br /&gt;
	local levelNumber = 1           --  for depth of iteration&lt;br /&gt;
	local childNumber = 1           --  number of sister elements on node  (always one for root)&lt;br /&gt;
	&lt;br /&gt;
	--  converted the newick string to the clade structure&lt;br /&gt;
	cladeString = cladeString .. '{{clade'&lt;br /&gt;
	cladeString = cladeString .. p.newickParseLevel(newickString, levelNumber, childNumber) &lt;br /&gt;
	cladeString = cladeString .. '\r}}'  &lt;br /&gt;
&lt;br /&gt;
	local resultString = ''&lt;br /&gt;
    local option = mw.getCurrentFrame():getParent().args['option'] or ''&lt;br /&gt;
    if option == 'tree' then&lt;br /&gt;
	 	--show the transcluded clade diagram&lt;br /&gt;
		resultString =   cladeString    	&lt;br /&gt;
    else&lt;br /&gt;
    	-- show the Newick string&lt;br /&gt;
    	resultString = '&amp;lt;div&amp;gt;Modified Newick string:'&lt;br /&gt;
    	                .. '&amp;lt;pre&amp;gt;'..newickString..'&amp;lt;/pre&amp;gt;'	&lt;br /&gt;
	    -- show the converted clade structure&lt;br /&gt;
	    resultString = resultString .. 'Output of clade template structure:'&lt;br /&gt;
	                                 .. '&amp;lt;pre&amp;gt;'.. cladeString ..'&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;'	&lt;br /&gt;
    end&lt;br /&gt;
    --resultString = frame:expandTemplate{ title = 'clade',  frame:preprocess(cladeString) }&lt;br /&gt;
&lt;br /&gt;
    return resultString&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ Parse one level of Newick string&lt;br /&gt;
     This function receives a Newick string, which has two components&lt;br /&gt;
      1. the right hand term is a clade label: |labelN=labelname&lt;br /&gt;
      2. the left hand term in parenthesis has common delimited child nodes, each of which can be&lt;br /&gt;
           i.  a taxon name which just needs:  |N=leafname &lt;br /&gt;
           ii. a Newick string which needs further processing through reiteration&lt;br /&gt;
]]&lt;br /&gt;
function p.newickParseLevel(newickString,levelNumber,childNumber)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
	local cladeString = &amp;quot;&amp;quot;&lt;br /&gt;
	local indent = p.getIndent(levelNumber) &lt;br /&gt;
	--levelNumber=levelNumber+1&lt;br /&gt;
	&lt;br /&gt;
	local j=0&lt;br /&gt;
	local k=0&lt;br /&gt;
	j,k = string.find(newickString, '%(.*%)')                 -- find location of outer parenthesised term&lt;br /&gt;
	local innerTerm = string.sub(newickString, j+1, k-1)      -- select content in parenthesis&lt;br /&gt;
	local outerTerm = string.gsub(newickString, &amp;quot;%b()&amp;quot;, &amp;quot;&amp;quot;)   -- delete parenthetic term&lt;br /&gt;
&lt;br /&gt;
	cladeString = cladeString .. indent .. '|label'..childNumber..'='  .. outerTerm&lt;br /&gt;
	cladeString = cladeString .. indent .. '|' .. childNumber..'='  .. '{{clade'&lt;br /&gt;
&lt;br /&gt;
	levelNumber=levelNumber+1&lt;br /&gt;
	indent = p.getIndent(levelNumber)&lt;br /&gt;
	&lt;br /&gt;
		-- protect commas in inner parentheses from split; temporarily replace commas between parentheses&lt;br /&gt;
	    local innerTerm2 =  string.gsub(innerTerm, &amp;quot;%b()&amp;quot;,  function (n)&lt;br /&gt;
	                                         	return string.gsub(n, &amp;quot;,%s*&amp;quot;, &amp;quot;XXX&amp;quot;)  -- also strip spaces after commas here&lt;br /&gt;
	                                            end)&lt;br /&gt;
	&lt;br /&gt;
		--local s = p.strsplit(innerTerm2, &amp;quot;,&amp;quot;)&lt;br /&gt;
		local s = mw.text.split(innerTerm2, &amp;quot;,&amp;quot;)&lt;br /&gt;
		local i=1	&lt;br /&gt;
		while s[i] do	&lt;br /&gt;
			local restoredString = string.gsub(s[i],&amp;quot;XXX&amp;quot;, &amp;quot;,&amp;quot;)   -- convert back to commas&lt;br /&gt;
	&lt;br /&gt;
			local outerTerm = string.gsub(restoredString, &amp;quot;%b()&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			if string.find(restoredString, '%(.*%)') then&lt;br /&gt;
				--cladeString = cladeString .. indent .. '|y' .. i .. '=' .. p.newickParseLevel(restoredString,levelNumber+1,i) &lt;br /&gt;
				cladeString = cladeString  .. p.newickParseLevel(restoredString,levelNumber,i) &lt;br /&gt;
			else&lt;br /&gt;
				cladeString = cladeString .. indent .. '|' .. i .. '=' .. restoredString --.. '(level=' .. levelNumber .. ')'&lt;br /&gt;
			end&lt;br /&gt;
			i=i+1&lt;br /&gt;
		end&lt;br /&gt;
--    end -- end splitting of strings&lt;br /&gt;
&lt;br /&gt;
	cladeString = cladeString .. indent .. '}}'  &lt;br /&gt;
    return cladeString&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getIndent(levelNumber)&lt;br /&gt;
	local indent = &amp;quot;\r&amp;quot;&lt;br /&gt;
	local extraIndent = pargs['indent'] or mw.getCurrentFrame().args['indent'] or 0&lt;br /&gt;
	&lt;br /&gt;
	while tonumber(extraIndent) &amp;gt; 0 do&lt;br /&gt;
	    indent = indent .. &amp;quot; &amp;quot; -- an extra indent to make aligining compound trees easier&lt;br /&gt;
	    extraIndent = extraIndent - 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	while levelNumber &amp;gt; 1 do&lt;br /&gt;
		indent = indent .. &amp;quot;   &amp;quot;&lt;br /&gt;
		levelNumber = levelNumber-1&lt;br /&gt;
	end&lt;br /&gt;
	return indent&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[ =================== experimental list to clade parser function =============================&lt;br /&gt;
&lt;br /&gt;
    Function of convert wikitext-like listss to clade format&lt;br /&gt;
      - use @ instead of * in wikitext to avoid processing&lt;br /&gt;
&lt;br /&gt;
    Usage: {{#invoke:Module:Clade/converter|listConverter|list={{{LIST_STRING}}} }}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function p.listConverter(frame)&lt;br /&gt;
	&lt;br /&gt;
	local listString = frame.args['list'] or mw.getCurrentFrame():getParent().args['list']&lt;br /&gt;
&lt;br /&gt;
	-- show the list string&lt;br /&gt;
	local cladeString = ''&lt;br /&gt;
	local levelNumber = 1           --  for depth of iteration&lt;br /&gt;
	local childNumber = 1           --  number of sister elements on node  (always one for root)&lt;br /&gt;
	local indent = p.getIndent(levelNumber)&lt;br /&gt;
	--  converted the newick string to the clade structure&lt;br /&gt;
	cladeString = cladeString .. indent .. '{{clade'&lt;br /&gt;
	cladeString = cladeString .. p.listParseLevel(listString, levelNumber, childNumber) &lt;br /&gt;
	--cladeString = cladeString .. '\r}}'  &lt;br /&gt;
&lt;br /&gt;
	local resultString = ''&lt;br /&gt;
    local option = mw.getCurrentFrame():getParent().args['option'] or ''&lt;br /&gt;
    if option == 'tree' then&lt;br /&gt;
	 	--show the transcluded clade diagram&lt;br /&gt;
		resultString =   cladeString    	&lt;br /&gt;
    else&lt;br /&gt;
    	-- show the list string&lt;br /&gt;
		--resultString = '&amp;lt;pre&amp;gt;'..listString..'&amp;lt;/pre&amp;gt;'	&lt;br /&gt;
	    -- show the converted clade structure&lt;br /&gt;
	    resultString = resultString .. '&amp;lt;pre&amp;gt;'.. cladeString ..'&amp;lt;/pre&amp;gt;'	&lt;br /&gt;
    end&lt;br /&gt;
    --resultString = frame:expandTemplate{ title = 'clade',  frame:preprocess(cladeString) }&lt;br /&gt;
&lt;br /&gt;
    return resultString&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.listParseLevel(listString,levelNumber,childNumber)&lt;br /&gt;
&lt;br /&gt;
	local cladeString = &amp;quot;&amp;quot;&lt;br /&gt;
	local indent = p.getIndent(levelNumber)&lt;br /&gt;
    levelNumber=levelNumber+1&lt;br /&gt;
&lt;br /&gt;
    local list = mw.text.split(listString, &amp;quot;\n&amp;quot;)&lt;br /&gt;
    local i=1&lt;br /&gt;
    local child=1&lt;br /&gt;
    local lastNode=0&lt;br /&gt;
    &lt;br /&gt;
    while list[i]  do&lt;br /&gt;
		list[i]=list[i]:gsub(&amp;quot;^@&amp;quot;, &amp;quot;&amp;quot;)               -- strip the first @&lt;br /&gt;
		&lt;br /&gt;
		if not string.match( list[i], &amp;quot;^@&amp;quot;, 1 ) then -- count children at this level (not beginning wiht @)&lt;br /&gt;
			lastNode = lastNode+1  &lt;br /&gt;
		end&lt;br /&gt;
		i=i+1&lt;br /&gt;
	end&lt;br /&gt;
    i=1&lt;br /&gt;
&lt;br /&gt;
	while list[i]  do&lt;br /&gt;
&lt;br /&gt;
	    --[[ pseudocode: &lt;br /&gt;
	         if next value begins with @ we have a subtree, &lt;br /&gt;
	        	which must be recombined and past iteratively&lt;br /&gt;
	         else we have a simple leaf&lt;br /&gt;
	    ]]&lt;br /&gt;
&lt;br /&gt;
	    -- if the next value begins with @, we have a subtree which should be recombined&lt;br /&gt;
	    if list[i+1] and string.match( list[i+1], &amp;quot;^@&amp;quot;, 1 )  then&lt;br /&gt;
	    	&lt;br /&gt;
	        local label=list[i]&lt;br /&gt;
           	i=i+1&lt;br /&gt;
	    	local recombined = list[i]&lt;br /&gt;
	    	while list[i+1] and string.match( list[i+1], &amp;quot;^@&amp;quot;, 1 ) do&lt;br /&gt;
	    		recombined = recombined .. &amp;quot;\n&amp;quot; .. list[i+1] &lt;br /&gt;
	    		i=i+1&lt;br /&gt;
	    	end&lt;br /&gt;
	    	cladeString = cladeString .. indent .. '|label' .. child ..'=' ..  label	&lt;br /&gt;
	    	cladeString = cladeString .. indent .. '|' .. child ..'=' ..  '{{clade'&lt;br /&gt;
	    	                          .. p.listParseLevel(recombined,levelNumber,i)  &lt;br /&gt;
	    else&lt;br /&gt;
	    	cladeString = cladeString .. indent .. '|' .. child ..'=' ..  list[i]	&lt;br /&gt;
	    end&lt;br /&gt;
		i=i+1&lt;br /&gt;
		child=child+1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	cladeString = cladeString .. indent .. '}}'  &lt;br /&gt;
	return cladeString&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>
	</entry>
</feed>