Module:AutomatedTabs

From Leaguepedia | League of Legends Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here.


local util_text = require('Module:TextUtil')
local util_table = require('Module:TableUtil')
local util_title = require('Module:TitleUtil')
local tabsheader = require('Module:TabsHeader')
local corr = require('Module:CorrespondingPageBox').makeBox
local sep = '%s*;%s*'

local p = {}
function p.main(json, data)
	local frame = mw.getCurrentFrame()
	p.getReverseFR(data.linkadjustments)
	local title = p.getCanonicalTitle(data.linkadjustments, data.basepage)
	local thisevent, thispath, tabstable = p.whereAreWe(json, title, data.basepage)
	
	local text = {}
	if data.navboxdata then p.makeNavboxes(frame, text, data.navboxdata, thisevent, title) end
	n = #text + 2
	if json then
		p.makeTabs(text, tabstable, data.linkadjustments, data.tabstype)
	end
	if data.corrdata then table.insert(text, n, p.makeCorrBox(data.corrdata, title)) end
	if data.after then text[#text+1] = data.after end
	local output = table.concat(text,'')
	return output
end

function p.getReverseFR(linkadjustments)
	-- this function lets us have two consecutive lookups in the find-replace
	-- that apply to the same title. otherwise one of the lookups would not get done properly
	-- we'll use the reversed args when we get canonical title, original order when we do
	-- the replacements back to live title
	if not linkadjustments then return end
	linkadjustments.fr_reverse = {
		replace = util_table.reverse(linkadjustments.fr.find),
		find = util_table.reverse(linkadjustments.fr.replace)
	}
	return
end

-- making parts of the page
function p.getCanonicalTitle(linkadjustments, basepage)
	local title = mw.title.getCurrentTitle()
	titlestr = title.nsText == 'Template' and basepage or title.prefixedText
	if not linkadjustments then
		return titlestr
	end
	return p.findReplace(titlestr, linkadjustments.fr_reverse)
end

function p.makeNavboxes(frame, text, data, thisevent, title)
	for i, navboxdata in ipairs(data) do
		if navboxdata.events.showAll or util_table.keyOf(navboxdata.events or {}, thisevent) or (navboxdata.titlematch and title:find(navboxdata.titlematch, 1, true)) then
			text[#text+1] = frame:expandTemplate({
				title = navboxdata.title,
				args = navboxdata.args
			})
		end
	end
	return
end

function p.makeCorrBox(args, title)
	local i = tonumber(args.showCorr) or p.getPageMatch(args.corr_titlematch,title,1)
	if not i or p.getPageMatch(args.corr_notitlematch and mw.text.split(args.corr_notitlematch[i] or '',sep), title) then
		return ''
	end
	return corr({
		find = mw.text.split(args.corr_find[i] or '',sep),
		replace = mw.text.split(args.corr_replace[i] or '',sep),
		display = args.corr_display and mw.text.split(args.corr_display[i] or '',sep),
		tournament = args.corr_tournament and mw.text.split(args.corr_tournament[i] or '',sep),
		targetpage = args.targetpage,
	})
end

function p.getPageMatch(matches, title, default)
	if not matches then return default end
	for k, v in ipairs(matches) do
		if v ~= '' and string.find(title,v,1,true) then
			return k
		end
	end
	return nil -- this is actually supposed to be nil, not default. default only applies when matches is nil.
end

function p.makeTabs(text, tabstable, linkadjustments, tabstype)
	for k, v in ipairs(tabstable) do
		p.linksToOutput(v.links, linkadjustments)
		text[#text+1] = tabsheader.fromTables(v.names, v.links, v.this, {
			tabstype = tabstype or 'header'
		})
	end
	return
end

function p.linksToOutput(links, linkadjustments)
	if not linkadjustments then return end
	for k, link in ipairs(links or {}) do
		links[k] = p.linkToOutput(link, linkadjustments.fr, linkadjustments.cd, k)
	end
	return
end

function p.linkToOutput(link, fr, cd, k)
	-- allow editors to give currentdata using either actual title or canonical title
	-- in the unlikely case that there's a cd entry for both canonical & actual
	-- we wouldn't want to change it twice. so make sure we didn't already change it when
	-- we do the second replacement. first replacement will be canonical, second is actual.
	-- the "proper" way to do this would be only replace canonical but this might be confusing.
	local used_cd
	if k ~= 1 and cd[link] then
		link = cd[link]
		used_cd = true
	end
	link = p.findReplace(link, fr)
	link = ((cd.force and cd.force[link]) or k~= 1) and not used_cd and cd[link] or link
	return link
end

-- where are we
function p.whereAreWe(json, titlestr, basepagestr)
	local title = mw.text.split(titlestr,'/')
	local basepage = mw.text.split(basepagestr,'/')
	local tbl = {}
	local i = #basepage + 1
	local thisevent = title[i] or 'Overview'
	local t = json
	local j = 1
	local thispath = ''
	while t do
		tbl[j] = {
			links = p.constructLinks(t.links,basepagestr),
			names = t.names,
			this = util_table.keyOf(t.links, title[i]) or 1
		}
		basepagestr = util_title.concatSubpage(basepagestr,t.links[tbl[j].this])
		thispath = t.path
		if t[title[i]] then
			t = t[title[i]]
			i = i + 1
		elseif tbl[j].this == 1 then
			t = t['Overview']
		else
			t = nil
		end
		j = j + 1
	end
	return thisevent, thispath, tbl
end

function p.constructLinks(links,path)
	local tbl = {}
	for i, link in ipairs(links) do
		tbl[i] = util_title.concatSubpage(path, link)
	end
	return tbl
end

-- Processing utils
function p.newIndex(base, extension)
	-- concatenate the two but don't add a / if the 2nd argument is empty
	if not base and extension == 'Overview' then
		return 'events/Overview'
	elseif not base or base == '' or base == 'events' then
		return extension
	elseif extension == '' or not extension then
		return base
	else
		return base .. '/' .. extension
	end
end

function p.findReplace(link, fr)
	local find = fr.find
	local replace = fr.replace
	for k, v in ipairs(find) do
		link = string.gsub(link, util_text.escape(v), util_text.escape(replace[k]))
	end
	return link
end

return p