Module:Jcon
Appearance
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module depends on the following other modules: |
This module implements Template:Jcon and Template:Shieldlist.
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local data = mw.loadData('Module:Jcon/data')
local anyTall = false -- Whether any tall shields have been found before adding MTO signs
-- Normalize the given road type
local function normalizeType(roadType)
roadType = (roadType or ''):lower() -- Make the road type lowercase
for index, placeType in ipairs(data.placeTypes) do
roadType = roadType -- Remove the place types from the road type
:gsub('^' .. placeType .. ' of ', '')
:gsub(' ' .. placeType .. '$', '')
:gsub(' ' .. placeType .. ' road$', '')
end
return data.aliases[roadType] or roadType -- Transform alias into proper name
end
-- Generate wikitext to show an icon
local function showFile(fileName, args, sign)
local size = args.size or '20px' -- Image size
if sign then
fileName = data.signs[fileName] -- Get the file name from the sign definition
if not anyTall then
-- Set height for MTO signs when no tall shields are present
size = 'x' .. size
end
else
local 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
end
return '[[File:' .. fileName .. '|alt=|link=|' .. size .. ']]' -- Return the file wikitext
end
-- Get the first defined shield from a table
local function getShield(shieldTable, route, shield, to)
if to and shield and shieldTable.toShield then
-- Shield format for "to" routes
anyTall = anyTall or shieldTable.shieldTall
return shieldTable.toShield:format(route)
elseif to and shieldTable.toGuide then
-- Guide format for "to" routes
return shieldTable.toGuide:format(route)
elseif shield and shieldTable.shield then
-- Shield format (used as reassurance marker)
anyTall = anyTall or shieldTable.shieldTall
return shieldTable.shield:format(route)
elseif shieldTable.guide then
-- Guide format (used on guide signs)
return shieldTable.guide:format(route)
else
return ''
end
end
-- Generate the wikitext for the shield
local function shieldWikitext(route, roadInfo, args, prefix)
local fileName = nil
if roadInfo.imgExceptions and roadInfo.imgExceptions[route] then
-- Handle exceptions
fileName = getShield(roadInfo.imgExceptions[route], route, yesno(args.shield), prefix == 'to')
elseif roadInfo.prefix == 'Ontario' and (tonumber(({route:gsub('%D', '')})[1]) or 0) >= 500 then
-- Handle secondary and tertiary highways
fileName = 'Ontario Highway ' .. route .. '.svg'
else
-- Handle regular routes
fileName = getShield(roadInfo, route, yesno(args.shield), prefix == 'to')
end
return showFile(fileName, args)
end
-- Display a link, accounting for presentation arguments
local function displayLink(link, display, args, followNoLink)
local titleObj = mw.title.new(link)
local noLink = followNoLink and yesno(args.nolink)
local showRed = yesno(args.showred)
if (not noLink) and (showRed or (titleObj and titleObj.exists)) then
return '[[' .. link .. '|' .. display .. ']]' -- Return the link
else
return display -- Fallback to returning the display text
end
end
-- Generate the text part of the output
local function getText(route, roadInfo, args)
local link = ''
local display = ''
if roadInfo.textExceptions and roadInfo.textExceptions[route] then
-- Handle exceptions
link = roadInfo.textExceptions[route].link
display = roadInfo.textExceptions[route].display
else
-- Construct links and display from prefix, type, and route number
link = roadInfo.prefix .. ' ' .. roadInfo.type .. ' ' .. route
display = roadInfo.type .. ' ' .. route
end
if yesno(args.fulltext) then
-- Display the full link title when requested
display = link
end
return displayLink(link, display, args, true)
end
-- Gets the wikitext link for a place
local function getPlace(place, args)
return displayLink(place .. ', Ontario', place, args)
end
-- Process routes present in the provided arguments
local function processRoutes(roadType, showShield, showText, args, prefix, name)
local roadInfo = data.types[roadType]
local shield = '' -- Generated shield wikitext
local text = '' -- Generated text/link wikitext
local conNumber = prefix ~= 'con' and 1 or 0 -- The number of the entry being processed
local paramName = prefix ~= 'con' and prefix or 2 -- Route number parameter name
local typeParam = prefix ~= 'con' and prefix .. 'type' or nil -- Road type override parameter name
local dirParam = prefix ~= 'con' and prefix .. 'dir' or 'dir' -- Direction parameter name
while args[paramName] do
local routeRoadInfo = roadInfo -- Local copy of the road info
if typeParam and args[typeParam] then
-- Override the road info if one is provided
local overrideRoadType = normalizeType(args[typeParam])
routeRoadInfo = data.types[overrideRoadType]
end
if showShield then
local routeShield = shieldWikitext(args[paramName], routeRoadInfo, args, prefix) -- Generate route shield
if routeShield ~= '' then
if shield ~= '' then shield = shield .. ' ' end -- Add space after existing shields
shield = shield .. routeShield -- Add the shield
end
end
if showText then
local routeText = getText(args[paramName], routeRoadInfo, args) -- Generate route text
if routeText ~= '' then
if text ~= '' then text = text .. ' / ' end -- Add " / " after existing text
text = text .. routeText -- Add route text
end
end
if args[dirParam] then
text = text .. ' ' .. args[dirParam] -- Add the direction
end
conNumber = conNumber + 1 -- Move on to the next concurrency
local suffix = conNumber == 1 and '' or conNumber -- Calculate the next parameter suffix
-- Update the parameter names
paramName = prefix .. suffix
typeParam = prefix .. 'type' .. suffix
dirParam = prefix .. 'dir' .. suffix
end
if name and yesno(args.namefirst) then
text = name .. ' (' .. text .. ')' -- Output name before text when namefirst is set to yes
elseif name then
text = text .. ' (' .. name .. ')' -- Add the name to the produced text
end
return shield, text -- Return generated shield and text wikitext
end
-- Entry function
function p.jcon(frame)
local args = getArgs(frame)
if yesno(args.ot) then
-- Set correct arguments if output should be only text
args.nosh = 'yes'
args.nolink = 'yes'
end
local roadType = normalizeType(args[1]) -- The first road type
local showShield = not yesno(args.nosh)
local showText = not yesno(args.notext)
local shieldAfter = yesno(args.picaft or args['pic aft'])
local shield = nil -- Generated shield wikitext
local text = nil -- Generated text/name wikitext
if data.signs[roadType] then
-- Handle MTO signs
shield = showFile(roadType, args, true)
text = args[2] or ''
elseif data.types[roadType] then
-- Handle numbered roads
shield, text = processRoutes(roadType, showShield, showText, args, 'con', args[3])
-- Handle to and via parameters
local toShield, toText = processRoutes(roadType, showShield, showText, args, 'to', args.toname)
local viaShield, viaText = processRoutes(roadType, showShield, showText, args, 'via', args.vianame)
if toShield ~= '' then
shield = shield .. (shield == '' and '' or ' ') .. toShield -- Add to shields to output
end
if toText ~= '' then
text = text .. (text == '' and 'To ' or ' to ') .. toText -- Add to text
end
if viaShield ~= '' then
-- Add via shields to the output
shield = shield .. (shield == '' and '' or ' <span style="vertical-align:middle;">Via</span> ') .. viaShield
end
if viaText ~= '' then
-- Add via text to the output
text = text .. (text == '' and 'Via ' or ' via ') .. viaText
end
else
return '​' -- Return ZWSP if road type is not supported
end
if args.sign and showShield then
if shield ~= '' then shield = shield .. ' ' end -- Add space after existing shields
-- Add the MTO sign if provided
shield = shield .. showFile(args.sign, args, true)
end
if yesno(args.tch) then
if showShield then
if shield ~= '' then shield = shield .. ' ' end -- Add space after existing shields
shield = shield .. showFile('tch', args, true) -- Add the TCH shield
end
if showText then
if text ~= '' then text = text .. ' / ' end -- Add " / " after existing text
text = text .. '[[Trans-Canada Highway|TCH]]' -- Add the TCH text
end
end
local output = '' -- The returned output
if not shieldAfter then
-- Add the shield if it goes first
output = output .. shield
end
if text ~= '' then
if output ~= '' then output = output .. ' ' end -- Add a NBSP after the shield if it exists
output = output .. text -- Add the generated text to the output
end
-- Process control cities
if args.city or args.town then
output = output .. ' – ' .. getPlace(args.city or args.town, args) -- Add the first city
local extraCityNum = 2 -- The number of the additional city being processed
while args['city' .. extraCityNum] or args['town' .. extraCityNum] do
local val = args['city' .. extraCityNum] or args['town' .. extraCityNum]
output = output .. ', ' .. getPlace(val, args) -- Add extra cities
extraCityNum = extraCityNum + 1
end
end
if shieldAfter 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
return p