Jump to content

Module:RankSort

From SpongeBob Wiki
Revision as of 21:39, 30 April 2025 by imported>AndromedaMapping1
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:RankSort/doc

local p = {}

-- Function to check if a number is a valid integer
local function isValidNumber(num)
    return type(num) == 'number' and math.floor(num) == num
end

-- Function to parse rendered AM1RK output
local function parseRenderedAM1RK(rendered, num)
    local params = { num = num }
    local debug = { "Parsing: " .. rendered }
    
    table.insert(debug, "Raw input: " .. rendered)
    table.insert(debug, "Raw input (hex): " .. mw.text.encode(rendered, '%x'))
    
    local title = rendered:match('|link=([^%]]+)]') or rendered:match('link%s*=%s*([^|%]]+)')
    if not title then
        table.insert(debug, "Failed to extract title")
        return nil, table.concat(debug, '\n')
    end
    params.title = mw.text.trim(title)
    table.insert(debug, "Title: " .. params.title)
    
    local image = rendered:match('%[%[File:([^|]+)|')
    if not image then
        table.insert(debug, "Warning: Failed to extract image")
        params.image = "Placeholder.jpg"
    else
        params.image = mw.text.trim(image)
    end
    table.insert(debug, "Image: " .. params.image)
    
    local trimmed = mw.text.trim(rendered)
    table.insert(debug, "Trimmed input: " .. trimmed)
    
    local value = trimmed:match('\'\'\'<span[^>]+>(%d+)</span>\'\'\'%s*$') or
                  trimmed:match('\'\'\'(%d+)\'\'\'%s*$') or
                  trimmed:match(']]<br>%s*\'\'\'(%d+)\'\'\'%s*$') or
                  trimmed:match(']]<br>%s*(%d+)%s*$') or
                  trimmed:match('|%s*(%d+)%s*$')
    if not value then
        table.insert(debug, "Failed to extract value")
        return nil, table.concat(debug, '\n')
    end
    params.value = mw.text.trim(value)
    table.insert(debug, "Value: " .. params.value)
    
    local textColor = trimmed:match('\'\'\'<span[^>]*style=[\'"]%s*color:%s*([%a#][%w#]*)[;%s]*[\'"]') or
                      rendered:match('\'\'\'<span[^>]*style=[\'"]%s*color:%s*([%a#][%w#]*)[;%s]*[\'"]') or
                      trimmed:match('\'\'\'<span[^>]*color:%s*([%a#][%w#]*)[;%s>]') or
                      'black'
    if not textColor then
        table.insert(debug, "Failed to extract textColor, defaulting to black")
    end
    params.textColor = mw.text.trim(textColor or 'black'):lower()
    table.insert(debug, "TextColor: " .. params.textColor)
    
    local color = rendered:match('style%s*=%s*[\'"]%s*background%-?color:%s*([^;\'"]+)[\'";%s]') or
                  rendered:match('style%s*=%s*[\'"]%s*background:%s*([^;\'"]+)[\'";%s]') or
                  'White'
    if not color then
        table.insert(debug, "Failed to extract background color, defaulting to White")
    else
        table.insert(debug, "Extracted background color: " .. color)
    end
    params.color = mw.text.trim(color or 'White')
    table.insert(debug, "Color (after trim): " .. params.color)
    if params.color == 'White' then
        table.insert(debug, "Warning: Background color is White, check AM1O|color output")
    end
    
    return params, table.concat(debug, '\n')
end

-- Function to reconstruct valid table cell
local function formatAM1RKCell(params, index)
    local cell = string.format(
        '| width=20%% style="background:%s" | [[File:%s|150px|link=%s]]<br>\'\'\'<span style="color:%s">%s</span>\'\'\'',
        params.color,
        params.image,
        mw.text.trim(params.title),
        params.textColor,
        mw.text.trim(params.value)
    )
    return cell
end

-- Main sorting function
function p.sortTemplates(frame)
    local args = frame.args
    local templates = {}
    local sortOrder = args.order or 'asc'
    local debugInfo = { "Debug: Arguments received:" }

    for key, value in pairs(args) do
        local keyStr = tostring(key)
        local index = keyStr:match("^(%d+)_num$")
        if index then
            local numStr = value or ''
            local contentKey = index
            local rendered = args[contentKey] or ''
            
            if numStr and rendered then
                table.insert(debugInfo, string.format("Arg %s_num: %s", index, numStr))
                table.insert(debugInfo, "Arg %s: " .. rendered)
                
                local num = tonumber(numStr)
                if num and isValidNumber(num) then
                    local params, err = parseRenderedAM1RK(rendered, num)
                    if params then
                        table.insert(templates, {
                            num = num,
                            params = params
                        })
                        table.insert(debugInfo, err)
                    else
                        table.insert(debugInfo, string.format("Failed to parse arg %s: %s", index, err))
                    end
                else
                    table.insert(debugInfo, string.format("Invalid number in arg %s: %s", index, numStr))
                end
            elseif numStr or rendered then
                table.insert(debugInfo, string.format("Incomplete pair for arg %s: num=%s, content=%s", index, numStr or 'nil', rendered))
            end
        end
    end

    if #templates == 0 then
        return table.concat(debugInfo, '\n') .. '\nError: No valid AM1RK templates found.'
    end

    if sortOrder:lower() == 'desc' then
        table.sort(templates, function(a, b) return a.num > b.num end)
    else
        table.sort(templates, function(a, b) return a.num < b.num end)
    end

    local output = {}
    for i, template in ipairs(templates) do
        table.insert(output, formatAM1RKCell(template.params, i))
        if i % 5 == 0 and i ~= #templates then
            table.insert(output, '|-')
        end
    end

    return table.concat(output, '\n')
end

return p