Module:ColorMap
From Psalms: Layer by Layer
Documentation for this module may be created at Module:ColorMap/doc
local p = {} local function makeShortname(label) return label:lower():gsub('[^%w]+', '') end function p.colorJSON(frame) local args = frame.args local labelStr = args.labels or '' if labelStr == '' then return '⚠️ Error: No labels provided.' end local rawLabels = mw.text.split(labelStr, ',') local labels = {} for _, label in ipairs(rawLabels) do local trimmed = mw.text.trim(label) if trimmed ~= '' then table.insert(labels, trimmed) end end if #labels == 0 then return '⚠️ Error: No valid labels after parsing.' end local numRows = tonumber(args.rows) or 4 local jsonMap = {} for _, label in ipairs(labels) do local short = makeShortname(label) local colorStr = args[label] if colorStr then local colors = mw.text.split(colorStr, ',') for i = 1, math.min(#colors, numRows) do local color = mw.text.trim(colors[i]) local key = string.format('%s.%d', short, i) jsonMap[key] = color end end end -- Build JSON local jsonParts = {} for k, v in pairs(jsonMap) do table.insert(jsonParts, string.format('"%s":"%s"', k, v)) end -- return '{' .. table.concat(jsonParts, ',') .. '}' return table.concat(jsonParts, ',') end function p.colorGrid(frame) local args = frame.args -- Collect and normalize labels local labelStr = args.labels or '' if labelStr == '' then return '⚠️ Error: No labels provided.' end local rawLabels = mw.text.split(labelStr, ',') local labels = {} for _, label in ipairs(rawLabels) do local trimmed = mw.text.trim(label) if trimmed ~= '' then table.insert(labels, trimmed) end end if #labels == 0 then return '⚠️ Error: No valid labels after parsing.' end local numRows = tonumber(args.rows) or 4 -- Build color mapping local colorMap = {} for _, label in ipairs(labels) do local colorStr = args[label] if colorStr then local colors = {} for _, c in ipairs(mw.text.split(colorStr, ',')) do table.insert(colors, mw.text.trim(c)) end colorMap[label] = colors end end -- Build table local out = {} local labelRow = {} table.insert(labelRow, '<div class="color-grid-labels" style="display: flex; justify-content: space-between; font-size: 0.9rem; margin-bottom: 4px;">') for _, label in ipairs(labels) do table.insert(labelRow, string.format('<div style="flex: 1; text-align: center;">%s</div>', label)) end table.insert(labelRow, '</div>') table.insert(out, '{| class="wikitable" style="text-align: center; border-collapse: collapse; padding: 0; margin: 0; border-spacing: 0;"') -- Header -- table.insert(out, '|-') -- for _, label in ipairs(labels) do -- table.insert(out, string.format('! style="padding: 0.5rem;" | %s', label)) -- end -- Rows for row = 1, numRows do table.insert(out, '|- style="padding: 0; margin: 0;"') for _, label in ipairs(labels) do local color = colorMap[label] and colorMap[label][row] or '#FFFFFF' local short = makeShortname(label) local tag = string.format( '<span class="color-cell" data-color="%s" data-participant="%s.%d" title="%s.%d" style="background-color:%s;"></span>', color, short, row, short, row, color ) table.insert(out, '| ' .. tag) end end table.insert(out, '|}') return table.concat(labelRow, '\n') .. '\n' .. table.concat(out, '\n') end return p