Module:Sandbox/AB-me/Racing table

This is an old revision of this page, as edited by AB-me (talk | contribs) at 16:59, 5 July 2020. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local p = {}
local getArgs = require('Module:Arguments').getArgs

function p.main(frame)
	local args = getArgs(frame)
	return p._main(args)
end

function p._main(args)
	local eventsArg = mw.text.split(args['events'], ',')
	local participantsArg = mw.text.split(args['participants'], ',')
	local pointPositionsArg = mw.text.split(args['points'], ',') or {}
	local specialArg = mw.text.split(args['special'], ',') or {}
	
	local events = {} -- contains event information (short, name)
	local participants = {} -- contains participant information (short, name)
	local pointPositions = {} -- contains the distribution of points based on position
	local special = {} -- contains information about distribution of points not based on position (short, adj, num)
	local results = {} -- contains race results
	local points = {} -- contains points earned per participant/race
	local pointsTotal = {} -- contains points total per participant
	
	for i,v in ipairs(eventsArg) do events[i] = {short = v, name = args['event_' .. v]} end
	for i,v in ipairs(participantsArg) do participants[i] = {short = v, name = args['participant_' .. v]} end
	for i,v in ipairs(pointPositionsArg) do pointPositions[i] = tonumber(v) or 0 end
	for i,v in ipairs(specialArg) do
		local adj = true
		local num = 0
		local arg = args['specialPoints_' .. v]
		
		if (arg ~= null) then
			local startsWith = mw.ustring.sub(arg, 1, 1)
			if (startsWith ~= '+' and startsWith ~= '-') then
				adj = false
			end
			
			num = tonumber(arg)
		end
		
		special[i] = {short = v, adj = adj, num = tonumber(args['specialPoints_' .. v] or 0)}
	end
	
	-- Point handling and calculations
	for iEvents,vEvents in ipairs(events) do
		if (args['result_' .. vEvents['short']] ~= nil) then
			local eventResult = mw.text.split(args['result_' .. vEvents['short']], ',') or nil
			
			for iEventResult,vEventResult in ipairs(eventResult) do
				if (results[vEventResult] == nil) then
					results[vEventResult] = {}
				end
				
				--The position is put as the value, so that we can retrieve it from the participant in the table
				results[vEventResult][iEvents] = iEventResult
				
				if (points[vEventResult] == nil) then
					points[vEventResult] = {}
				end

				if (pointPositions[iEventResult] ~= nil) then
					points[vEventResult][iEvents] = pointPositions[iEventResult]
				end
				
				points[vEventResult][iEvents] = pointPositions[iEventResult]

			end
			
			-- Handling of special results
			for iSpecial,vSpecial in ipairs(special) do
				if (args['special_' .. vEvents['short'] .. '_' .. vSpecial['short']] ~= nil) then
					local eventSpecial = mw.text.split(args['special_' .. vEvents['short'] .. '_' .. vSpecial['short']], ',')
					
					for iEventSpecial,vEventSpecial in ipairs(eventSpecial) do
						if (results[vEventSpecial] == nil) then
							results[vEventSpecial] = {}
						end
						
						if (results[vEventSpecial][iEvents] == nil) then
							results[vEventSpecial][iEvents] = vSpecial['short']
						else
							results[vEventSpecial][iEvents] = results[vEventSpecial][iEvents] .. '<span style="margin:0 0.1em 0 0.1em;font-size:110%;"><sup>' .. vSpecial['short'] .. '</sup></span>'
						end
						
						if (vSpecial['adj'] == true and vSpecial['num'] ~= nil) then
							--points[vEventSpecial] = (points[vEventSpecial] or 0) + (vSpecial['num'] or 0)
						end
						--todo: non-adj special points
					end
					
				end
			end
			
		end
	end
	
	--Summation of points
	for iParticipants,vParticipants in ipairs(participants) do
		if (points[vParticipants] ~= nil) then
			for iPoints,vPoints in points[vParticipants] do
				if (vPoints ~= nil) then
					pointsTotal[vParticipants] = (pointsTotal[vParticipants] or 0) + vPoints
				end
			end
		end
	end
	
	--Writing table
	local stack = {}
	
	table.insert(stack, '{| class="wikitable" style="font-size: 85%; vertical-align:top; text-align:center""\n')
	table.insert(stack, '!style="vertical-align:middle;"|<abbr title="Position">Pos</abbr>\n')
	table.insert(stack, '!style="vertical-align:middle;"|'.. (args['text_participant'] or 'Participant') .. '\n')
	
	for i,v in ipairs(events) do
		table.insert(stack, '!' .. (v['name'] or v['short'] or i) .. '\n')
	end
	
	table.insert(stack, '!style="vertical-align:middle"|Points\n')
	
	for i,v in ipairs(participants) do
		table.insert(stack, '|-\n')
		table.insert(stack, '!' .. i .. '\n')
		table.insert(stack, '|style="text-align:left;"|' .. (v['name'] or v['short']) .. '\n')
		
		for j,w in ipairs(events) do
			table.insert(stack, '|')
			if (results[v['short']] ~= nil and results[v['short']][j] ~= nil) then
				table.insert(stack, results[v['short']][j])
			end
			table.insert(stack, '\n')
		end
		
		--todo
		--table.insert(stack, '!' .. '&ndash;\n')
		--table.insert(stack, '!' .. (pointsTotal[v['short']] or '&ndash;') .. '\n')
		--table.insert(stack, '!' .. v['short'] .. '\n')
		--table.insert(stack, '!' .. points[v['short']][1] or '&ndash' .. '\n')
	end
	
	table.insert(stack, '|}')
	
	return table.concat(stack)
end

	
return p;