<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/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://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3AClade%2Fconverter"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Clade/converter&amp;action=history"/>
	<updated>2026-06-07T03:11:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Clade/converter&amp;diff=135656&amp;oldid=prev</id>
		<title>imported&gt;Legoktm: Replace Module:No globals with require( &quot;strict&quot; )</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Clade/converter&amp;diff=135656&amp;oldid=prev"/>
		<updated>2022-10-23T04:16:44Z</updated>

		<summary type="html">&lt;p&gt;Replace &lt;a href=&quot;/research/Module:No_globals&quot; title=&quot;Module:No globals&quot;&gt;Module:No globals&lt;/a&gt; with require( &amp;quot;strict&amp;quot; )&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--require(&amp;#039;strict&amp;#039;)   -- 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[&amp;#039;newickstring&amp;#039;] or pargs[&amp;#039;newick&amp;#039;] or pargs[&amp;#039;newickstring&amp;#039;] then&lt;br /&gt;
		return p.newickConverter(frame)&lt;br /&gt;
	elseif frame.args[&amp;#039;list&amp;#039;] or pargs[&amp;#039;list&amp;#039;] 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[&amp;#039;newickstring&amp;#039;] or pargs[&amp;#039;newick&amp;#039;] or pargs[&amp;#039;newickstring&amp;#039;]&lt;br /&gt;
	&lt;br /&gt;
	--if newickString == &amp;#039;{{{newickstring}}}&amp;#039; then return newickString  end&lt;br /&gt;
&lt;br /&gt;
    newickString = require(&amp;#039;Module:Clade&amp;#039;).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 = &amp;#039;&amp;#039;&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 .. &amp;#039;{{clade&amp;#039;&lt;br /&gt;
	cladeString = cladeString .. p.newickParseLevel(newickString, levelNumber, childNumber) &lt;br /&gt;
	cladeString = cladeString .. &amp;#039;\r}}&amp;#039;  &lt;br /&gt;
&lt;br /&gt;
	local resultString = &amp;#039;&amp;#039;&lt;br /&gt;
    local option = mw.getCurrentFrame():getParent().args[&amp;#039;option&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    if option == &amp;#039;tree&amp;#039; 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;#039;&amp;lt;div&amp;gt;Modified Newick string:&amp;#039;&lt;br /&gt;
    	                .. &amp;#039;&amp;lt;pre&amp;gt;&amp;#039;..newickString..&amp;#039;&amp;lt;/pre&amp;gt;&amp;#039;	&lt;br /&gt;
	    -- show the converted clade structure&lt;br /&gt;
	    resultString = resultString .. &amp;#039;Output of clade template structure:&amp;#039;&lt;br /&gt;
	                                 .. &amp;#039;&amp;lt;pre&amp;gt;&amp;#039;.. cladeString ..&amp;#039;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;	&lt;br /&gt;
    end&lt;br /&gt;
    --resultString = frame:expandTemplate{ title = &amp;#039;clade&amp;#039;,  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, &amp;#039;%(.*%)&amp;#039;)                 -- 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 .. &amp;#039;|label&amp;#039;..childNumber..&amp;#039;=&amp;#039;  .. outerTerm&lt;br /&gt;
	cladeString = cladeString .. indent .. &amp;#039;|&amp;#039; .. childNumber..&amp;#039;=&amp;#039;  .. &amp;#039;{{clade&amp;#039;&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, &amp;#039;%(.*%)&amp;#039;) then&lt;br /&gt;
				--cladeString = cladeString .. indent .. &amp;#039;|y&amp;#039; .. i .. &amp;#039;=&amp;#039; .. 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 .. &amp;#039;|&amp;#039; .. i .. &amp;#039;=&amp;#039; .. restoredString --.. &amp;#039;(level=&amp;#039; .. levelNumber .. &amp;#039;)&amp;#039;&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 .. &amp;#039;}}&amp;#039;  &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[&amp;#039;indent&amp;#039;] or mw.getCurrentFrame().args[&amp;#039;indent&amp;#039;] 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[&amp;#039;list&amp;#039;] or mw.getCurrentFrame():getParent().args[&amp;#039;list&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
	-- show the list string&lt;br /&gt;
	local cladeString = &amp;#039;&amp;#039;&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 .. &amp;#039;{{clade&amp;#039;&lt;br /&gt;
	cladeString = cladeString .. p.listParseLevel(listString, levelNumber, childNumber) &lt;br /&gt;
	--cladeString = cladeString .. &amp;#039;\r}}&amp;#039;  &lt;br /&gt;
&lt;br /&gt;
	local resultString = &amp;#039;&amp;#039;&lt;br /&gt;
    local option = mw.getCurrentFrame():getParent().args[&amp;#039;option&amp;#039;] or &amp;#039;&amp;#039;&lt;br /&gt;
    if option == &amp;#039;tree&amp;#039; 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;#039;&amp;lt;pre&amp;gt;&amp;#039;..listString..&amp;#039;&amp;lt;/pre&amp;gt;&amp;#039;	&lt;br /&gt;
	    -- show the converted clade structure&lt;br /&gt;
	    resultString = resultString .. &amp;#039;&amp;lt;pre&amp;gt;&amp;#039;.. cladeString ..&amp;#039;&amp;lt;/pre&amp;gt;&amp;#039;	&lt;br /&gt;
    end&lt;br /&gt;
    --resultString = frame:expandTemplate{ title = &amp;#039;clade&amp;#039;,  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 .. &amp;#039;|label&amp;#039; .. child ..&amp;#039;=&amp;#039; ..  label	&lt;br /&gt;
	    	cladeString = cladeString .. indent .. &amp;#039;|&amp;#039; .. child ..&amp;#039;=&amp;#039; ..  &amp;#039;{{clade&amp;#039;&lt;br /&gt;
	    	                          .. p.listParseLevel(recombined,levelNumber,i)  &lt;br /&gt;
	    else&lt;br /&gt;
	    	cladeString = cladeString .. indent .. &amp;#039;|&amp;#039; .. child ..&amp;#039;=&amp;#039; ..  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 .. &amp;#039;}}&amp;#039;  &lt;br /&gt;
	return cladeString&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Legoktm</name></author>
	</entry>
</feed>