Documentation for this module may be created at Module:Franchise/doc
local p = {} local h = {} local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable") local cache = mw.loadData("Module:Franchise/Cache") local CATEGORY_INVALID_ARGS = "Category:"..require("Module:Constants/category/invalidArgs") -- Many templates need "Series" as if it were a game. Since it does not fit into the data model of Data:Franchise, it is manually defined here. local series = { article = "The Legend of Zelda (Series)", shortName = "The Legend of Zelda Series", logo = "File:Zelda Logo TP.png", link = "[[The Legend of Zelda (Series)|''The Legend of Zelda'' series]]", display = "''The Legend of Zelda'' series", canonicity = "canon", type = "main", code = "Series", } function p.Article(frame) return h.templateQuery("article", frame) end function p.BaseGame(frame) return h.templateQuery("baseGame", frame) end function p.Display(frame) return h.templateQuery("display", frame) end function p.Link(frame) return h.templateQuery("link", frame) end function p.ShortName(frame) return h.templateQuery("shortName", frame) end function h.templateQuery(fn, frame) local args = frame.args local game, nowarn = args[1], args.nowarn if game == nil or game == "" then return "", h.error("No game provided", CATEGORY_INVALID_ARGS, nowarn) end game = utilsString.trim(game) local value = p[fn](game) if not value then return "", h.error(string.format("Invalid entry <code>%s</code>", game), CATEGORY_INVALID_ARGS, nowarn, "See [[Data:Franchise]] for a list of valid entries.") end local correctGameCode = p.code(game) if game ~= correctGameCode then local utilsError = require("Module:UtilsError") utilsError.warn(string.format("<code>%s</code> should be written as <code>%s</code>", game, correctGameCode)) return value, "[["..CATEGORY_INVALID_ARGS.."]]" else return value end end function h.error(errorMsg, category, nowarn, additionalWarningInfo) local utilsError = require("Module:UtilsError") local warnMsg = not nowarn and additionalWarningInfo and (errorMsg.. ". ".. additionalWarningInfo) return utilsError.error(errorMsg, warnMsg).."[["..category.."]]" end -- [[Guidelines:Main]] function p.ListTitlesByCanonicity(frame) local utilsLayout = require("Module:UtilsLayout") local canonicity = frame.args[1] local rows = {} for i, code in ipairs(p.enum()) do if canonicity == p.canonicity(code) then local link = p.link(code) local releaseDate = p.releaseDate(code) table.insert(rows, {link, releaseDate}) end end local wikitable = utilsLayout.table({ sortable = true, headers = {"Media", "Release Date"}, rows = rows, }) return wikitable end function p.ListAllTitles(frame) local utilsLayout = require("Module:UtilsLayout") local canonicityStatuses = { ["canon"] = "Canon", ["non-canon"] = "Non-canon", ["ambiguous"] = "Ambiguously-canon", } local rows = {} for i, code in ipairs(p.enum()) do local link = p.link(code) local releaseDate = p.releaseDate(code) local canonicity = p.canonicity(code) local canonicityStatus = canonicityStatuses[canonicity] local supersededBy = h.get(code, "supersededBy") if canonicityStatus and supersededBy ~= nil and supersededBy ~= "" then local supersederLink = p.link(supersededBy) canonicityStatus = canonicityStatus .. string.format(" <small>(superseded by %s)</small>", supersederLink) end table.insert(rows, {link, code, releaseDate, canonicityStatus}) end local rows = utilsTable.sortBy(rows, 3) -- sort by release date local wikitable = utilsLayout.table({ sortable = true, headers = {"Media", "Abbreviation", "Release Date", "Status"}, rows = rows, }) return wikitable end -- Template:Franchise/Store * function p.AddToPreview(frame) -- Performance optimization local utilsArg = require("Module:UtilsArg") local utilsVar = require("Module:UtilsVar") local utilsMarkup = require("Module:UtilsMarkup") local templateData = mw.loadData("Module:Franchise/TemplateData") local orderCounter = utilsVar.counter("releaseOrder") local entryType = frame.args[1] local args, err = utilsArg.parse(frame:getParent().args, templateData["Franchise/Store " .. entryType]) if err then return utilsMarkup.categories(err.categories) end args = utilsTable.merge({}, args, { entryType = entryType, link = p.deriveLink(entryType, args), display = p.deriveDisplay(entryType, args), }) if entryType == "Game" or entryType == "Book" or entryType == "TV" then args.releaseOrder = orderCounter.value() else args.releaseOrder = "—" end if entryType == "Book" then args.phraseLink = p.derivePhraseLink(args) end utilsVar.add("rows", args) end function p.StoreOrder(frame) -- Performance optimization local utilsVar = require("Module:UtilsVar") local orderCounter = utilsVar.counter("releaseOrder") return orderCounter.increment() end function p.StoreLink(frame) return p.deriveLink(frame.args[1], frame:getParent().args) end function p.StoreDisplay(frame) return p.deriveDisplay(frame.args[1], frame:getParent().args) end function p.StorePhraseLink(frame) return p.derivePhraseLink(frame:getParent().args) end function p.deriveDisplay(entryType, args) if args.display ~= nil and args.display ~= "" then return args.display elseif entryType == "Book" then return h.deriveBookFields(args).display else return ("''%s''"):format(args.shortName) end end function p.deriveLink(entryType, args) if args.display ~= nil and args.display ~= "" then return args.link elseif entryType == "Book" then return h.deriveBookFields(args).link else return ("''[[%s|%s]]''"):format(args.article, args.shortName) end end function p.derivePhraseLink(args) return h.deriveBookFields(args).phraseLink end function p.Preview(frame) -- Performance optimization local utilsMarkup = require("Module:UtilsMarkup") local utilsLayout = require("Module:UtilsLayout") local utilsVar = require("Module:UtilsVar") local previewColumns = { common = {"releaseOrder", "code", "link", "display", "logo", "releaseDate", "canonicity"}, Game = {"type", "graphics", "family", "remakeOf", "supersededBy"}, Book = {"type", "phraseLink", "publisher", "authors", "basedOn"}, Nonfiction = {"publisher", "titles"}, TV = {"type"}, Group = {"games"}, } previewColumns.Game = utilsTable.concat(previewColumns.common, previewColumns.Game) previewColumns.Book = utilsTable.concat(previewColumns.common, previewColumns.Book) previewColumns.TV = utilsTable.concat(previewColumns.common, previewColumns.TV) previewColumns.Nonfiction = utilsTable.concat(previewColumns.common, previewColumns.Nonfiction) previewColumns.Group = utilsTable.concat(previewColumns.common, previewColumns.Group) local rows = utilsVar.get("rows") for _, row in ipairs(rows) do row.logo = utilsMarkup.link(row.logo) end local rowGroups = utilsTable.groupBy(rows, "entryType") local titles = utilsLayout.table({ sortable = true, headers = previewColumns.common, rows = utilsTable.map(rows, utilsTable._toArray(previewColumns.common, "")) }) local games = utilsLayout.table({ sortable = true, headers = previewColumns.Game, rows = utilsTable.map(rowGroups.Game, utilsTable._toArray(previewColumns.Game, "")) }) local books = utilsLayout.table({ sortable = true, headers = previewColumns.Book, rows = utilsTable.map(rowGroups.Book, utilsTable._toArray(previewColumns.Book, "")) }) local tv = utilsLayout.table({ sortable = true, headers = previewColumns.TV, rows = utilsTable.map(rowGroups.TV, utilsTable._toArray(previewColumns.TV, "")) }) local nonfiction = utilsLayout.table({ sortable = true, headers = previewColumns.Nonfiction, rows = utilsTable.map(rowGroups.Nonfiction or {}, utilsTable._toArray(previewColumns.Nonfiction, "")) }) local groups = utilsLayout.table({ sortable = true, headers = previewColumns.Group, rows = utilsTable.map(rowGroups.Group or {}, utilsTable._toArray(previewColumns.Group, "")) }) local preview = utilsLayout.tabs({ { label = "All Titles", content = titles, }, { label = "Games", content = games, }, { label = "Books (fiction)", content = books, }, { label = "Books (nonfiction)", content = nonfiction }, { label = "Movies and TV Shows", content = tv, }, { label = "Groups", content = groups, } }, { columns = 15 }) return preview end function p.UploadField(frame) -- Performance optimization local utilsMarkup = require("Module:UtilsMarkup") local utilsVar = require("Module:UtilsVar") local rows = utilsVar.get("rows") local groups = utilsTable.groupBy(rows, "entryType") local mainGames, otherGames = utilsTable.partition(groups["Game"], { canonicity = "canon" }) local gamesByBaseGame = utilsTable.groupBy(mainGames, function(game) return p.baseGame(game.code) end) local books = groups["Book"] local tvShows = groups["TV"] local sortedMainGames = {} for _, mainGame in ipairs(utilsTable.reverse(mainGames)) do for _, game in ipairs(gamesByBaseGame[mainGame.code] or {}) do table.insert(sortedMainGames, game) end end local result = "" result = result .. "**|None\n" result = result .. "**Series|The Legend of Zelda Series\n" result = h.append(result, "Main Series", sortedMainGames) result = h.append(result, "Other Games", otherGames) result = h.append(result, "Books, Comics, and Manga", books) result = h.append(result, "TV Shows", tvShows) return utilsMarkup.pre(result) end function h.append(result, title, entries) result = result .. "\n*"..title.."\n" for _, entry in ipairs(entries) do result = result .. string.format("**%s|%s\n", entry.code, entry.shortName) end return result end function h.deriveBookFields(args) local ListPages = require("Module:List Pages") local utilsString = require("Module:UtilsString") local subtitle, display, link, phraseLink local parens = string.find(args.shortName, "%s%([^)]+%)") if parens then subtitle = string.sub(args.shortName, 1, parens - 1) local descriptor = string.sub(args.shortName, parens) display = ("''%s''%s"):format(subtitle, descriptor) link = ("[[%s|%s]]"):format(args.article, display) local authors = ListPages.main(utilsString.split(args.authors)) phraseLink = ("[[%s|''%s'' %s]] by %s"):format(args.article, subtitle, args.type, authors) else display = ("''%s''"):format(args.shortName) link = ("''[[%s|%s]]''"):format(args.article, args.shortName) phraseLink = link end return { display = display, link = link, phraseLink = phraseLink, } end -- QUERIES: ALL function p.enum(options) if not options then return cache.enum end enum = utilsTable.clone(cache.enum) -- clone the read-only cache item so that we can modify it if options.includeSeries then table.insert(enum, 1, "Series") end if options.includeNonfiction then local codes = utilsTable.map(cache.nonfiction, "code") enum = utilsTable.concat(codes, enum) end if options.includeGroups then -- insert "groups" so as to not disrupt the release order. This matters for Template:Media (e.g. the Fighter page, which uses SSB4) for _, group in ipairs(cache.groups) do local i = 1 repeat i = i + 1 until i == #enum or p.isCanon(enum[i]) == p.isCanon(group.code) and p.releaseDate(enum[i]) and p.releaseDate(enum[i]) >= p.releaseDate(group.code) table.insert(enum, i, group.code) end end enum.reference = "[[Data:Franchise]]" return enum end function p.article(code) return h.get(code, "article") end function p.canonicity(code) return h.get(code, "canonicity") end function p.releaseOrder(code) local releaseOrder = h.get(code, "releaseOrder") return releaseOrder and tonumber(releaseOrder) end function p.code(code) return h.get(code, "code") end function p.display(code) return h.get(code, "display") end function p.isCanon(code) return p.canonicity(code) == "canon" end function p.link(code) return h.get(code, "link") end function p.logo(code) return h.get(code, "logo") end function p.releaseDate(code) return h.get(code, "releaseDate") end function p.shortName(code) return h.get(code, "shortName") end function p.type(code) return h.get(code, "type") end -- QUERIES: GAMES function p.enumGames(includeSeries) if includeSeries then local enum = utilsTable.concat({"Series"}, cache.enumGames) enum.reference = "[[Data:Franchise]]" return enum end return cache.enumGames end function p.baseGame(code) local baseGames = h.get(code, "remakeOf") if baseGames == nil then -- game not found return nil elseif baseGames == "" then -- game has no remakes return code else return utilsString.split(baseGames)[1] end end function p.family(code) return h.get(code, "family") end function p.graphics(code) return h.get(code, "graphics") end function p.hasRemakes(code) return utilsTable.hasKey(cache.remakes, string.lower(code)) end function p.isRemake(code) local remakeOf = h.get(code, "remakeOf") return remakeOf ~= nil and remakeOf ~= "" end function p.remakes(code) return utilsTable.clone(cache.remakes[string.lower(code)]) or {} end function p.superseder(code) local supersededBy = h.get(code, "supersededBy") if supersededBy == "" then supersededBy = nil end return supersededBy end -- QUERIES: BOOKS function p.publisher(code) return h.get(code, "publisher") end function p.phraseLink(code) return h.get(code, "phraseLink") end function h.get(code, prop) code = string.lower(code) if code == "series" then return series[prop] end local title = cache.titlesByCode[code] if not title then return nil -- we return nil here to indicate an invalid code else return title[prop] or "" -- we return "" here to indicate the absence of an optional property on a valid code end end local nowarnParam = { desc = "<p>If present, the template will not issue an [[Module:Error|editor warning]] when <code>game</code> is invalid. Use this when a template needs custom error handling (see examples).</p><p>However, an editor warning will still be issued if a game code is written with incorrect casing (e.g. <code>oot</code> instead of <code>OoT</code>)</p>", } function p.Documentation() return { sections = { { heading = "Template functions", section = { Article = { frameParams = { [1] = { name = "game", required = true, desc = "The code for a game or other entry in [[Data:Franchise]].", }, nowarn = nowarnParam, }, cases = { resultOnly = true, { args = {"OoT"}, }, { args = {"OoT (Himekawa)"}, }, { desc = "Error handling", args = {"oot"}, }, { args = {"notAGame"}, }, { args = {""}, }, { input = "{{#iferror:{{#invoke:Franchise|Article|invalid game}}|custom error handling}}", }, }, }, BaseGame = { frameParams = { [1] = { name = "game", required = true, desc = "The code for a game entry in [[Data:Franchise]].", }, nowarn = nowarnParam, }, cases = { resultOnly = true, { args = {"TWW"}, }, { args = {"TWWHD"}, }, { desc = "Error handling", args = {"notAGame"}, }, { args = {"twwhd"}, }, { args = {""}, }, { input = "{{#iferror:{{#invoke:Franchise|BaseGame|invalid game}}|custom error handling}}", }, }, }, Display = { frameParams = { [1] = { name = "game", required = true, desc = "The code for a game or other Zelda-related title defined at [[Data:Franchise]].", }, nowarn = nowarnParam, }, cases = { resultOnly = true, { args = {"LA"}, }, { args = {"LANS"}, }, { args = {"LA (Cagiva)"}, }, { args = {"invalid game"}, }, { args = {""}, }, }, }, Link = { frameParams = { [1] = { name = "game", required = true, desc = "The code for a game or other Zelda-related title defined at [[Data:Franchise]].", }, nowarn = nowarnParam, }, cases = { resultOnly = true, { args = {"OoT"}, }, { args = {"OoT (Himekawa)"}, }, { desc = "Error handling", args = {"oot"}, }, { args = {"notAGame"}, }, { args = {""}, }, { input = "{{#iferror:{{#invoke:Franchise|Link|invalid game}}|custom error handling}}", }, }, }, ShortName = { frameParams = { [1] = { name = "game", required = true, desc = "The code for a game or other Zelda-related title defined at [[Data:Franchise]].", }, nowarn = nowarnParam, }, cases = { resultOnly = true, { args = {"OoT"}, }, { args = {"OoT (Himekawa)"}, }, { args = {"E"}, }, { desc = "Error handling", args = {"oot"}, }, { args = {"notAGame"}, }, { args = {""}, }, { desc = "Custom error handling", input = "{{#iferror:{{#invoke:Franchise|ShortName|invalid game}}|[[Dodongo]]|[[Dodongo#{{#invoke:Franchise|ShortName|invalid game}}]]}}", }, { input = "{{#iferror:{{#invoke:Franchise|ShortName|oot}}|[[Dodongo]]|[[Dodongo#{{#invoke:Franchise|ShortName|oot}}]]}}", }, { input = "{{#iferror:{{#invoke:Franchise|ShortName|OoT}}|[[Dodongo]]|[[Dodongo#{{#invoke:Franchise|ShortName|OoT}}]]}}", }, } } }, }, { heading = "Module functions - all media", section = { enum = { desc = "See also {{Sect|enumGames}}.", params = {"options"}, returns = "An array of all codes in [[Guidelines:Main#Canon_Order|canon order]], plus a <code>reference</code> key so that it can be used for [[Module:Documentation|documentation]] and [[Module:UtilsArg|validation]].", cases = { outputOnly = true, { snippet = 1, expect = {"TLoZ", "TAoL", "ALttP", "LA", "LADX", "LANS", "OoT"}, }, { snippet = 2, expect = "[[Data:Franchise]]", }, { snippet = "IncludeSeries", desc = "When <code>includeSeries</code> is true, then <code>Series</code> is the first item in the enum.", expect = {"Series", "TLoZ", "TAoL"}, }, { snippet = "IncludeNonfiction", desc = "When <code>includeNonfiction</code> is true, then books such as {{E}} are in the list.", expect = true, }, { snippet = "IncludeGroups", desc = "When <code>includeGroups</code> is true, then collective terms such as {{ALttP&FS}} are included in the list.", expect = true, }, }, }, releaseOrder = { params = {"code"}, returns = "Position of the franchise title in the [[Guidelines:Main#Canon Order|Canon Order]].", cases = { { args = {"LA"}, expect = 4, }, { args = {"LADX"}, expect = 5, }, { args = {"Not a Game"}, expect = nil, }, { desc = "Non-ficition books such as {{E}} have no position in the canon order.", args = {"E"}, expect = nil, }, }, }, code = { params = {"code"}, returns = "The same code but correctly formatted, or <code>nil</code> if no such code exists", cases = { outputOnly = true, { args = {"alttp"}, expect = "ALttP", }, { args = {"fakegame"}, expect = nil, }, }, }, shortName = { params = {"code"}, returns = "Short name for franchise title used in [[:Category:Games|category names]]. Usually the subtitle.", cases = { { args = {"LA"}, expect = "Link's Awakening", }, { args = {"la"}, expect = "Link's Awakening" }, { args = {"LANS"}, expect = "Link's Awakening (Nintendo Switch)", }, { args = {"LA (Cagiva)"}, expect = "Link's Awakening (Cagiva)", }, { args = {"E"}, expect = "Encyclopedia", }, { args = {"ALttP&FS"}, expect = "A Link to the Past & Four Swords", }, { args = {"Series"}, expect = "The Legend of Zelda Series" }, { args = {"fakeGame"}, expect = nil, }, } }, link = { params = {"code"}, returns = "Formatted link used in infoboxes and so on.", cases = { { args = {"LA"}, expect = "''[[The Legend of Zelda: Link's Awakening|Link's Awakening]]''", }, { args = {"la"}, expect = "''[[The Legend of Zelda: Link's Awakening|Link's Awakening]]''", }, { args = {"LADX"}, expect = "''[[The Legend of Zelda: Link's Awakening DX|Link's Awakening DX]]''", }, { args = {"LANS"}, expect = "[[The Legend of Zelda: Link's Awakening (Nintendo Switch)|''Link's Awakening'' for Nintendo Switch]]", }, { desc = "For books, comics and manga, see also {{Sect|phraseLink}}.", args = {"LA (Cagiva)"}, expect = "[[The Legend of Zelda: Link's Awakening (Cagiva)|''Link's Awakening'' (Cagiva)]]", }, { args = {"E"}, expect = "''[[The Legend of Zelda: Encyclopedia|Encyclopedia]]''", }, { args = {"ALttP&FS"}, expect = "''[[The Legend of Zelda: A Link to the Past & Four Swords|A Link to the Past & Four Swords]]''" }, { args = {"Series"}, expect = "[[The Legend of Zelda (Series)|''The Legend of Zelda'' series]]" }, { args = {"fakeGame"}, expect = nil, }, } }, isCanon = { params = {"code"}, returns = "True if title is canon, else false.", cases = { { args = {"LANS"}, expect = true, }, { args = {"lans"}, expect = true, }, { args = {"CoH"}, expect = false, }, { args = {"SSBU"}, expect = false, }, { args = {"E"}, expect = true, }, { args = {"Series"}, expect = true, }, }, }, display = { params = {"code"}, returns = "Formatted text for the title.", cases = { { args = {"LA"}, expect = "''Link's Awakening''", }, { args = {"la"}, expect = "''Link's Awakening''", }, { args = {"LANS"}, expect = "''Link's Awakening'' for Nintendo Switch", }, { args = {"E"}, expect = "''Encyclopedia''" }, { args = {"ALttP&FS"}, expect = "''A Link to the Past & Four Swords''", }, { args = {"Series"}, expect = "''The Legend of Zelda'' series" }, { args = {"fakeGame"}, expect = nil, }, } }, logo = { params = {"code"}, returns = "Filename for the title's logo.", cases = { { args = {"TWW"}, expect = "File:TWW English Logo.png", }, { args = {"tww"}, expect = "File:TWW English Logo.png" }, { args = {"E"}, expect = "File:The Legend of Zelda Encyclopedia Cover.png" }, { args = {"Series"}, expect = "File:Zelda Logo TP.png" }, { args = {"fakeGame"}, expect = nil } } }, article = { params = {"code"}, returns = "Wiki article name for the title", cases = { outputOnly = true, { args = {"LA"}, expect = "The Legend of Zelda: Link's Awakening", }, { args = {"la"}, expect = "The Legend of Zelda: Link's Awakening", }, { args = {"LANS"}, expect = "The Legend of Zelda: Link's Awakening (Nintendo Switch)", }, { args = {"TAoL"}, expect = "Zelda II: The Adventure of Link", }, { args = {"TLoZ"}, expect = "The Legend of Zelda", }, { args = {"Series"}, expect = "The Legend of Zelda (Series)", }, { args = {"E"}, expect = "The Legend of Zelda: Encyclopedia" }, { args = {"SSB4"}, expect = "Super Smash Bros. for Nintendo 3DS / Wii U", }, }, }, canonicity = { params = {"code"}, returns = "A string: <code>canon</code>, <code>ambiguous</code>, or <code>non-canon</code>.", cases = { outputOnly = true, { args = {"LA"}, expect = "canon", }, { args = {"la"}, expect = "canon", }, { args = {"CoH"}, expect = "ambiguous", }, { args = {"LA (Cagiva)"}, expect = "non-canon", }, { args = {"E"}, expect = "canon", }, { args = {"fake"}, expect = nil, } }, }, releaseDate = { params = {"code"}, returns = 'The "main" release date for a title.', cases = { outputOnly = true, { args = {"LA"}, expect = "1993-08-06", }, { args = {"LANS"}, expect = "2019-09-20", }, { args = {"LA (Cagiva)"}, expect = "1994-05-01", }, { args = {"E"}, expect = "2018-06-19", }, { args = {"ALttP&FS"}, expect = "2002-12-02", }, { args = {"Series"}, expect = nil }, { args = {"fakeGame"}, expect = nil, }, }, }, }, }, { heading = "Module functions - games", section = { enumGames = { params = {"includeSeries"}, returns = "An array of all game codes in [[Guidelines:Main#Canon_Order|canon order]], plus a <code>reference</code> key so that it can be used for [[Module:Documentation|documentation]] and [[Module:UtilsArg|validation]].", cases = { outputOnly = true, { snippet = "1", expect = {"TLoZ", "TAoL", "ALttP"}, }, { snippet = "2", expect = "[[Data:Franchise]]", }, { snippet = "IncludeSeries", desc = "When <code>includeSeries</code> is true, then <code>Series</code> is the first item in the enum.", expect = {"Series", "TLoZ", "TAoL"}, }, }, }, baseGame = { params = {"code"}, returns = "If <code>code</code> is a remake, returns the code for the original game, else returns <code>code</code> as-is.", cases = { outputOnly = true, { args = {"LANS"}, expect = "LA", }, { args = {"LA"}, expect = "LA", }, { args = {"fake"}, expect = nil, }, }, }, family = { params = {"code"}, returns = "A grouping name used for certain non-canon games on the [[Main Page]].", cases = { outputOnly = true, { args = {"OoT"}, expect = "", }, { args = {"LCT"}, expect = "", }, { args = {"FPTRR"}, expect = "Tingle", }, { args = {"HWDE"}, expect = "Hyrule Warriors", }, }, }, graphics = { params = {"code"}, returns = "A string: <code>2D</code> or <code>3D</code>.", cases = { outputOnly = true, { args = {"LA"}, expect = "2D", }, { args = {"la"}, expect = "2D", }, { args = {"LANS"}, expect = "3D", }, { args = {"fake"}, expect = nil, }, }, }, hasRemakes = { params = {"code"}, returns = "True if game has at least one remake, remaster, or enhanced port. Else false.", cases = { { args = {"LA"}, expect = true, }, { args = {"LADX"}, expect = true, }, { args = {"ST"}, expect = false }, { args = {"fakeGame"}, expect = false, }, }, }, isRemake = { params = {"code"}, returns = "True if game is a remake, remaster, or enhanced port. Else false.", cases = { { args = {"LANS"}, expect = true, }, { args = {"LADX"}, expect = true, }, { args = {"LA"}, expect = false, }, { args = {"HWDE"}, expect = true, } }, }, remakes = { params = {"code"}, returns = "List of remakes for a specific game, or a table of all remakes if no game specified", cases = { { args = {"LA"}, expect = {"LADX", "LANS"}, }, { args = {"LADX"}, expect = {"LANS"}, }, { args = {"ST"}, expect = {} }, { args = {"fake"}, expect = {}, }, }, }, superseder = { params = {"code"}, returns = "The game code of the latest canon version of the game corresponding to <code>code</code>", cases = { { args = {"LA"}, expect = "LANS", }, { desc = "<p><code>nil</code> is returned the game has no newer canon versions or does not exist in [[Data:Franchise]].</p><p>FSAE is not returned for FS as it not considered a canon remake.</p>", args = {"FS"}, expect = nil, }, { args = {"BotW"}, expect = nil, }, { args = {"notACode"}, expect = nil, }, }, }, type = { params = {"code"}, returns = 'One of: <code>"main"</code>, <code>"remake"</code>, <code>"spin-off"</code>, <code>""</code> (other games)', cases = { { args = {"BotW"}, expect = "main", }, { args = {"HWAoC"}, expect = "spin-off", }, { args = {"SSBU"}, expect = "", }, }, }, }, }, { heading = "Module functions - books", section = { publisher = { params = {"code"}, returns = "The book's publisher - in North America if available.", cases = { { args = {"OoT (Himekawa)"}, expect = "VIZ Media", }, { args = {"E"}, expect = "Dark Horse Books", }, }, }, phraseLink = { params = {"code"}, returns = "Formatted link to page and authors.", cases = { { args = {"TLoZ (Ran)"}, expect = "[[The Legend of Zelda (Ran)|''The Legend of Zelda'' manga]] by [[Maru Ran]]", }, { args = {"tloz (ran)"}, expect = "[[The Legend of Zelda (Ran)|''The Legend of Zelda'' manga]] by [[Maru Ran]]", }, { args = {"AOV"}, expect = "''[[The Legend of Zelda: An Original Version|The Legend of Zelda: An Original Version]]''", }, { args = {"fake"}, expect = nil, }, { desc = "Nonfiction books such as {{E}} are not supported by this function.", args = {"E"}, expect = "", }, }, }, }, }, }, } end return p