Module:ColorMap

From Psalms: Layer by Layer
Jump to: navigation, search

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