Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Appearances: Difference between revisions

From Gensopedia
Created page with "-- Module:Appearances -- Renders appearance lists and auto-adds categories for characters. -- Supports custom display text and category overrides. local p = {} -- Define all possible appearances and their default categories. local appearances = { ["Suikoden"] = "Characters in Suikoden", ["Suikoden II"] = "Characters in Suikoden II", ["Suikoden III"] = "Characters in Suikoden III", ["Suikoden IV"] = "Characters in Suikoden IV", ["Suikoden V"] = "Characters in Suiko..."
 
mNo edit summary
Line 1: Line 1:
-- Module:Appearances
-- Module:Appearances
-- Renders appearance lists and auto-adds categories for characters.
-- Handles both short codes (S1, G1, etc.) and full names (Suikoden II, etc.)
-- Supports custom display text and category overrides.
-- Backward compatible with |S1=yes|G1=yes|...
-- Supports mixed inputs like |Codes=S1,Suikoden II,G1


local p = {}
local p = {}


-- Define all possible appearances and their default categories.
-- Master lookup: short code → { page name, category, display text (optional) }
local appearances = {
local games = {
["Suikoden"] = "Characters in Suikoden",
S1  = { "Suikoden", "Characters in Suikoden" },
["Suikoden II"] = "Characters in Suikoden II",
S2  = { "Suikoden II", "Characters in Suikoden II" },
["Suikoden III"] = "Characters in Suikoden III",
G1  = { "Genso Suikogaiden Vol.1", "Characters in Genso Suikogaiden Vol.1" },
["Suikoden IV"] = "Characters in Suikoden IV",
G2  = { "Genso Suikogaiden Vol.2", "Characters in Genso Suikogaiden Vol.2" },
["Suikoden V"] = "Characters in Suikoden V",
CS  = { "Genso Suikoden Card Stories", "Characters in Genso Suikoden Card Stories" },
["Suikoden Tactics"] = "Characters in Suikoden Tactics",
S3  = { "Suikoden III", "Characters in Suikoden III" },
["Genso Suikogaiden Vol.1"] = "Characters in Genso Suikogaiden Vol.1",
S4  = { "Suikoden IV", "Characters in Suikoden IV" },
["Genso Suikogaiden Vol.2"] = "Characters in Genso Suikogaiden Vol.2",
ST  = { "Suikoden Tactics", "Characters in Suikoden Tactics" },
["Genso Suikoden Card Stories"] = "Characters in Genso Suikoden Card Stories",
S5  = { "Suikoden V", "Characters in Suikoden V" },
["Genso Suikoden Tierkreis Hoshikuzu no Shiro"] = "Characters in Genso Suikoden Tierkreis Hoshikuzu no Shiro",
HS  = { "Genso Suikoden Tierkreis Hoshikuzu no Shiro", "Characters in Genso Suikoden Tierkreis Hoshikuzu no Shiro" },
["Suikoden Tierkreis"] = "Characters in Suikoden Tierkreis",
TK  = { "Suikoden Tierkreis", "Characters in Suikoden Tierkreis" },
["Pachislot Genso Suikoden"] = "Characters in Pachislot Genso Suikoden",
PS  = { "Pachislot Genso Suikoden", "Characters in Pachislot Genso Suikoden" },
["Genso Suikoden Tsumugareshi Hyakunen no Toki"] = "Characters in Genso Suikoden Tsumugareshi Hyakunen no Toki",
HT  = { "Genso Suikoden Tsumugareshi Hyakunen no Toki", "Characters in Genso Suikoden Tsumugareshi Hyakunen no Toki" },
["Suikoden STAR LEAP"] = "Characters in Suikoden STAR LEAP",
SP  = { "Suikoden STAR LEAP", "Characters in Suikoden STAR LEAP" },
["Konami Parody Comic Series Genso Suikoden"] = "Characters from Konami Parody Comic Series Genso Suikoden",
SL  = { "Suikoden STAR LEAP", "Characters in Suikoden STAR LEAP" },
["Genso Suikoden: Soul Eater 1"] = "Characters from Genso Suikoden Soul Eater",
kpc = { "Konami Parody Comic Series Genso Suikoden", "Characters from Konami Parody Comic Series Genso Suikoden" },
["Genso Suikoden: Soul Eater 3"] = "Characters from Genso Suikoden Soul Eater",
SE  = { "Genso Suikoden: Soul Eater 1", "Characters from Genso Suikoden Soul Eater", "Soul Eater 1" },
["Genso Suikoden II: 1 (novel)"] = "Characters from the Genso Suikoden II novel",
SE3 = { "Genso Suikoden: Soul Eater 3", "Characters from Genso Suikoden Soul Eater", "Soul Eater 3" },
["Genso Suikoden II: 4 (novel)"] = "Characters from the Genso Suikoden II novel",
S2n = { "Genso Suikoden II: 1 (novel)", "Characters from the Genso Suikoden II novel" },
["Genso Suikoden Short Story Collection 1"] = "Characters from Genso Suikoden Short Story Collection 1",
S2n4= { "Genso Suikoden II: 4 (novel)", "Characters from the Genso Suikoden II novel" },
["Genso Suikoden Short Story Collection 2"] = "Characters from Genso Suikoden Short Story Collection 2",
SS1 = { "Genso Suikoden Short Story Collection 1", "Characters from Genso Suikoden Short Story Collection 1" },
["Genso Suikoden Short Story Collection 3"] = "Characters from Genso Suikoden Short Story Collection 3",
SS2 = { "Genso Suikoden Short Story Collection 2", "Characters from Genso Suikoden Short Story Collection 2" },
["Genso Suikoden Short Story Collection 4"] = "Characters from Genso Suikoden Short Story Collection 4",
SS3 = { "Genso Suikoden Short Story Collection 3", "Characters from Genso Suikoden Short Story Collection 3" },
["Genso Suikoden IV: 1 (novel)"] = "Characters from the Genso Suikoden IV novel",
SS4 = { "Genso Suikoden Short Story Collection 4", "Characters from Genso Suikoden Short Story Collection 4" },
S4n = { "Genso Suikoden IV: 1 (novel)", "Characters from the Genso Suikoden IV novel" },
}
}


-- Helper to trim whitespace
-- Reverse lookup: full title → code
local titleToCode = {}
for code, data in pairs(games) do
titleToCode[data[1]] = code
end
 
local function trim(s)
local function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
end


-- Renders a single appearance entry
local function makeLine(entry)
local function renderEntry(name, display, category)
local title, category, display = entry[1], entry[2], entry[3]
name = trim(name)
return string.format("* [[%s|%s]] [[Category:%s]]", title, display or title, category)
display = display or name
category = category or appearances[name] or ("Characters in " .. name)
 
return string.format("* [[%s|%s]] [[Category:%s]]", name, display, category)
end
end


-- Main entry point
function p.render(frame)
function p.render(frame)
local input = frame.args[1] or ""
local args = frame.args
if input == "" then return "" end
local inputCodes = {}


-- Split by comma
-- 1️⃣ Get from comma-separated list
local entries = mw.text.split(input, ",")
if args.Codes and args.Codes ~= "" then
local output = {}
for _, token in ipairs(mw.text.split(args.Codes, ",")) do
token = trim(token)
if token ~= "" then
-- Normalize to short code if it’s a full name
local code = titleToCode[token] or token
if games[code] then
table.insert(inputCodes, code)
end
end
end
end


for _, entry in ipairs(entries) do
-- 2️⃣ Get from named parameters (legacy |S1=yes|)
entry = trim(entry)
for code, _ in pairs(games) do
if entry ~= "" then
if (args[code] or ""):lower() == "yes" then
-- Handle custom syntax: Game|Display|Category
table.insert(inputCodes, code)
local parts = mw.text.split(entry, "|")
end
local game = trim(parts[1] or "")
end
local display = trim(parts[2] or "")
local category = trim(parts[3] or "")


if game ~= "" then
-- 3️⃣ Remove duplicates
table.insert(output, renderEntry(game, display ~= "" and display or nil, category ~= "" and category or nil))
local seen, unique = {}, {}
end
for _, code in ipairs(inputCodes) do
if not seen[code] then
seen[code] = true
table.insert(unique, code)
end
end
end
-- 4️⃣ Sort codes for consistent order (optional)
table.sort(unique, function(a, b) return a < b end)
-- 5️⃣ Build output
local output = {}
for _, code in ipairs(unique) do
table.insert(output, makeLine(games[code]))
end
end



Revision as of 13:05, 10 October 2025

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

-- Module:Appearances
-- Handles both short codes (S1, G1, etc.) and full names (Suikoden II, etc.)
-- Backward compatible with |S1=yes|G1=yes|...
-- Supports mixed inputs like |Codes=S1,Suikoden II,G1

local p = {}

-- Master lookup: short code → { page name, category, display text (optional) }
local games = {
	S1  = { "Suikoden", "Characters in Suikoden" },
	S2  = { "Suikoden II", "Characters in Suikoden II" },
	G1  = { "Genso Suikogaiden Vol.1", "Characters in Genso Suikogaiden Vol.1" },
	G2  = { "Genso Suikogaiden Vol.2", "Characters in Genso Suikogaiden Vol.2" },
	CS  = { "Genso Suikoden Card Stories", "Characters in Genso Suikoden Card Stories" },
	S3  = { "Suikoden III", "Characters in Suikoden III" },
	S4  = { "Suikoden IV", "Characters in Suikoden IV" },
	ST  = { "Suikoden Tactics", "Characters in Suikoden Tactics" },
	S5  = { "Suikoden V", "Characters in Suikoden V" },
	HS  = { "Genso Suikoden Tierkreis Hoshikuzu no Shiro", "Characters in Genso Suikoden Tierkreis Hoshikuzu no Shiro" },
	TK  = { "Suikoden Tierkreis", "Characters in Suikoden Tierkreis" },
	PS  = { "Pachislot Genso Suikoden", "Characters in Pachislot Genso Suikoden" },
	HT  = { "Genso Suikoden Tsumugareshi Hyakunen no Toki", "Characters in Genso Suikoden Tsumugareshi Hyakunen no Toki" },
	SP  = { "Suikoden STAR LEAP", "Characters in Suikoden STAR LEAP" },
	SL  = { "Suikoden STAR LEAP", "Characters in Suikoden STAR LEAP" },
	kpc = { "Konami Parody Comic Series Genso Suikoden", "Characters from Konami Parody Comic Series Genso Suikoden" },
	SE  = { "Genso Suikoden: Soul Eater 1", "Characters from Genso Suikoden Soul Eater", "Soul Eater 1" },
	SE3 = { "Genso Suikoden: Soul Eater 3", "Characters from Genso Suikoden Soul Eater", "Soul Eater 3" },
	S2n = { "Genso Suikoden II: 1 (novel)", "Characters from the Genso Suikoden II novel" },
	S2n4= { "Genso Suikoden II: 4 (novel)", "Characters from the Genso Suikoden II novel" },
	SS1 = { "Genso Suikoden Short Story Collection 1", "Characters from Genso Suikoden Short Story Collection 1" },
	SS2 = { "Genso Suikoden Short Story Collection 2", "Characters from Genso Suikoden Short Story Collection 2" },
	SS3 = { "Genso Suikoden Short Story Collection 3", "Characters from Genso Suikoden Short Story Collection 3" },
	SS4 = { "Genso Suikoden Short Story Collection 4", "Characters from Genso Suikoden Short Story Collection 4" },
	S4n = { "Genso Suikoden IV: 1 (novel)", "Characters from the Genso Suikoden IV novel" },
}

-- Reverse lookup: full title → code
local titleToCode = {}
for code, data in pairs(games) do
	titleToCode[data[1]] = code
end

local function trim(s)
	return (s:gsub("^%s*(.-)%s*$", "%1"))
end

local function makeLine(entry)
	local title, category, display = entry[1], entry[2], entry[3]
	return string.format("* [[%s|%s]] [[Category:%s]]", title, display or title, category)
end

function p.render(frame)
	local args = frame.args
	local inputCodes = {}

	-- 1️⃣ Get from comma-separated list
	if args.Codes and args.Codes ~= "" then
		for _, token in ipairs(mw.text.split(args.Codes, ",")) do
			token = trim(token)
			if token ~= "" then
				-- Normalize to short code if it’s a full name
				local code = titleToCode[token] or token
				if games[code] then
					table.insert(inputCodes, code)
				end
			end
		end
	end

	-- 2️⃣ Get from named parameters (legacy |S1=yes|)
	for code, _ in pairs(games) do
		if (args[code] or ""):lower() == "yes" then
			table.insert(inputCodes, code)
		end
	end

	-- 3️⃣ Remove duplicates
	local seen, unique = {}, {}
	for _, code in ipairs(inputCodes) do
		if not seen[code] then
			seen[code] = true
			table.insert(unique, code)
		end
	end

	-- 4️⃣ Sort codes for consistent order (optional)
	table.sort(unique, function(a, b) return a < b end)

	-- 5️⃣ Build output
	local output = {}
	for _, code in ipairs(unique) do
		table.insert(output, makeLine(games[code]))
	end

	return table.concat(output, "<br />\n")
end

return p