Module:Jcon

Permanently protected module
From Wikipedia, the free encyclopedia

local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local data = mw.loadData('Module:Jcon/data')

-- Generate the wikitext for the shield
local function shieldWikitext(route, roadInfo, args)
	local size = args.size or '20px' -- Image size

	local fileName
	local titleObj
	
	if roadInfo.prefix == 'Ontario' and (tonumber(({route:gsub('%D', '')})[1]) or 0) >= 500 then -- Exception for secondary and tertiary highways
		fileName = 'Ontario Highway ' .. route .. '.svg'
	elseif roadInfo.prefix == 'Ontario' and route:gsub('%s+', ''):upper() == '407ETR' then -- Exception for 407 ETR
		fileName = yesno(args.shield) and '407 Express Toll Route Traffic Sign.svg' or 'Highway407crest.svg'
	elseif roadInfo.shield and yesno(args.shield) then -- Shield format (used as reassurance marker)
		fileName = roadInfo.shield:format(route)
	elseif roadInfo.guide then -- Guide format (used on guide signs)
		fileName = roadInfo.guide:format(route)
	else
		return '' -- Return nothing if no file format was found
	end
	
	titleObj = mw.title.new('File:' .. fileName)

	if not titleObj or not titleObj.file.exists then
		return '' -- Return nothing if no existing file was found
	end
	
	return '[[File:' .. fileName .. '|alt=|link=|' .. size .. ']]' -- Return the file wikitext
end

-- Generate the text part of the output
local function getText(route, roadInfo, args)
	local link = ''
	local display = ''

	if roadInfo.prefix == 'Ontario' and route:gsub('%s+', ''):upper() == '407ETR' then -- Exception for the 407 ETR
		link = 'Ontario Highway 407'
		display = '407 ETR'
	elseif roadInfo.prefix == 'Ontario' and route:upper() == 'QEW' then -- Exception for the QEW
		link = 'Queen Elizabeth Way'
		display = 'Queen Elizabeth Way'
	elseif roadInfo.prefix == 'Toronto' and route:upper() == 'DVP' then -- Exception for the DVP
		link = 'Don Valley Parkway'
		display = 'Don Valley Parkway'
	elseif roadInfo.prefix == 'Toronto' and route == 'Gardiner' then -- Exception for the Gardiner Expressway
		link = 'Gardiner Expressway'
		display = 'Gardiner Expressway'
	else
		link = roadInfo.prefix .. ' ' .. roadInfo.type .. ' ' .. route
		display = roadInfo.type .. ' ' .. route
	end
	
	local titleObj = mw.title.new(link)
	
	if (((titleObj and titleObj.exists) or yesno(args.showred)) and not yesno(args.nolink)) then -- Check if the link show be shown
		return '[[' .. link .. '|' .. display .. ']]' -- Return the link
	else
		return display -- Fallback to returning the display text
	end
end

-- Gets the wikitext for a place
local function getPlace(place, args)
	local placeArticle = place .. ', Ontario'
	local titleObj = mw.title.new(placeArticle)
	
	if (titleObj and titleObj.exists) or yesno(args.showred) then
		return '[[' .. placeArticle .. '|' .. place .. ']]'
	else
		return place
	end
end

-- Entry function
function p.jcon(frame)
	local args = getArgs(frame)

	local roadType = (args[1] or ''):lower() -- Get the route type (region)
	local route = args[2] or '' -- Get the route number

	local placeTypes = { -- Place types to remove from lowercase road type
		'municipality',
		'municipal',
		'city',
		'township',
		'district',
		'county',
		'counties',
		'united counties',
		'region',
		'regional',
		'regional municipality',
		'road'
	}

	for index, placeType in ipairs(placeTypes) do
		roadType = roadType -- Remove the place types from the road type
			:gsub('^' .. placeType .. ' of ', '')
			:gsub(' ' .. placeType .. '$', '')
			:gsub(' ' .. placeType .. ' road$', '')
	end

	roadType = data.aliases[roadType] or roadType -- Transform alias into proper name

	if data.signs[roadType] or data.signs[route:lower()] then
		return data.signs[roadType] or data.signs[route:lower()] -- Return signs symbols like airport and hospital
	end

	local roadInfo = data.types[roadType] -- Get road type info from the data module

	if not roadInfo or not route then
		return '​' -- Return ZWSP if road type is not supported or the route is not specified
	end
	
	local output = ''
	local shield = ''

	if yesno(args.ot) then -- Set correct arguments if output should be only text
		args.nosh = 'yes'
		args.nolink = 'yes'
	end

	-- Define the shield
	if not yesno(args.nosh) then -- If allowed to add shield
		shield = shieldWikitext(route, roadInfo, args) -- Return the shield of the main road
	
		if args.con then
			if shield ~= '' then shield = shield .. ' ' end -- Add a NBSP if there's already a shield
			shield = shield .. shieldWikitext(args.con, roadInfo, args) -- Add the shield for the first concurrency
		end

		if args.con2 then
			if shield ~= '' then shield = shield .. ' ' end -- Add a NBSP if there's already a shield
			shield = shield .. shieldWikitext(args.con2, roadInfo, args) -- Add the shield for the second concurrency
		end

		if yesno(args.tch) then
			if shield ~= '' then shield = shield .. ' ' end -- Add a NBSP if there's already a shield
			shield = shield .. '[[File:TCH-blank.svg|x20px]]' -- Add the TCH shield
		end
	end
	
	if not yesno(args['pic aft']) then
		output = shield -- Add the shield if it goes first
	end

	-- Define the text
	if not yesno(args.notext) then -- If allowed to show text
		if output ~= '' then output = output .. ' ' end -- Add a NBSP after the shield if it exists
		output = output .. getText(route, roadInfo, args) -- Add text of the main route
	
		if args.con then
			output = output .. ' / ' .. getText(args.con, roadInfo, args) -- Add text of the first concurrency
		end
	
		if args.con2 then
			output = output .. ' / ' .. getText(args.con2, roadInfo, args) -- Add text of the second concurrency
		end
	
		if yesno(args.tch) then
			output = output .. ' / [[Trans-Canada Highway|TCH]]' -- Add the TCH text
		end
	end

	if args.dir then
		output = output .. ' ' .. args.dir -- Add main route direction
	end

	if args.condir then
		output = output .. '/' .. args.condir -- Add first concurrency direction
	end

	if args.condir2 then
		output = output .. '/' .. args.condir2 -- Add second concurrency direction
	end

	if args[3] then
		output = output .. ' (' .. args[3] .. ')' -- Add the name to the output
	end

	if args.city or args.town then
		output = output .. ' – ' .. getPlace(args.city or args.town, args) -- Add the first city
	
		if args.city2 or args.town2 then
			output = output .. ', ' .. getPlace(args.city2 or args.town2, args) -- Add the second city
		end
	end

	if yesno(args['pic aft']) and shield then
		if output ~= '' then output = output .. ' ' end -- Add a space if output already has text
		output = output .. shield -- Add the shield if it goes last
	end

	return output
end

-- Generates a list of supported regions
function p.supported(frame)
	local reverseAliases = {}
	local entries = {}
	local list = mw.html.create('ul') -- Create output list element

	for alias, name in pairs(data.aliases) do -- Reverse the alias table to allow lookup by name
		if not reverseAliases[name] then
			reverseAliases[name] = {}
		end
		
		table.insert(reverseAliases[name], alias)
	end

	for name, info in pairs(data.types) do -- Create tables for each region
		if reverseAliases[name] then
			for _, alias in ipairs(reverseAliases[name]) do
				name = name .. ' / ' .. alias -- Add alias to list item
			end
		end
		
		list:tag('li'):wikitext(name, ' ', '(' .. info.prefix .. ' ' .. info.type .. ')')
	end
		
	for sign, wikitext in pairs(data.signs) do
		if reverseAliases[sign] then
			for _, alias in ipairs(reverseAliases[sign]) do
				sign = sign .. ' / ' .. alias -- Add alias to list item
			end
		end
		
		list:tag('li'):wikitext(sign, ' ', wikitext)
	end

	return tostring(list)
end

return p