Module:Individual placements table
Appearance
Documentation for this module may be created at Module:Individual placements table/doc
local p = {};
local trials = false;
local getArgs = require('Module:Arguments').getArgs
function p.trim(str)
-- trim string function
return (string.gsub(str, "^%s*(.-)%s*$", "%1"))
end
function p.split(inputstr, sep)
-- split string function
t = {}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
str = p.trim(str)
table.insert(t, str)
end
return t
end
function p.generateMedalCell(frame, place, limit)
-- generates mw code for proper medal cell display
-- if no number if found, no value
if place == nil then
return " ";
end
if place == "N" then
return "data-sort-value='1000' | N/A";
end
if string.find(place, '%d+') == nil then
return place;
end
-- some number is found
local number = string.match(place, '%d+');
local res = number;
if tonumber(number) <= limit then
res = "data-sort-value='" .. number .. "' class='place" .. number .. "' | " .. frame:preprocess("{{mdl|" .. number .. "}}");
end
if string.find(place, 'T') ~= nil and string.find(place, '%d') then
res = res .. "<sup>T</sup>";
trials = true;
end
return res
end
-- From: https://stackoverflow.com/a/27028488
function 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..'] = ' .. dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
function p.main(frame)
-- Main function
local args = getArgs(frame)
local tournaments = {}; -- {{'name': name, 'count': 3,}, {...}, ...}
local tournamentTeams = {}; -- {{{'name': 'Team A', 'medals': {3, 4}}, {...}, ...}}
local teamCount = 0; -- Number of total team columns in table
local events = {}; -- {'Anatomy and Physiology', 'Boomilever'}
-- Get tournament names
for k, v in pairs(args) do
if string.find(k, "tourney") ~= nil and string.find(k, 'team') == nil and string.find(k, 'medals') == nil then
-- Tourney name was found
num = tonumber(string.match(k, '%d+'));
if tournaments[num] ~= nil then
tournaments[num]["name"] = v;
else
tournaments[num] = {name = v};
end
elseif string.find(k, "tourney") ~= nil and string.find(k, "medals") ~= nil then
-- Number of medals for tourney was found
num = tonumber(string.match(k, '%d+'));
if tournaments[num] ~= nil then
tournaments[num]["medals"] = v;
else
tournaments[num] = {medals = v};
end
elseif string.find(k, "tourney") ~= nil and string.find(k, "team") ~= nil then
-- Team placements found
nums = string.gmatch(k, '%d+');
numsResult = {};
for num in nums do
table.insert(numsResult, tonumber(num));
end
tourneyNum, teamNum = numsResult[1], numsResult[2];
valueArgs = p.split(v, ",");
name = valueArgs[1];
medals = {unpack(valueArgs, 2)}
if tournamentTeams[tourneyNum] ~= nil then
tournamentTeams[tourneyNum][teamNum] = {name = name, medals = medals};
else
tournamentTeams[tourneyNum] = {[teamNum] = {name = name, medals = medals}};
end
-- Add one to tournament's team count
if tournaments[tourneyNum] ~= nil then
if tournaments[tourneyNum]["count"] == nil then
tournaments[tourneyNum]["count"] = 1;
else
tournaments[tourneyNum]["count"] = tournaments[tourneyNum]["count"] + 1;
end
else
tournaments[tourneyNum] = {count = 1};
end
teamCount = teamCount + 1;
elseif string.find(k, "event") ~= nil then
-- Event found
num = tonumber(string.match(k, '%d+'))
events[num] = v;
else
tournaments[1][k] = "Not found"
end
end
-- Start table
local res = "{| class='wikitable sortable' style='text-align: center; font-size: 90%;'\n|-\n"
res = res .. "!rowspan=2 | Events\n"
for k, v in pairs(tournaments) do
res = res .. "!colspan=" .. v["count"] .. " | " .. (v["name"] or "Not Found") .. "\n";
end
res = res .. "|-\n";
for k, v in pairs(tournamentTeams) do
-- For each tournament with teams
for k1, v1 in pairs(v) do
-- For each team
res = res .. "! " .. frame:preprocess("{{vertical header|" .. v1["name"] .. "|stp=1}}") .. "\n";
end
end
res = res .. "|-\n";
-- Add actual placements
eventCount = 1;
for i=1,#events do
tourneyCount = 1;
localTeamCount = 0;
res = res .. "|" .. events[i] .. "\n"
for j=1,teamCount do
localTeamCount = localTeamCount + 1;
if tournamentTeams[tourneyCount][localTeamCount] == nil then
tourneyCount = tourneyCount + 1;
localTeamCount = 1;
end
local limit = tonumber(tournaments[tourneyCount]["medals"]);
res = res .. "|" .. p.generateMedalCell(frame, tournamentTeams[tourneyCount][localTeamCount]["medals"][i], limit) .. "\n";
end
res = res .. "|-\n";
end
res = res .. "|}";
if trials then
res = res .. frame:preprocess("<div style=\"margin-left: 15px;\"><sup>T</sup> indicates a trial event.</div>");
end
return res;
end
return p;