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
Tag: Reverted
// via Wikitext Extension for VSCode
Tag: Manual revert
Line 340: Line 340:
elements, parts, ops = fixInputs(elements, parts, ops)
elements, parts, ops = fixInputs(elements, parts, ops)
local outWords = filterWords(elements, parts, ops)
local outWords = filterWords(elements, parts, ops)
return elements[0]
-- out = '{| class="mw-collapsible mw-collapsed wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\n'
out = '{| class="mw-collapsible mw-collapsed wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\n'
-- -- Header row
-- Header row
-- local rowNum = 0
local rowNum = 0
-- out = out .. '!' .. bgStr(rowNum, 'op') .. 'OP'
out = out .. '!' .. bgStr(rowNum, 'op') .. 'OP'
-- local actualColumns = {}
local actualColumns = {}
-- for _, elementName in pairs(elements) do
for _, elementName in pairs(elements) do
-- for _, part in pairs(parts) do
for _, part in pairs(parts) do
-- if outWords[elementName] and outWords[elementName][part] and (#outWords[elementName][part] > 0) then
if outWords[elementName] and outWords[elementName][part] and (#outWords[elementName][part] > 0) then
-- local elementTitle = elementName:gsub("_", " "):gsub("^%l", string.upper)
local elementTitle = elementName:gsub("_", " "):gsub("^%l", string.upper)
-- local titleLink = elementName .. " Mage"
local titleLink = elementName .. " Mage"
-- if elementTitle == "Necro" then
if elementTitle == "Necro" then
-- elementTitle = "Necromancy"
elementTitle = "Necromancy"
-- elementLink = "Necromancer"
elementLink = "Necromancer"
-- end
end
-- local partTitle = part:gsub("_", " "):gsub("^%l", string.upper)
local partTitle = part:gsub("_", " "):gsub("^%l", string.upper)
-- local titleText = elementTitle .. ' ' .. partTitle
local titleText = elementTitle .. ' ' .. partTitle
-- local title = '{{L|Class|' .. titleLink .. '|' .. titleText .. '}}'
local title = '{{L|Class|' .. titleLink .. '|' .. titleText .. '}}'
-- out = out .. ' !!' .. bgStr(rowNum, elementName) .. frame:preprocess(title)
out = out .. ' !!' .. bgStr(rowNum, elementName) .. frame:preprocess(title)
-- table.insert(actualColumns, {
table.insert(actualColumns, {
-- element = elementName,
element = elementName,
-- part = part
part = part
-- })
})
-- end
end
-- end
end
-- end
end
-- rowNum = rowNum + 1
rowNum = rowNum + 1
-- local opRowNum = 1
local opRowNum = 1


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



Revision as of 18:39, 31 March 2025

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

local p = {}

-- Column mappings
local columns = {
    op = 1,
    celestial_nouns = 2,
    celestial_verbs = 3,
    adjectives = 4,
    adverbs = 5,
    pronouns = 6,
    propositions = 7,
    conjunctives = 8,
    articles = 9,
    flame_verbs = 10,
    flame_nouns = 11,
    storm_verbs = 12,
    storm_nouns = 13,
    life_verbs = 14,
    life_nouns = 15,
    necro_verbs = 16,
    necro_nouns = 17,
    nature_verbs = 18,
    nature_nouns = 19
}

local backgrounds = {
    op = '#f9f06b1A',
    celestial_nouns = '#dc8add1A',
    celestial_verbs = '#dc8add1A',
    adjectives = '#dc8add1A',
    adverbs = '#dc8add1A',
    pronouns = '#dc8add1A',
    propositions = '#dc8add1A',
    conjunctives = '#dc8add1A',
    articles = '#dc8add1A',
    flame_verbs = '#f661511A',
    flame_nouns = '#f661511A',
    storm_verbs = '#99c1f11A',
    storm_nouns = '#99c1f11A',
    life_verbs = '#ffffff1A',
    life_nouns = '#ffffff1A',
    necro_verbs = '#77767b1A',
    necro_nouns = '#77767b1A',
    nature_verbs = '#8ff0a41A',
    nature_nouns = '#8ff0a41A'
}

local backgrounds_even = {
    op = '#e5a50a1A',
    celestial_nouns = '#6135831A',
    celestial_verbs = '#6135831A',
    adjectives = '#6135831A',
    adverbs = '#6135831A',
    pronouns = '#6135831A',
    propositions = '#6135831A',
    conjunctives = '#6135831A',
    articles = '#6135831A',
    flame_verbs = '#a51d2d1A',
    flame_nouns = '#a51d2d1A',
    storm_verbs = '#1a5fb41A',
    storm_nouns = '#1a5fb41A',
    life_verbs = '#9a99961A',
    life_nouns = '#9a99961A',
    necro_verbs = '#0000001A',
    necro_nouns = '#0000001A',
    nature_verbs = '#26a2691A',
    nature_nouns = '#26a2691A'
}

local links = {
    flame_verbs = '{{L|Class|Flame Mage|Flame Verbs}}',
    flame_nouns = '{{L|Class|Flame Mage|Flame Nouns}}',
    storm_verbs = '{{L|Class|Storm Mage|Storm Verbs}}',
    storm_nouns = '{{L|Class|Storm Mage|Storm Nouns}}',
    life_verbs = '{{L|Class|Life Mage|Life Verbs}}',
    life_nouns = '{{L|Class|Life Mage|Life Nouns}}',
    necro_verbs = '{{L|Class|Necromancer|Necro Verbs}}',
    necro_nouns = '{{L|Class|Necromancer|Necro Nouns}}',
    nature_verbs = '{{L|Class|Nature Mage|Nature Verbs}}',
    nature_nouns = '{{L|Class|Nature Mage|Nature Nouns}}'
}

-- Helper function to parse the source table
local function parseTable(frame, output)
    local source = mw.text.split(frame:preprocess('{{:MediaWiki:ESTable}}'), '\n')
    local data = {}
    
    for i, line in ipairs(source) do
        if line:match('^|%-') then
            -- Skip separator lines
        elseif line:match('^|') then
            local row = {}
            for cell in line:gmatch('|%s*([^||]+)%s*') do
                table.insert(row, cell:match('^%s*(.-)%s*$'))
                -- output = output .. cell .. '\n'
            end
            if #row > 0 then
                table.insert(data, row)
            end
        end
    end
    
    return data, output
end

-- Helper function to trim whitespace and new lines
local function trim(s)
    return s:match('^%s*(.-)%s*$')
end

local function supertrim(s)
    return s:match('^%s*(.-)%s*$'):gsub('%d', '')
end

-- Main function to generate filtered table
function p.filter(frame)
    local output = ''
    local args = frame.args
    local data, output = parseTable(frame, output)
    -- if true then
    --     return data
    -- end
    local selectedCols = {}

    if args then
        -- Trim whitespace from args
        for k, v in pairs(args) do
            args[k] = trim(v)
        end

        -- Remove empty arguments
        for k, v in pairs(args) do
            if v == '' then
                args[k] = nil
            end
        end
        
        -- Determine which columns to show
        for k, v in pairs(args) do
            if ((v ~= '') and columns[k]) then
                table.insert(selectedCols, {name = k, index = columns[k]})
            end
        end
    end

    local bg = (args.bg ~= '')

    -- Sort columns by their original index
    table.sort(selectedCols, function(a, b) return a.index < b.index end)

    -- for _, col in ipairs(selectedCols) do
    --     output = output .. ' !! ' .. tostring(col.index)
    -- end

    -- output = output .. '\n\n'
    
    -- Generate output table
    output = output .. '{| class="mw-collapsible mw-collapsed wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\n'
    
    -- Header row
    -- output = output .. '! OP'
    -- for _, col in ipairs(selectedCols) do
    --     local header = col.name:gsub("_", " "):gsub("^%l", string.upper)
    --     output = output .. ' !! ' .. header
    -- end
    -- output = output .. '\n'
    
    -- Data rows
    local header = true
    for _, row in ipairs(data) do
        if (#row > 0) and (#selectedCols > 0) then
            output = output .. '\n\n|-\n\n'
            local dontskip = false
            row_content = ''
            for _, col in ipairs(selectedCols) do
                if header then
                    d = '!'
                else
                    d = '|'
                end
                content = d
                op = tonumber(row[1]) or 0
                if bg then
                    if op % 2 == 0 then
                        content = content .. ' style="background-color: ' .. backgrounds_even[col.name] .. '" |'
                    else
                        content = content .. ' style="background-color: ' .. backgrounds[col.name] .. '" |'
                    end
                    -- content = content .. ' style="background-color: ' .. backgrounds[col.name] .. '" |'
                end
                word = tostring(row[col.index])
                if links[word] then
                    word = frame:preprocess(links[word])
                end
                if supertrim(word) ~= '' then
                    dontskip = true
                end
                content = content .. ' ' .. word .. ' ' .. d
                row_content = row_content .. content
            end
            if dontskip then
                output = output .. row_content
            end
            output = output:sub(1, -3)
            -- output = output .. '\n'
        end
        if header then
            header = false
        end
    end
    
    output = output .. '\n|}'
    return output
end

-- NEW CONTENT
-- -----------

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 == "*" then
        elements = {}
        for elementName, _ in pairs(words) do
            table.insert(elements, elementName)
        end
    end

    if parts == "*" 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 == "*" then
        ops = {}
        local firstElement = next(words)
        if firstElement then
            local firstPart = next(words[firstElement])
            if firstPart then
                for opLevel, _ in pairs(words[firstElement][firstPart]) do
                    table.insert(ops, opLevel)
                end
            end
        end
    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)
    
    out = '{| class="mw-collapsible mw-collapsed wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\n'
    -- Header row
    local rowNum = 0
    out = out .. '!' .. bgStr(rowNum, 'op') .. 'OP'
    local actualColumns = {}
    for _, elementName in pairs(elements) do
        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"
                    elementLink = "Necromancer"
                end
                local partTitle = part:gsub("_", " "):gsub("^%l", string.upper)
                local titleText = elementTitle .. ' ' .. partTitle
                local title = '{{L|Class|' .. titleLink .. '|' .. titleText .. '}}'
                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)
            -- 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
                -- 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

return p