Module:Jcon/sandbox

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 '' -- 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  .. 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  .. place ..  else return place end end

-- Process routes present in the provided arguments local function processRoutes(roadType, showShield, showText, args, prefix) 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 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') -- Handle to and via parameters local toShield, toText = processRoutes(roadType, showShield, showText, args, 'to') local viaShield, viaText = processRoutes(roadType, showShield, showText, args, 'via') 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 ' Via ') .. viaShield end if viaText ~= '' then -- Add via text to the output text = text .. (text == '' and 'Via ' or ' via ') .. viaText end else return '&#8203;' -- 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 .. '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

if args[3] then output = output .. ' (' .. args[3] .. ')' -- Add the name 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