This wiki has had no edits or log actions made within the last 45 days and has been automatically marked as inactive. If you would like to prevent this wiki from being closed, please start showing signs of activity here. If there are no signs of this wiki being used within the next 15 days, this wiki will be closed in accordance to the Dormancy Policy (which all wiki founders accept when requesting a wiki). If this wiki is closed and no one reopens it 135 days from now, this wiki will become eligible for deletion. Note: If you are a bureaucrat, you can go to Special:ManageWiki and uncheck "inactive" yourself.

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