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 20:29, 19 June 2025 (sticky-header functioning). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

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"

    -- 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
            for j = i + 1, #raw_rows do
                if raw_rows[j].participation == row.participation then
                    rowspan = rowspan + 1
                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
            })
            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

    -- 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
            wikitext = wikitext .. string.format("|-\n| align=left | %s || colspan=%d rowspan=%d | %s\n",
                row.games_list[1],
                show_dual_ranks and 7 or 6,
                row.rowspan,
                row.participation)
            for i = 2, row.rowspan do
                wikitext = wikitext .. string.format("|-\n| align=left | %s\n", row.games_list[i])
            end
        else
            local tr_style = row.is_host and ' style="border: 3px solid purple"' or ""
            local line = "|-" .. tr_style .. "\n"
            line = line .. "| align=left | " .. row.games .. " || " .. row.athletes
            local g = bold_if_max(row.gold, max_gold)
            local s = bold_if_max(row.silver, max_silver)
            local b = bold_if_max(row.bronze, max_bronze)
            local t = bold_if_max(row.total, max_total)
            line = line .. string.format(" || %s || %s || %s || %s", g, s, b, t)

            if show_dual_ranks then
                if row.bgcolor_gold ~= "" then
                    line = line .. string.format(" || style=\"background-color:%s\" | %s", row.bgcolor_gold, row.gold_rank)
                else
                    line = line .. " || " .. (row.gold_rank or "")
                end
                if row.bgcolor_total ~= "" then
                    line = line .. string.format(" || style=\"background-color:%s\" | %s", row.bgcolor_total, row.total_rank)
                else
                    line = line .. " || " .. (row.total_rank or "")
                end
            else
                if row.bgcolor_gold ~= "" then
                    line = line .. string.format(" || style=\"background-color:%s\" | %s", row.bgcolor_gold, row.gold_rank)
                else
                    line = line .. " || " .. (row.gold_rank or "")
                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