Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:ESTable: Difference between revisions

From Teriock
Content deleted Content added
// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
 
(8 intermediate revisions by the same user not shown)
Line 116: Line 116:
local outWords = filterWords(elements, parts, ops)
local outWords = filterWords(elements, parts, ops)
out = '{| class="wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\n'
local tableTitle = '{{L|Core|Elder Sorcery Words|u=1}}'
if #elements == 1 then
-- If there's only one element, part, and op, use a more specific title
local elementName = elements[1]:gsub("_", " "):gsub("^%l", string.upper)
if elementName == "Necro" then
elementName = "Necromancy"
end
tableTitle = elementName .. ' ' .. tableTitle
end
if #ops == 1 then
-- If there's only one OP level, use it in the title
tableTitle = 'OP ' .. tostring(ops[1]) .. ' ' .. tableTitle
end

out = '{| class="wikitable sortable"\n|+ style=white-space:nowrap | ' .. frame:preprocess(tableTitle) .. '\n'
-- Header row
-- Header row
local rowNum = 0
local rowNum = 0
Line 165: Line 179:
numRows = math.max(numRows, columnNumRows)
numRows = math.max(numRows, columnNumRows)
table.sort(columnWords, function(a, b) return a < b end)
table.sort(columnWords, function(a, b) return a < b end)
for word in pairs(columnWords) do
-- Ensure we have a sorted list of words for this column and op level
columnWords[word] = columnWords[word] -- This ensures the order is maintained
end
-- Store the words for this column and op level
-- Store the words for this column and op level
wordCollections[opLevel][columnElement .. "_" .. columnPart] = {
wordCollections[opLevel][columnElement .. "_" .. columnPart] = {
Line 191: Line 201:
if wordCollections[opLevel][columnElement .. "_" .. columnPart] and wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex] then
if wordCollections[opLevel][columnElement .. "_" .. columnPart] and wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex] then
cellContent = wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex]
cellContent = wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex]
end
if cellContent:find("%^") then
cellContent = "''" .. cellContent:gsub("%^", "") .. "''"
cellContent = frame:preprocess(cellContent)
end
end
-- Add the cell content to the output
-- Add the cell content to the output

Latest revision as of 20:25, 31 March 2025

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

local p = {}

local esw = require('Module:ESWords')

local words = esw.words()

local function contains(tbl, val)
    for _, v in ipairs(tbl) do
        if v == val then return true end
    end
    return false
end

local function fixInputs(elements, parts, ops)
    if elements == "all" then
        elements = {}
        for elementName, _ in pairs(words) do
            table.insert(elements, elementName)
        end
    end

    if parts == "all" then
        parts = {}
        local firstElement = next(words)
        if firstElement then
            for partName, _ in pairs(words[firstElement]) do
                table.insert(parts, partName)
            end
        end
    end

    if ops == "all" then
        ops = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    end

    -- Normalize inputs to tables if they are not already
    if type(elements) ~= "table" then
        elements = { elements }
    end
    if type(parts) ~= "table" then
        parts = { parts }
    end
    if type(ops) ~= "table" then
        ops = { ops }
    end
    return elements, parts, ops
end

local function filterWords(elements, parts, ops)
    local outWords = {}
    for elementName, elementData in pairs(words) do
        if contains(elements, elementName) then
            outWords[elementName] = {}
            for _, part in ipairs(parts) do
                if elementData[part] then
                    outWords[elementName][part] = {}
                    for _, op in ipairs(ops) do
                        if elementData[part][op] then
                            outWords[elementName][part][op] = elementData[part][op]
                        end
                    end
                end
            end
        end
    end
    return outWords
end

local bgs = {
    even = {
        op = '#e5a50a1A',
        celestial = '#6135831A',
        flame = '#a51d2d1A',
        storm = '#1a5fb41A',
        life = '#9a99961A',
        necro = '#0000001A',
        nature = '#26a2691A',
    },
    odd = {
        op = '#f9f06b1A',
        celestial = '#dc8add1A',
        flame = '#f661511A',
        storm = '#99c1f11A',
        life = '#ffffff1A',
        necro = '#77767b1A',
        nature = '#8ff0a41A',
    }
}

local function bgHex(rowNum, col)
    -- Determine the background color based on the row number and column type
    local bgColor
    if rowNum % 2 == 0 then
        -- Even row
        bgColor = bgs.even[col]
    else
        -- Odd row
        bgColor = bgs.odd[col]
    end
    return bgColor or '#ffffff1A' -- Fallback to white if no color is defined
end

local function bgStr(rowNum, col)
    -- Generate the background style string for a given row and column
    local bgColor = bgHex(rowNum, col)
    return ' style="background-color: ' .. bgColor .. '" | '
end

function p.getWords(frame, elements, parts, ops)
    elements, parts, ops = fixInputs(elements, parts, ops)
    return filterWords(elements, parts, ops)
end

function p.getTable(frame, elements, parts, ops)
    elements, parts, ops = fixInputs(elements, parts, ops)
    local outWords = filterWords(elements, parts, ops)
    
    local tableTitle = '{{L|Core|Elder Sorcery Words|u=1}}'
    if #elements == 1 then
        -- If there's only one element, part, and op, use a more specific title
        local elementName = elements[1]:gsub("_", " "):gsub("^%l", string.upper)
        if elementName == "Necro" then
            elementName = "Necromancy"
        end
        tableTitle = elementName .. ' ' .. tableTitle
    end
    if #ops == 1 then
        -- If there's only one OP level, use it in the title
        tableTitle = 'OP ' .. tostring(ops[1]) .. ' ' .. tableTitle
    end

    out = '{| class="wikitable sortable"\n|+ style=white-space:nowrap | ' .. frame:preprocess(tableTitle) .. '\n'
    -- Header row
    local rowNum = 0
    out = out .. '!' .. bgStr(rowNum, 'op') .. 'OP'
    local actualColumns = {}
    table.sort(elements, function(a, b) return a < b end)
    for _, elementName in pairs(elements) do
        table.sort(parts, function(a, b) return a < b end)
        for _, part in pairs(parts) do
            if outWords[elementName] and outWords[elementName][part] and (#outWords[elementName][part] > 0) then
                local elementTitle = elementName:gsub("_", " "):gsub("^%l", string.upper)
                local titleLink = elementName .. " Mage"
                if elementTitle == "Necro" then
                    elementTitle = "Necromancy"
                    titleLink = "Necromancer"
                end
                local partTitle = part:gsub("_", " "):gsub("^%l", string.upper)
                local titleText = elementTitle .. ' ' .. partTitle
                local title = '{{L|Class|' .. titleLink .. '|' .. titleText .. '}}'
                if elementName == "celestial" then
                    title = titleText
                end
                out = out .. ' !!' .. bgStr(rowNum, elementName) .. frame:preprocess(title)
                table.insert(actualColumns, {
                    element = elementName,
                    part = part
                })
            end
        end
    end
    rowNum = rowNum + 1
    local opRowNum = 1

    local wordCollections = {}
    -- Collect all words for each OP level
    for opLevel = 1, 10 do
        wordCollections[opLevel] = {}
        local numRows = 0
        for _, column in ipairs(actualColumns) do
            local columnElement = column.element
            local columnPart = column.part
            local columnNumRows = 0
            local columnWords = {}
            if outWords[columnElement] and outWords[columnElement][columnPart] and outWords[columnElement][columnPart][opLevel] then
                columnWords = outWords[columnElement][columnPart][opLevel]
                columnNumRows = #columnWords
            end
            numRows = math.max(numRows, columnNumRows)
            table.sort(columnWords, function(a, b) return a < b end)
            -- Store the words for this column and op level
            wordCollections[opLevel][columnElement .. "_" .. columnPart] = {
                words = columnWords,
                count = columnNumRows
            }
        end
        -- Now we have the max number of rows for this OP level, we can proceed to build the table
        -- Iterate over each column to build the rows for this OP level
        for rowIndex = 1, numRows do
            out = out .. '\n|-\n' -- Start a new row
            if rowIndex == 1 then
                out = out .. '|rowspan="' .. tostring(numRows) .. '" ' ..bgStr(opRowNum, 'op') .. opLevel
                opRowNum = opRowNum + 1
            else
                out = out .. ' '
            end
            for _, column in ipairs(actualColumns) do
                local columnElement = column.element
                local columnPart = column.part
                local cellContent = ''
                if wordCollections[opLevel][columnElement .. "_" .. columnPart] and wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex] then
                    cellContent = wordCollections[opLevel][columnElement .. "_" .. columnPart].words[rowIndex]
                end
                if cellContent:find("%^") then
                    cellContent = "''" .. cellContent:gsub("%^", "") .. "''"
                    cellContent = frame:preprocess(cellContent)
                end
                -- Add the cell content to the output
                out = out .. '\n|' .. bgStr(rowNum, columnElement) .. cellContent
            end
            rowNum = rowNum + 1
        end
    end
    out = out .. '\n|}'
    return out
end

function p.get(frame)
    -- This function will be the main entry point to get the table
    local args = frame.args
    local elements = args.elements or 'all'
    if elements ~= 'all' then
        elements = mw.text.split(elements, '%s')
    end
    local parts = args.parts or 'all'
    if parts ~= 'all' then
        parts = mw.text.split(parts, '%s')
    end
    local ops = args.ops or 'all'
    if ops ~= 'all' then
        ops = mw.text.split(ops, '%s')
        for i, op in ipairs(ops) do
            ops[i] = tonumber(op)
        end
    end
    
    return p.getTable(frame, elements, parts, ops)
end

function p.all(frame)
    return p.getTable(frame, 'all', 'all', {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
end

function p.testInput(frame)
    local args = frame.args
    local out = ''
    for k, v in pairs(args) do
        out = out .. k .. ': ' .. tostring(v) .. '\n'
    end
    return out
end

return p