Module:Sandbox/Jts1882/Test

require('strict') local fn = require('Module:Formatnum') local mm = require('Module:Math') local p ={} local pargs ={}

function p.lighthouse(frame) local page = frame.args['page'] local qid = frame.args['qid'] local property = frame.args['property'] local text = page .. ": instance of :" --local item = mw.wikibase.getEntity('P'..prop) --('P5354') if page then qid = mw.wikibase.getEntityIdForTitle(page) text = page .. ': instance of :' elseif qid then text = mw.wikibase.getLabel(qid) .. ' (' .. qid .. '): instance of :' else return "No page or qid given" end local statements = mw.wikibase.getBestStatements(qid, 'P31')  -- get instance of	for index, statement in pairs( statements ) do    	local instanceOfId if statement and statement.mainsnak and statement.mainsnak.datavalue then instanceOfId = statement.mainsnak.datavalue.value.id text = text .. '\n:::' .. instanceOfId .. ' (' .. mw.wikibase.getLabel(instanceOfId) .. ') ' --local item2 = mw.wikibase.getEntity(instanceOfId) -- returns full claims table [expensive,so just use best statements] --local statements2 = item2:getBestStatements( 'P279') local instanceOfStatements = mw.wikibase.getBestStatements(instanceOfId, 'P279') text = text .. '[subclass: ' for _, instanceOfStatement in pairs( instanceOfStatements ) do   			if instanceOfStatement.mainsnak and instanceOfStatement.mainsnak.datavalue then local subclassId = instanceOfStatement.mainsnak.datavalue.value.id text = text .. '\n:::::' .. subclassId .. ' (' .. mw.wikibase.getLabel(subclassId) .. ') ' end end text = text .. ']; '   	end

end return text end function p.testExpensive(frame, page, mode) local mode = frame.args['mode'] if not mode then mode = "makeTitle" end local title local page = frame.args['page'] if not page then p.errormsg("Target page not found") end -- TODO check for page existence here if mode == "new" then title = mw.title.new( page) --, ns)  	else    		title = mw.title.makeTitle( "Template", page)    	end   	if not title then return p.errormsg("Title object not created") end 	    if not title.exists then     	return "Invalid page name = " .. title.text  .. " (using mw.title." .. mode .. ")"    end   	return "Title = " ..title.text   .. " (using mw.title." .. mode .. ")" end

function p.getdomain(frame) local url = frame.args[1] local domain = string.match( url, "%/%/(.-)%/" ) local domain2 = mw.uri.new(url).host return domain .. "|" .. domain2 end

function p.getclade(frame) local page = frame.args['page'] if not page then p.errormsg("Target page not found") end -- TODO check for page existence here

local title = mw.title.new( page) --, ns)  	if not title then p.errormsg("Title not retrieved from page") end 	local content = title:getContent    local cladogram = p.matchClade(content)    if 1==2 then    	return  frame:preprocess(p.matchClade(cladogram))    else -- now do something with it    	return p.parseCladogram(frame, cladogram)    end

end function p.parseCladogram(frame, cladogram) local pattern = '|1=(.+)[|}]' --local value = p.matchClade(cladogram, pattern) for match in cladogram:gmatch(pattern) do     -- most inclusive if match:find("^") pattern      = ''                -- most inclusive (until last "}}", e.g. the taxonbar close) end

for match in content:gmatch(pattern) do     -- most inclusive for match2 in match:gmatch('%b{}') do   -- match paired brackets return match2 end end end

function p.getpage(frame) local page = frame.args['page'] local wrap = frame.args['wrap'] if not page then p.errormsg("Target page not found") end -- TODO check for page existence here local title = mw.title.new( page) --, ns)	if title then 		local content = title:getContent		if wrap then			content = '<' .. wrap .. '>' .. tostring(content) .. ''		end		return content	end

end

p.main = function(frame) -- called from template pargs = frame:getParent.args local output local page = pargs['page'] if not page then p.errormsg("Target page not found") end -- TODO check for page existence here local section = pargs['section'] or pargs['section1'] or pargs[1] if section then output = p._section(frame, page, section) end local label = pargs['label'] or pargs['label1'] or pargs[1] if label then output = p._label(frame, page, label) end local subtree = pargs['subtree'] or pargs['subtree1'] or pargs[1] if subtree then output = p._label(frame, page, subtree) end local wrap = pargs['wrap'] if wrap and (label or subtree) then local label1 = label or string.lower(subtree) if wrap ~= "" then label1 = wrap end output = "" end if output then return frame:preprocess(output) end return p.errormsg("No valid option for transclusion") end

p.test = function(frame)

--mw.title.makeTitle( namespace, title, fragment, interwiki ) --mw.title.new( text, namespace ) local page = "User:Jts1882/sandbox/test/Passeriformes" --"Atelopus andinus" local section = "Passeriformes" local ns = 1 if page:find("^User") then ns = 2 end if page:find("^Template") then ns = 10 end -- TODO check number --mw.site.namespaces.User.id -- returns 2 --TEST PAGE = User:Jts1882/sandbox return p._section(frame,page, "Passeroidea ", "Corvida", "Tyranni")

end

p.test_working_prototype = function(frame)

--mw.title.makeTitle( namespace, title, fragment, interwiki ) --mw.title.new( text, namespace ) local page = "User:Jts1882/sandbox/test/Passeriformes" --"Atelopus andinus" local ns = 1 if page:find("^User") then ns = 2 end if page:find("^Template") then ns = 10 end -- TODO check number --mw.site.namespaces.User.id -- returns 2 --TEST PAGE = User:Jts1882/sandbox local title = mw.title.new( page) --, ns)	if title then 		local content = title:getContent		local pattern = "(.+)"		pattern = "(.+)"		local value = string.match( content , pattern )		if value then			return frame:preprocess(value)			--return value	    else	    	return  "no match found"    	end	   return content	end 	return "Hello"	end --================================== exclude LABEL ================================================

p.xlabel = function (frame, page, ...) local page = frame.args[1] --"User:Jts1882/sandbox/test/Passeriformes" local label = frame.args[1] or frame.args['label'] or frame.args['label1'] -- page, target tree, subtrees to exclude ... --                      page,   include clade, multple clades to exclude | return p._xlabel (frame, page, frame.args[2], frame.args[3], frame.args[4], frame.args[5])

end p._xlabel = function (frame, page, target, ...) --	local page = "User:Jts1882/sandbox/test/Passeriformes" --	local label = frame.args[1] or frame.args['label'] local args = { ... }	local output = "" if not args[1] then return p.errormsg ("Label name not provided") end

local fullOutput = p._label(frame, page, target) --local fullOutput = p._section(frame, page, target)

output=fullOutput

local title = mw.title.new( mw.text.trim(page)) --, ns) -- creates object if page doesn't exist (and valid page name)	                                            --TODO: could use mw.title.makeTitle, but that needs ns	if title and title.exists then 		local content = title:getContent

for k,v in pairs(args) do			local section = mw.text.trim(v) local targetType = "label%d" local cladePrefix = "%d" if string.upper( section) == section then targetType = "target%u"              -- by convention subtrees must be uppercase cladePrefix = "subclade%u" end

--               label      =         name                        |n=   {...} local pattern = "("..targetType.."=[%s%p]*"..section .. "[%s%p]*.-"..cladePrefix.."=.-)(%b{})" -- ^^ this .- skips section tags before clade -- ^^this .- skips |sublabel and styling following the label (but can return wrong clade when a subtree) --for value in string.gmatch( fullOutput, pattern ) do           local value = string.match( fullOutput , pattern )

if value then local trimmedTree, matches = string.gsub(fullOutput, pattern, "%1".."replacement string")--replaces pattern with capture %1 --output = output .. trimmedTree --output = output .. " " .. trimmedTree .. " "               fullOutput = trimmedTree else output = output .. p.errormsg ("Failed to capture subclade with label "..section) end

end

else return ' No page title found ' end

if output ~= "" then return frame:preprocess(fullOutput) else return ' Section for label not found ' end end

--=============================== extract LABELS or SUBTREES======================================= p.label = function (frame, page, ...) local page = frame.args[1] --"User:Jts1882/sandbox/test/Passeriformes" local label = frame.args[1] or frame.args['label'] or frame.args['label1'] local wrap = frame.args['wrap'] local output = p._label (frame, page, frame.args[2], frame.args[3], frame.args[4], frame.args[5] ) if wrap then local label1 = string.lower(frame.args[2]) if wrap ~= "" then label1 = wrap end output = "" end return frame:preprocess(output) end

p._label = function (frame, page, ... ) --	local page = "User:Jts1882/sandbox/test/Passeriformes" --	local label = frame.args[1] or frame.args['label'] local args = { ... }	local output = "" if not args[1] then return p.errormsg ("Label name not provided") end local title = mw.title.new( mw.text.trim(page)) --, ns) -- creates object if page doesn't exist (and valid page name)	                                            --TODO: could use mw.title.makeTitle, but that needs ns	if title and title.exists then 		local content = title:getContent		local targetType = "label%d"		local cladePrefix = "%d"		for k,v in pairs(args) do			local section = mw.text.trim(v)			if string.upper( section) == section then				 targetType = "target%u"               -- by convention subtrees must be uppercase				 cladePrefix = "subclade%u"		    end

--              label =           name        |n=   {...} --local pattern = "label%d=[%s%p]*"..section .. "[%s%p]*%d=(%b{})" -- the .- skips section tags before clade --local pattern = "label%d=[%s%p]*"..section .. "[%s%p]*%d=.-(%b{})" -- this .- skips |sublabel and styling following the label (but can return wrong clade when a subtree) --local pattern = "label%d=[%s%p]*"..section .. ".-%d=.-(%b{})" local pattern = targetType.."=[%s%p]*"..section .. "[%s%p]*.-"..cladePrefix.."=.-(%b{})" -- for subtrees (how to capture right ) --local pattern = "[%u]=[%s%p]*"..section .. ".-%d=.-(%b{})" local value = string.match( content, pattern ) if value then -- what if we have something like {FABIDS}  "{%u}" local pattern = "({%u-})" if string.find(value, pattern ) then         -- if a subtree that hasn't been substituted. --local i,j,target = string.find(value, pattern) -- only one subtree for target in string.gmatch( value, pattern ) do	           	   	 local subtree = p._label (frame, page, target) if subtree then value = string.gsub(value, target, subtree) end --return value --value = value .. " (subtree needs transcluding)" end end --if (1==1) then return "Captured pattern=" .. (value or "no match") end section = string.lower(section) output = output .. value --output = output .. ""           else output = output .. p.errormsg ("Failed to capture subclade with label "..section) end

end

else return ' No page title found ' end

if output ~= "" then --return frame:preprocess(output) return output -- preprocess in entry function else return ' Section for label not found ' end end p.section = function (frame) -target page  sections return frame:preprocess(p._section(frame, mw.text.trim(frame.args[1]),frame.args[2],frame.args[3],frame.args[4],frame.args[5])) end p._section = function (frame,page,...) local args = { ... }	local output = "" local title = mw.title.new( page) --, ns) -- creates object if page doesn't exist (and valid page name)	                                            --TODO: could use mw.title.makeTitle, but that needs ns	if title and title.exists then 		local content = title:getContent		content = string.gsub( content , "%<%!%-%-.-%-%-%>", "" ) -- strip out comments		for k,v in pairs(args) do			local section = mw.text.trim(v)			-- note: using the non-greedy - in (.-) to allow capture of several sections 			    this allows internal clade structures to be closed without capturing sisters clades			    e.g. see section Tyranni in User:Jts1882/sandbox/test/Passeriformes						local pattern = "(.-)"

for value in string.gmatch( content, pattern ) do			   if value then if frame.args.wrap or frame:getParent.args.wrap then local label1 = frame.args.wrap or frame:getParent.args.wrap if label1 == "" then label1 = section end value = "" end output = output .. value end

end end

else return ' No page title found ' end if output ~= "" then --return frame:preprocess(output) return output -- leave preprocessing for entry function else return ' Section not found ' end

end

p.xsection = function (frame) local page = frame.args[1] --"User:Jts1882/sandbox/test/Passeriformes" local label = frame.args[1] or frame.args['label'] or frame.args['label1'] -- page, target tree, sections to exclude ... return frame:preprocess(p._xsection(frame, page ,frame.args[2],frame.args[3],frame.args[4],frame.args[5])) end

p._xsection = function (frame,page, target, ...) local args = { ... }	local output = "" local title = mw.title.new( page) --, ns) -- creates object if page doesn't exist (and valid page name)	                                            --TODO: could use mw.title.makeTitle, but that needs ns	if title and title.exists then 		local content = title:getContent		local fullOutput =  p._section(frame, page, target) 	    output=fullOutput		for k,v in pairs(args) do			local section = mw.text.trim(v)			-- note: using the non-greedy - in (.-) to allow capture of several sections 			    this allows internal clade structures to be closed without capturing sisters clades			    e.g. see section Tyranni in User:Jts1882/sandbox/test/Passeriformes						local pattern = "()(.-)()"

local value = string.match( fullOutput, pattern )

if value then local trimmedTree, matches = string.gsub(fullOutput, pattern, "replacement string")--replaces pattern with capture %1 output = output .. trimmedTree output = output .. " " .. trimmedTree .. " "               fullOutput = trimmedTree else output = output .. p.errormsg ("Failed to capture subclade with label "..section) end

end

else return ' No page title found ' end if output ~= "" then --return frame:preprocess(output) return output -- leave preprocessing for entry function else return ' Section not found ' end

end function p.populations(frame) local args = frame.args local page = "List of countries by population (United Nations)" local output = "" local data = {} local total = 0 local totalProjected = 0 local count = 0 local title = mw.title.new( page) --, ns) -- creates object if page doesn't exist (and valid page name)	                                            --TODO: could use mw.title.makeTitle, but that needs ns	if title and title.exists then 		local content = title:getContent

local pattern = "(.-)" for value in string.gmatch( content, pattern ) do			data['date']=value                                   -- date of latest data end local pattern = "(.-)" for value in string.gmatch( content, pattern ) do			data['date2']=value                                   -- date of previous data data['date2']=mw.getContentLanguage:formatDate('j F Y', value) end data['today'] = mw.getContentLanguage:formatDate('j F Y')     -- today's date (for formatting see https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time)

local ay = (frame:callParserFunction{ name = '#time', args = { "U", data['today'] } }                   - frame:callParserFunction{ name = '#time', args = { "U", data['date2'] } }) /60/60/24/365.2425 -- number of years since first date until today‬

for k,v in pairs(args) do			local country = mw.text.trim(v) -- get population data from section local section = country .. "_1"			local pattern = "(.-)"

for value in string.gmatch( content, pattern ) do			   if value then count=count+1 data[count] = {} data[count]['country'] = country data[count]['populationString'] = frame:preprocess(value) local raw = string.gsub(data[count]['populationString'], ",", "") -- strip formatting from number string data[count]['populationNumber'] = tonumber(raw) total = total + data[count]['populationNumber'] local section = country .. "_0"		          	local pattern2 = "(.-)" for value2 in string.gmatch( content, pattern2 ) do						data[count]['populationString2'] = frame:preprocess(value2) local raw = string.gsub(data[count]['populationString2'], ",", "") -- strip formatting from number string data[count]['populationNumber2'] = tonumber(raw) data[count]['populationIncrement']=data[count]['populationNumber'] - data[count]['populationNumber2'] data[count]['populationGrowth'] =data[count]['populationIncrement']/data[count]['populationNumber2'] data[count]['populationDouble'] = math.log( 2 ) / math.log(1 + data[count]['populationGrowth'])

data[count]['populationProjected'] = math.pow(data[count]['populationNumber2'], 1 - ay ) * math.pow(data[count]['populationNumber'], ay) totalProjected = totalProjected + data[count]['populationProjected'] end end end end local sort_function = function( a,b ) if (tonumber(a.populationNumber) > tonumber(b.populationNumber)) then               -- primary sort on 'population' -> a before b		        return true end end local test = "test: " local number=5435.12345 test= 	fn.formatNum(5435.12345,"en",0) --test=  frame:expandTemplate{ title = "formatnum", args = { totalProjected ,"en",0 } } --test=frame:callParserFunction{ name = 'formatnum', args = { totalProjected, decs=2 } } table.sort(data, sort_function) local i = 1 -- output table output = '{| class="wikitable sortable" style="text-align:right;" ' .. '\n!rowspan=2|#' .. '\n!rowspan=2|Country' .. '\n!rowspan=2|Projected population (' .. data['today'] .. ')' .. '\n!rowspan=2|Pct of total' .. '\n!rowspan=2|Population (' .. data['date'] .. ')' --.. '\n!rowspan=2|Pct of total' .. '\n!rowspan=2|Previous Population (' .. data['date2'] .. ')' .. '\n!colspan=2|Annual growth' .. '\n!rowspan=2|Doubling time (years)' .. '\n|-\n!Increment' .. '\n!Rate' while (data[i]) do          output = output .. '\n|-\n|' .. i           output = output .. '\n|style="text-align:left;" |' .. frame:expandTemplate{ title = "flagcountry", args = {data[i]['country'] } } output = output .. '\n| ' .. mm._precision_format(data[i]['populationProjected'],0) --output = output .. '\n| ' .. fn.formatNum(data[i]['populationProjected'],"en",0) output = output .. '\n| ' .. mm._precision_format(data[i]['populationProjected']/totalProjected*100,2) .. "%" -- projected output = output .. '\n| ' .. data[i]['populationString'] --output = output .. '\n| ' .. fn.formatNum(data[i]['populationNumber']/total*100,"en",2) .. "%"          output = output .. '\n| ' .. data[i]['populationString2'] output = output .. '\n| ' .. mm._precision_format(data[i]['populationIncrement'],0) output = output .. '\n| ' .. mm._round(data[i]['populationGrowth']*100,2) .. "%"          output = output .. '\n| ' .. mm._round(data[i]['populationDouble'],0) i=i+1 end output = output .. '\n|-\n! !! Total' .. '\n! style="text-align:right;" |' .. fn.formatNum(mm._round(totalProjected,0),"en",0) .. '\n! style="text-align:right;" | 100% ' .. '\n! style="text-align:right;" |' .. fn.formatNum(total,"en",0) --.. '\n! style="text-align:right;" | 100% ' .. '\n! || || ||' -- ..test output = output .. '\n|}' else return ' No page title found ' end

return output end

function p.firstToUpper(str) return (str:gsub("^%l", string.upper)) end p.errormsg = function (message) return ' ' .. message .. ' ' end

return p