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 10:07, 5 September 2021 (Rewrote to use new format of Module:Jcon/data, make the code easier to read, and to fix some edge case errors). 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 picture
local function pictureWikitext(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', '')
		routeNum = tonumber(routeNum)

		-- 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)
	if mw.title.new(place .. ', Ontario').exists or yesno(args['showred']) then
		return '[[' .. place .. ', Ontario|' .. place .. ']]'
	else
		return place
	end
end

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

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

	local removeRegex = {  -- Regex to remove from lowercase input
		'^ ',
		'^municipality of',
		'^city of',
		'^region of',
		'^county of',
		' $',
		'regional road$',
		'region$',
		'county$',
		'county road$',
	}

	for _,v in ipairs(removeRegex) do
		roadType = mw.ustring.gsub(roadType, v, '') -- Remove items in removeRegex from the road type
	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 export = ''
	local picture = ''

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

	-- Define the picture
	if not yesno(args['nosh']) then -- If allowed to add shield
		picture = pictureWikitext(frame, route, roadType, roadInfo, args) -- Return picture of road 1
	
		if args['con'] then
			if picture ~= '' then picture = picture .. ' ' end -- Add a NBSP if there's already a picture
			picture = picture .. pictureWikitext(frame, args['con'], roadType, roadInfo, args) -- Add the picture of the first concurrency
		end

		if args['con2'] then
			if picture ~= '' then picture = picture .. ' ' end -- Add a NBSP if there's already a picture
			picture = picture .. pictureWikitext(frame, args['con2'], roadType, roadInfo, args)  -- Add the picture of the second concurrency
		end

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

	-- Define the text
	if not yesno(args['notext']) then -- If allowed to show text
		if export ~= '' then export = export .. ' ' end -- Add a NBSP after the picture if it exists
		export = export .. getText(frame, route, roadInfo, args) -- Return text of road 1
	
		if args['con'] then
			export = export .. ' / ' .. getText(frame, args['con'], roadInfo, args) -- Add the text of the first concurrency
		end
	
		if args['con2'] then
			export = export .. ' / ' .. getText(frame, args['con2'], roadInfo, args) -- Add the text of the second concurrency
		end
	
		if yesno(args['tch']) then
			export = export .. ' / [[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
		export = export .. ' – ' .. dirs -- Add the directions to the output
	end

	 -- Add the name to the text output
	if args[3] then
		export = export .. ' (' .. 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
		export = export .. ' – ' .. cities -- Add the cities to the output
	end

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

	return export
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