require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local data = mw.loadData('Module:Jcon/data/sandbox')
-- 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, skipCheck)
local size = args.size or '20px' -- Image size
local titleObj = mw.title.new('File:' .. fileName)
if not skipCheck and (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 wikitext for the shield
local function shieldWikitext(route, roadInfo, args, prefix)
local fileName = nil
local shieldKey = prefix == 'to' and 'toShield' or 'shield' -- Shield key in the road data
local guideKey = prefix == 'to' and 'toGuide' or 'guide' -- Guide key in the road data
if roadInfo.imgExceptions and roadInfo.imgExceptions[route] then
-- Handle exceptions
fileName = roadInfo.imgExceptions[route][yesno(args.shield) and shieldKey or guideKey]
elseif roadInfo.prefix == 'Ontario' and (tonumber(({route:gsub('%D', '')})[1]) or 0) >= 500 then
-- Handle secondary and tertiary highways
fileName = 'Ontario Highway ' .. route .. '.svg'
elseif roadInfo[shieldKey] and yesno(args.shield) then
-- Shield format (used as reassurance marker)
fileName = roadInfo[shieldKey]:format(route)
elseif roadInfo[guideKey] then
-- Guide format (used on guide signs)
fileName = roadInfo[guideKey]:format(route)
else
return '' -- Return nothing if no file format was found
end
return showFile(fileName, args)
end
-- Display a link, accounting for presentation arguments
local function displayLink(link, display, args)
local titleObj = mw.title.new(link)
local showLink = ((titleObj and titleObj.exists) or yesno(args.showred)) and not yesno(args.nolink)
if showLink 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)
end
-- Gets the wikitext link 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
-- 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 .. shieldWikitext(args[paramName], routeRoadInfo, args, prefix) -- 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 .. getText(args[paramName], routeRoadInfo, args) -- 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 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(data.signs[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 .. ' ' .. 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(data.signs[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(data.signs.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