Jump to content

Module:Medals table country

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Miria~01 (talk | contribs) at 14:34, 20 June 2025 (with optional flags). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

local flagicon_data = require("Module:Sandbox/Miria~01/data")

function p.render(frame)
    local args = frame:getParent().args
    local country = args["country"] or "Country"
    local maxRows = 50
    local show_dual_ranks = args["show_dual_ranks"] == "yes"
    local show_game_flags = args["show_game_flags"] == "yes"

    -- Determine season
    local season = (args["season"] or "summer"):lower()
    local is_winter = (season == "winter")
    local season_name = is_winter and "Winter" or "Summer"

    -- Step 1: Collect raw rows
    local raw_rows = {}
    for i = 1, maxRows do
        local games = args["row"..i.."_games"]
        if games and games ~= "" then
            local athletes_val = args["row"..i.."_athletes"]
            local participation = args["row"..i.."_participation"]
            local is_host = args["row"..i.."_host"] == "yes"

            if athletes_val == "no" then
                participation = "''did not participate''"
            end

            local gold = tonumber(args["row"..i.."_gold"]) or 0
            local silver = tonumber(args["row"..i.."_silver"]) or 0
            local bronze = tonumber(args["row"..i.."_bronze"]) or 0
            local rank_raw = args["row"..i.."_rank"] or ""
            local total_rank_raw = args["row"..i.."_total_rank"] or ""

            table.insert(raw_rows, {
                games = games,
                athletes_val = athletes_val,
                participation = participation,
                gold = gold,
                silver = silver,
                bronze = bronze,
                rank_raw = rank_raw,
                total_rank_raw = total_rank_raw,
                is_host = is_host,
            })
        end
    end

    -- Step 2: Process rows and merge
    local rows = {}
    local i = 1
    while i <= #raw_rows do
        local row = raw_rows[i]
        if row.participation and row.participation ~= "" then
            local rowspan = 1
            local is_host_in_merged = row.is_host
            for j = i + 1, #raw_rows do
                if raw_rows[j].participation == row.participation then
                    rowspan = rowspan + 1
                    if raw_rows[j].is_host then
                        is_host_in_merged = true
                    end
                else
                    break
                end
            end
            local merged_games = {}
            for k = i, i + rowspan - 1 do
                table.insert(merged_games, raw_rows[k].games)
            end
            table.insert(rows, {
                participation = row.participation,
                rowspan = rowspan,
                games_list = merged_games,
                merged = true,
                is_host = is_host_in_merged,
            })
            i = i + rowspan
        else
            local year = row.games:match("(%d%d%d%d)") or ""
            local athletes_num = tonumber(row.athletes_val) or 0
            local athletes_cell = string.format("[[%s at the %s %s Olympics|%d]]", country, year, season_name, athletes_num)

            local total = row.gold + row.silver + row.bronze

            local function make_rank_link(rank_raw)
                local rank_num = tonumber(rank_raw)
                local medal_table_title = string.format("%s %s Olympics medal table", year, season_name)
                if rank_num then
                    return string.format("[[%s|%d]]", medal_table_title, rank_num), rank_num
                elseif rank_raw == "–" then
                    return string.format("[[%s|–]]", medal_table_title), nil
                elseif rank_raw ~= "" then
                    return rank_raw, nil
                else
                    return "", nil
                end
            end

            local gold_rank_link, gold_rank_num = make_rank_link(row.rank_raw)
            local total_rank_link, total_rank_num = make_rank_link(row.total_rank_raw)

            local function rank_color(rank)
                if rank == 1 then return "#F7F6A8"
                elseif rank == 2 then return "#dce5e5"
                elseif rank == 3 then return "#ffdab9"
                else return ""
                end
            end

            local bgcolor_gold = rank_color(gold_rank_num)
            local bgcolor_total = rank_color(total_rank_num)

            table.insert(rows, {
                games = row.games,
                athletes = athletes_cell,
                gold = row.gold,
                silver = row.silver,
                bronze = row.bronze,
                total = total,
                gold_rank = gold_rank_link,
                total_rank = total_rank_link,
                bgcolor_gold = bgcolor_gold,
                bgcolor_total = bgcolor_total,
                is_host = row.is_host,
                merged = false
            })
            i = i + 1
        end
    end

    -- Helper: format game name with flagicon if enabled
	local function format_game_with_flag(game)
	    local expanded_game = frame:preprocess(game)
	    local year = expanded_game:match("(%d%d%d%d)")
	    if show_game_flags and year then
	        local flag_name = flagicon_data[season] and flagicon_data[season][year]
	        if flag_name then
	            return string.format("{{flagicon|%s}} %s", flag_name, expanded_game)
	        end
	    end
	    return expanded_game
	end

    -- Step 3: Medal stats
    local max_gold, max_silver, max_bronze, max_total = 0, 0, 0, 0
    local total_gold, total_silver, total_bronze = 0, 0, 0
    for _, row in ipairs(rows) do
        if not row.merged then
            total_gold = total_gold + row.gold
            total_silver = total_silver + row.silver
            total_bronze = total_bronze + row.bronze
            if row.gold > max_gold then max_gold = row.gold end
            if row.silver > max_silver then max_silver = row.silver end
            if row.bronze > max_bronze then max_bronze = row.bronze end
            if row.total > max_total then max_total = row.total end
        end
    end

    local total_medals = total_gold + total_silver + total_bronze
    local total_rank_raw = args["total_rank"] or ""
    local total_total_rank_raw = args["total_total_rank"] or ""

    local total_rank = total_rank_raw ~= "" and
        string.format("[[All-time Olympic Games medal table#Complete ranked medals (excluding precursors)|%s]]", total_rank_raw) or ""
    local total_total_rank = total_total_rank_raw ~= "" and
        string.format("[[All-time Olympic Games medal table#Complete ranked medals (excluding precursors)|%s]]", total_total_rank_raw) or ""

    -- Step 4: Begin table
    local sticky_header = frame:expandTemplate{ title = "sticky-header" }
    local wikitext = '{| class="wikitable sticky-header" style="text-align:center; font-size:90%;"\n'
    wikitext = wikitext .. "|-\n! Games !! Athletes"
    wikitext = wikitext .. ' !! style="background:gold; width:3.7em; font-weight:bold;"| Gold'
    wikitext = wikitext .. ' !! style="background:silver; width:3em; font-weight:bold;"| Silver'
    wikitext = wikitext .. ' !! style="background:#c96; width:3.7em; font-weight:bold;"| Bronze'
    wikitext = wikitext .. ' !! style="width:3.7em; font-weight:bold;"| Total'

    if show_dual_ranks then
        wikitext = wikitext .. ' !! style="width:4em; font-weight:bold;"| Rk<br/>[[Olympic medal table|<small>Gold Medals</small>]]'
        wikitext = wikitext .. ' !! style="width:4em; font-weight:bold;"| Rk<br/>[[Olympic medal table|<small>Total Medals</small>]]\n'
    else
        wikitext = wikitext .. ' !! style="width:3em; font-weight:bold;"| Rank\n'
    end

    -- Helper to bold maximums
    local function bold_if_max(val, max)
        return val > 0 and val == max and ("'''" .. val .. "'''") or tostring(val)
    end

    -- Step 5: Add table rows
    for _, row in ipairs(rows) do
        if row.merged then
            local colspan_val = show_dual_ranks and 7 or 6
            wikitext = wikitext .. string.format(
                "|-\n| align=left %s | %s || colspan=%d rowspan=%d %s | %s\n",
                row.is_host and 'style="border-top:3px solid purple; border-left:3px solid purple; border-bottom:3px solid purple;"' or "",
                format_game_with_flag(row.games_list[1]),
                colspan_val,
                row.rowspan,
                row.is_host and 'style="border-top:3px solid purple; border-bottom:3px solid purple; border-right:3px solid purple;"' or "",
                row.participation
            )
            for i = 2, row.rowspan do
                wikitext = wikitext .. string.format(
                    "|-\n| align=left %s | %s\n",
                    row.is_host and 'style="border-top:3px solid purple; border-bottom:3px solid purple;"' or "",
                    format_game_with_flag(row.games_list[i])
                )
            end
        else
            local line = "|-\n"
            local game_display = format_game_with_flag(row.games)
            if row.is_host then
                local middle_border = 'border-top: 3px solid purple; border-bottom: 3px solid purple;'
                local right_border = middle_border .. ' border-right: 3px solid purple;'
                line = line .. string.format('| align=left style="border-left: 3px solid purple; %s" | %s', middle_border, game_display)
                line = line .. string.format(' || style="%s" | %s', middle_border, row.athletes)
                line = line .. string.format(' || style="%s" | %s', middle_border, bold_if_max(row.gold, max_gold))
                line = line .. string.format(' || style="%s" | %s', middle_border, bold_if_max(row.silver, max_silver))
                line = line .. string.format(' || style="%s" | %s', middle_border, bold_if_max(row.bronze, max_bronze))
                line = line .. string.format(' || style="%s" | %s', middle_border, bold_if_max(row.total, max_total))
                if show_dual_ranks then
                    line = line .. string.format(' || style="%s%s" | %s', row.bgcolor_gold ~= "" and 'background-color:' .. row.bgcolor_gold .. '; ' or "", middle_border, row.gold_rank)
                    line = line .. string.format(' || style="%s%s" | %s', row.bgcolor_total ~= "" and 'background-color:' .. row.bgcolor_total .. '; ' or "", right_border, row.total_rank)
                else
                    line = line .. string.format(' || style="%s%s" | %s', row.bgcolor_gold ~= "" and 'background-color:' .. row.bgcolor_gold .. '; ' or "", right_border, row.gold_rank)
                end
            else
                line = line .. "| align=left | " .. game_display
                line = line .. " || " .. row.athletes
                line = line .. " || " .. bold_if_max(row.gold, max_gold)
                line = line .. " || " .. bold_if_max(row.silver, max_silver)
                line = line .. " || " .. bold_if_max(row.bronze, max_bronze)
                line = line .. " || " .. bold_if_max(row.total, max_total)
                if show_dual_ranks then
                    line = line .. (row.bgcolor_gold ~= "" and (' || style="background-color:' .. row.bgcolor_gold .. '" | ' .. row.gold_rank) or (" || " .. row.gold_rank))
                    line = line .. (row.bgcolor_total ~= "" and (' || style="background-color:' .. row.bgcolor_total .. '" | ' .. row.total_rank) or (" || " .. row.total_rank))
                else
                    line = line .. (row.bgcolor_gold ~= "" and (' || style="background-color:' .. row.bgcolor_gold .. '" | ' .. row.gold_rank) or (" || " .. row.gold_rank))
                end
            end
            wikitext = wikitext .. line .. "\n"
        end
    end

    -- Step 6: Total row
    wikitext = wikitext .. "|-\n! colspan=2 | Total"
    wikitext = wikitext .. string.format(" !! %d !! %d !! %d !! %d", total_gold, total_silver, total_bronze, total_medals)
    if show_dual_ranks then
        wikitext = wikitext .. " !! " .. total_rank .. " !! " .. total_total_rank .. "\n"
    else
        wikitext = wikitext .. " !! " .. total_rank .. "\n"
    end
    wikitext = wikitext .. "|}"

    local full_wikitext = sticky_header .. "\n" .. wikitext
    return frame:preprocess(full_wikitext)
end

return p