Module:Sandbox/Tom.Reding/sandbox

From English Wikipedia @ Freddythechick
--use "local arg1 = frame.args[1]" for sandboxing via #invoke
--use "local args = frame:getParent().args" for use via template

local p = {}

function p.amdb( frame )
	local args_module = require('Module:Arguments')
	local args = args_module.getArgs(frame, {frameOnly = true})
	return (args[1] or 'no1')..'&'..(args['blah'] or 'noblah')
end

function p.yndb( frame )
	local yesno = require('Module:Yesno')
	return yesno(frame.args[1], true)
end

function p.sc( frame )
	local special_chars = '([%%%(%)%.%+%-%*%?%[%]%^%$])'
	local esc = frame.args[1]:gsub(special_chars, '%%%1') -- escape each special character
	return esc
end

function p.template_outside_shell( frame )
	local banner_name   = mw.text.trim(frame.args[1]) -- name of template to look for, e.g. WikiProject Finland
	local banner_name_u = mw.text.trim(frame.args[1]) -- name of template to look for, e.g. WikiProject Finland
	local banner_name_s = mw.text.trim(frame.args[1]) -- name of template to look for, e.g. WikiProject Finland
	local WPBSredirects = mw.loadData('Module:WikiProject banner/config').banner_shell.redirects -- load the current set of redirects to Template:WikiProjct banner shell
	local page_content = mw.title.getCurrentTitle():getContent() -- get content of current page
	local content_without_shell
	for capture in mw.ustring.gmatch(page_content, '%b{}') do -- look for possible templates on page
		for _, redirect in ipairs(WPBSredirects) do
			if mw.ustring.find(capture, '^{{%s*' .. redirect .. '%s*[|}].*}}$') then -- found a banner shell
				
				local capture_u = capture
				local capture_s = capture
				
				--[[ loop test ]]
				--local special_chars = {'%', '(', ')', '.', '+', '-', '*', '?', '[', ']', '^', '$'}
				--for _, chr in ipairs(special_chars) do -- escape each special character
				--	banner_name_u = mw.ustring.gsub(banner_name_u, '%'..chr, '%%'..chr)
				--	banner_name_s =     string.gsub(banner_name_s, '%'..chr, '%%'..chr)
				--	capture      = capture:gsub('%'..chr, '%%'..chr)			--returns '%�' when encountering "listas=100%"
				--	capture_u = mw.ustring.gsub(capture_u, '%'..chr, '%%'..chr)	--returns '%%'
				--	capture_s =     string.gsub(capture_s, '%'..chr, '%%'..chr)	--returns '%�'
				--end
				
				--[[ [set] test ]]
				local special_chars = '([%%%(%)%.%+%-%*%?%[%]%^%$])'
				banner_name = banner_name:gsub(special_chars, '%%%1') -- escape each special character
				capture   =    capture:gsub(special_chars, '%%%1')				--returns '%%' hen encountering "listas=100%"
				capture_u = mw.ustring.gsub(capture_u, special_chars, '%%%1')	--returns '%%'
				capture_s =     string.gsub(capture_s, special_chars, '%%%1')	--returns '%%'
				
				content_without_shell = mw.ustring.gsub(page_content, capture, '') -- remove banner shell content from page content
				if (true) then return '----\n'..banner_name..'\n==:gsub==\n'..capture..'\n==ustring==\n'..capture_u..'\n==string==\n'..capture_s..'\n==orig==\n'..content_without_shell end
				break -- ideally want to break out from both for loops now
			end
		end
		if content_without_shell then break end
	end
	local template_outside_shell
	if content_without_shell then -- banner shell was found
		if mw.ustring.find(content_without_shell, '{{%s*' .. banner_name .. '%s*[|}]') then -- found banner template outside of the shell
			template_outside_shell = true
		else -- banner template must be inside the shell
			template_outside_shell = false
		end
	else -- no banner shell on page
		template_outside_shell = 'no banner shell on page'
	end
	return template_outside_shell
end

function p.blind_epfc_test( frame )
	mw.incrementExpensiveFunctionCount()
	
	--return mw.getExpensiveFunctionCount() --returns nil
	--return mw.ExpensiveFunctionCount() --returns nil
	return mw.expensiveFunctionCount() --returns nil
end

function p.select_test( frame ) --not for table counting
	local t = { 1, 2, 3 }
	local c = table.concat(t, ',')
	local c2 = table.concat(t, ', ')
	
	--local s = select( '#', c )
	--return s --returns 1
	
	--local s = select( '#', t )
	--return s --returns 1
	
	local s = select( '#', c2 )
	return s --returns 1
end

function p.get_info( frame )
	local pn = frame.args[1]
	local wp = p.getSd( frame )
	local wd = p.getWdSd( frame )
	
	local dab_dne = 'dab_dne'
	local pn_dab = pn..' (disambiguation)'
	local pn_dab_result = dab_dne
	local pn_dab_content = mw.title.new(pn_dab):getContent() or nil
	if pn_dab_content then pn_dab_result = '[['..pn_dab..']]' end
	
	local info = '# [['..pn..']] - '..pn_dab_result..' - '..wp..';	'..wd
	
	if wp == 'wp_sd_dne' and 
	   wd == 'wd_sd_dne'
	then
		local R = p.isR( frame )
		if R then
			local R_content = mw.title.new(pn):getContent() or ''
			local R_target = mw.ustring.match(R_content, '^%s*#[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]%s*%[%[(.-)%]%]') or ''
			if R_target ~= '' then
				local R_pn = R_target
				frame.args[1] = R_pn
				local R_wp = p.getSd( frame )
				local R_wd = p.getWdSd( frame )
				
				local R_pn_dab = R_pn..' (disambiguation)'
				local R_pn_dab_result = dab_dne
				local R_pn_dab_content = mw.title.new(R_pn_dab):getContent() or nil
				if R_pn_dab_content then R_pn_dab_result = '[['..R_pn_dab..']]' end
				
				local R_info = '## [['..R_pn..']] - '..R_pn_dab_result..' - '..R_wp..';	'..R_wd
				return info..'\n'..R_info
			else
				return info..' (malformed #R)'
			end
		end
	end
	return info
end

function p.getWdSd( frame )
	local pn = frame.args[1]
	local args = { ['1'] = 'description',
				   ['page'] = pn }
	local sd = frame:expandTemplate{ title = 'Wikidata', args = args }
	if sd == '' then sd = 'wd_sd_dne' end
	return mw.text.trim(sd)
end

function p.getSd( frame )
	local pn = frame.args[1]
	local content = mw.title.new(pn):getContent() or ''
	local sd = mw.ustring.match(content, '{{%s*[Ss]hort ?[dD]escription%s*%|(.-)}}') or
			   mw.ustring.match(content, '{{%s*[Ss]hort ?desc%s*%|(.-)}}') or
			   mw.ustring.match(content, '{{%s*[Dd]es%s*%|(.-)}}') or
			   'wp_sd_dne'
	return mw.text.trim(sd)
end

function p.sizeof( frame )
	local out = ''
	for _, pn in pairs( frame.args ) do
		local content = mw.title.new(pn):getContent() or ''
		out = out..'#'..#content..'	'..pn..'\n'
	end
	return out
end

function p.blt( frame )
	local myBlacklist = require( 'Module:Taxonbar/blacklist' ).blacklist{ args = {} }

	local selfdocout = 'myVariable = {\n'
	for k, q in pairs( myBlacklist ) do
		selfdocout = selfdocout..'\t\''..k..'\' = '..q..',\n'
	end
	selfdocout = selfdocout..'}'
	local args = { ['lang'] = 'lua',
				   ['code'] = selfdocout }
	out = frame:expandTemplate{ title = 'Syntaxhighlight', args = args }
	return out
end

function p.isR( frame )
	local pn = frame.args[1]
	local title = mw.title.new( pn )
	return title.isRedirect
end

function p.argt( frame )
	local list = 'strict'
	local doc = 'doc'
	local strict = p.whitelist( frame, list, doc )
	local tstrict = p.whitelist( frame, list )
	return 'doc:\n\n'..strict..'\n\ntable[Q16521]:'..tstrict[Q16521]
end

function p.expandTemplate(frame)
	local Q = 'Q16521'
	local Q_expanded = frame:expandTemplate{ title = 'Q', args = { Q } }
	return Q_expanded
end

function p.whitelist( frame )
	local listType = frame.args[1]
	local documentation = frame.args[2]
	local acceptableInstanceOf_Strict = {
		['Q16521'] = 'taxon',
		['Q310890'] = 'monotypic taxon',
		['Q98961713'] = 'extinct taxon',
		['Q2568288'] = 'ichnotaxon',
		['Q23038290'] = 'fossil taxon',
		['Q47487597'] = 'monotypic fossil taxon',
		['Q58051350'] = 'paraphyletic group', --subclass of taxon
		['Q59278506'] = 'ootaxon',
	}
	local acceptableInstanceOf_Lax = {
		['Q42621'] = 'hybrid',
		['Q235536'] = 'incertae sedis',
		['Q713623'] = 'clade',
		['Q848328'] = 'serotype',
		['Q857968'] = 'candidatus',
		['Q17487588'] = 'unavailable combination',
	}
	local acceptableInstanceOf_All = {} --create IFF requested
	if listType == 'all' then
		for k, v in pairs( acceptableInstanceOf_Strict ) do
			acceptableInstanceOf_All[k] = v
		end
		for k, v in pairs( acceptableInstanceOf_Lax ) do
			acceptableInstanceOf_All[k] = v
		end
	end
	
	if (documentation == nil) or --module-use only; order & format irrelevant
	   (documentation and documentation == '') then
		local out = {}
		if listType == 'strict'  then out = acceptableInstanceOf_Strict['Q16521']
		elseif listType == 'lax' then out = acceptableInstanceOf_Lax['Q42621']
		elseif listType == 'all' then out = acceptableInstanceOf_All['Q17487588']
		end
		return out
	else
		local displayOrder_Strict = {
			'Q16521',		--taxon
			'Q310890',		--monotypic taxon
			'Q47487597',	--monotypic fossil taxon
			'Q2568288',		--ichnotaxon
			'Q23038290',	--fossil taxon
			'Q59278506',	--ootaxon
			'Q98961713',	--extinct taxon
			'Q58051350',	--paraphyletic group
		}
		local displayOrder_Lax = {
			'Q42621',		--hybrid
			'Q235536',		--incertae sedis
			'Q713623',		--clade
			'Q848328',		--serotype
			'Q857968',		--candidatus
			'Q17487588',	--unavailable combination
		}
		local displayOrder_All = {} --create IFF requested
		if listType == 'all' then
			--concatenate strict + lax display order tables
			local i = 0
			for _, v in pairs( displayOrder_Strict ) do
				i = i + 1
				displayOrder_All[i] = v
			end
			for _, v in pairs( displayOrder_Lax ) do
				i = i + 1
				displayOrder_All[i] = v
			end
		end
		
		local outOrder = {}
		if listType == 'strict'  then outOrder = displayOrder_Strict
		elseif listType == 'lax' then outOrder = displayOrder_Lax
		elseif listType == 'all' then outOrder = displayOrder_All
		end
		
		local out = ''
		for _, q in pairs( outOrder ) do
			local Q = frame:expandTemplate{ title = 'Q', args = { q } }
			out = out..'# '..Q..'\n'
		end
		return out
	end
	
end

function p.trr_test(frame)
	local getRegex = require('Module:Template redirect regex').main
	local tregex = getRegex(nil)
	return tregex or 'nil'
end

function p.string_match(frame)
	local r = "2008–09 in Scottish women's football"
	local regex_hyph  = '%d%d%d%d[–-]%d+'
	
--	if string.match(r, regex_hyph) then     --returns 'false'!
--	if mw.ustring.match(r, regex_hyph) then --returns 'true'
	if string.match(r, 'ball$') then --returns 'true'
		return 'true'
	else
		return 'false'
	end
end

function p.avoidself(frame)
	local currtitle = mw.title.getCurrentTitle()
	local testcases = string.match(currtitle.subpageText, '^testcases')
	local avoidself =  (currtitle.text ~= 'Navseasoncats' and 
						not string.match(currtitle.text, 'Navseasoncats with') and
						not string.match(currtitle.text, 'Navseasoncats.*/doc') and
						not string.match(currtitle.text, 'Navseasoncats.*/sandbox') and
						currtitle.nsText:gsub('_', ' ') ~= 'User talk' and -- [[phab:T369784]]
						(currtitle.nsText ~= 'Template' or testcases)) --avoid nested transclusion errors (i.e. {{Infilmdecade}})
	return  'text: '..currtitle.text..
			'<br/>nsText: "'..currtitle.nsText..'"'..
			'<br/>testcases: '..(testcases or 'nil')..
			'<br/>avoidself: '..tostring(avoidself)
end

function p.ttest(frame)							--#t
	local t0 = {}								--0
	local t1 = { [0] = 1 }						--0
	local t2 = { [1] = 1 }						--1
	local t31 = { [0] = 1, [1] = 1, [2] = 1  }	--2
	local t32 = { [2] = 1, [3] = 1, [4] = 1  }	--0
	local t33 = { [3] = 1, [4] = 1, [5] = 1  }	--0
	local tneg = { [-1]=1, [0] = 1, [1] = 1  }	--1
									--output
	return	'#t0: '      ..#t0..	--0
			'<br/>#t1: ' ..#t1..	--0
			'<br/>#t2: ' ..#t2..	--1
			'<br/>#t31: '..#t31..	--2
			'<br/>#t32: '..#t32..	--0
			'<br/>#t33: '..#t33..	--0
			'<br/>#tneg: '..#tneg..	--1
			'<br/>mw.log'..(mw.log( #t31 ) or '')
end

function p.indexcalctest(frame)
	local t = {}
	t[1+3] = 5
	return t[4] or 'nil' --returns 5 as expected
end

function p.fort(frame)
	local i = 0
	for i=1, 10 do
		i = i + 1
	end
	return i --returns '0' as expected
end

function p.whilet(frame)
	local i = 0
	while i < 10 do
		i = i + 1
	end
	return i --returns '10' as expected
end

function p.ifevaluationtest(frame)
	local cat1 = '2010s awards'
	local cat2 = '2020s awards'
	if mw.title.new(cat1, 'Category').exists and
	   mw.title.new(cat2, 'Category').exists
	then
		return 1
	end
	return 0
end

function p.zerotest(frame)
	local neg = -0               --displays '-0' as expected
	local nneg = tonumber('-0')  --displays '-0' as expected
	local pos = 0                --displays '-0' NOT as expected
	local ppos = tonumber('0')   --displays '0'
	local pppos = tonumber('+0') --displays '0' as expected
	local s = tostring(pos)      --displays '-0' NOT as expected
	local ss = tostring(ppos)    --displays '0'
	local t = (neg < 0) --false
	local tt = (s == '-0') --true
	local u = (neg == 0) --true
	local v = (neg == -0) --true
	return tostring(nneg)..' '..pppos..' '..s..' '..tostring(tt)..' '..tostring(v) --returns '-0 0 -0 true true'
end

function p.test(frame)
	local conf = require( "Module:Authority control" ).conf
	local out = ''
	for _, c in pairs( conf ) do
		out = out..'<br/>'..c[1]
	end
	return out
end

function p.iffalsetest(frame)
	local f = false
	if f then
		return 'f'
	else
		return 'endd' --debugger thinks "'end'" == "end"...
	end				  --returns endd, as expected
end

function p.fortest(frame)
	local out = ''
	for gs = 0, 5 do
		out = out..gs
	end
	return out --returns 012345
end

function p.regex_group_test(frame)
	local R = 'asdfasdf 2020–'
	local y, hyph, ending = mw.ustring.match(R, '^.-(%d+)([–-])(.*)$')
	return (y or 'nil')..', '..(hyph or 'nil')..', '..(ending or 'nil') --returns '2020, –,' as expected
end

function p.empty_regex_group_test(frame)
	local text = '2020–'
--	return (mw.ustring.match(text, '%d+([–-])$') or 'nil')   --returns –
--	return (mw.ustring.match(text, '%d+[–-]()$') or 'nil')   --returns 6
--	return (mw.ustring.match(text, '%d+[–-]($)') or 'nil')   --returns nil
	return (mw.ustring.match(text, '%d+[–-](.*)$') or 'nil') --returns '' as expected
end

function p.regex_gsub_test(frame)
	local cat1 = '2006 Super 14 season'
	local base1   = '"'..mw.ustring.gsub(cat1, '%d+[–-]?%d?%d?%d?%d?', '')..'"'            --returns " Super season"
	local base1_1 = '"'..mw.ustring.gsub(cat1, '%d+[–-]?%d?%d?%d?%d?', '', 1)..'"'         --returns " Super 14 season"
	local cat2 = '14 Super 2006 season'
	local base2   = '"'..mw.ustring.gsub(cat2, '%d+[–-]?%d?%d?%d?%d?', '')..'"'            --returns " Super season"
	local base2_2 = '"'..mw.ustring.gsub(cat2, '%d+[–-]?%d?%d?%d?%d?', '', 1)..'"'         --returns " Super 2006 season"
	local base2_3 = '"'..mw.ustring.gsub(cat2, '%d%d?%d?%d?[–-]?%d?%d?%d?%d?', '')..'"'    --returns " Super season"
	local base2_4 = '"'..mw.ustring.gsub(cat2, '%d%d?%d?%d?[–-]?%d?%d?%d?%d?', '', 1)..'"' --returns " Super 2006 season"
	return base2_4
end

function p.regex_gsub_test2(frame)
	--return (mw.ustring.gsub('123', '%d', '$1')[1] or 'n')..(mw.ustring.gsub('123', '%d', '')[2] or 'o')..(mw.ustring.gsub('123', '%d', '0') or 'p') --returns no000
	
	--local one, two = mw.ustring.gsub('123', '%d', '')
	--return (one or '1')..(two or '2') --returns 3
	--return (two or '2') --returns 3
	
	local one, two = mw.ustring.gsub('123', '%D', '')
	return (two or '?') --returns 0
end

function p.match_or_match_test(frame)
	local text = '2020–'
	
--	local y, hyph = mw.ustring.match(text, '(%d+)([–-])present$') or mw.ustring.match(text, '(%d+)([–-])$')
--	return (y or 'nil')..' & '..(hyph or 'nil') --returns 2020 & nil (NOT as expected)
	
--	local y, hyph = mw.ustring.match(text, '(%d+)([–-])$') or mw.ustring.match(text, '(%d+)([–-])present$')
--	return (y or 'nil')..' & '..(hyph or 'nil') --returns 2020 & nil (NOT as expected)
	
--	local y, hyph = mw.ustring.match(text, '(%d+)([–-])$')
--	return (y or 'nil')..' & '..(hyph or 'nil') --returns 2020 & – (as expected)
	
	local y, hyph = mw.ustring.match(text, '(%d+)([–-])present$')
	return (y or 'nil')..' & '..(hyph or 'nil') --returns nil & nil (as expected)
end

function p.mw_title_new_exists_wstest(frame)
	local cat = 'UK MPs 2015–2017 '..' '
	return tostring(mw.title.new( cat, 'Category' ).exists) --returns true (as expected)
end

function p.tonumber_test(frame)
	local cat = 'Wikipedia articles with VIAF identifiers' --800,000 something
	local lang = mw.getContentLanguage()
	local count = mw.site.stats.pagesInCategory(cat, 'pages') --800000
	local count_lang = lang:formatNum( count ) --800,000
--	return (count or 'nil')..', '..(tonumber(count or '-1') or '-2') --returns 880843, 880843 as expected
--	return (count_lang or 'nil')..', '..(tonumber(count_lang or '-1') or '-2') --returns 881,195, -2 --use lang:parseFormattedNumber() instead
	return (count_lang or 'nil')..', '..(lang:parseFormattedNumber(count_lang or '-1') or '-2') --returns 880,358, 880358
end

function p.lastedit_test(frame)
	return mw.title.new( 'Special:Contributions/Tom.Reding', 'Special' ):getContent() or 'nil'
end

function p.split_test(frame)
--	return table.concat( mw.text.split('test-1 two-',    ' '), ',' ) or 'nil'   --returns test-1,two- 
--	return table.concat( mw.text.split('test-1 two-',   '%s'), ',' ) or 'nil'   --returns test-1,two-
--	return table.concat( mw.text.split('test-1 two-',    '-'), ',' ) or 'nil'   --returns test,1 two,
--	return table.concat( mw.text.split('test-1 two-',  ' %-'), ',' ) or 'nil'   --returns test-1 two-
--	return table.concat( mw.text.split('test-1 two-',   ' -'), ',' ) or 'nil'   --returns t,e,s,t,-,1, ,t,w,o,-
--	return table.concat( mw.text.split('test-1 two-',   '- '), ',' ) or 'nil'   --returns test-1 two-
--	return table.concat( mw.text.split('test-1 two-', '%s%-'), ',' ) or 'nil'   --returns test-1 two-
	return table.concat( mw.text.split('test-1 two-', '[%s%-]'), ',' ) or 'nil' --returns test,1,two,
end

function p.regex_greed_and_nested_groups_test(frame)
	local t = '{{category redirect | {{title year}}s in New Spain }}'
	local r = '{{category redirect%s*|%s*([^{}]*{{([^{|}]+)}}[^{}]-)%s*}}'
	local g1, g2 = mw.ustring.match(t, r)
	return '"'..g1..'" "'..g2..'"' --returns "{{title year}}s in New Spain" "title year" as expected
end

function p.redirectTarget_test(frame)
--	local title  = mw.title.new( '1670s in Mexico', 'Category' )	--#R		--returns false
--	local title2 = mw.title.new( '1670s in New Spain', 'Category' )	--#R target	--returns false
	
--	local title  = mw.title.makeTitle( 'Category', '1670s in Mexico' )    --#R        --returns false
--	local title2 = mw.title.makeTitle( 'Category', '1670s in New Spain' ) --#R target --returns false
	
	local title  = mw.title.new( 'EL 61' )	--#R		--returns "Haumea"
	local title2 = mw.title.new( 'Haumea' )	--#R target	--returns "false"
	
	local rtitle  = title.redirectTarget  --only works in mainspace; ignorant of {{category redirect}}s
	local rtitle2 = title2.redirectTarget --only works in mainspace; ignorant of {{category redirect}}s
	if type(rtitle) == 'boolean' then
		return tostring(rtitle)..' '..tostring(rtitle)
	else
		return '"'..title.redirectTarget.baseText..'" "'..tostring(rtitle2)..'"'
	end
end

function p.frame_newChild_test(frame)
	local t = 'Category:1670s in Mexico'
	local child = frame:newChild{ title = t, args = {} }
--	return '"'..child:getTitle()..'"'  --returns "Category:1670s in Mexico" as expected
--	return '"'..child:expandTemplate{ title = 'title year', args = {} }..'"'           --returns "" NOT as expected...
--	return '"'..child:expandTemplate{ title = 'title year', args = { page = t } }..'"' --returns "1670" as expected
	return '"'..frame:expandTemplate{ title = 'title year', args = { page = t } }..'"' --returns "1670" as expected
end

function p.ns_test(frame)
	local title = mw.title.getCurrentTitle()
	local namespace = title.namespace
	return namespace
end

return p