Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:TopGoalscorers

From Wikipedia, the free encyclopedia
local p = {}

-- Hücre içi metinleri temizleme fonksiyonu (vikilink ve etiketleri sadeleştirir)
local function cleanText(text)
    if not text then return '' end
    text = text:gsub('%[%[[^%]|]*|([^%]]*)%]%]', '%1') -- [[Sayfa|Görünen]] -> Görünen
    text = text:gsub('%[%[([^%]]*)%]%]', '%1')         -- [[Sayfa]] -> Sayfa
    text = text:gsub('{{[^}]*}}', '')                   -- Şablonları kaldır
    text = text:gsub('<[^>]*>', '')                     -- HTML etiketlerini kaldır
    text = text:gsub('&nbsp;', ' ')
    text = mw.text.decode(text)
    return mw.text.trim(text)
end

-- Hücre başındaki stil ve parametreleri temizleme (örneğin: style="..." | Değer)
local function getCellContent(cellStr)
    cellStr = mw.text.trim(cellStr or '')
    -- Şablon ve bağlantıların içindeki boru (|) işaretlerini maskele
    local masked = cellStr:gsub('%b{}', function(s) return string.rep('_', #s) end)
    masked = masked:gsub('%b[]', function(s) return string.rep('_', #s) end)
    
    local pipePos = masked:find('|')
    if pipePos then
        return mw.text.trim(cellStr:sub(pipePos + 1))
    else
        return cellStr
    end
end

-- Olay türünü (Normal Gol / Penaltı / Geçersiz) belirleme
local function getGoalEventType(cellText)
    if not cellText then return 'invalid' end
    local s = cellText:lower()
    
    -- Kırmızı kart kontrolü
    if s:find('sent off', 1, true) or s:find('sent_off', 1, true) or s:find('red_card', 1, true) or s:find('red card', 1, true) then
        return 'invalid'
    end
    
    -- Kaçan penaltı kontrolü
    if s:find('penmiss', 1, true) or s:find('pen_miss', 1, true) or s:find('penalty miss', 1, true) or s:find('penalty_miss', 1, true) or s:find('missed penalty', 1, true) or s:find('missed_penalty', 1, true) then
        return 'invalid'
    end
    
    -- Kendi kalesine gol kontrolü
    if s:find('o.g.', 1, true) or s:find('own goal', 1, true) or s:find('own_goal', 1, true) then
        return 'invalid'
    end

    -- Sarı kart veya oyuncu değişikliği kontrolü
    if s:find('yel', 1, true) or s:find('yellow', 1, true) or s:find('subon', 1, true) or s:find('suboff', 1, true) then
        return 'invalid'
    end
    
    -- Penaltı golü
    if s:find('pengoal', 1, true) or s:find('pen_goal', 1, true) or s:find('penalty goal', 1, true) or s:find('penalty_goal', 1, true) or s:find('goal|pen', 1, true) or s:find('pen|goal', 1, true) then
        return 'penalty'
    end
    
    -- Normal gol ({{goal}}, goal, top ikonu veya boş hücre)
    if s:find('goal', 1, true) or s:find('soccerball', 1, true) or s:find('football', 1, true) or mw.text.trim(cellText) == '' then
        return 'goal'
    end
    
    return 'invalid'
end

-- Metin içerisindeki {| ve |} arasındaki tabloları hatasız ayıklama
local function extractTables(content)
    local tables = {}
    local pos = 1
    local len = #content
    while pos <= len do
        local s, e = content:find('{|', pos, true)
        if not s then break end
        
        local depth = 1
        local cur = e + 1
        local tableEnd = nil
        while cur <= len do
            local nextOpen = content:find('{|', cur, true)
            local nextClose = content:find('|}', cur, true)
            
            if not nextClose then break end
            
            if nextOpen and nextOpen < nextClose then
                depth = depth + 1
                cur = nextOpen + 2
            else
                depth = depth - 1
                if depth == 0 then
                    tableEnd = nextClose
                    break
                end
                cur = nextClose + 2
            end
        end
        
        if tableEnd then
            table.insert(tables, content:sub(e + 1, tableEnd - 1))
            pos = tableEnd + 2
        else
            pos = e + 1
        end
    end
    return tables
end

-- Tabloyu satırlarına ayırma
local function extractRows(tableWikitext)
    tableWikitext = tableWikitext:gsub('\r\n', '\n'):gsub('\r', '\n')
    local firstNewline = tableWikitext:find('\n')
    local body = firstNewline and tableWikitext:sub(firstNewline + 1) or tableWikitext
    
    local rows = {}
    local delimited = ('\n' .. body):gsub('\n%s*|%-[^\n]*', '\0')
    for row in mw.text.gsplit(delimited, '\0', true) do
        row = mw.text.trim(row)
        if row ~= '' then
            table.insert(rows, row)
        end
    end
    return rows
end

-- Bir satır içerisindeki hücreleri (|| ve \n|) ayıklama
local function parseRowCells(rowStr)
    local cells = {}
    local lines = mw.text.split(rowStr, '\n')
    for _, line in ipairs(lines) do
        line = mw.text.trim(line)
        if line ~= '' and not line:match('^!') then
            if line:match('^|') then
                line = line:sub(2)
            end
            local rawParts = mw.text.split(line, '||', true)
            for _, rawPart in ipairs(rawParts) do
                table.insert(cells, getCellContent(rawPart))
            end
        end
    end
    return cells
end

-- Wikitext'i işleyip golleri sayma
local function processWikitext(content, players, seenGoals)
    if not content or content == '' then return end
    
    local tables = extractTables(content)
    for _, tableWikitext in ipairs(tables) do
        local lowerTable = tableWikitext:lower()
        
        -- JS'teki hariç tutulan tablolar
        if not lowerTable:find('id%s*=%s*["\']?world%-cup%-table') and
           not lowerTable:find('id%s*=%s*["\']?uefa%-table') and
           not lowerTable:find('id%s*=%s*["\']?top%-scorers%-table') and
           not lowerTable:find('id%s*=%s*["\']?table%-filter') then
            
            local rows = extractRows(tableWikitext)
            for _, row in ipairs(rows) do
                local cells = parseRowCells(row)
                local N = #cells
                
                -- JS'teki en az 12 hücre şartı
                if N >= 12 then
                    local playerRaw      = cells[N]
                    local playerFlagRaw  = cells[N - 1]
                    local scoringTeamRaw = cells[N - 2]
                    local eventRaw       = cells[N - 3]
                    local minuteRaw      = cells[N - 4]
                    local team2FlagRaw   = cells[N - 5]
                    local team2Raw       = cells[N - 6]
                    local team1Raw       = cells[N - 8]
                    local team1FlagRaw   = cells[N - 9]
                    
                    local eventType = getGoalEventType(eventRaw)
                    
                    if eventType == 'goal' or eventType == 'penalty' then
                        local playerName    = cleanText(playerRaw)
                        local minuteText    = cleanText(minuteRaw)
                        local team1Text     = cleanText(team1Raw):lower()
                        local team2Text     = cleanText(team2Raw):lower()
                        local scoreTeamText = cleanText(scoringTeamRaw):lower()
                        
                        if playerName ~= '' then
                            local goalKey = (team1Text .. '|' .. team2Text .. '|' .. minuteText .. '|' .. playerName):lower()
                            
                            if not seenGoals[goalKey] then
                                seenGoals[goalKey] = true
                                
                                local teamFlag = team1FlagRaw
                                if scoreTeamText == team2Text or (team2Text ~= '' and scoreTeamText:find(team2Text, 1, true)) then
                                    teamFlag = team2FlagRaw
                                elseif scoreTeamText == team1Text or (team1Text ~= '' and scoreTeamText:find(team1Text, 1, true)) then
                                    teamFlag = team1FlagRaw
                                end
                                
                                if not players[playerName] then
                                    players[playerName] = {
                                        name = playerName,
                                        rawName = playerRaw,
                                        teamRaw = scoringTeamRaw,
                                        teamFlag = teamFlag,
                                        flag = playerFlagRaw,
                                        goals = 0,
                                        penGoals = 0
                                    }
                                end
                                
                                players[playerName].goals = players[playerName].goals + 1
                                if eventType == 'penalty' then
                                    players[playerName].penGoals = players[playerName].penGoals + 1
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end

-- Ana fonksiyon
function p.render(frame)
    local players = {}
    local seenGoals = {}
    
    local mainPageName = 'User:Ozicanbro'
    if frame.args[1] and mw.text.trim(frame.args[1]) ~= '' then
        mainPageName = mw.text.trim(frame.args[1])
    end
    
    local mainTitle = mw.title.new(mainPageName)
    local mainContent = mainTitle and mainTitle:getContent() or ''
    
    -- Ana sayfadaki varsa maçları tara
    processWikitext(mainContent, players, seenGoals)
    
    -- Sayfadaki tüm Event / Arşiv alt bağlantılarını otomatik tespit et (Büyük/küçük harf duyarsız)
    local subpages = {}
    local subpageList = {}
    
    for link in mainContent:gmatch('%[%[%s*([^%]|]+)') do
        link = mw.text.trim(link)
        local lower = link:lower()
        if (lower:find('user:ozicanbro/', 1, true) or lower:sub(1,1) == '/') and lower:find('event', 1, true) then
            if lower:sub(1, 1) == '/' then
                link = mainPageName .. link
            end
            if not subpages[link] then
                subpages[link] = true
                table.insert(subpageList, link)
            end
        end
    end
    
    -- Bulunan her bir arşiv sayfasını tara
    for _, subpageName in ipairs(subpageList) do
        local subTitle = mw.title.new(subpageName)
        if subTitle and subTitle.exists and subpageName ~= mainPageName then
            local subContent = subTitle:getContent()
            processWikitext(subContent, players, seenGoals)
        end
    end
    
    -- Oyuncuları toplayıp sırala
    local sortedPlayers = {}
    for _, player in pairs(players) do
        table.insert(sortedPlayers, player)
    end
    
    if #sortedPlayers == 0 then
        return '<div style="color:#777; font-style:italic; padding:10px;">TopGoalscorers: Toplam ' .. #subpageList .. ' arşiv sayfası tarandı ancak henüz listelenecek gol verisi bulunamadı.</div>'
    end
    
    table.sort(sortedPlayers, function(a, b)
        if a.goals ~= b.goals then
            return a.goals > b.goals
        end
        if a.penGoals ~= b.penGoals then
            return a.penGoals > b.penGoals
        end
        return a.name < b.name
    end)
    
    -- Wikitable formatında çıktıyı üret
    local out = {}
    table.insert(out, '=== Top Goalscorers ===\n')
    table.insert(out, '{| id="top-scorers-table" class="wikitable sortable" style="text-align:center; margin-top:20px; font-family:\'Trebuchet MS\', \'Lucida Sans Unicode\', \'Lucida Grande\', Arial, sans-serif;"')
    table.insert(out, '|-\n! style="background:#005587; color:#fff;" | #')
    table.insert(out, '! style="background:#005587; color:#fff;" | C')
    table.insert(out, '! style="background:#005587; color:#fff;" | Player')
    table.insert(out, '! style="background:#005587; color:#fff;" | C')
    table.insert(out, '! style="background:#005587; color:#fff;" | Team')
    table.insert(out, '! style="background:#005587; color:#fff;" | Goals')
    table.insert(out, '! style="background:#005587; color:#fff;" | Pen Goals')
    
    for i, pl in ipairs(sortedPlayers) do
        table.insert(out, '|-\n| ' .. i ..
            ' || ' .. (pl.flag ~= '' and pl.flag or '&nbsp;') ..
            ' || style="text-align:center;" | ' .. pl.rawName ..
            ' || ' .. (pl.teamFlag ~= '' and pl.teamFlag or '&nbsp;') ..
            ' || style="text-align:center;" | ' .. pl.teamRaw ..
            ' || \'\'\'' .. pl.goals .. '\'\'\'' ..
            ' || \'\'\'' .. pl.penGoals .. '\'\'\''
        )
    end
    table.insert(out, '|}')
    
    return table.concat(out, '\n')
end

return p