Mudanças entre as edições de "Módulo:I.Utils"
Ir para navegação
Ir para pesquisar
(Criou página com '-- Módulo:C.Utils — funções utilitárias compartilhadas local M = {} -- Cache de módulos carregados M._moduleCache = {} -----------------------------------------------...') |
m |
||
| Linha 1: | Linha 1: | ||
-- Módulo: | -- Módulo:I.Utils — funções utilitárias compartilhadas | ||
local M = {} | local M = {} | ||
| Linha 5: | Linha 5: | ||
M._moduleCache = {} | M._moduleCache = {} | ||
-- | -- ===== Funções básicas ===== | ||
function M.trim(s) | function M.trim(s) | ||
| Linha 13: | Linha 11: | ||
end | end | ||
function M.safeArgs(node) | |||
function M. | return (node and node.args) or {} | ||
end | end | ||
-- | -- Separa uma sequência de {} (JSONs colados) em uma tabela de chunks | ||
function M. | function M.collectJsonObjects(s) | ||
s = tostring(s or "") | |||
local out = {} | |||
for chunk in s:gmatch("%b{}") do | |||
table.insert(out, chunk) | |||
end | end | ||
return out | |||
end | end | ||
-- Carrega módulo de personagem com cache | |||
-- Carrega | |||
-- Carrega APENAS pelo nome exato passado, sem fallbacks | -- Carrega APENAS pelo nome exato passado, sem fallbacks | ||
function M. | function M.requireCharacterModule(charName) | ||
charName = M.trim(charName or "") | |||
if | if charName == "" then | ||
return nil | return nil | ||
end | end | ||
-- Verifica cache primeiro | -- Verifica cache primeiro | ||
if M._moduleCache[ | if M._moduleCache[charName] then | ||
return M._moduleCache[ | return M._moduleCache[charName] | ||
end | end | ||
-- Tenta carregar diretamente | |||
local ok, data = pcall(function() | |||
-- Tenta | return require("Módulo:" .. charName) | ||
ok, data = pcall(function() | |||
return require("Módulo:" .. | |||
end) | end) | ||
if ok and type(data) == "table" then | if ok and type(data) == "table" then | ||
M._moduleCache[ | M._moduleCache[charName] = data | ||
return data | return data | ||
end | end | ||
-- Tenta com espaços (underscores → espaço) | -- Tenta com espaços (underscores → espaço) | ||
local spaced = | local spaced = charName:gsub("_", " ") | ||
if spaced ~= | if spaced ~= charName then | ||
ok, data = pcall(function() | ok, data = pcall(function() | ||
return require("Módulo:" .. spaced) | return require("Módulo:" .. spaced) | ||
end) | end) | ||
if ok and type(data) == "table" then | if ok and type(data) == "table" then | ||
M._moduleCache[ | M._moduleCache[charName] = data | ||
return data | return data | ||
end | end | ||
| Linha 98: | Linha 60: | ||
-- Tenta com underscores (espaços → _) | -- Tenta com underscores (espaços → _) | ||
local underscored = | local underscored = charName:gsub(" ", "_") | ||
if underscored ~= | if underscored ~= charName then | ||
ok, data = pcall(function() | ok, data = pcall(function() | ||
return require("Módulo:" .. underscored) | return require("Módulo:" .. underscored) | ||
end) | end) | ||
if ok and type(data) == "table" then | if ok and type(data) == "table" then | ||
M._moduleCache[ | M._moduleCache[charName] = data | ||
return data | return data | ||
end | end | ||
| Linha 110: | Linha 72: | ||
-- Fallback: tenta última palavra do nome (ex: "Trafalgar Law" → "Law") | -- Fallback: tenta última palavra do nome (ex: "Trafalgar Law" → "Law") | ||
local lastWord = | local lastWord = charName:match("(%S+)%s*$") | ||
if lastWord and lastWord ~= | if lastWord and lastWord ~= charName then | ||
ok, data = pcall(function() | ok, data = pcall(function() | ||
return require("Módulo:" .. lastWord) | return require("Módulo:" .. lastWord) | ||
end) | end) | ||
if ok and type(data) == "table" then | if ok and type(data) == "table" then | ||
M._moduleCache[ | M._moduleCache[charName] = data | ||
return data | return data | ||
end | end | ||
end | end | ||
-- | return nil | ||
end | |||
return | |||
end) | -- Resolve nome do personagem/módulo a partir dos frames (busca recursiva em todos os níveis) | ||
if | -- 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 | 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 | |||
M. | |||
return | -- ===== 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 = "#ff5252", | |||
atk = "#ff9000", | |||
def = "#006cfe", | |||
ms = "#43a047", | |||
hp = "#01d8d0", | |||
sec = "#ffcc00" | |||
} | |||
-- 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 | end | ||
return (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)) | |||
end | |||
return nil | -- ===== Funções auxiliares ===== | ||
function M.nz(v) | |||
v = v or "" | |||
return (M.trim(v) ~= "" and v or nil) | |||
end | end | ||
-- | -- Parse flags CSV (normaliza para tokens válidos) | ||
function M. | 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 | end | ||
return | return flagsArr | ||
end | end | ||
return M | return M | ||
Edição atual tal como às 22h10min de 31 de dezembro de 2025
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 = "#ff5252",
atk = "#ff9000",
def = "#006cfe",
ms = "#43a047",
hp = "#01d8d0",
sec = "#ffcc00"
}
-- 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
return (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))
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