Module:UnitLinker

From Heroes of Might and Magic: Olden Era Official Wiki

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

local p = {}

-- Charge la table de correspondance en mémoire avec filtrage strict
local function getUnitRegistry(lang)
    local registry = {}
    
    -- On ajoute bien 'type = "unit"' pour garantir l'unicité du contexte
    local query = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')"
    
    -- On récupère target_id et name
    local results = mw.ext.cargo.query("Translation", "target_id, name", { 
        where = query,
        -- On définit un orderBy pour que les traductions écrasent éventuellement 
        -- les entrées en double si nécessaire, bien que le type 'unit' devrait suffire
        orderBy = "language DESC" 
    })
    
    for _, row in ipairs(results) do
        -- row.name est le nom détectable (ex: "Swordsman" ou "Épéiste")
        -- row.target_id est la référence unique (ex: "Swordsman")
        if row.name and row.target_id then
            registry[row.name] = row.target_id
        end
    end
    return registry
end

function p.link(frame)
    local text = frame.args[1] or ""
    if not text or text == "" then return "" end
    
    local title = mw.title.getCurrentTitle().text
    local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
    
    local registry = getUnitRegistry(lang)
    
    -- Trier par longueur décroissante pour traiter "Temple Swordsman" avant "Swordsman"
    local keys = {}
    for k in pairs(registry) do table.insert(keys, k) end
    table.sort(keys, function(a, b) return #a > #b end)
    
    -- Remplacement
    for _, unitName in ipairs(keys) do
        local engName = registry[unitName]
        
        -- Construction du lien
        local target = (lang == "en") and engName or (engName .. "/" .. lang)
        local link = "[[" .. target .. "|" .. unitName .. "]]"
        
        -- Pattern pour éviter de casser des liens existants
        -- On cherche le nom de l'unité avec des frontières de mot
        local escapedName = mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
        local pattern = "(%f[%a])" .. escapedName .. "(%f[%A])"
        
        text = mw.ustring.gsub(text, pattern, function(prefix, suffix)
            -- Si le texte contient déjà [[ devant, on ne touche à rien
            if mw.ustring.find(text, "%[%[" .. escapedName) then return prefix .. unitName .. suffix end
            return prefix .. link .. suffix
        end)
    end
    
    return text
end

return p