Module:References

-- (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 = {};

-- 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) return ' &#91;Invalid citation&#93; '; end

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

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

-- 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 textFormat = ": %s"; if isempty(text) then textFormat = ""; end if isempty(chapter) then chapterFormat = descriptor.noChapterFormat; end -- handle special chapters in a series local specialCase = descriptor.specialChapters[string.lower(chapter)]; if specialCase then chapterFormat = specialCase.chapterFormat; 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(textFormat, text); 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", },   rize = { chapterFormat = "Tokyo Ghoul Side Story: Rize", },   joker = { chapterFormat = "Tokyo Ghoul:re Side Story: Joker", },   oneshot = { chapterFormat = "Tokyo Ghoul Oneshot", },   epilogue = { chapterFormat = "Tokyo Ghoul Epilogue", }, }

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

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

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

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

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

-- describes light novels local daysdescriptor = { chapterFormat = "Tokyo Ghoul: Days Chapter %s", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: Days", minimum = 1, maximum = 6, specialChapters = {} }

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

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

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

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

local rezakkidescriptor = { chapterFormat = "Tokyo Ghoul: zakki:re Pages %s", chapterOptional = true, noChapterFormat = "Tokyo Ghoul: zakki:re", specialChapters = {} }

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

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

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

-- creates 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 manga and volume handlers registerseriesdescriptor("tg-manga", tgmangadescriptor); handlers["tg"] = handlers["tg-manga"];

registerseriesdescriptor("tg-vol", tgvoldescriptor);

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

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

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

-- register book handlers registerseriesdescriptor("days", daysdescriptor); handlers["hibi"] = handlers["days"];

registerseriesdescriptor("void", voiddescriptor); handlers["kuuhaku"] = handlers["void"];

registerseriesdescriptor("past", pastdescriptor); handlers["sekijitsu"] = handlers["past"];

registerseriesdescriptor("quest", questdescriptor);

-- register special book handlers registerseriesdescriptor("zakki", zakkidescriptor);

registerseriesdescriptor("re-zakki", rezakkidescriptor)

registerseriesdescriptor("anime-book", animebookdescriptor);

registerseriesdescriptor("jail-book", jailbookdescriptor);

registerseriesdescriptor("movie-book", moviebookdescriptor);

-- test function function m.chapter(f)   local args = f.args;    -- get the correct handler    local handler = m.sourceHandlers[args["series"];    -- if no registered handler -> error    if not handler then        return incorrectReferenceHandler(args);    end    -- call the handler    return handler(args); end -- --- --- --- function m.episode(f) local args = f.args; -- get the correct ephandler local ephandler = m.sourceEpisodeHandlers[args["series"]]; -- if no registered ephandler -> error if not ephandler then return incorrectReferenceHandler(args); end -- call the ephandler return ephandler(args); end

-- this function provides generic formatting for mangas or episodes local function formatGenericSeries(args, descriptor) local episode = args[1]; local text = args[2];

-- if no episode given -> invalid input if not descriptor.episodeOptional and isempty(episode) then return incorrectReferenceHandler(args); end -- format strings used later local episodeFormat = descriptor.episodeFormat; local textFormat = ": %s"; if isempty(text) then textFormat = ""; end if isempty(episode) then episodeFormat = descriptor.noEpisodeFormat; end -- handle special episodes in a series local specialCase = descriptor.specialEpisodes[string.lower(episode)]; if specialCase then episodeFormat = specialCase.episodeFormat; end -- now general episodes episodeNum = tonumber(episode); -- check if this is a valid episode number, if not output error if not specialCase and not isempty(episode) then if not episodeNum or       (descriptor.minimum and episodeNum < descriptor.minimum) or        (descriptor.maximum and episodeNum > descriptor.maximum) or        episodeNum ~= episodeNum then return incorrectReferenceHandler(args); end end -- do the formatting return string.format(episodeFormat, episode, episode) .. "" ..       string.format(textFormat, text); end

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

-- special manga episodes local specialEpisodes = { jack = { episodeFormat = "Tokyo Ghoul: Jack (OVA)", },   pinto = { episodeFormat = "Tokyo Ghoul: Pinto (OVA)", }, }

-- describes anime local animedescriptor = { episodeFormat = "Tokyo Ghoul Episode %s", minimum = 1, maximum = 24, specialEpisodes = specialEpisodes } -- describes re anime local reanimedescriptor = { episodeFormat = "Tokyo Ghoul:re Episode %s", minimum = 1, maximum = 24, specialEpisodes = {} }

-- creates ephandler functions based on a series descriptor local function createdescriptorephandler(descriptor) return function(args) return formatGenericSeries(args, descriptor); end end

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

-- standard registering function local function registerseriesdescriptor(name, descriptor) assert(name, "name missing"); assert(descriptor, "descriptor missing"); local ephandler = createdescriptorephandler(descriptor); ephandlers[name] = ephandler; end

-- register anime ephandlers registerseriesdescriptor("tg", animedescriptor);

registerseriesdescriptor("re", reanimedescriptor);

--- --- ---

function m.volume(f) local args = f.args; -- get the correct volhandler local volhandler = m.sourceVolumeHandlers[args["series"]]; -- if no registered volhandler -> error if not volhandler then return incorrectReferenceHandler(args); end -- call the volhandler return volhandler(args); end

-- this function provides generic formatting for mangas or episodes local function formatGenericSeries(args, descriptor) local volume = args[1]; local text = args[2];

-- if no volume given -> invalid input if not descriptor.volumeOptional and isempty(volume) then return incorrectReferenceHandler(args); end -- format strings used later local volumeFormat = descriptor.volumeFormat; local textFormat = ": %s"; if isempty(text) then textFormat = ""; end if isempty(volume) then volumeFormat = descriptor.noVolumeFormat; end -- handle special volumes in a series local specialCase = descriptor.specialVolumes[string.lower(volume)]; if specialCase then volumeFormat = specialCase.volumeFormat; end -- now general volumes volumeNum = tonumber(volume); -- check if this is a valid volume number, if not output error if not specialCase and not isempty(volume) then if not volumeNum or       (descriptor.minimum and volumeNum < descriptor.minimum) or        (descriptor.maximum and volumeNum > descriptor.maximum) or        volumeNum ~= volumeNum then return incorrectReferenceHandler(args); end end -- do the formatting return string.format(volumeFormat, volume, volume) .. "" ..       string.format(textFormat, text); end

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

-- describes manga volumes local tgvoldescriptor = { volumeFormat = "Tokyo Ghoul Volume %s", minimum = 1, maximum = 14, specialVolumes = {} }

local revoldescriptor = { volumeFormat = "Tokyo Ghoul:re Volume %s", minimum = 1, maximum = 16, specialVolumes = {} }

-- creates volhandler functions based on a series descriptor local function createdescriptorvolhandler(descriptor) return function(args) return formatGenericSeries(args, descriptor); end end

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

-- standard registering function local function registerseriesdescriptor(name, descriptor) assert(name, "name missing"); assert(descriptor, "descriptor missing"); local volhandler = createdescriptorvolhandler(descriptor); volhandlers[name] = volhandler; end

-- register manga and volume volhandlers registerseriesdescriptor("tg", tgvoldescriptor);

registerseriesdescriptor("re", revoldescriptor);

return m;

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