Mudanças entre as edições de "Módulo:I.Utils"

De Wiki Gla
Ir para navegação Ir para pesquisar
m
m
 
Linha 192: Linha 192:
         return ""
         return ""
     end
     end
     return (tostring(txt):gsub("%[%s*(%a+)%s*:%s*([^%]]+)%s*%]", function(tag, inner)
     local result = (tostring(txt):gsub("%[%s*(%a+)%s*:%s*([^%]]+)%s*%]", function(tag, inner)
         tag = tag:lower()
         tag = tag:lower()
         local hex = M.COLOR[tag] or ""
         local hex = M.COLOR[tag] or ""
Linha 198: Linha 198:
             return "[" .. tag .. ":" .. inner .. "]"
             return "[" .. tag .. ":" .. inner .. "]"
         end
         end
         return string.format('<span style="color:%s;"><strong>%s</strong></span>', hex, M.trim(inner))
         return string.format('<span style="color:%s;font-weight:bold;">%s</span>', hex, M.trim(inner))
     end))
     end))
    -- Garante negrito em textos com <font color="...">
    result = result:gsub("<font([^>]*)>", function(attrs)
        local lower = attrs:lower()
        if not lower:match("color%s*=") then
            return "<font" .. attrs .. ">"
        end
        if lower:match("font%-weight") then
            return "<font" .. attrs .. ">"
        end
        if attrs:match("style%s*=") then
            local updated = attrs:gsub("style%s*=%s*(['\"])(.-)%1", function(quote, style)
                local styleLower = style:lower()
                if styleLower:find("font%-weight") then
                    return " style=" .. quote .. style .. quote
                end
                local sep = ""
                if style ~= "" and not style:match(";%s*$") then
                    sep = ";"
                end
                return " style=" .. quote .. style .. sep .. "font-weight:bold;" .. quote
            end, 1)
            return "<font" .. updated .. ">"
        end
        return "<font" .. attrs .. ' style="font-weight:bold;">'
    end)
    return result
end
end



Edição atual tal como às 00h34min de 25 de janeiro de 2026

A documentação para este módulo pode ser criada em Módulo:I.Utils/doc

-- Módulo:I.Utils — funções utilitárias compartilhadas
local M = {}

-- Cache de módulos carregados
M._moduleCache = {}

-- ===== Funções básicas =====

function M.trim(s)
    return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end

function M.safeArgs(node)
    return (node and node.args) or {}
end

-- Separa uma sequência de {} (JSONs colados) em uma tabela de chunks
function M.collectJsonObjects(s)
    s = tostring(s or "")
    local out = {}
    for chunk in s:gmatch("%b{}") do
        table.insert(out, chunk)
    end
    return out
end

-- Carrega módulo de personagem com cache
-- Carrega APENAS pelo nome exato passado, sem fallbacks
function M.requireCharacterModule(charName)
    charName = M.trim(charName or "")
    if charName == "" then
        return nil
    end

    -- Verifica cache primeiro
    if M._moduleCache[charName] then
        return M._moduleCache[charName]
    end

    -- Tenta carregar diretamente
    local ok, data = pcall(function()
        return require("Módulo:" .. charName)
    end)
    if ok and type(data) == "table" then
        M._moduleCache[charName] = data
        return data
    end

    -- Tenta com espaços (underscores → espaço)
    local spaced = charName:gsub("_", " ")
    if spaced ~= charName then
        ok, data = pcall(function()
            return require("Módulo:" .. spaced)
        end)
        if ok and type(data) == "table" then
            M._moduleCache[charName] = data
            return data
        end
    end

    -- Tenta com underscores (espaços → _)
    local underscored = charName:gsub(" ", "_")
    if underscored ~= charName then
        ok, data = pcall(function()
            return require("Módulo:" .. underscored)
        end)
        if ok and type(data) == "table" then
            M._moduleCache[charName] = data
            return data
        end
    end

    -- Fallback: tenta última palavra do nome (ex: "Trafalgar Law" → "Law")
    local lastWord = charName:match("(%S+)%s*$")
    if lastWord and lastWord ~= charName then
        ok, data = pcall(function()
            return require("Módulo:" .. lastWord)
        end)
        if ok and type(data) == "table" then
            M._moduleCache[charName] = data
            return data
        end
    end

    return nil
end

-- Resolve nome do personagem/módulo a partir dos frames (busca recursiva em todos os níveis)
-- Prioridade: |module= > |char= > |nome= > parent frames > título da página (último recurso)
function M.resolveCharFromFrames(frame, a)
    a = a or {}

    -- Prioridade 1: parâmetro explícito |module=
    if a.module and M.trim(a.module) ~= "" then
        return M.trim(a.module)
    end

    -- Prioridade 2: parâmetro explícito |char=
    if a.char and M.trim(a.char) ~= "" then
        return M.trim(a.char)
    end

    -- Prioridade 3: parâmetro |nome=
    if a.nome and M.trim(a.nome) ~= "" then
        return M.trim(a.nome)
    end

    -- Prioridade 4: busca recursiva em todos os parent frames (até 10 níveis)
    if frame and frame.getParent then
        local current = frame
        for i = 1, 10 do
            local parent = current:getParent()
            if not parent then break end
            if parent.args then
                -- Primeiro verifica |module= nos pais
                if parent.args.module and M.trim(parent.args.module) ~= "" then
                    return M.trim(parent.args.module)
                end
                if parent.args.nome and M.trim(parent.args.nome) ~= "" then
                    return M.trim(parent.args.nome)
                end
                if parent.args.char and M.trim(parent.args.char) ~= "" then
                    return M.trim(parent.args.char)
                end
            end
            current = parent
        end
    end

    -- Último recurso: título da página atual
    -- Só usado se nenhum |module=, |nome= ou |char= foi encontrado
    local title = mw.title.getCurrentTitle()
    return title and M.trim(title.text) or ""
end

-- ===== I18N =====

M.I18N = {
    pt = {
        level = "Nível",
        power = "Poder",
        power_pvp = "Poder PvP",
        energy = "Energia",
        energy_cost = "Energia",
        energy_gain = "Energia",
        cooldown = "Recarga"
    },
    en = {
        level = "Level",
        power = "Power",
        power_pvp = "Power PvP",
        energy = "Energy",
        energy_cost = "Energy",
        energy_gain = "Energy",
        cooldown = "Cooldown"
    },
    es = {
        level = "Nivel",
        power = "Poder",
        power_pvp = "Poder PvP",
        energy = "Energía",
        energy_cost = "Energía",
        energy_gain = "Energía",
        cooldown = "Enfriamiento"
    },
    pl = {
        level = "Poziom",
        power = "Moc",
        power_pvp = "Moc PvP",
        energy = "Energia",
        energy_cost = "Energia",
        energy_gain = "Energia",
        cooldown = "Odnawianie"
    }
}

-- ===== Cores inline =====

M.COLOR = {
    debuff = "#F78181",
    atk = "#FAAC58",
    def = "#2E9AFE",
    ms = "#04B45F",
    hp = "#01DFD7",
    sec = "#F5DA81"
}

-- Substitui [atk:], [def:], etc. por spans coloridos
-- Usa [tag:value] em vez de {{tag:value}} para evitar que MediaWiki interprete como predefinição
function M.colorize(txt)
    if not txt or txt == "" then
        return ""
    end
    local result = (tostring(txt):gsub("%[%s*(%a+)%s*:%s*([^%]]+)%s*%]", function(tag, inner)
        tag = tag:lower()
        local hex = M.COLOR[tag] or ""
        if hex == "" then
            return "[" .. tag .. ":" .. inner .. "]"
        end
        return string.format('<span style="color:%s;font-weight:bold;">%s</span>', hex, M.trim(inner))
    end))
    -- Garante negrito em textos com <font color="...">
    result = result:gsub("<font([^>]*)>", function(attrs)
        local lower = attrs:lower()
        if not lower:match("color%s*=") then
            return "<font" .. attrs .. ">"
        end
        if lower:match("font%-weight") then
            return "<font" .. attrs .. ">"
        end
        if attrs:match("style%s*=") then
            local updated = attrs:gsub("style%s*=%s*(['\"])(.-)%1", function(quote, style)
                local styleLower = style:lower()
                if styleLower:find("font%-weight") then
                    return " style=" .. quote .. style .. quote
                end
                local sep = ""
                if style ~= "" and not style:match(";%s*$") then
                    sep = ";"
                end
                return " style=" .. quote .. style .. sep .. "font-weight:bold;" .. quote
            end, 1)
            return "<font" .. updated .. ">"
        end
        return "<font" .. attrs .. ' style="font-weight:bold;">'
    end)
    return result
end

-- ===== Funções auxiliares =====

function M.nz(v)
    v = v or ""
    return (M.trim(v) ~= "" and v or nil)
end

-- Parse flags CSV (normaliza para tokens válidos)
function M.parseFlags(flagsStr)
    local flagsArr = {}
    if flagsStr and M.trim(flagsStr) ~= "" then
        local validFlags = { aggro = true, bridge = true, wall = true, quickcast = true, wallpass = true }
        local seen = {}
        for token in string.gmatch(M.trim(flagsStr), "[^,]+") do
            local normalized = M.trim(token):lower()
            if validFlags[normalized] and not seen[normalized] then
                table.insert(flagsArr, normalized)
                seen[normalized] = true
            end
        end
    end
    return flagsArr
end

return M