Documentation for this module may be created at Module:Codename/doc

-- <nowiki>
--------------------------------------------------------------------------------
-- This module calls information from releases and series by their Codename.
-- Functions are invoked for use in various templates and for generation of
-- site CSS.
-- See [[Help:Codenames]] for details on how they are used.
--------------------------------------------------------------------------------
local Codename = {}

local getArgs = require('Dev:Arguments').getArgs
local userError = require('Dev:User error')
local printTable = require('Module:Table').tostring
local uoTables = mw.loadData('Module:Codename/data')

--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------

-- For a dictionary t and list f, returns t[f[1]][f[2]][f[...]][f[#f]] or nil if
-- any of those intermediate values are missing.
--
-- @example
-- dive({foo = {bar = {baz = 'hi'}}}, {'foo', 'bar', 'baz'}) --> 'hi'
--
-- @TODO
-- Move to [[Module:Table]] or something? It might be useful elsewhere...
local function dive(t, f)
    for _, value in ipairs(f) do
        if type(t) ~= 'table' then
            return nil
        end

        t = t[value]
    end

    return t
end

--------------------------------------------------------------------------------
-- Database queries
--------------------------------------------------------------------------------

Codename.tables = {}
Codename.tables.odr = {}

for key, value in pairs(uoTables) do
    Codename.tables[key] = {}
    Codename.tables.odr[key] = {}

    -- For use in modules
    for index, value2 in ipairs(value) do
        local id = value2.id

        -- Convert a list of tables with ids to a dictionary, where each key is
        -- an id, and each value is its corresponding table.
        --
        -- ex. {{id='a'}, {id='b'}} --> {a={id='a'}, b={id='b'}}
        Codename.tables[key][id] = value2

        -- Convert a list of tables with ids to a list of ids.
        --
        -- ex. {{id='a'}, {id='b'}} --> {'a', 'b'}
        table.insert(Codename.tables.odr[key], id)
    end

    -- For use in wikitext via #invoke
    Codename[key] = function (frame)
        local args = getArgs(frame)
        local value = dive(Codename.tables[key], args)

        if type(value) == 'table' then
            return printTable(value)
        end

        return value
    end
end
--------------------------------------------------------------------------------
-- Generators for lists (for use on [[Help:Codename]], [[Project:Scope]], etc.)
--------------------------------------------------------------------------------

-- Generates an ordered list of media.
-- arg == 'rel' or 'ser'.
-- optional info allows it to display some info from /data.
function Codename._generator(dset, info)
    local list = mw.html.create('ul')
    local data = Codename.tables[dset]
    local odr = Codename.tables.odr[dset]

    local function addItem(node, elem, info)
        if not elem then
            return 'null'
        end

        local addedinfo = ''

        if info then
            addedinfo = ': (' .. elem[info] .. ')'
        end

        return node:tag('li')
            :wikitext('[[' .. elem.link .. "|''" .. elem.name .. "'']]" .. addedinfo)
    end

    for _, parent in ipairs(odr) do
        if not data[parent].sub then
            local item = addItem(list, data[parent], info)
            local sublist

            for _, child in ipairs(odr) do
                if data[child].sub == parent then
                    if not sublist then
                        sublist = item:tag('ul')
                    end

                    addItem(sublist, data[child], info)
                end
            end
        end
    end

    return list
end

function Codename.generator(frame)
    local args = getArgs(frame)

    return Codename._generator(args[1], args[2])
end

-- Generate tables of all class colors
function Codename.ctbl()
    local container = mw.html.create('div')
        :css('display', 'flex')
        :css('font-family', '\'Source Code Pro\',monospace')
        :css('text-align', 'center')
    local namedtbls = {
        ser = 'Series',
        rel = 'Releases'
    }

    for _, dset in ipairs{'ser', 'rel'} do
        local odr = Codename.tables.odr[dset]
        local tbl = container:tag('table')
            :addClass('article-table darktext mw-collapsible mw-collapsed')
            :attr('data-expandtext', 'Show ' .. #odr .. ' items')
            :attr('data-collapsetext', 'Hide ' .. #odr .. ' items')
            :css('width', '50%')
            :tag('tr')
                :css('background', '#F5F5F5')
                :css('font-style', 'italic')
                :tag('th')
                    :attr('colspan', '7')
                    :css('text-align', 'left')
                    :wikitext(namedtbls[dset])
                    :done()
                :done()
            :tag('tr')
                :css('background', '#CCC')
                :tag('th')
                    :attr('scope', 'col')
                    :wikitext('Codename')
                    :done()
                :tag('th')
                    :attr('scope', 'col')
                    :wikitext('Header')
                    :done()
                :tag('th')
                    :attr('scope', 'col')
                    :wikitext('Subheader')
                    :done()
                :done()

        for _, cname in ipairs(odr) do
            tbl:tag('tr')
                :tag('th')
                    :attr('scope', 'row')
                    :css('background', '#CCC')
                    :css('font-style', 'italic')
                    :wikitext('[[' .. Codename.tables[dset][cname].link .. '|' .. cname .. ']]')
                    :done()
                :tag('td')
                    :addClass(cname .. ' a')
                    :wikitext(cname .. ' a')
                    :done()
                :tag('td')
                    :addClass(cname .. ' b')
                    :wikitext(cname .. ' b')
                    :done()
        end
    end

    return container
end

-- Generate table of all sideicons
function Codename.icontable()
    local odr = Codename.tables.odr['rel']
    local tbl = mw.html.create('table')
        :addClass('article-table darktext mw-collapsible mw-collapsed')
        :attr('data-expandtext', 'Show ' .. #odr .. ' items')
        :attr('data-collapsetext', 'Hide ' .. #odr .. ' items')
        :css('font-family', '\'Source Code Pro\',monospace')
        :css('text-align', 'center')
        :tag('tr')
            :tag('th')
                :wikitext('Codename')
                :css('width', '50%')
                :done()
            :tag('th')
                :wikitext('Icon')
                :css('width', '50%')
                :done()
            :done()

    for _, cname in ipairs(odr) do
        tbl:tag('tr')
            :tag('th')
                :wikitext(cname .. '<br>' .. '[[' .. Codename.tables['rel'][cname].link .. '|' .. Codename.tables['rel'][cname].name .. ']]')
                :done()
            :tag('td')
                :wikitext('[[' .. 'File:' .. cname .. ' wiki icon.png|60px|' .. cname .. ']]')
                :done()
            :done()
    end

    return tbl
end

-- Generate table of all infobox and navbox theme headers
function Codename.themebgtable()
    local odr = Codename.tables.odr['rel']
    local tbl = mw.html.create('table')
        :addClass('article-table darktext mw-collapsible mw-collapsed')
        :attr('data-expandtext', 'Show ' .. #odr .. ' items')
        :attr('data-collapsetext', 'Hide ' .. #odr .. ' items')
        :css('font-family', '\'Source Code Pro\',monospace')
        :css('text-align', 'center')
        :tag('tr')
            :tag('th')
                :wikitext('Codename')
                :css('width', '50%')
                :done()
            :tag('th')
                :wikitext('Header')
                :css('width', '50%')
                :done()
            :done()

    for _, cname in ipairs(odr) do
        tbl:tag('tr')
            :tag('th')
                :wikitext(cname .. '<br>' .. '[[' .. Codename.tables['rel'][cname].link .. '|' .. Codename.tables['rel'][cname].name .. ']]')
                :done()
            :tag('td')
                :wikitext('[[' .. 'File:' .. cname .. ' theme header background.png|100px|' .. cname .. ']]')
                :done()
            :done()
    end

    return tbl
end


function Codename.themebgtable()
    local container = mw.html.create('div')
        :css('display', 'flex')
        :css('font-family', '\'Source Code Pro\',monospace')
        :css('text-align', 'center')
    local namedtbls = {
        ser = 'Series',
        rel = 'Releases'
    }

    for _, dset in ipairs{'ser', 'rel'} do
        local odr = Codename.tables.odr[dset]
        local tbl = container:tag('table')
            :addClass('article-table darktext mw-collapsible mw-collapsed')
            :attr('data-expandtext', 'Show ' .. #odr .. ' items')
            :attr('data-collapsetext', 'Hide ' .. #odr .. ' items')
            :css('width', '50%')
            :tag('tr')
                :css('background', '#F5F5F5')
                :css('font-style', 'italic')
                :tag('th')
                    :attr('colspan', '7')
                    :css('text-align', 'left')
                    :wikitext(namedtbls[dset])
                    :done()
                :done()
            :tag('tr')
                :css('background', '#CCC')
                :tag('th')
                    :attr('scope', 'col')
                    :wikitext('Codename')
                    :done()
                :tag('th')
                    :attr('scope', 'col')
                    :wikitext('Header')
                    :done()
                :done()

        for _, cname in ipairs(odr) do
            if Codename.tables[dset][cname]['theme'] then
                tbl:tag('tr')
                    :tag('th')
                        :wikitext(cname .. '<br>' .. '[[' .. Codename.tables[dset][cname].link .. '|' .. Codename.tables[dset][cname].name .. ']]')
                        :done()
                    :tag('td')
                        :wikitext('[[' .. 'File:' .. cname .. ' theme header background.png|100px|' .. cname .. ']]')
                        :done()
                    :done()
            end
        end
    end

    return container
end

return Codename
-- </nowiki>
Community content is available under CC-BY-SA unless otherwise noted.