Module:HighlightHTML

From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search

local p = {}

-- Define syntax colors for HTML
local colors = {
	tag = "#0077aa",        -- Tag names (<div>)
	attribute = "#dd1144",  -- Attribute names (class, id)
	string = "#228822",     -- Attribute values ("value")
	comment = "#888888",    -- <!-- comment -->
	entity = "#aa7700",     -- &nbsp;
	text = "#000000"        -- Default text
}

local function escapeHTML(t)
	return t:gsub("&", "&amp;"):gsub("<", "&lt;"):gsub(">", "&gt;")
end

function p.highlight(frame)
	local code = frame.args[1] or ""
	code = escapeHTML(code)

	local spans = {}
	local function mark(html)
		table.insert(spans, html)
		return "\x00SPAN" .. #spans .. "\x00"
	end

	-- Comments <!-- ... -->
	code = code:gsub("(&lt;!%-%-.-%-%-&gt;)", function(c)
		return mark('<span style="color:' .. colors.comment .. ';">' .. c .. '</span>')
	end)

	-- HTML Entities &nbsp; &lt; etc.
	code = code:gsub("(&[%a#][%w%d]+;)", function(e)
		return mark('<span style="color:' .. colors.entity .. ';">' .. e .. '</span>')
	end)

	-- HTML Tags (handle opening and closing tags with attributes)
	code = code:gsub("(&lt;/?[%a_][%w:%-_.]*)(.-)(&gt;)", function(open, inside, close)
		local tagColored = mark('<span style="color:' .. colors.tag .. '; font-weight:bold;">' .. open .. '</span>')
		local attributes = inside

		-- Highlight attributes with values (attr="..." or attr='...')
		attributes = attributes:gsub('([%a_:][%w:_.%-]*)%s*=%s*(".-")', function(attr, val)
			local a = mark('<span style="color:' .. colors.attribute .. ';">' .. attr .. '</span>')
			local v = mark('<span style="color:' .. colors.string .. ';">' .. val .. '</span>')
			return a .. '=' .. v
		end)
		attributes = attributes:gsub("([%a_:][%w:_.%-]*)%s*=%s*('.-')", function(attr, val)
			local a = mark('<span style="color:' .. colors.attribute .. ';">' .. attr .. '</span>')
			local v = mark('<span style="color:' .. colors.string .. ';">' .. val .. '</span>')
			return a .. '=' .. v
		end)

		-- Highlight attribute names without values
		attributes = attributes:gsub('([%a_:][%w:_.%-]*)', function(attr)
			return mark('<span style="color:' .. colors.attribute .. ';">' .. attr .. '</span>')
		end)

		local closeColored = mark('<span style="color:' .. colors.tag .. '; font-weight:bold;">' .. close .. '</span>')
		return tagColored .. attributes .. closeColored
	end)

	-- Replace placeholders with HTML spans
	code = code:gsub("\x00SPAN(%d+)\x00", function(i)
		return spans[tonumber(i)] or ""
	end)

	-- Final wrapping
	return '<pre style="background:#f8f8f8; padding:0.5em; border:1px solid #ddd; overflow-x:auto;">' .. code .. '</pre>'
end

return p