Module:TitleAnchor

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

-- <nowiki>
--
-- Implements [[Template:TitleAnchor]]
--
local p = {}

local yesno = require('Module:Yesno')
local hc = require('Module:Paramtest').has_content

local locs = {
	p = 'p',
	P = 'p',
	s = 's',
	S = 's'
}

function colourPartToLumPart(part)
	part = (part/255)
	if (part < 0.03928) then
		part = part / 12.92
	else
		part = ((part + 0.055)/1.055)^2.4
	end
	return part
end

function coloursToLum(r,g,b)
	r = colourPartToLumPart(r)
	g = colourPartToLumPart(g)
	b = colourPartToLumPart(b)

	return (r * 0.2126) + (g * 0.7152) + (b * 0.0722) + 0.05;
end;

function parseColor(col)
	local r,g,b = col:match('#([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])')
	if r ~= nil then
		r = tonumber(r, 16)
		g = tonumber(g, 16)
		b = tonumber(b, 16)
	else
		r,g,b = col:match('#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])')
		if r ~= nil then
			r = tonumber(r .. r, 16)
			g = tonumber(g .. g, 16)
			b = tonumber(b .. b, 16)
		else
			return nil
		end
	end

	if r == nil then
		return ''
	end

	local lum = coloursToLum(r,g,b)

	--RGB values of light and dark theme respectively
	local rl, gl, bl, rd, gd, bd = 251, 251, 251, 23, 33, 54

	local luml = coloursToLum(rl, gl, bl)
	local lumd = coloursToLum(rd, gd, bd)
	
	local ratiol = luml / lum
	if lum > luml then
		ratiol = 1 / ratiol
	end

	local ratiod = lumd / lum
	if lum > lumd then
		ratiod = 1 / ratiod
	end

	if ratiol < 3 then
		return 'rs-title-bg-on-light'
	end

	if ratiod < 3 then
		return 'rs-title-bg-on-dark'
	end

	return ''
end

p.parseColor = parseColor


function p.main(frame)
	local args = frame:getParent().args
	local title = args.t or '<title>'
	local loc = locs[args.loc]
	local comma = args[',']
	local bg = string.lower(args.bg or 'no') == 'yes'
	local name = args.name or '[Name]'

	-- default no colouring
	local commacolor = false
	local dos = false
	if comma and comma:lower() == 'cdos' then
		comma = true
		commacolor = true
		dos = true
	elseif comma and comma:lower() == 'dos' then
		comma = true
		dos = true
	elseif comma and comma:lower() == 'c' then
		comma = true
		commacolor = true
	elseif comma then
		comma = yesno(comma)
	end

	-- yesno defaults to false if the argument is nil, have it default to true
	local space = yesno(args.space or 'true')

	-- default colour black
	local color = args.c or 'black'
	
	local bgclass = parseColor(color)
	
	local link = false
	if hc(args.link) then
		link = args.link
	end

	return p._main(title, color, loc, comma, commacolor, space, bgclass, link, name, dos)
end

function p._main(title,color, loc, comma, commacolor, space, bgclass, link, name, dos)
	-- Copy title to a different variable before editing it
	local titleid = title

	-- If comma needs colouring
	-- Edit a comma into the title before adding to span
	if comma and commacolor and dos then
		if loc == 'p' then
			title = title..' dos '
		elseif loc == 's' then
			title = ' dos '..title
		end
	elseif comma and commacolor then
		if loc == 'p' then
			title = title..', '
		elseif loc == 's' then
			title = ', '..title
		end
	end

	-- Tag to keep everything on one line
	local ret = mw.html.create('span')
		:css({ ['font-weight'] = 'bold',
			['white-space'] = 'nowrap' })
		:addClass('rs-title')

	-- for "<title> [Name]"
	if loc == 'p' then
		ret:tag('span')
			:css('color',color)
			:addClass(bgclass)
			:wikitext(title)
			:done()
		if dos and not commacolor then
			ret:wikitext(' dos ')
		elseif not commacolor then
			if comma then
				ret:wikitext(', ')
			elseif space then
				ret:wikitext(' ')
			end
		end
		ret:wikitext(name)

	-- for "[Name] <title>"
	elseif loc == 's' then
		ret:wikitext(name)
		if dos and not commacolor then
			ret:wikitext(' dos ')
		elseif not commacolor then
			if comma then
				ret:wikitext(', ')
			elseif space then
				ret:wikitext(' ')
			end
		end
		ret:tag('span')
			:css('color',color)
			:wikitext(title)
			:addClass(bgclass)
			:done()

	-- Otherwise just do <title>
	else
		ret:css('color',color)
			:wikitext(title)
			:addClass(bgclass)
	end

	-- Don't add the anchor except on [[Titles]]
	if mw.title.getCurrentTitle().text == 'Titles' then
		-- Look for and strip various mark-ups for multi colored titles
		-- <span>
		titleid = titleid:gsub('</?span.->','')

		-- Uppercase first letter
		titleid = mw.text.split(titleid,'')
		titleid[1] = titleid[1]:upper()
		titleid = table.concat(titleid,'')

		ret:attr('id',titleid)
	end

	if link == 'no' then
	    ret = ret
	elseif link then
		ret = string.format('[[%s|%s]]', link, tostring(ret))
    else
        ret = string.format('[[%s|%s]]', titleid, tostring(ret))
	end
	return ret
end

return p