Module:Lyrics/sandbox

From Heterodontosaurus Balls

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

local getArgs   = require('Module:Arguments').getArgs
local stringToArray = require('Module:ProcessingFunctions').stringToArray
local VariablesLua = mw.ext.VariablesLua

local data = mw.loadData('Module:Lyrics/data')

local p = {}

local tableIdKey = 'lyrics_table_id'
local columnVariableKey = 'lyrics_columns'
local bgBlackKey = 'lyrics_bg_black'

function p.head(frame)
	local args = getArgs(frame)
	
	local previousId = tonumber(VariablesLua.var(tableIdKey)) or 0
	
	local id = args['id'] or tostring(previousId + 1)
	local columnsStr = args['columns'] or ''
	
	-- Check for bg-black argument (supports '1', 'true', or 'black')
	local bgBlackArg = args['bg-black'] or args['bg'] or ''
	local isBgBlack = bgBlackArg == '1' or bgBlackArg == 'true' or bgBlackArg:lower() == 'black'
	VariablesLua.vardefine(bgBlackKey, isBgBlack and '1' or '0')
	
	local splitColumns = stringToArray(',')(columnsStr)
	local definedColumns = {}
	local columns = {}
	local languages = {}
	local labels = {}
	
	for _,column in ipairs(splitColumns) do
		local columnTrimmed = mw.text.trim(column)
		
		if columnTrimmed ~= '' then
			if definedColumns[columnTrimmed] then
				error(string.format('Column "%s" already defined', columnTrimmed))
			end
			
			local headerParam = columnTrimmed .. '-header'
			local headerPlainParam = columnTrimmed .. '-header-plain'
			local headerWikitextParam = columnTrimmed .. '-header-wikitext'
			
			local columnValue = args[columnTrimmed] or args[headerParam] or args[headerPlainParam] or args[headerWikitextParam]
			
			if columnValue and columnValue ~= '' then
				table.insert(columns, columnTrimmed)
				
				local formattedKey = columnTrimmed:gsub(' ', '-')
				table.insert(languages, formattedKey)
				
				local gadgetLabel = args[headerPlainParam] or args[headerParam] or columnValue
				
				if gadgetLabel then
					gadgetLabel = mw.ustring.gsub(gadgetLabel, '{{[^}]-}}', '')
					gadgetLabel = mw.ustring.gsub(gadgetLabel, '%[%[[^%]|]-|?([^%]]-)%]%]', '%1')
					gadgetLabel = mw.text.trim(gadgetLabel)
				end
				
				if gadgetLabel and gadgetLabel ~= '' then
					labels[formattedKey] = gadgetLabel
				else
					error(string.format('Column "%s" needs a header label', columnTrimmed))
				end
				
				definedColumns[columnTrimmed] = true
			end
		end
	end
	
	if #columns == 0 then
		error('No columns enabled. Use parameters like |japanese=1 or |japanese-header-plain=... to enable columns.')
	end
	
	local lyricsOptions = mw.html.create('div')
		:addClass('lyrics-options')
		:attr('data-id', id)
		:attr('data-languages', table.concat(languages, ','))
		:attr('data-labels', mw.text.jsonEncode(labels))
	
	local row = mw.html.create('tr')
		:addClass('lyrics-row')
		:addClass('lyrics-header-row')
	
	for _,column in ipairs(columns) do
		local formattedKey = column:gsub(' ', '-')
		local headerParam = column .. '-header'
		local headerWikitextParam = column .. '-header-wikitext'
		
		local headerContent = args[headerWikitextParam] or args[headerParam] or args[column] or column
		
		row:tag('th')
			:addClass('lyrics-' .. formattedKey)
			:attr('width', math.floor(100 / #columns) .. '%')
			:css('min-width', '150px')
			:wikitext(headerContent)
	end
	
	if tonumber(id) ~= nil then
		VariablesLua.vardefine(tableIdKey, id)
	end
	VariablesLua.vardefine(columnVariableKey, table.concat(columns, ','))
	
	return '<div>' ..
		tostring(lyricsOptions) ..
		string.format('<table class="wikitable" id="lyrics-%s">', id) ..
		tostring(row)
end

function p.line(frame)
	local function formatArg(arg)
		if arg and arg ~= '' then
			return table.concat(stringToArray('\n')(arg), '<br>')
		else
			return '<br>'
		end
	end

	local args = getArgs(frame)
	
	local root = mw.html.create('tr'):addClass('lyrics-row')
	
	local columnOrder = VariablesLua.var(columnVariableKey, '')
	local columns = stringToArray(',')(columnOrder)
	
	-- Determine background color mode from the state set in p.head
	local isBgBlack = VariablesLua.var(bgBlackKey, '0') == '1'
	
	-- Allow overriding per line if the argument is explicitly passed to p.line
	if args['bg-black'] or args['bg'] then
		local bgArg = args['bg-black'] or args['bg']
		isBgBlack = bgArg == '1' or bgArg == 'true' or bgArg:lower() == 'black'
	end

	-- UPDATED: Set colors based on the mode with new default oklch values
	local bgColor = isBgBlack and '#000000' or 'oklch(14% 0.9733 0 0)'
	local textColor = isBgBlack and '#ffffff' or 'oklch(80% 0 0 0)'
	
	for _,column in ipairs(columns) do
		local formattedCol = column:gsub(' ', '-')
		
		root:tag('td')
			:addClass('lyrics-' .. formattedCol)
			:wikitext(formatArg(args[column]))
			:css('background-color', bgColor)
			:css('color', textColor)
	end
	
	return tostring(root)
end

function p.color(frame)
	local args = getArgs(frame)
	
	local singers = args[1] or ''
	local lyrics = args[2] or ''
	
	local splitSingers = stringToArray(',')(singers)
	local expandedSingers = {}
	
	for _,singer in ipairs(splitSingers) do
		local key = mw.text.trim(singer):lower()
		local mappedValue = data.singerMap[key] or {}
		
		for _,value in ipairs(mappedValue) do
			table.insert(expandedSingers, value)
		end
	end
	
	local singerData = {}
	
	singerData['v-1'] = expandedSingers
	
	local text = mw.html.create('span')
		:wikitext(lyrics)
		:attr('data-singers', mw.text.jsonEncode(singerData))
	
	return tostring(text)
end

function p.tail(frame)
	local args = getArgs(frame)
	
	if args[1] then
		local columnOrder = VariablesLua.var(columnVariableKey, '')
		local columns = stringToArray(',')(columnOrder)
		
		local row = mw.html.create('tr')
			:tag('th')
			:attr('colspan', #columns)
			:wikitext(args[1])
	
		return tostring(row) .. '</table>' .. '</div>'
	end
	
	return '</table></div>'
end

return p