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("^{{clade") then

local value = p.matchClade(match)

return p.parseCladogram(frame, value)

--return frame:preprocess(p.matchClade(match)) --found clade

else

return "no clade found" .. match

end

return "no match found in match : " ..match

end

--return frame:preprocess(value)

return "no match found in cladogram: " .. cladogram

end

function p.matchClade(content, pattern)

if not pattern then

pattern = '{{clade.-}}' -- least inclusive (until first "}}")

pattern = '{{clade.+}}' -- 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 = "{{clade |label1=" .. p.firstToUpper(label1) .. "|1=" .. 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 = "{{#tag:section||begin=Test}}(.+){{#tag:section||end=Test}}"

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 = "{{clade |label1=" .. p.firstToUpper(label1) .. "|1=" .. 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 .. "{{clade |label1=" .. p.firstToUpper(section) .. "|1=" .. value .. "}}"

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 = "{{clade |label1=" .. label1 .. "|1=" .. 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