![](https://static.miraheze.org/metawiki/5/5f/Out_of_date_clock_icon.png)
Module:Ep/Matcher
From Queen's Court Games
Documentation for this module may be created at Module:Ep/Matcher/doc
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
-- NOTE: "the sunken tomb" is ambiguous whether 1x44 or LVM2x03
-- NOTE: "those who walk away" is ambiguous whether 1x45 or LVM2x04
function p.matchCode(ep)
local epCode
if p.areYouACode(ep) then
ep = p.zeropadCode(ep)
end
epInfos = mw.loadData('Module:Ep/Array')
if epInfos[ep] then
epCode = ep
else
queryPairs = makeQueryPairs()
ep = ep:gsub("_", " "):gsub("^%s*(.-)%s*$", "%1")
ep = p.cleanMarkup(ep)
if (queryPairs[ep] and
ep ~= 'the sunken tomb' and
ep ~= 'those who walk away') then
epCode = queryPairs[ep]
else
epCode = '0x00'
end
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[p.cleanMarkup(k)] = k
for key, val in pairs(v) do
if type(val) == 'string' then
queryPairs[p.cleanMarkup(val)] = k
else
for i, option in pairs(val) do
queryPairs[p.cleanMarkup(option)] = 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
-- remove all characters not spaces or alphanumeric
p.cleanMarkup = function(text)
result = string.gsub(string.lower(text), "[^%w%s]", "")
-- clean up double spaces that might result
result = string.gsub(result, "%s+", " ")
return result
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