Module:C: Difference between revisions
From Teriock
More actions
// via Wikitext Extension for VSCode Tag: Reverted |
// via Wikitext Extension for VSCode Tag: Reverted |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
-- | -- Simple memo table so repeated checks in one render are cheap | ||
local | local _catMemo = {} | ||
-- | -- Robust category check using the title object, following redirects | ||
local function pageInCategory(pagetitle, cat) | local function pageInCategory(pagetitle, cat) | ||
if not pagetitle then return false end | if not pagetitle or pagetitle == "" then return false end | ||
local key = pagetitle .. "@@" .. cat | |||
if _catMemo[key] ~= nil then | |||
return _catMemo[key] | |||
end | |||
local title = mw.title.new(pagetitle) | local title = mw.title.new(pagetitle) | ||
if not title or not title.exists then return false end | if not title or not title.exists then | ||
local | _catMemo[key] = false | ||
if not | return false | ||
-- match | end | ||
local | |||
return | -- If this is a redirect, follow it | ||
if title.isRedirect then | |||
local target = title.redirectTarget | |||
if target and target.exists then | |||
title = target | |||
end | |||
end | |||
-- parent categories is a map like ["Category:Foo"] = sortkey | |||
local parents = title:getParentCategories() | |||
if not parents then | |||
_catMemo[key] = false | |||
return false | |||
end | |||
-- We match exact category name (without namespace) | |||
-- Build "Category:<name>" and compare keys case-sensitively as MW does | |||
local want = "Category:" .. cat | |||
for parentCat, _ in pairs(parents) do | |||
if parentCat == want then | |||
_catMemo[key] = true | |||
return true | |||
end | |||
end | |||
_catMemo[key] = false | |||
return false | |||
end | end | ||
| Line 95: | Line 124: | ||
if improvedMatch then improved = mw.text.trim(improvedMatch) end | if improvedMatch then improved = mw.text.trim(improvedMatch) end | ||
-- clean name | -- clean name (strip markers and payloads/flags) | ||
name = mw.ustring.gsub(name, "%-l%-.+", "") | name = mw.ustring.gsub(name, "%-l%-.+", "") | ||
name = mw.ustring.gsub(name, "%-i%-.+", "") | name = mw.ustring.gsub(name, "%-i%-.+", "") | ||
| Line 123: | Line 152: | ||
} | } | ||
local shouldRemove = { | local shouldRemove = { | ||
["Normal Intelligence"] = false, | ["Normal Intelligence"] = false, | ||
| Line 133: | Line 161: | ||
for _, inName in ipairs(incomingNames) do | for _, inName in ipairs(incomingNames) do | ||
for normalName, cat in pairs(catMap) do | for normalName, cat in pairs(catMap) do | ||
if not shouldRemove[normalName] | if not shouldRemove[normalName] and pageInCategory(inName, cat) then | ||
shouldRemove[normalName] = true | |||
end | end | ||
end | end | ||
| Line 149: | Line 174: | ||
end | end | ||
-- Sort alphabetically by name | -- Sort alphabetically by name (case-insensitive, but stable on original) | ||
table.sort(abilities, function(a, b) return a.name < b.name end) | table.sort(abilities, function(a, b) | ||
local aa, bb = mw.ustring.lower(a.name), mw.ustring.lower(b.name) | |||
if aa == bb then return a.name < b.name end | |||
return aa < bb | |||
end) | |||
-- Assemble output | -- Assemble output and expand the AE templates right here | ||
local outParts = {} | local outParts = {} | ||
for _, a in ipairs(abilities) do | for _, a in ipairs(abilities) do | ||
Revision as of 02:06, 12 August 2025
Documentation for this module may be created at Module:C/doc
local p = {}
-- Simple memo table so repeated checks in one render are cheap
local _catMemo = {}
-- Robust category check using the title object, following redirects
local function pageInCategory(pagetitle, cat)
if not pagetitle or pagetitle == "" then return false end
local key = pagetitle .. "@@" .. cat
if _catMemo[key] ~= nil then
return _catMemo[key]
end
local title = mw.title.new(pagetitle)
if not title or not title.exists then
_catMemo[key] = false
return false
end
-- If this is a redirect, follow it
if title.isRedirect then
local target = title.redirectTarget
if target and target.exists then
title = target
end
end
-- parent categories is a map like ["Category:Foo"] = sortkey
local parents = title:getParentCategories()
if not parents then
_catMemo[key] = false
return false
end
-- We match exact category name (without namespace)
-- Build "Category:<name>" and compare keys case-sensitively as MW does
local want = "Category:" .. cat
for parentCat, _ in pairs(parents) do
if parentCat == want then
_catMemo[key] = true
return true
end
end
_catMemo[key] = false
return false
end
-- Build AE template from an ability object
local function aeTemplate(a)
local parts = {"{{AE|", a.name}
if a.limited and a.limited ~= "" then table.insert(parts, "|limited=" .. a.limited) end
if a.improved and a.improved ~= "" then table.insert(parts, "|improved=" .. a.improved) end
if a.gifted then table.insert(parts, "|gifted=1") end
if a.adept then table.insert(parts, "|adept=1") end
table.insert(parts, "}}")
return table.concat(parts)
end
function p.c(frame)
local args = frame.args
local rawAbilities = args['a'] or ''
-- Prepopulate defaults
local abilities = {}
local indexByName = {}
local function addAbility(obj, isDefault)
local key = mw.text.trim(obj.name or "")
if key == "" then return end
obj.name = key
if indexByName[key] then
abilities[indexByName[key]] = obj
else
table.insert(abilities, obj)
indexByName[key] = #abilities
end
if isDefault then abilities[indexByName[key]]._isDefault = true end
end
local function removeByName(name)
local i = indexByName[name]
if not i then return end
table.remove(abilities, i)
-- rebuild index
indexByName = {}
for idx, ab in ipairs(abilities) do
indexByName[ab.name] = idx
end
end
-- Defaults
local defaults = {
"Normal Intelligence",
"Normal Strength",
"Normal Movement",
"Normal Sneak",
"Normal Perception",
}
for _, n in ipairs(defaults) do
addAbility({
name = n, limited = "", improved = "", gifted = false, adept = false
}, true)
end
-- Parse incoming abilities
local incomingNames = {} -- keep a list to check categories against (only incoming)
for ability in mw.text.gsplit(rawAbilities, ";;", true) do
ability = mw.text.trim(ability)
if ability ~= "" then
local name = ability
local limited, improved = "", ""
local gifted, adept = false, false
if mw.ustring.find(ability, "%-g%-") then gifted = true end
if mw.ustring.find(ability, "%-a%-") then adept = true end
local limitedMatch = mw.ustring.match(ability, "%-l%-(.-)(%-[liag]%-|$)")
or mw.ustring.match(ability, "%-l%-(.+)$")
if limitedMatch then limited = mw.text.trim(limitedMatch) end
local improvedMatch = mw.ustring.match(ability, "%-i%-(.-)(%-[liag]%-|$)")
or mw.ustring.match(ability, "%-i%-(.+)$")
if improvedMatch then improved = mw.text.trim(improvedMatch) end
-- clean name (strip markers and payloads/flags)
name = mw.ustring.gsub(name, "%-l%-.+", "")
name = mw.ustring.gsub(name, "%-i%-.+", "")
name = mw.ustring.gsub(name, "%-g%-", "")
name = mw.ustring.gsub(name, "%-a%-", "")
name = mw.text.trim(name)
addAbility({
name = name,
limited = limited,
improved = improved,
gifted = gifted,
adept = adept
}, false)
table.insert(incomingNames, name)
end
end
-- If any incoming ability is in the mapped category, remove the corresponding default
local catMap = {
["Normal Intelligence"] = "INT setting abilities",
["Normal Strength"] = "STR setting abilities",
["Normal Movement"] = "MOV setting abilities",
["Normal Sneak"] = "SNK setting abilities",
["Normal Perception"] = "PER setting abilities",
}
local shouldRemove = {
["Normal Intelligence"] = false,
["Normal Strength"] = false,
["Normal Movement"] = false,
["Normal Sneak"] = false,
["Normal Perception"] = false,
}
for _, inName in ipairs(incomingNames) do
for normalName, cat in pairs(catMap) do
if not shouldRemove[normalName] and pageInCategory(inName, cat) then
shouldRemove[normalName] = true
end
end
end
for normalName, flag in pairs(shouldRemove) do
if flag then
removeByName(normalName)
end
end
-- Sort alphabetically by name (case-insensitive, but stable on original)
table.sort(abilities, function(a, b)
local aa, bb = mw.ustring.lower(a.name), mw.ustring.lower(b.name)
if aa == bb then return a.name < b.name end
return aa < bb
end)
-- Assemble output and expand the AE templates right here
local outParts = {}
for _, a in ipairs(abilities) do
table.insert(outParts, aeTemplate(a))
end
local inner = table.concat(outParts, "")
local out = '<div class="expandable-table"><div>' .. frame:preprocess(inner) .. '</div></div>'
return out
end
return p