Module:Ep/Matcher

local p = {}

-- how templates can call this module -- only uses one unnamed arg function p.matchCodeTemplate(frame) local ep = frame.args[1] epCode = p.matchCode(ep) return epCode end

-- for other modules to use the query pairs to match any input string to the formatted episode code function p.matchCode(ep) local epCode if p.areYouACode(ep) then ep = p.zeropadCode(ep) end queryPairs = makeQueryPairs ep = ep:lower if queryPairs[ep] then epCode = queryPairs[ep] else epCode = '0x00' end return epCode end

-- for converting Ep/Array array into pairs of input string:output episode code function makeQueryPairs local epInfos = mw.loadData('Module:Ep/Array') queryPairs = {} for k, v in pairs(epInfos) do       queryPairs[k:lower] = k        for key, val in pairs(v) do            if type(val) == 'string' then queryPairs[val:lower] = k           else for i, option in pairs(val) do                   queryPairs[option:lower] = k            end end end end return queryPairs end

-- functions to parse epcode into campaign, season, number, and suffix, using Module:Ep/Decoder p.parseCode = function(ep) i, j = string.find(ep,"x") prefix, ep_num = ,  if i then prefix = string.sub(ep,1,i-1) ep_num = string.sub(ep,j+1) end return prefix, ep_num end

p.parseCodeFull = function(ep) local campaign_code local season local num local suffix prefix, ep_num = p.parseCode(ep) if (not tonumber(prefix) and tonumber(prefix:sub(-1))) then campaign_code = prefix:sub(1, -2) season = prefix:sub(-1) else campaign_code = prefix season = '' end -- get episode number if tonumber(ep_num) then num = tonumber(ep_num) suffix = '' else suffix = ep_num:sub(-1):lower num = ep_num:sub(1, -2) end return campaign_code, season, num, suffix end

-- will zeropad code if fits, otherwise return same value p.zeropadCode = function(ep) campaign_code, season, num, suffix = p.parseCodeFull(ep) local new_code local padded_num if tonumber(num) then padded_num = string.format("%02d", num) new_code = campaign_code .. season .. 'x' .. padded_num .. suffix else new_code = frame end return new_code end

-- true/false test for whether a string is a valid episode code p.areYouACode = function(ep) local campaign_code, season, num, suffix = p.parseCodeFull(ep) local decoder = mw.loadData('Module:Ep/Decoder')

-- if no num, invalid if not num or num == '' then return false

-- is the campaign prefix one of the acceptable ones? elseif not searchKeys(campaign_code, decoder) then return false -- is the season a number or blank? elseif not (tonumber(season) or season == '') then return false -- is the num a number and if suffix is it 'a' or 'b'? elseif tonumber(num) and (suffix == 'a' or suffix == 'b' or suffix == '') then return true else return false end 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