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)
out = '{| class="wikitable sortable"\n|+ style=white-space:nowrap | Elder Sorcery Words\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