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..."
 
m Text replacement - "Genso Suikoden STAR LEAP: Hoshi Boshi no Kiseki" to "Suikoden STAR LEAP: Trails of the Stars"
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
-- Module:Appearances
-- Module:Appearances
-- Renders appearance lists and auto-adds categories for characters.
-- Renders a character's appearances using short codes or full titles.
-- Supports custom display text and category overrides.
-- Keeps order as defined in this file, not alphabetically.
-- Supports:
--  |appears=S1, Suikoden II, G1|
--  |S1=yes|G1=yes| (legacy)
--  Mixed usage.


local p = {}
local p = {}


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


-- Helper to trim whitespace
-- Reverse lookup: title → short 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 requested = {}
local seen = {}


-- Split by comma
-- 1️⃣ Collect from |appears=
local entries = mw.text.split(input, ",")
if args.appears and args.appears ~= "" then
for _, token in ipairs(mw.text.split(args.appears, ",")) do
token = trim(token)
if token ~= "" then
local code = titleToCode[token] or token
if games[code] and not seen[code] then
seen[code] = true
requested[code] = true
end
end
end
end
 
-- 2️⃣ Add legacy |S1=yes| flags
for code, _ in pairs(games) do
if (args[code] or ""):lower() == "yes" then
requested[code] = true
end
end
 
-- 3️⃣ Output in canonical order (no alphabetical sort)
local output = {}
local output = {}
for code, entry in pairs(games) do
-- preserve insertion order: we’ll iterate over an ordered key list instead
end


for _, entry in ipairs(entries) do
-- To preserve order, we must iterate in sequence as defined:
entry = trim(entry)
local orderedKeys = {
if entry ~= "" then
"S1","S2","G1","G2","CS","S3","S4","ST","S5","HS","TK","PS","HT",
-- Handle custom syntax: Game|Display|Category
"SP","SL","HB","kpc","SE","SE3","S2n","S2n4","SS1","SS2","SS3","SS4","S4n","SPm"
local parts = mw.text.split(entry, "|")
}
local game = trim(parts[1] or "")
local display = trim(parts[2] or "")
local category = trim(parts[3] or "")


if game ~= "" then
for _, code in ipairs(orderedKeys) do
table.insert(output, renderEntry(game, display ~= "" and display or nil, category ~= "" and category or nil))
if requested[code] then
end
table.insert(output, makeLine(games[code]))
end
end
end
end

Latest revision as of 09:51, 5 December 2025

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

-- Module:Appearances
-- Renders a character's appearances using short codes or full titles.
-- Keeps order as defined in this file, not alphabetically.
-- Supports:
--   |appears=S1, Suikoden II, G1|
--   |S1=yes|G1=yes| (legacy)
--   Mixed usage.

local p = {}

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

-- Reverse lookup: title → short 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 requested = {}
	local seen = {}

	-- 1️⃣ Collect from |appears=
	if args.appears and args.appears ~= "" then
		for _, token in ipairs(mw.text.split(args.appears, ",")) do
			token = trim(token)
			if token ~= "" then
				local code = titleToCode[token] or token
				if games[code] and not seen[code] then
					seen[code] = true
					requested[code] = true
				end
			end
		end
	end

	-- 2️⃣ Add legacy |S1=yes| flags
	for code, _ in pairs(games) do
		if (args[code] or ""):lower() == "yes" then
			requested[code] = true
		end
	end

	-- 3️⃣ Output in canonical order (no alphabetical sort)
	local output = {}
	for code, entry in pairs(games) do
		-- preserve insertion order: we’ll iterate over an ordered key list instead
	end

	-- To preserve order, we must iterate in sequence as defined:
	local orderedKeys = {
		"S1","S2","G1","G2","CS","S3","S4","ST","S5","HS","TK","PS","HT",
		"SP","SL","HB","kpc","SE","SE3","S2n","S2n4","SS1","SS2","SS3","SS4","S4n","SPm"
	}

	for _, code in ipairs(orderedKeys) do
		if requested[code] then
			table.insert(output, makeLine(games[code]))
		end
	end

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

return p