×
Create a new article
Write your page title here:
We currently have 2,839 articles on YumeWiki. Type your article name above or click on one of the titles below and start writing!



    YumeWiki
    2,839Articles

    Module:SoundtrackTable

    Documentation for this module may be created at Module:SoundtrackTable/doc

    local p = {}
    
    function split(str, sep, max)
        local z = #sep; sep = '^.-'..sep:gsub('[$%%()*+%-.?%[%]^]', '%%%0')
        local t,n,p, q,r = {},1,1, str:find(sep)
        while q and n~=max do
            t[n],n,p = str:sub(q,r-z),n+1,r+1
            q,r = str:find(sep,p)
        end
        t[n] = str:sub(p)
        return t
    end
    
    function trim(s)
       return s:match( "^%s*(.-)%s*$" )
    end
    
    function toMap(entries)
    	local fields = split(entries, '$$')
    	local map = {}
    	for var=1,#fields-1 do
    		local tmp = {}
    		local current = fields[var]
    		for k, s in pairs(split(current, '$')) do
    			local tmp2 = split(s, '=')
    			tmp[tmp2[1]] = tmp2[2]
    		end
    		map[var] = tmp
    	end
    	return map
    end
    
    function value(entries, i, j, args)
    	if not entries[i] then
    		return 'Out Of Range'
    	else
    		if not entries[i][j] or entries[i][j] == '' then
    			return args['default/' .. j] or ''
    		else
    			return entries[i][j]
    		end
    	end
    end
    
    function uniq(entries, i, j, args, columns)
    	if not entries[i] then
    		return 'Out Of Range'
    	end
    	if not args['unique/' .. j] then
    		return value(entries, i, j, args)
    	end
    	local ret = args['unique/' .. j]
    	for k, column in pairs(columns) do
    		ret = ret:gsub(column, value(entries, i, column, args))
    	end
    	return ret
    end
    
    function p.overrides(frame)
    	local args = frame:getParent().args
    	local result = ''
    	for key, value in pairs(args) do
    		local t = split(key, '/')
    		result = result .. '$id=' .. t[2] .. '$' .. t[1] .. '=' .. value .. '$$'
    	end
    	return result
    end
    
    function p.entry(frame)
    	local parent = frame:getParent()
    	local ids = {}
    	for i, value in pairs(split(parent.args["id"], ",")) do
    		ids[i] = trim(value)
    	end
    	local idIndexes = {}
    	for k, v in pairs(ids) do
    		idIndexes[v] = k
    	end
    	local filesBySpeed = {}
    	
    	local t = {}
    	for k, value in pairs(parent.args) do
    		local kSplit = split(k, '/')
    		local key, override = kSplit[1], kSplit[2]
    		if not t[key] then
    			t[key] = {}
    		end
    		if override then
    			if key and tonumber(override) then
    				filesBySpeed[override] = trim(value)
    			else
    				t[key][idIndexes[override]] = trim(value)
    			end
    		elseif value:find(",") then
    			t[key] = split(value, ",")
    			for i = 1, #ids do
    				t[key][i] = trim(t[key][i])
    			end
    		else
    			for i = 1, #ids do
    				if not t[key][i] then
    					t[key][i] = trim(value)
    				end
    			end
    		end
    	end
    	
    	for i = 1, #ids do
    		if t["file"] then
    			if not t["file"][i] then
    				t["file"][i] = filesBySpeed[t["speed"][i]]
    			end
    		end
    	end
    	
    	local result = ""
    	for i = 1, #ids do
    		local id = t["id"][i]
    		for key, tvalue in pairs(t) do
    			local value = tvalue[i] or ""
    			result = result .. "$" .. key .. "=" .. value
    		end
    		result = result .. "$$"
    	end
    	return result
    end
    
    local function compare(a, b)
    	return a["id"] < b["id"]
    end
    
    local function groupByID(entries)
    	local table1 = {}
    	for i, x in ipairs(entries) do
    		mw.logObject(x)
    		local id = x["id"]
    		if not table1[id] then
    			table1[id] = {}
    		end
    		for key, value in pairs(x) do
    			if not table1[id][key] then
    				table1[id][key] = {}
    			end
    			table1[id][key][value] = 4
    		end
    	end
    	local table2 = {}
    	for id, x in pairs(table1) do
    		local tmp = {}
    		for key, value in pairs(x) do
    			for entry, q in pairs(value) do
    				if not tmp[key] then
    					tmp[key] = entry
    				else
    					tmp[key] = tmp[key] .. '<br />' .. entry
    				end
    			end
    		end
    		table.insert(table2, tmp)
    	end
    	table.sort(table2, compare)
    	return table2
    end
    
    function p.generate(frame)
    	local args = frame.args
    	local entries = groupByID(toMap(frame.args['entries']))
    	local columns = split(frame.args['columns'], ',')
    	
    	local result = ""
    	for var, x in ipairs(entries) do
    		local subobject = "{{#subobject:BGM/" .. value(entries, var, "id", args)
    		for k, column in pairs(columns) do
    			local val = value(entries, var, column, args)
    			
    			subobject = subobject .. "\n|BGM/" .. column .. "="
    			if column == "location" then
    				local lines = split(val:gsub('<br />', '\n\n'), '\n\n')
    				local locations = {}
    				for _, line in pairs(lines) do
    					if line:find('%[%[') then
    						local namespaceName = split(split(line, ':')[1], '[')[3]
    						local pageName = split(split(split(line, ':')[2], '|')[1], '#')[1]
    						local displayName = split(split(line, '|')[2], ']')[1]
    						local label = split(split(line, ']')[3], ':')[2]
    						
    						local record = namespaceName .. ":" .. pageName .. ";"
    						if pageName == displayName then
    							record = record .. trim(label or "")
    						else
    							if not label then
    								record = record .. displayName
    							else
    								record = record .. displayName .. ": " .. trim(label)
    							end
    						end
    						--mw.log(record)
    						table.insert(locations, record)
    					else
    						table.insert(locations, line .. ";")
    					end
    				end
    				subobject = subobject .. table.concat(locations, ",") .. "|+sep=,"
    			else
    				subobject = subobject .. val
    			end
    			
    			local id = uniq(entries, var, column, args, columns)
    			if (id ~= uniq(entries, var - 1, column, args, columns)) then
    				local rowspan = 1
    				while (id == uniq(entries, var + rowspan, column, args, columns)) do
    					rowspan = rowspan + 1
    				end
    				if val ~= '' and frame.args['display/' .. column] then
    					val = frame.args['display/' .. column]:gsub('value', val)
    				end
    				result = result .. '|rowspan="' .. tostring(rowspan) .. '"|' .. val .. "\n"
    			end
    		end
    		if (var ~= #entries) then
    			result = result .. "|-\n"
    		end
    		
    		subobject = subobject .. "\n}}"
    		frame:preprocess(subobject)
    	end
    	return result
    end
    
    function p.formatRecord(frame)
    	local input = frame.args[1]
    	if (input == '') then
    		return ''
    	end
    	local s = split(input, ',')
    	local result = ''
    	for i, x in pairs(s) do
    		x = trim(x)
    		local m = x:match('^%d+')
    		local n = string.sub(x, #m + 1)
    		while (#m < 4) do
    			m = '0' .. m
    		end
    		result = result .. ',' .. m .. n
    	end
    	result = string.sub(result, 2)
    	return result
    end
    
    return p