Jump to content

Module:Designation

Permanently protected module
From Wikipedia, the free encyclopedia

require('strict')
local p = {}
local sandbox-- = '/sandbox' -- COMMENT OUT this defintion on the live version

local validate = function(args)
	local former = false
	if args.delisted=='yes' then
		former = true
	end
	local par
	if args and args[1] and args[1]~='' then
		par = args[1]:lower()
		if par:sub(1, 6)=='former' then
			former = true
			par = par:sub(7) -- strip off "former" from start
		end
		local list = mw.loadJsonData('Module:Designation/list' .. (sandbox or ''))
		if list[par] then -- lookup not needed
			return list[par], former
		else -- attempt lookup
			local lookup = mw.loadJsonData('Module:Designation/lookup' .. (sandbox or ''))
			if lookup[par] then -- successful lookup
				par = lookup[par]
				return list[par], former
			else
				local category = mw.title.getCurrentTitle().namespace==0 and '[[Category:Articles using Template:Designation with invalid designation]]' or ''
				return 'Invalid designation' .. category
			end
		end
	else
		return 'No parameter'
	end
end

local get_data = function(frame)
	local getArgs = require('Module:Arguments').getArgs
	local args = getArgs(frame, {wrappers = {
		'Template:Designation',
		'Template:Designation/text',
		'Template:Designation/colour',
		'Template:Designation/colour2',
		'Template:Designation/divbox',
		'Template:Designation/abbreviation'
	}})
	return validate(args)
end

local text = function(frame, data, former)
	local text = data.text
	if data.lang then
		text = frame:expandTemplate{title = 'lang', args = {
			code = data.lang,
			text = text
		}}
	end
	return text and ((former and 'Former ' or '') .. text)
end

p.text = function(frame)
	local data, former = get_data(frame)
	if type(data)=='string' then
		return data
	end
	return text(frame, data, former)
end

local colour = function(data, former, index)
	local color
	if former then
		color = 'DDDDDD'
	elseif data[index] then
		color = data[index]
	else
		color = 'A8EDEF' -- default colour
	end
	return color and ('#' .. color)
end

p.color = function(frame)
	local data, former = get_data(frame)
	if type(data)=='string' then
		return data
	end
	return mw.text.nowiki(colour(data, former, 'col'))
end

p.color2 = function(frame)
	local data, former = get_data(frame)
	if type(data)=='string' then
		return data
	end
	return mw.text.nowiki(colour(data, former, 'col2'))
end

p.abbr = function(frame)
	local data, former = get_data(frame)
	if type(data)=='string' then
		return data
	end
	return former and '???' or data.abbr or '???'
end

local box = function(data, color, text)
	local div = mw.html.create('div')
		:css('line-height', '1.5')
		:css('text-align', 'center')
	if type(data)=='string' then
		local invalid = mw.html.create('span')
			:css('color', 'red')
			:wikitext('Error: ' .. data)
		div:node(invalid)
	else
		div:css('border-style', 'solid')
			:css('border-width', '4px')
			:css('border-color', color)
			:wikitext(text)
	end
	return div
end

p.divbox = function(frame)
	local data, former = get_data(frame)
	local color = colour(data, former, 'col2')
	local text = text(frame, data, former)
	return tostring(box(data, color, text))
end

p.doc_table = function(frame)
	local scope = frame.args and frame.args.scope
	local scopes = {}
	for s in mw.text.gsplit(scope, ",", true) do
		scopes[mw.text.trim(s:lower())] = true
	end
	local lookup = mw.loadJsonData('Module:Designation/lookup' .. (sandbox or ''))
	local rev_lookup = {}
	for alias, code in pairs(lookup) do
		if rev_lookup[code] then
			table.insert(rev_lookup[code], alias)
		else
			rev_lookup[code] = {alias}
		end
	end
	local list = mw.loadJsonData('Module:Designation/list' .. (sandbox or ''))
	local header = mw.html.create('tr')
		:tag('th'):wikitext('Code'):done()
		:tag('th'):wikitext('Designation'):done()
		:tag('th'):css('width', '250px'):wikitext('Bordered version'):done()
		:tag('th'):wikitext('Scope'):done()
		:tag('th'):wikitext('Aliases'):done()
	local tab = mw.html.create('table')
		:addClass('wikitable')
		:addClass('sortable')
		:node(header)
	for code, data in pairs(list) do
		if scopes[data.scope:lower()] then
			local des = mw.html.create('td')
				:css('text-align', 'center')
				:css('background', '#' .. (data.col or 'A8EDEF'))
				:wikitext(data.text)
			local border = mw.html.create('td')
				:node(box(data, '#'..(data.col2 or 'A8EDEF'), data.text))
			local row = mw.html.create('tr')
				:tag('th'):wikitext(code):done()
				:node(des)
				:node(border)
				:tag('td'):css('text-align', 'center'):wikitext(data.scope):done()
				:tag('td'):wikitext(rev_lookup[code] and table.concat(rev_lookup[code], ', ')):done()
			tab:node(row)
		end
	end
	return tostring(tab)
end

local check_params = function(args, n)
	local desp = {root = args['designated_other' .. n]}
	local suffixes = {'name', 'color', 'textcolor', 'link', 'num_position', 'number', 'abbr'}
	for _, s in ipairs(suffixes) do
		desp[s] = args['designated_other' .. n .. '_' .. s]
	end
	local data = desp.root and validate{[1]=desp.root}
	return desp, data
end

p.header = function(frame)
	local desp, data = check_params(frame:getParent().args, frame.args[1])
	local makediv = function(text, bgcolor, num, textcolor)
		local autolink = require('Module:Link if exists')._main
		local link = autolink{[1]=text}
		local span = mw.html.create('span')
			:css('color', textcolor)
			:wikitext(link)
		local div = mw.html.create('div')
			:css('width', '100%')
			:css('text-align', 'center')
			:css('line-height', '1.5')
			:css('color', 'var(--color-base)')
			:css('background', bgcolor)
			:node(span)
			:wikitext(num)
		return tostring(div)
	end
	local num = ''
	local position = desp.num_position and desp.num_position:lower()
	if desp.number and desp.number~='' and (position=='both' or position=='top') then
		local abbr = frame:expandTemplate{title = 'abbr', args = {[1]='No.', [2]='Number'}}
		num = ' ' .. abbr .. ' ' .. desp.number
	end
	if data and type(data)=='table' then
		return makediv(data.text, '#' .. (data.col or 'A8EDEF'), num)
	elseif desp.name then
		return makediv(desp.name, desp.color or 'FFFFFF', num, desp.textcolor)
	end
end

p.label = function(frame)
	local desp, data = check_params(frame:getParent().args, frame.args[1])
	local abbr = (data and data.abbr) or desp.abbr or '???'
	local category = abbr=='???' and mw.title.getCurrentTitle().namespace==0 and '[[Category:Articles using Template:Designation with undefined abbreviation]]' or ''
	return frame.args[2] .. ' ' .. abbr .. category
end

p.number = function(frame)
	local desp, data = check_params(frame:getParent().args, frame.args[1])
	local out = ''
	local position = desp.num_position and desp.num_position:lower()
	if position~='top' then
		local noabbr = frame:expandTemplate{title = 'abbr', args = {[1]='No.', [2]='Number'}}
		local abbr = data and data.abbr or desp.abbr or '???'
		local category = abbr=='???' and mw.title.getCurrentTitle().namespace==0 and '[[Category:Articles using Template:Designation with undefined abbreviation]]' or ''
		out = abbr .. ' ' .. noabbr .. category
	end
	return out
end

return p