« Module:Episode/index » : différence entre les versions
Apparence
Contenu supprimé Contenu ajouté
Page créée avec « local p = {} local sources = { "Module:Episode/SG1Season1", "Module:Episode/SG1Season2", "Module:Episode/SG1Season3", "Module:Episode/SG1Season4", "Module:Episode/SG1Season5", "Module:Episode/SG1Season6", "Module:Episode/SG1Season7", "Module:Episode/SG1Season8", "Module:Episode/SG1Season9", "Module:Episode/SG1Season10", "Module:Episode/SGASeason1", "Module:Episode/SGASeason2", "Module:Episode/SGASeason3", "Module:Episode/SGASeason4", "Module:Episo... » |
Aucun résumé des modifications |
||
| (10 versions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
local p = {} |
local p = {} |
||
------------------------------------------------------------ |
|||
-- GLOBAL CACHE (empêche la reconstruction multiple) |
|||
------------------------------------------------------------ |
|||
local frame = mw.getCurrentFrame() |
|||
local globalCache = mw.getCurrentFrame().args |
|||
if globalCache.__EPISODE_INDEX_BUILT then |
|||
return globalCache.__EPISODE_INDEX |
|||
end |
|||
------------------------------------------------------------ |
|||
-- List of source modules |
|||
------------------------------------------------------------ |
|||
local sources = { |
local sources = { |
||
-- Stargate SG-1 |
|||
"Module:Episode/SG1Season1", |
|||
"Module:Episode/SG1Season1", |
|||
"Module:Episode/SG1Season2", |
|||
"Module:Episode/SG1Season3", |
|||
"Module:Episode/SG1Season4", |
|||
"Module:Episode/SG1Season5", |
|||
"Module:Episode/SG1Season6", |
|||
"Module:Episode/SG1Season7", |
|||
"Module:Episode/SG1Season8", |
|||
"Module:Episode/SG1Season9", |
|||
"Module:Episode/SG1Season10", |
|||
"Module:Episode/SGASeason2", |
|||
-- Stargate Atlantis |
|||
"Module:Episode/SGASeason3", |
|||
"Module:Episode/SGASeason1", |
|||
"Module:Episode/SGASeason2", |
|||
"Module:Episode/SGASeason3", |
|||
"Module:Episode/SGASeason4", |
|||
"Module:Episode/SGASeason5", |
|||
"Module:Episode/SGOSeason1", |
|||
-- Stargate Universe |
|||
"Module:Episode/SGUMovies", |
|||
"Module:Episode/SGUSeason1", |
|||
"Module:Episode/SGUSeason2", |
|||
-- Stargate Infinity |
|||
"Module:Episode/SGISeason1", |
|||
-- Stargate Origins |
|||
"Module:Episode/SGOSeason1", |
|||
-- Films |
|||
"Module:Episode/SGUMovies", |
|||
} |
} |
||
p.index = {} |
p.index = {} |
||
------------------------------------------------------------ |
|||
-- Normalization |
|||
------------------------------------------------------------ |
|||
local function normalize(s) |
local function normalize(s) |
||
-- Default to empty string if nil |
|||
s = s or "" |
s = s or "" |
||
-- Trim leading and trailing whitespace |
|||
s = mw.text.trim(s) |
s = mw.text.trim(s) |
||
-- Normalize Unicode to NFD (decomposed form) |
|||
-- This allows us to remove accents by stripping combining marks |
|||
s = mw.ustring.toNFD(s) |
s = mw.ustring.toNFD(s) |
||
-- Remove combining diacritical marks (U+0300 to U+036F) |
|||
local combining_start = mw.ustring.char(0x0300) |
local combining_start = mw.ustring.char(0x0300) |
||
local combining_end = mw.ustring.char(0x036F) |
local combining_end = mw.ustring.char(0x036F) |
||
s = mw.ustring.gsub(s, "[" .. combining_start .. "-" .. combining_end .. "]", "") |
s = mw.ustring.gsub(s, "[" .. combining_start .. "-" .. combining_end .. "]", "") |
||
-- Normalize apostrophes to a single straight apostrophe |
|||
s = mw.ustring.gsub(s, "[’‘´`]", "'") |
s = mw.ustring.gsub(s, "[’‘´`]", "'") |
||
-- Normalize curly quotes to straight quotes |
|||
s = mw.ustring.gsub(s, "[“”]", "\"") |
s = mw.ustring.gsub(s, "[“”]", "\"") |
||
-- Normalize all dash types to a simple hyphen |
|||
s = mw.ustring.gsub(s, "[–—−]", "-") |
s = mw.ustring.gsub(s, "[–—−]", "-") |
||
-- Collapse multiple spaces into a single space |
|||
s = mw.ustring.gsub(s, "%s+", " ") |
s = mw.ustring.gsub(s, "%s+", " ") |
||
return mw.text.trim(mw.ustring.lower(s)) |
|||
-- Convert to lowercase |
|||
end |
|||
s = mw.ustring.lower(s) |
|||
------------------------------------------------------------ |
|||
-- Final trim |
|||
-- Alias variant generators + cache |
|||
s = mw.text.trim(s) |
|||
------------------------------------------------------------ |
|||
local function alias_no_dash(a) |
|||
return s |
|||
return mw.ustring.gsub(a, "[-–—]", "") |
|||
end |
end |
||
local function alias_dash_to_space(a) |
|||
-- Building the multi-key index |
|||
return mw.ustring.gsub(a, "[-–—]", " ") |
|||
for _, modname in ipairs(sources) do |
|||
local ok, mod = pcall(require, modname) |
|||
if ok and mod.episodes then |
|||
for _, ep in ipairs(mod.episodes) do |
|||
for _, key in ipairs(ep.alias or {}) do |
|||
local nkey = normalize(key) |
|||
if p.index[nkey] then |
|||
mw.log(string.format( |
|||
"[EpisodeIndex] Collision d'alias détectée : '%s' → %s et %s", |
|||
nkey, |
|||
p.index[nkey].id or "(sans id)", |
|||
ep.id or "(sans id)" |
|||
)) |
|||
else |
|||
p.index[nkey] = ep |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
end |
||
local alias_cache = {} |
|||
local function get_variants(key) |
|||
if alias_cache[key] then |
|||
return alias_cache[key] |
|||
end |
|||
local variants = { key } |
|||
local nd = alias_no_dash(key) |
|||
if nd ~= key then table.insert(variants, nd) end |
|||
local sp = alias_dash_to_space(key) |
|||
if sp ~= key then table.insert(variants, sp) end |
|||
alias_cache[key] = variants |
|||
return variants |
|||
end |
|||
------------------------------------------------------------ |
|||
-- Build the multi-key index (optimized) |
|||
------------------------------------------------------------ |
|||
for _, modname in ipairs(sources) do |
|||
local ok, mod = pcall(require, modname) |
|||
if ok and mod.episodes then |
|||
local isMovieModule = modname:match("SGUMovies") |
|||
for _, ep in ipairs(mod.episodes) do |
|||
ep = mw.clone(ep) |
|||
if isMovieModule then |
|||
ep.namespace = ep.namespace or "" |
|||
ep.season = ep.season or "" |
|||
ep.episode = ep.episode or "" |
|||
end |
|||
for _, key in ipairs(ep.alias or {}) do |
|||
for _, raw in ipairs(get_variants(key)) do |
|||
local nkey = normalize(raw) |
|||
if not p.index[nkey] then |
|||
p.index[nkey] = ep |
|||
else |
|||
mw.log(string.format( |
|||
"[EpisodeIndex] Alias collision: '%s' → %s / %s", |
|||
nkey, |
|||
p.index[nkey].id or "(no id)", |
|||
ep.id or "(no id)" |
|||
)) |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
end |
|||
------------------------------------------------------------ |
|||
-- Access function |
-- Access function |
||
------------------------------------------------------------ |
|||
function p.get(key) |
function p.get(key) |
||
local ep = p.index[normalize(key)] |
|||
if not ep then return nil end |
|||
return { |
|||
id = ep.id, |
|||
namespace = ep.namespace, |
|||
page_title = ep.page_title, |
|||
title_fr = ep.title_fr, |
|||
title_qc = ep.title_qc, |
|||
title_vo = ep.title_vo, |
|||
property = ep.property, |
|||
season = ep.season, |
|||
episode = ep.episode, |
|||
} |
|||
} |
|||
end |
end |
||
------------------------------------------------------------ |
|||
-- STORE IN GLOBAL CACHE |
|||
------------------------------------------------------------ |
|||
globalCache.__EPISODE_INDEX_BUILT = true |
|||
globalCache.__EPISODE_INDEX = p |
|||
return p |
return p |
||
Dernière version du 30 mai 2026 à 18:34
| Il sera peut-être nécessaire de créer une page documentation pour ce module Scribunto programmé dans la page créer Les éditeurs peuvent faire des tests sur les pages bac à sable (créer | miroir) et études de cas (créer) du module. Veuillez ajouter les catégories dans la sous-page /documentation. Sous-pages de ce module. |
local p = {}
------------------------------------------------------------
-- GLOBAL CACHE (empêche la reconstruction multiple)
------------------------------------------------------------
local frame = mw.getCurrentFrame()
local globalCache = mw.getCurrentFrame().args
if globalCache.__EPISODE_INDEX_BUILT then
return globalCache.__EPISODE_INDEX
end
------------------------------------------------------------
-- List of source modules
------------------------------------------------------------
local sources = {
-- Stargate SG-1
"Module:Episode/SG1Season1",
"Module:Episode/SG1Season2",
"Module:Episode/SG1Season3",
"Module:Episode/SG1Season4",
"Module:Episode/SG1Season5",
"Module:Episode/SG1Season6",
"Module:Episode/SG1Season7",
"Module:Episode/SG1Season8",
"Module:Episode/SG1Season9",
"Module:Episode/SG1Season10",
-- Stargate Atlantis
"Module:Episode/SGASeason1",
"Module:Episode/SGASeason2",
"Module:Episode/SGASeason3",
"Module:Episode/SGASeason4",
"Module:Episode/SGASeason5",
-- Stargate Universe
"Module:Episode/SGUSeason1",
"Module:Episode/SGUSeason2",
-- Stargate Infinity
"Module:Episode/SGISeason1",
-- Stargate Origins
"Module:Episode/SGOSeason1",
-- Films
"Module:Episode/SGUMovies",
}
p.index = {}
------------------------------------------------------------
-- Normalization
------------------------------------------------------------
local function normalize(s)
s = s or ""
s = mw.text.trim(s)
s = mw.ustring.toNFD(s)
local combining_start = mw.ustring.char(0x0300)
local combining_end = mw.ustring.char(0x036F)
s = mw.ustring.gsub(s, "[" .. combining_start .. "-" .. combining_end .. "]", "")
s = mw.ustring.gsub(s, "[’‘´`]", "'")
s = mw.ustring.gsub(s, "[“”]", "\"")
s = mw.ustring.gsub(s, "[–—−]", "-")
s = mw.ustring.gsub(s, "%s+", " ")
return mw.text.trim(mw.ustring.lower(s))
end
------------------------------------------------------------
-- Alias variant generators + cache
------------------------------------------------------------
local function alias_no_dash(a)
return mw.ustring.gsub(a, "[-–—]", "")
end
local function alias_dash_to_space(a)
return mw.ustring.gsub(a, "[-–—]", " ")
end
local alias_cache = {}
local function get_variants(key)
if alias_cache[key] then
return alias_cache[key]
end
local variants = { key }
local nd = alias_no_dash(key)
if nd ~= key then table.insert(variants, nd) end
local sp = alias_dash_to_space(key)
if sp ~= key then table.insert(variants, sp) end
alias_cache[key] = variants
return variants
end
------------------------------------------------------------
-- Build the multi-key index (optimized)
------------------------------------------------------------
for _, modname in ipairs(sources) do
local ok, mod = pcall(require, modname)
if ok and mod.episodes then
local isMovieModule = modname:match("SGUMovies")
for _, ep in ipairs(mod.episodes) do
ep = mw.clone(ep)
if isMovieModule then
ep.namespace = ep.namespace or ""
ep.season = ep.season or ""
ep.episode = ep.episode or ""
end
for _, key in ipairs(ep.alias or {}) do
for _, raw in ipairs(get_variants(key)) do
local nkey = normalize(raw)
if not p.index[nkey] then
p.index[nkey] = ep
else
mw.log(string.format(
"[EpisodeIndex] Alias collision: '%s' → %s / %s",
nkey,
p.index[nkey].id or "(no id)",
ep.id or "(no id)"
))
end
end
end
end
end
end
------------------------------------------------------------
-- Access function
------------------------------------------------------------
function p.get(key)
local ep = p.index[normalize(key)]
if not ep then return nil end
return {
id = ep.id,
namespace = ep.namespace,
page_title = ep.page_title,
title_fr = ep.title_fr,
title_qc = ep.title_qc,
title_vo = ep.title_vo,
property = ep.property,
season = ep.season,
episode = ep.episode,
}
end
------------------------------------------------------------
-- STORE IN GLOBAL CACHE
------------------------------------------------------------
globalCache.__EPISODE_INDEX_BUILT = true
globalCache.__EPISODE_INDEX = p
return p