Module:Jct

local p = {}

local SUFFIX = "" -- Change to main module upon deployment local parserModuleName = "Module:Road data/parser" .. SUFFIX local cityModuleName = "Module:Jct/city" .. SUFFIX

local concat = table.concat local insert = table.insert local format = mw.ustring.format local roadDataModule = require("Module:Road data" .. SUFFIX)

local rdt

-- Links/abbreviations local function routeText(route, jctname, frame) local link local type = route.type if not type or type == '' then link = route.route else link = roadDataModule.link(route) end

local dir = route.dir and ' ' .. string.lower(route.dir) or '' local routeText = link .. dir

local name = route.name if name and name ~= '' then local mainText = jctname and name or routeText local parenText = jctname and routeText or name

if route.rdt then return frame:expandTemplate{ title = 'BSsplit', args = {mainText, parenText, align = 'left', valign = 'middle' } } else return format('%s (%s)', mainText, parenText) end else return routeText end end

local function extra(args) local extraTypes = mw.loadData('Module:Road data/extra') local extraIcon = extraTypes[string.lower(args.extra or '')] if not extraIcon then return '' end local size = require("Module:Road data/size").size({style = 'jct'}) local countryIcon = extraIcon[args.country] or extraIcon.default if type(countryIcon) == 'table' then local localIcon = countryIcon[args.state] or countryIcon.default return string.format("", localIcon, size) else return string.format("", countryIcon, size) end end

local function parseArgs(args) local state = args.state or args.province or '' args.state = state local country if args.country and args.country ~= '' then country = string.upper(args.country) else local countryModule = mw.loadData("Module:Road data/countrymask") country = countryModule[state] or 'UNK' end args.country = country

local params = {'denom', 'county', 'township', 'dab', 'nolink', 'noshield', 'to', 'dir', 'name'} local routes = {} local routeCount = 1 local seenTo = false while true do		local routeType = args[routeCount * 2 - 1] if not routeType then break end local route = {type = routeType, route = args[routeCount * 2]} for _,v in pairs(params) do route[v] = args[v .. routeCount] end route.country = country route.state = state

-- Set the first .to to true. -- Set all following .to to ''. if seenTo then if route.to then -- Report duplicate to flag. route.toerror = true end route.to = '' elseif route.to then route.to = true seenTo = true end

route.rdt = args.rdt insert(routes, route) routeCount = routeCount + 1 end return routes end

local function prefix(to, num) if to and to ~= '' then return num == 1 and 'To ' or ' to ' end return num == 1 and '' or ' / ' end

local function addErrorMsg(catCode, msg, errorMsg) errorMsg.code = errorMsg.code or catCode insert(errorMsg, format(' Module:Jct %s ', msg)) end

function p._jct(args, frame) rdt = args.rdt local routes = parseArgs(args) local shields = {} local links = {} local allMissingShields = {} local typeErr = false local toErr = false frame = frame or mw.getCurrentFrame for num,route in ipairs(routes) do		if not (args.noshield or route.noshield) then local shield, missingShields = roadDataModule.shield(route) insert(shields, shield) if missingShields[1] then insert(allMissingShields, concat(missingShields, ' / ')) end end local prefix = prefix(route.to, num) if prefix ~= '' then insert(links, prefix) end insert(links, routeText(route, args.jctname, frame)) typeErr = typeErr or route.typeerror or false toErr = toErr or route.toerror or false end local graphics = concat(shields) .. extra(args) .. ' '	local linkText = concat(links) local cities = '' if args.city1 or args.location1 then local citiesPrefix if args.citiesprefix then citiesPrefix = args.citiesprefix ~=  and format(" %s ", args.citiesprefix) or  else citiesPrefix = ' ' end local cityModule = require(cityModuleName) cities = citiesPrefix .. cityModule.city(args) end

local errorMsg = {} -- Errors must be reported by the level of severity, most severe first. if typeErr then -- Report invalid type errors. addErrorMsg("§", 'error: Invalid route type', errorMsg) end if #allMissingShields > 0 then -- Report missing shield error. -- shieldExists would have populated missingShields if shields are missing. addErrorMsg("¶", 'error: Missing route marker graphics: ' .. concat(allMissingShields, ' / '), errorMsg) end if toErr then -- Report invalid to errors. addErrorMsg("&", 'error: Invalid "to" argument', errorMsg) end if args.road then -- Report deprecated "road" warning. addErrorMsg("∆", 'warning: "road" parameter is deprecated', errorMsg) end if #errorMsg > 0 then local page = mw.title.getCurrentTitle.prefixedText -- Get transcluding page's title -- Add a category for the first, most severe error. insert(errorMsg, format('', errorMsg.code, page)) errorMsg = concat(errorMsg) else errorMsg = '' end

return graphics .. linkText .. cities .. errorMsg end

function p.jct(frame) -- Import module function to work with passed arguments local getArgs = require('Module:Arguments').getArgs local args = getArgs(frame, {removeBlanks = false}) return p._jct(args, frame) end

function p._roadlink(args, frame) local routes = parseArgs(args) local links = {} local typeErr = false local toErr = false frame = frame or mw.getCurrentFrame for num,route in ipairs(routes) do		local prefix = prefix(route.to, num) if prefix ~= '' then insert(links, prefix) end insert(links, routeText(route, args.jctname, frame)) typeErr = typeErr or route.typeerror or false toErr = toErr or route.toerror or false end local linkText = concat(links) local cities = '' if args.city1 or args.location1 then local citiesPrefix if args.citiesprefix then citiesPrefix = args.citiesprefix ~=  and format(" %s ", args.citiesprefix) or  else citiesPrefix = ' ' end local cityModule = require(cityModuleName) cities = citiesPrefix .. cityModule.city(args) end

local errorMsg = {} -- Errors must be reported by the level of severity, most severe first. if typeErr then -- Report invalid type errors. addErrorMsg("2", 'error: Invalid route type', errorMsg) end if toErr then -- Report invalid to errors. addErrorMsg("3", 'error: Invalid "to" argument', errorMsg) end if args.road then -- Report deprecated "road" warning. addErrorMsg("W", 'warning: "road" parameter is deprecated', errorMsg) end if #errorMsg > 0 then local page = mw.title.getCurrentTitle.prefixedText -- Get transcluding page's title -- Add a category for the first, most severe error. insert(errorMsg, format('', errorMsg.code, page)) errorMsg = concat(errorMsg) else errorMsg = '' end

return linkText .. cities end

function p.roadlink(frame) -- Import module function to work with passed arguments local getArgs = require('Module:Arguments').getArgs local args = getArgs(frame, {removeBlanks = true}) return p._roadlink(args, frame) end

return p