Jump to content

Module:Jcon

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by BrandonXLF (talk | contribs) at 05:50, 6 September 2021 (Remove place types rather than a table of regex). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

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(frame, route, division, roadInfo, args)
	local existingFile = ''	
	local size = args['size'] or 'x20px' -- Image size

	if roadInfo['pic'] then
		local fileName = roadInfo['pic'][1] .. route .. roadInfo['pic'][2] -- Get filename from template
		local routeNum = string.gsub(route, '%D', '') -- Get the digits from the route number
		routeNum = tonumber(routeNum) -- Turn them into an actual number

		-- Override the default format with exceptions for some highways
		if division == 'highway' or division == 'toll' then
			if route:upper() == '407ETR' then -- Exception for 407 ETR
				fileName = 'Highway407crest.png'
			elseif routeNum and routeNum >= 500 then -- Exception for secondary and tertiary highways
				fileName = 'Ontario Highway ' .. route .. '.svg'
			elseif yesno(args['shield']) then
				fileName = 'Ontario ' .. route .. '.svg'
			end
		end

		if mw.title.new('File:' .. fileName).file.exists then -- Check if the file exists and record it if it does
			existingFile = fileName

			-- Override default size with exceptions
			if route:upper() == '407ETR' then
				size = '24px'
			elseif division == 'kawartha lakes' then
				size = '21px'
			elseif routeNum and routeNum >= 800 and division == 'highway' then
				size = '20px'
			elseif yesno(args['shield']) and division == 'highway' then
				size = 'x25px'
			elseif division == 'toll' then
				size = 'x30px'
			end
		end
	end
	
	if existingFile == '' and division ~= 'highway' and division ~= 'toll' then -- Check if fallback should be used
		local fileName = 'RR ' .. route .. ' jct.svg' -- Get fallback file name

		if mw.title.new('File:' .. fileName).file.exists then -- Check if the fallback file exists and recoed it if it does
			existingFile = fileName
		end
	end

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

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

	if route:upper() == '407ETR' then -- Exception for the 407 ETR
		link = 'Ontario Highway 407'
		display = '407 ETR'
	elseif route:upper() == 'QEW' then -- Exception for the QEW
		link = 'Queen Elizabeth Way'
		display = 'Queen Elizabeth Way'
	else
		link = (roadInfo['prefix'] and roadInfo['prefix'] .. ' ' or '') .. roadInfo['type'] .. ' ' .. route
		display = roadInfo['type'] .. ' ' .. route
	end
	
	if ((mw.title.new(link).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(frame, place, args)
	local placeArticle = place .. ', Ontario'
	
	if mw.title.new(placeArticle).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(frame, route, roadType, 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(frame, args['con'], roadType, 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(frame, args['con2'], roadType, 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(frame, route, roadInfo, args) -- Return text of road 1
	
		if args['con'] then
			output = output .. ' / ' .. getText(frame, args['con'], roadInfo, args) -- Add the text of the first concurrency
		end
	
		if args['con2'] then
			output = output .. ' / ' .. getText(frame, args['con2'], roadInfo, args) -- Add the text of the second concurrency
		end
	
		if yesno(args['tch']) then
			output = output .. ' / [[Trans-Canada Highway|TCH]]' -- Add the TCH text
		end
	end
	
	local dirs = {} -- Table to store directions
	
	if args['dir'] then
		table.insert(dirs, args['dir']) -- Add the primary direction
	end

	if args['condir'] then
		table.insert(dirs, args['condir']) -- Add the first concurrency direction
	end

	if args['condir2'] then
		table.insert(dirs, args['condir2']) -- Add the second concurrency direction
	end
	
	dirs = table.concat(dirs, '/') -- Concat the directions into a single string
	if dirs ~= '' then
		output = output .. ' – ' .. dirs -- Add the directions to the output
	end

	 -- Add the name to the output
	if args[3] then
		output = output .. ' (' .. args[3] .. ')'
	end
	
	local cities = {} -- Table to store cities

	if args['city'] or args['town'] then
		table.insert(cities, getPlace(frame, args['city'] or args['town'], args)) -- Add the first city
	end -- Add the first city
	
	if args['city2'] or args['town2'] then
		table.insert(cities, getPlace(frame, args['city2'] or args['town2'], args)) -- Add the second city
	end -- Add the second city
	
	cities = table.concat(cities, ', ') -- Concat the cities into a single string
	if cities ~= '' then
		output = output .. ' – ' .. cities -- Add the cities to the output
	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 = {}

	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
	
	local list = mw.html.create('ul') -- Create output element

	for name, info in pairs(data.types) do -- Create tables for each region
		nameList = list
			:tag('li')
			:wikitext(info['prefix'] and info['prefix'] .. ' ' or '', info['type'])
			:tag('ul')
			:tag('li')
			:wikitext(name)
			:done()
		
		if reverseAliases[name] then -- Display aliases
			for _, alias in ipairs(reverseAliases[name]) do
				nameList
					:tag('li')
					:wikitext(alias)
			end
		end
	end

	mtoSignList = list
		:tag('li')
		:wikitext('MTO signs')
		:tag('ul')
		
	for sign, wikitext in pairs(data.signs) do
		mtoSignList -- Add the sign name and image to the MTO sign list
			:tag('li')
			:wikitext(sign, ' ', wikitext)
		
		if reverseAliases[sign] then -- Display aliases
			for _, alias in ipairs(reverseAliases[sign]) do
				mtoSignList -- Add the sign name and image to the MTO sign list
					:tag('li')
					:wikitext(alias, ' ', wikitext)
			end
		end
	end

	return tostring(list)
end

return p