local p = {}
local getArgs = require('Module:Arguments').getArgs
local DEFAULT_CODE = 'default' .. os.time()
local data = {
events = {},
eventColumns = 1,
participants = {},
pointSystems = {},
results = {},
notes = {},
texts = { pos = '<abbr title="Position">Pos.</abbr>', participant = 'Participant', points = 'Points' },
styles = { pos = { '#FFFFBF', '#DFDFDF', '#FFDF9F' }, pts = '#DFFFDF', noPts = '#CFCFFF', notes = { Ret = '#EFCFFF', DNQ = '#FFCFCF', DNPQ = '#FFCFCF', DSQ = 'background-color:#000000;color:white', DNS = '#FFFFFF', C = '#FFFFFF' } }
}
--local debug = ''
function p.main(frame)
local args = getArgs(frame)
return p._main(args)
end
function p._main(args)
p.handleArg('eventColumns', args.eventColumns, 'number')
p.handleCsvArg('events', args.events)
p.handleItemArgs('events', 'event', 'name', 'string', args)
p.handleItemArgs('events', 'eventColumns', 'columns', 'number', args)
p.handleCsvArg('participants', args.participants)
p.handleCsvArg('notes', args.notes)
p.handleItemArgs('notes', 'note', 'name', 'string', args)
-- Handling of default pointSystem
if (args.pointSystem ~= nil) then
if (args.pointSystems == nil) then
args.pointSystems = DEFAULT_CODE
else
args.pointSystems = DEFAULT_CODE .. ',' .. args.pointSystems
end
args['pointSystem_' .. DEFAULT_CODE] = args.pointSystem
end
if (args.pointSystems ~= nil) then
p.handleCsvArg('pointSystems', args.pointSystems)
p.handleItemArgsCsv('pointSystems', args.pointSystems, 'pos', 'number', args)
end
p.handleItemArgsCsv('events', 'eventPointSystems', 'pointSystems', 'string', args)
p.handleItemArgs('participants', 'participant', 'name', 'string', args)
p.handleItemArgs('texts', 'text', nil, 'string', args)
local colCount = 0
for i,v in ipairs(data.events) do
for j = 1, v.columns do
colCount = colCount + 1
if (j == 1) then
p.handleResult(colCount, (args['result_' .. v.code] or args['result_' .. v.code .. '_1']))
for k,w in ipairs(data.notes) do
p.handleResultNotes(colCount, (args['resultNotes_' .. v.code .. '_' .. w.code] or args['resultNotes_' .. v.code .. '_1' .. '_' .. w.code]), w.code)
end
else
p.handleResult(colCount, args['result_' .. v.code .. '_' .. j])
for k,w in ipairs(data.notes) do
p.handleResultNotes(colCount, args['resultNotes_' .. v.code .. '_' .. j .. '_' .. w.code], w.code)
end
end
end
end
--p.handleResult()
-- Draw table
local stack = {}
--table.insert(stack, '<code><nowiki>' .. debug .. '</nowiki></code>\n\n')
table.insert(stack, '{| class="wikitable" style="font-size:85%; text-align:center;"')
p.writeTableHeader(stack)
for i,v in ipairs(data['participants']) do
p.writeTableRow(stack, v)
end
p.writeTableHeader(stack)
table.insert(stack, '|}')
return table.concat(stack)
end
function p.handleArg(key, value, type)
if (value ~= nil) then
data[key] = p.valueToType(value, type)
end
end
function p.handleCsvArg(key, value)
if (value ~= nil) then
local split = mw.text.split(value, ',')
if (data[key] == nil or #data[key] == 0) then
for i,v in ipairs(split) do
data[key][i] = p.handleCsvArgItem(key, v, i)
end
end
end
end
function p.handleCsvArgItem(key, v, i)
if (key == 'events') then
return { code = v, name = v, columns = data['eventColumns'], pointSystems = { DEFAULT_CODE } }
elseif (key == 'participants') then
return { code = v, name = v, pos = i, results = {}, resultNotes = {}, points = {} }
elseif (key == 'pointSystems') then
return { code = v, pos = {}, notes = {} }
else
return { code = v, name = v }
end
end
function p.handleItemArgs(key, argPrefix, property, type, args)
local arg = {}
for k,v in pairs(data[key]) do
arg = args[argPrefix .. '_' .. (v['code'] or k)]
if (arg ~= nil) then
if (property ~= nil) then
v[property] = p.valueToType(arg, type)
else
data[key][k] = p.valueToType(arg, type)
end
end
end
end
function p.handleItemArgsCsv(key, argPrefix, property, type, args)
local arg = {}
for k,v in pairs(data[key]) do
arg = args[argPrefix .. '_' .. (v['code'] or k)]
if (arg ~= nil) then
local split = mw.text.split(arg, ',')
for j,w in ipairs(split) do
v[property][j] = p.valueToType(w, type)
end
end
end
end
function p.handleResult(column, csv)
if (csv ~= nil) then
--debug = debug .. 'Handling column ' .. column .. ' with content ' .. csv .. '\n\n'
local split = mw.text.split(csv, ',')
local res = {}
for i,v in ipairs(split) do
res[v] = i
end
for i, v in ipairs(data.participants) do
if v.results[column] ~= nil then
v.results[column].pos = res[v.code]
else
v.results[column] = { pos = res[v.code], pts = tonumber(res[v.code]), notes = { } }
end
end
end
end
function p.handleResultNotes(column, csv, noteCode)
if (csv ~= nil) then
local split = mw.text.split(csv, ',')
local res = {}
for i,v in ipairs(split) do
res[v] = 1
end
for i,v in ipairs(data.participants) do
if res[v.code] ~= nil then
if v.results[column] ~= nil then
table.insert(v.results[column].notes, noteCode)
else
v.results[column] = { pos = nil, pts = 0, notes = { noteCode } }
end
end
end
end
end
function p.valueToType(value, type)
if (type == 'number') then
return tonumber(value)
else
return value
end
end
-- Render functions
function p.writeTableHeader(stack)
table.insert(stack, '|-\n')
table.insert(stack, '! ' .. data.texts.pos .. '\n')
table.insert(stack, '!' .. data.texts.participant .. '\n')
if (#data['events'] > 0) then
for i,v in ipairs(data['events']) do
table.insert(stack, '!colspan="' .. v.columns .. '"|' .. v.name .. '\n')
end
end
table.insert(stack, '!' .. data.texts.points .. '\n')
end
function p.writeTableRow(stack, participant)
table.insert(stack, '|-\n')
table.insert(stack, '!' .. (participant['pos'] or '–') .. '\n')
table.insert(stack, '|style="text-align:left;"|' .. participant['name'] .. '\n')
local colCount = 0
for i,v in ipairs(data['events']) do
for j=1,v['columns'] do
colCount = colCount + 1
--table.insert(stack, '|' .. (participant.results[colCount] or '') .. '\n')
if participant.results[colCount] ~= nil then
p.writeTableCellResult(stack, participant.results[colCount].pos, participant.results[colCount].notes)
else
p.writeTableCellResult(stack, nil, nil)
end
end
end
--table.insert(stack, '!' .. '0' .. '\n')
p.writeTableCellSum(stack, participant)
end
function p.writeTableCellResult(stack, pos, notes)
p.writeTableCellResultStyle(stack, pos)
if (pos ~= nil and notes ~= nil and #notes > 0) then
table.insert(stack, pos)
for i,v in ipairs(notes) do
table.insert(stack, '<span style="margin:0 0 0 0.1em;"><sup>' .. v .. '</sup></span>')
end
elseif pos ~= nil then
table.insert(stack, pos)
elseif notes ~= nil and #notes > 0 then
local firstNote = true
for i,v in ipairs(notes) do
if firstNote then
table.insert(stack, v)
else
table.insert(stack, '<span style="margin:0 0 0 0.1em;"><sup>' .. v .. '</sup></span>')
end
firstNote = false
end
end
table.insert(stack, '\n')
end
function p.writeTableCellSum(stack, participant)
table.insert(stack, '!')
sum = 0
for i,v in ipairs(participant.results) do
sum = sum + (v.pts or 0)
end
table.insert(stack, sum)
table.insert(stack, '\n')
end
function p.writeTableCellResultStyle(stack, pos)
if data.styles.pos[pos] ~= nil then
table.insert(stack, '|style="' .. p.getStyle(data.styles.pos[pos]) .. '"')
end
table.insert(stack, '|')
end
function p.getStyle(styleString)
if not string.find(styleString, ':', 1, true) then
return 'background-color:' .. styleString
end
return styleString
end
--debug
function p.dump(o)
if type(o) == 'table' then
local s = '{ '
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. p.dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
return p;