Module:Ep/Info/sandbox

-- TO DO: update this so other modules don't need to call Module:Ep/Matcher directly -- TO DO: consider changing so the individual functions can be called directly when invoked (instead of using param)

local p = {}

-- For templates to use this module. First unnamed arg is the value to be interpreted. function p.ep(frame) local ep = frame.args[1] local title = frame.args['title'] or nil local pagename = frame.args['pagename'] or nil local campaign = frame.args['campaign'] or nil local campaignName = frame.args['campaignname'] or nil local campaignLink = frame.args['campaignlink'] or nil local season = frame.args['season'] or nil local seasonDisplay = frame.args['seasondisplay'] or nil local epNum = frame.args['epnum'] or nil local transcript = frame.args['transcript'] or nil local linkedList = frame.args['linkedlist'] or nil local category = frame.args['category'] or nil local noCat = frame.args['nocat'] or nil local epMatcher = require('Module:Ep/Matcher/sandbox') local epCode = epMatcher.matchCode(ep) local data = '' local exists local validCampaign local validConstruction -- handle calls to non-existent and/or invalid episodes if isempty(epCode) or epCode == '0x00' then -- epCode not in array but construction and campaign is valid if epMatcher.areYouACode(ep) then epCode = epMatcher.zeropadCode(ep) validConstruction = true validCampaign = true exists = false -- invalid and non-existent epCodes. can still try a few operations below else local prefix, epNum = p.parseCode(ep) -- campaign is invalid but code is constructed properly if not isempty(prefix) and not isempty(epNum) then validConstruction = true validCampaign = false exists = false epCode = epMatcher.zeropadCode(ep) -- code is constructed improperly else validConstruction = false validCampaign = false exists = false end end -- epCode is in Ep/Array, AOK else exists = true validCampaign = true validConstruction = true end if not isempty(title) then if exists then data = p.title(epCode) -- can't infer title from code if not in Ep/Array else data = '' end elseif not isempty(pagename) and exists then data = p.pagename(epCode) elseif not isempty(campaign) and validCampaign then data = p.campaign(epCode) elseif not isempty(campaignName) and validCampaign then data = p.campaignName(epCode) elseif not isempty(campaignLink) and validConstruction then if validCampaign then data = p.campaignLink(epCode) else data = string.format('Undefined campaign code "%s" in "%s"; check Module:Ep/Decoder ', p.prefix(epCode), epCode) end elseif not isempty(season) and validCampaign then data = p.season(epCode) elseif not isempty(seasonDisplay) then -- handle nonexistent seasons of existing shows if validCampaign and isempty(p.seasonDisplay(epCode)) and not isempty(p.season(epCode)) then data = string.format('Error for %s: No Season #%s for %s; check Module:Ep/Decoder ', epCode, p.season(epCode), p.campaignName(epCode)) -- handle completely invalid episode codes elseif not validConstruction then data = string.format('Invalid episode code "%s"; use CxNN format ', ep) else data = p.seasonDisplay(epCode) end -- handle valid episode codes not in Ep/Array with maintenance category and no error message -- change so category doesn't display before pushing live if validCampaign and not exists then data = data .. 'Category:Calls to episode codes missing from Ep/Array' end elseif not isempty(epNum) and validConstruction then data = p.epNum(epCode) elseif not isempty(transcript) and exists then data = p.transcript(epCode) elseif not isempty(linkedList) and validCampaign then data = p.linkedList(epCode) elseif not isempty(category) and validConstruction then data = p.category(epCode, noCat) elseif validCampaign and validConstruction then data = epCode end return data end

-- Functions for querying Module:Ep/Array to get title and/or pagename for output function p.epInfo(epCode) local result

local epInfos = mw.loadData('Module:Ep/Array') if epInfos[epCode] == nil then result = "" else result = epInfos[epCode] end

return result

end

p.title = function(epCode) return p.epInfo(epCode)['title'] end

p.pagename = function(epCode) if p.epInfo(epCode)['pagename'] then pagename = p.epInfo(epCode)['pagename'] else pagename = p.title(epCode) end return pagename end

-- functions to parse epcode into campaign, season and epnumber, using EPISODE_DECODER

p.parseCode = function(epCode) if type(epCode) ~= "string" then epCode = epCode.args[1] end i, j = string.find(epCode,"x") prefix, epNum = ,  if i then prefix = string.sub(epCode,1,i-1) epNum = string.sub(epCode,j+1) end return prefix, epNum end

-- Parse out shows and (optionally) seasons. Prevents TM from being parsed as having seasons. -- TO DO: make it so it uses the Module:Ep/Decoder prefix (so it can handle any number of seasons) p.campSeason = function(epCode) local campaign local season local decoder = mw.loadData('Module:Ep/Decoder/sandbox') prefix, epNum = p.parseCode(epCode) if prefix == 'TMOS' then campaign = 'TM' elseif (not tonumber(prefix) and tonumber(prefix:sub(-1))) then -- this is not flexible for >9 seasons campaign = prefix:sub(1, -2) season = prefix:sub(-1) elseif decoder[prefix] then campaign = prefix end -- Talks Machina exception if campaign == 'TM' then season = '' end return campaign, season end

p.prefix = function(epCode) prefix, epNum = p.parseCode(epCode) return prefix end

p.campaign = function(epCode) campaign, season = p.campSeason(epCode) return campaign end

p.campaignName = function(epCode, noItal) if not noItal then noItal = false end local campaign = p.campaign(epCode) local decoder = mw.loadData('Module:Ep/Decoder/sandbox') local campaignName = decoder[campaign]['title'] if decoder[campaign]['italics'] == true and not noItal and campaignName then campaignName = "''" .. campaignName .. "''"	end return campaignName end

-- for the link to the campaign in the episode infobox field "subheader" p.campaignLink = function(epCode) local titleLink local titleName local campaignLink local campaign = p.campaign(epCode) local campaignName = p.campaignName(epCode, false) local campaignNamePlain = p.campaignName(epCode, true) local decoder = mw.loadData('Module:Ep/Decoder/sandbox') if decoder[campaign]['titleLink'] then titleLink = decoder[campaign]['titleLink'] else titleLink = campaignNamePlain end if decoder[campaign]['infoboxTitle'] then titleName = decoder[campaign]['infoboxTitle'] else titleName = campaignName end if titleLink ~= titleName then campaignLink = titleLink .. '|' .. titleName else campaignLink = titleLink end campaignLink =  .. campaignLink ..  -- should be a helper function return campaignLink end

p.season = function(epCode) campaign, season = p.campSeason(epCode) return season end

-- displays in the infobox "Episode" field before the episode number p.seasonDisplay = function(epCode) local seasonDisplay local decoder = mw.loadData('Module:Ep/Decoder/sandbox') local campaign, season = p.campSeason(epCode) local valid_seasons local pagename local nameForDisplay local italics season = tostring(season) if campaign then valid_seasons = decoder[campaign]['seasons'] or nil end

-- if there's no season or the campaign doesn't have seasons, blank if isempty(season) or isempty(valid_seasons) then return '' -- is season valid? if not, blank elseif not searchKeys(season, valid_seasons) then return '' -- get season info from decoder else pagename = valid_seasons[season]['page'] or '' nameForDisplay = valid_seasons[season]['name'] or '' italics = valid_seasons[season]['italics'] or false end

-- Default display is e.g. "Season 1", other build with season data from decoder if isempty(nameForDisplay) then nameForDisplay = 'Season ' .. season end if not isempty(pagename) then seasonDisplay =  .. nameForDisplay ..  else seasonDisplay = nameForDisplay end if italics then seasonDisplay = "''" .. seasonDisplay .. "''"	end return seasonDisplay end

p.epNum = function(epCode) local prefix, epNum = p.parseCode(epCode) if epNum then epNum = string.format("%d", epNum) end return epNum end

p.transcript = function(epCode) local pagename = p.pagename(epCode) local transcript = "Transcript:" .. pagename return transcript end

-- for the link to list of episodes in the infobox field "below" p.linkedList = function(epCode) local listLink local listTitle local listContent local linkedListFinal local decoder = mw.loadData('Module:Ep/Decoder/sandbox') local camp = p.campaign(epCode) if not isempty(decoder[camp]['listLink']) then listLink = decoder[camp]['listLink'] else listLink = decoder[camp]['title'] end if not isempty(decoder[camp]['listTitle']) then listTitle = decoder[camp]['listTitle'] else listTitle = listLink end if listLink ~= listTitle then listContent = listLink .. '|' .. listTitle else listContent = listLink end linkedListFinal =  .. listContent ..  return linkedListFinal end

p.category = function(epCode, noCat) local categoryName if not noCat then noCat = false end local campaign = p.campaign(epCode) local decoder = mw.loadData('Module:Ep/Decoder/sandbox') if campaign then categoryName = decoder[campaign]['category'] or nil end if isempty(categoryName) then categoryName = 'Episodes not assigned to category' end if noCat then categoryName = 'Category:' .. categoryName .. '' else categoryName = '' end return categoryName end

--function to determine if a string is empty function isempty(s) return s == nil or s == '' end

-- functions for searching an array for a value (case-insensitive) function keyset(dict) local keys = {} for k,v in pairs(dict) do	   keys[k:lower]=true end return keys end

function searchKeys(item, dict) local keys = keyset(dict) if keys[item:lower] then return true else return false end end

return p