Module:File series source

-- (don't remove this; it prevents this module --     from being categorized unintentionally into --      wrong categories) -- script that creates a formatted image source based on input local m = {};

local monthname = require("module:month name"); local ordinal = require("module:ordinal");

-- tests if the value is nil, false or "" local function isempty(x) return not x or x == ""; end

-- formats a generic error message local function incorrectReferenceHandler(args) local start = " Invalid source; List of template arguments: "; for k, v in pairs(args) do       start = start .. tostring(k) .. " = " .. tostring(v) .. " ";    end return start; end

-- this function provides generic formatting for mangas or episodes local function formatGenericSeries(args, descriptor) local chapter = args[2]; local page = args[3];

-- if no chapter given -> invalid input if not descriptor.chapterOptional and isempty(chapter) then return incorrectReferenceHandler(args); end -- format strings used later local chapterFormat = descriptor.chapterFormat; local categoryFormat = descriptor.categoryFormat; local pageFormat = "Page %s"; if isempty(page) then pageFormat = ""; end if isempty(chapter) then chapterFormat = descriptor.noChapterFormat; categoryFormat = ""; end -- handle special chapters in a series local specialCase = descriptor.specialChapters[string.lower(chapter)]; if specialCase then chapterFormat = specialCase.chapterFormat; categoryFormat = specialCase.categoryFormat; end -- now general chapters chapterNum = tonumber(chapter); -- check if this is a valid chapter number, if not output error if not specialCase and not isempty(chapter) then if not chapterNum or       (descriptor.minimum and chapterNum < descriptor.minimum) or        (descriptor.maximum and chapterNum > descriptor.maximum) or        chapterNum ~= chapterNum then return incorrectReferenceHandler(args); end end -- do the formatting return string.format(chapterFormat, chapter, chapter) .. " " ..       string.format(pageFormat, page) .. " " ..       string.format(categoryFormat, chapter); end

-- handles twitter and/or tumblr links local function twittertumblrlink(prefix, suffix, args) if isempty(args[2]) then incorrectReferenceHandler(args); end return prefix .. args[2] .. suffix; end

-- the following tables describe the different formatting depending on manga/anime/novel series -- the formatting is applied by formatGenericSeries

-- special manga chapters local specialChapters = { remake = { chapterFormat = "Tokyo Ghoul Chapter 1: Remake", categoryFormat = "", },   rize = { chapterFormat = "Tokyo Ghoul Side Story: Rize", categoryFormat = "", },   joker = { chapterFormat = "Tokyo Ghoul:re Side Story: Joker", categoryFormat = "", },   oneshot = { chapterFormat = "Tokyo Ghoul Oneshot", categoryFormat = "", },   epilogue = { chapterFormat = "Tokyo Ghoul Epilogue", categoryFormat = "", }, }

-- describes the original manga local tgmangadescriptor = { chapterFormat = "Tokyo Ghoul Chapter %s", categoryFormat = "", minimum = 1, maximum = 143, specialChapters = specialChapters }

-- describes :re local remangadescriptor = { chapterFormat = "Tokyo Ghoul:re Chapter %s", categoryFormat = "", minimum = 1, specialChapters = specialChapters }

-- describes jack local jackmangadescriptor = { chapterFormat = "Tokyo Ghoul: Jack Chapter %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Jack ", minimum = 1, maximum = 7, specialChapters = {} }

--describes the anime local animedescriptor = { chapterFormat = "Tokyo Ghoul Episode %s", categoryFormat = "", minimum = 1, maximum = 24, specialChapters = { jack = { chapterFormat = "Tokyo Ghoul: Jack (OVA)", categoryFormat = "", },       pinto = { chapterFormat = "Tokyo Ghoul: Pinto (OVA)", categoryFormat = "", },       op1 = { chapterFormat = "Tokyo Ghoul Opening 1", categoryFormat = "", },       op2 = { chapterFormat = "Tokyo Ghoul Opening 2", categoryFormat = "", },       ed1 = { chapterFormat = "Tokyo Ghoul Ending 1", categoryFormat = "", },       ed2 = { chapterFormat = "Tokyo Ghoul Ending 2", categoryFormat = "", }   } } -- re-anime local reanimedescriptor = { chapterFormat = "Tokyo Ghoul:re Episode %s", categoryFormat = "", minimum = 1, specialChapters = {} }

-- descriptors for volumes local tgvoldescriptor = { chapterFormat = "Tokyo Ghoul Volume %s", categoryFormat = "", minimum = 1, maximum = 14, specialChapters = {} }

local revoldescriptor = { chapterFormat = "Tokyo Ghoul:re Volume %s", categoryFormat = "", minimum = 1, specialChapters = {} }

-- descriptors for novels local hibidescriptor = { chapterFormat = "Tokyo Ghoul: Days Chapter %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Days ", minimum = 1, maximum = 6, specialChapters = {} }

local kuuhakudescriptor = { chapterFormat = "Tokyo Ghoul: Void Chapter %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Void ", minimum = 1, maximum = 5, specialChapters = {} }

local sekijitsudescriptor = { chapterFormat = "Tokyo Ghoul: Past Chapter %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Past ", minimum = 1, maximum = 6, specialChapters = {} }

local questdescriptor = { chapterFormat = "Tokyo Ghoul:re: quest Chapter %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul:re: quest ", minimum = 1, maximum = 6, specialChapters = {} }

-- descriptors for special books local zakkidescriptor = { chapterFormat = "Tokyo Ghoul: zakki Page %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: zakki ", specialChapters = {} }

local animebookdescriptor = { chapterFormat = "Tokyo Ghoul: anime Page %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: anime ", specialChapters = {} }

local jailbookdescriptor = { chapterFormat = "Tokyo Ghoul: Jail Page %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Jail ", specialChapters = {} }

local moviebookdescriptor = { chapterFormat = "Tokyo Ghoul: Movie Page %s", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Movie ", specialChapters = {} }

-- descriptor for Jail game local jailgamedescriptor = { chapterFormat = "Tokyo Ghoul: Jail", categoryFormat = "", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Jail ", specialChapters = {} }

-- used to create handler functions based on a series descriptor local function createdescriptorhandler(descriptor) return function(args) return formatGenericSeries(args, descriptor); end end

-- register functions that will handle the different series local handlers = {}; m.sourceHandlers = handlers;

-- standard registering function local function registerseriesdescriptor(name, descriptor) assert(name, "name missing"); assert(descriptor, "descriptor missing"); local handler = createdescriptorhandler(descriptor); handlers[name] = handler; end

-- register original manga handlers registerseriesdescriptor("tg-manga", tgmangadescriptor); handlers["tg"] = handlers["tg-manga"];

registerseriesdescriptor("tg-vol", tgvoldescriptor);

-- register :re handlers registerseriesdescriptor("re", remangadescriptor); handlers[":re"] = handlers["re"];

registerseriesdescriptor("re-vol", revoldescriptor); handlers[":re-vol"] = handlers["re-vol"];

-- register Jack handler registerseriesdescriptor("jack", jackmangadescriptor);

-- register anime handler registerseriesdescriptor("anime", animedescriptor);

-- register re anime handler registerseriesdescriptor("re-anime", reanimedescriptor);

-- register book handlers registerseriesdescriptor("hibi", hibidescriptor);

registerseriesdescriptor("kuuhaku", kuuhakudescriptor);

registerseriesdescriptor("sekijitsu", sekijitsudescriptor);

registerseriesdescriptor("quest", questdescriptor);

-- register scenario/illustration book handlers registerseriesdescriptor("zakki", zakkidescriptor);

registerseriesdescriptor("anime-book", animebookdescriptor);

registerseriesdescriptor("jail-book", jailbookdescriptor);

registerseriesdescriptor("movie-book", moviebookdescriptor);

-- register Jail game handlers registerseriesdescriptor("jail-game", jailgamedescriptor);

-- handle twitter, tumblr, other social media source links handlers["sotonami"] = function(args) return twittertumblrlink(       "Sui Ishida's twitter, Tweet: ",         " ", args); end

handlers["twitter"] = function(args) return twittertumblrlink(       "[",         " Tweet] ", args); end

handlers["sui-zakki"] = function(args) return twittertumblrlink(       "Sui Ishida's tumblr, Post: ",         " ", args); end

handlers["tumblr"] = function(args) return twittertumblrlink(       "[",         " Tumblr post] ", args); end

handlers["sui-pixiv"] = function(args) return twittertumblrlink(      "Sui Ishida's pixiv, Link: ",       " ", args); end

handlers["trump"] = function(args) if not isempty(args[2]) then return twittertumblrlink(           "Tokyo Ghoul Trump card deck, Source: ",            " ", args); end return "Tokyo Ghoul Trump card deck "; end

handlers["calendar-2016"] = function(args) local month, day = "", ""; if not isempty(args[2]) then month = " " .. monthname.getmonth(args[2]); if not isempty(args[3]) then day = " " .. ordinal.formatordinal(assert(tonumber(args[3]))); end end return "Tokyo Ghoul Flip Calendar" .. month .. day .. ""; end

handlers["carnaval"] = function(args) return "Tokyo Ghoul: carnaval "; end

handlers["invoke"] = function(args) return "Tokyo Ghoul :re Invoke "; end

handlers["dark-war"] = function(args) return "Tokyo Ghoul: Dark War "; end

-- main function function m.formatsource(f) local args = f.args; -- get the correct handler local handler = m.sourceHandlers[args[1]]; -- if no registered handler -> error if not handler then return incorrectReferenceHandler(args); end -- call the handler return handler(args); end

return m;

-- (don't remove this; see comment at top)