Module:UnitLinker: Difference between revisions

From Heroes of Might and Magic: Olden Era Official Wiki
No edit summary
No edit summary
Line 1: Line 1:
local p = {}
local p = {}


-- Fonction pour charger toutes les unités en mémoire (Mise en cache interne)
-- Charge la table de correspondance en mémoire
local function getUnitRegistry(lang)
local function getUnitRegistry(lang)
     local registry = {}
     local registry = {}
     local cargoQuery = mw.ext.cargo.query("Translation", "target_id, name", {
    -- On récupère tout pour la langue en cours + l'anglais comme sécurité
        where = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')",
     local query = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')"
        orderBy = "target_id"
    local results = mw.ext.cargo.query("Translation", "target_id, name", { where = query })
    })
      
      
    -- On organise les données pour un accès rapide : registry[nom_traduit] = nom_anglais
     for _, row in ipairs(results) do
     for _, row in ipairs(cargoQuery) do
        -- On stocke le nom trouvé (qu'il soit anglais ou traduit)
        -- associé à son identifiant unique (target_id)
         registry[row.name] = row.target_id
         registry[row.name] = row.target_id
     end
     end
Line 16: Line 16:
end
end


-- Fonction principale : replace les noms d'unités dans un texte
function p.link(frame)
function p.link(frame)
     local text = frame.args[1] or ""
     local text = frame.args[1] or ""
     local title = mw.title.getCurrentTitle().text
     local title = mw.title.getCurrentTitle().text
    -- Détecte le suffixe de langue (ex: /fr, /de, /es), sinon par défaut 'en'
     local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
     local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
      
      
    -- Si la langue est "en", on ne traite que les noms anglais, sinon on charge les deux
     local registry = getUnitRegistry(lang)
     local registry = getUnitRegistry(lang)
      
      
     -- On trie les clés par longueur décroissante pour éviter de remplacer "Swordsman"
     -- Trier par longueur pour remplacer les noms composés avant les noms simples
    -- dans "Temple Swordsman" avant de traiter le nom complet.
     local keys = {}
     local keys = {}
     for k in pairs(registry) do table.insert(keys, k) end
     for k in pairs(registry) do table.insert(keys, k) end
     table.sort(keys, function(a, b) return #a > #b end)
     table.sort(keys, function(a, b) return #a > #b end)
      
      
    -- Remplacement
     for _, unitName in ipairs(keys) do
     for _, unitName in ipairs(keys) do
         local engName = registry[unitName]
         local engName = registry[unitName]
        local link
          
          
         -- Construction du lien selon la langue
         -- Définir la cible du lien
         if lang == "en" then
         local target = (lang == "en") and engName or (engName .. "/" .. lang)
            link = "[[" .. engName .. "]]"
         local link = "[[" .. target .. "|" .. unitName .. "]]"
         else
            link = "[[" .. engName .. "/" .. lang .. "|" .. unitName .. "]]"
        end
          
          
         -- Échappement des caractères spéciaux pour le pattern (si nécessaire)
         -- Pattern complexe :
         -- On utilise une frontière de mot (%f[%a]) pour éviter de couper des mots.
         -- %f[%a] : frontière de mot
         local pattern = "%f[%a]" .. mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1") .. "%f[%A]"
         -- [%[%]|\n] : on vérifie que le mot n'est pas déjà à l'intérieur d'un lien [[ ]]
         text = mw.ustring.gsub(text, pattern, link)
        local escapedName = mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
       
        -- On remplace uniquement si le mot n'est pas déjà dans un lien
        -- Cette logique cherche à éviter de casser les liens déjà présents
        local pattern = "(%f[%a])" .. escapedName .. "(%f[%A])"
       
         text = mw.ustring.gsub(text, pattern, function(prefix, suffix)
            -- On vérifie si on est déjà dans un bloc de lien (simplifié)
            if mw.ustring.find(text, "%[%[" .. escapedName) then return prefix .. unitName .. suffix end
            return prefix .. link .. suffix
        end)
     end
     end
      
      

Revision as of 15:40, 13 June 2026

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

local p = {}

-- Charge la table de correspondance en mémoire
local function getUnitRegistry(lang)
    local registry = {}
    -- On récupère tout pour la langue en cours + l'anglais comme sécurité
    local query = "type = 'unit' AND (language = 'en' OR language = '" .. lang .. "')"
    local results = mw.ext.cargo.query("Translation", "target_id, name", { where = query })
    
    for _, row in ipairs(results) do
        -- On stocke le nom trouvé (qu'il soit anglais ou traduit) 
        -- associé à son identifiant unique (target_id)
        registry[row.name] = row.target_id
    end
    return registry
end

function p.link(frame)
    local text = frame.args[1] or ""
    local title = mw.title.getCurrentTitle().text
    -- Détecte le suffixe de langue (ex: /fr, /de, /es), sinon par défaut 'en'
    local lang = mw.ustring.match(title, "/([a-z_]+)$") or "en"
    
    local registry = getUnitRegistry(lang)
    
    -- Trier par longueur pour remplacer les noms composés avant les noms simples
    local keys = {}
    for k in pairs(registry) do table.insert(keys, k) end
    table.sort(keys, function(a, b) return #a > #b end)
    
    for _, unitName in ipairs(keys) do
        local engName = registry[unitName]
        
        -- Définir la cible du lien
        local target = (lang == "en") and engName or (engName .. "/" .. lang)
        local link = "[[" .. target .. "|" .. unitName .. "]]"
        
        -- Pattern complexe : 
        -- %f[%a] : frontière de mot
        -- [%[%]|\n] : on vérifie que le mot n'est pas déjà à l'intérieur d'un lien [[ ]]
        local escapedName = mw.ustring.gsub(unitName, "([%(%)%.%%%+%-%*%?%[%^%$])", "%%%1")
        
        -- On remplace uniquement si le mot n'est pas déjà dans un lien
        -- Cette logique cherche à éviter de casser les liens déjà présents
        local pattern = "(%f[%a])" .. escapedName .. "(%f[%A])"
        
        text = mw.ustring.gsub(text, pattern, function(prefix, suffix)
            -- On vérifie si on est déjà dans un bloc de lien (simplifié)
            if mw.ustring.find(text, "%[%[" .. escapedName) then return prefix .. unitName .. suffix end
            return prefix .. link .. suffix
        end)
    end
    
    return text
end

return p