Module:Exp App

Jump to navigation Jump to search

See Template:Exp App/Documentation.


local getArgs = require('Module:Arguments').getArgs
local p = {}
local platformTable = mw.loadData("Module:Data/Media/Platform").media
local mediaTypes = {
	"series","game","drama","manga","anthology","movie","book","novel","short story",
	"ova","stage","tv","cards","tabletop","pachinko","soundtrack","concert","show","platform"
}

--Allows removing of whitespace and line breaks from inputs; adapted from (https://www.lua.org/manual/2.4/node32.html)
local function trim(s) 
	local l = 1
	while string.sub(s,l,l) == ' ' do
		l = l+1
	end
	while string.sub(s,l,l+1) == '\n' do
		l = l+2
	end
	local r = string.len(s)
	while string.sub(s,r,r) == ' ' do
		r = r-1
	end
	while string.sub(s,r,r-1) == '\n' do
		r = r-2
	end
	return string.sub(s,l,r)
end

--Parse comma-separated values and make a list
local function parseList(input)
	local mediaList = {}
	if not input then
		return mediaList
	end
	local currentMedia = ""
	local parenthesesDepth = 0
	
	--Make sure to only split if comma is not inside of parentheses
	for i = 1, #input do
		local currentChar = input:sub(i,i)
		
		if currentChar == "," and parenthesesDepth == 0 then
			table.insert(mediaList, trim(currentMedia))
			currentMedia = ""
		else
			if currentChar == "(" then
				parenthesesDepth = parenthesesDepth + 1
			elseif currentChar == ")" then
				parenthesesDepth = parenthesesDepth - 1
			end
			currentMedia = currentMedia .. currentChar
		end
	end

	if currentMedia ~= "" then
		table.insert(mediaList, trim(currentMedia))
	end

	return mediaList
end

--Adds entries to the output based on input
local function populateOutput(frame,args,type)
	local output = ""
	local function handleEntry(media)
		if media:lower() == "p1psp" then
			media = "P1PSP (PSP)"
		elseif media:lower() == "lb1gg" then
			media = "LB1GG (GG)"
		end
		local appendation = ""
		local splitMedia, parenthetical = media:match("^(.-)%s*%((.-)%)$")
		
		if splitMedia and parenthetical then
			--Handle parenthetical (platform or otherwise)
			media = splitMedia
			if type == "game" and platformTable[parenthetical:lower()] then
				appendation = ' <span style="font-size: calc(2em / 3);">(' .. platformTable[parenthetical:lower()] .. ')</span>'
			else
				appendation = ' <span style="font-size: calc(2em / 3);">(' .. parenthetical:gsub("\\", "") .. ')</span>'
			end
		end
		output = output .. frame:expandTemplate{ title = "Link", args = { type, media } } .. appendation .. "<br/>"
	end
	--Game media
	if type == "game" then
		for i, media in ipairs(parseList(args[1])) do
			handleEntry(media)
		end
	--Non-game media
	else
		if args[type] then
			for i, media in ipairs(parseList(args[type])) do
				handleEntry(media)
			end
		end
	end

	return output
end

function p.main(frame)
	local args = getArgs(frame)
	local output = '<span class="tooltip tooltipsup"><sup>[[File:Exp Icon.svg|10px|link=]]</sup><span class="tooltiptext tooltiptextsup noexcerpt">'
	for i, type in ipairs(mediaTypes) do
		output = output .. populateOutput(frame, args, type)
	end
	output = output .. "</span></span>"
	return output
end

return p