Permanently protected module
From Wikipedia, the free encyclopedia


local p = {}

-- Change to "" upon deployment.

local moduleSuffix = ""



local parserModuleName = "Module:Road data/parser" .. moduleSuffix

local statenameModuleName = "Module:Jct/statename" .. moduleSuffix -- TODO transition

local cityModuleName = "Module:Jct/city" .. moduleSuffix



local concat = table.concat

local insert = table.insert

local format = mw.ustring.format

local trim = mw.text.trim



local parserModule = require(parserModuleName)

local parser = parserModule.parser

local util = require("Module:Road data/util")





-- Shields

local defaultShieldSize = 24



local function addContextBanner(route, name, suffix, bannerSpec)

	local bannerModule = 'Module:Road data/banners/' .. string.upper(route.country)

	local shieldfield = name .. 'shield'

	local shield = parser(route, shieldfield)

	if shield == nil then

		-- This route type does not define shield.

		-- Find shield in the default banner table.

		shield = parser(route, 'shield', name, bannerModule)

		if shield and shield ~= '' then

			if suffix == nil then

				suffix = parser(route, 'shield', 'suffix', bannerModule)

			end

			if suffix and suffix ~= '' then

				shield = shield .. " " .. suffix

			end

			shield = shield .. ".svg"

		end

	end

	if shield and shield ~= '' then

		local shieldSize = defaultShieldSize

		-- Add banner plate.

		insert(bannerSpec, {shield, shieldSize})

	end

end



local function bannerSpec(banner, bannerSize, bannerSuffix, route)

	local banners = {}

	if type(banner) == "table" then

		local bannerSizeIsNotTable = type(bannerSize) ~= "table"

		for i,filename in ipairs(banner) do

			local bannersize = bannerSizeIsNotTable and bannerSize or bannerSizei or defaultShieldSize

			insert(banners, {filename, bannersize})

		end

	elseif banner ~= '' then

		insert(banners, {banner, bannerSize})

	end



	if route.dir then

		addContextBanner(route, 'dir', bannerSuffix, banners)

	end

	if route.to then

		addContextBanner(route, 'to', bannerSuffix, banners)

	end



	return banners

end



local function shieldSpec(route, mainShield, shieldList)

	local shieldSpec = {}



	local shield

	local shieldto = parser(route, 'shieldto')

	

	if route.to then

		if not shield then shield = shieldto or parser(route, 'shield') or '' end

	else

		if not shield then shield = parser(route, 'shield') or '' end

	end

	if shield == '' then return shieldSpec end

	local orientation = parser(route, 'orientation')



	local function size(route)

		if orientation == "upright" then

			return defaultShieldSize

			else return "x" .. defaultShieldSize

		end

	end

	

	local shieldsize = size(route)

	

	local banner = parser(route, 'banner') or {}

	local bannersize = defaultShieldSize

	local bannersuffix = parser(route, 'bannersuffix')



	local bannerIsNotTable = type(banner) ~= "table"

	local bannersizeIsNotTable = type(bannersize) ~= "table"

	local bannersuffixIsNotTable = type(bannersuffix) ~= "table"



	if type(shield) == "table" then

		for i,filename in ipairs(shield) do

			local size = shieldsize or shieldsizei

			if size == "" then size = nil end

			-- banner.all describes banners that apply to all multiple shields.

			local shieldBanner = bannerIsNotTable and banner or (banneri or banner.all or {})

			-- Banner size is default if the corresponding entry

			-- in bannerSize table is not set.

			local shieldBannerSize =

				bannersizeIsNotTable and bannersize

				or (bannersizei or bannersize.all or defaultShieldSize)

			local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffixi])

			insert(shieldSpec, {

				shield = {filename, size},

				banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route)

			})

		end

	elseif shield ~= '' then

		if shieldsize == "" then shieldsize = nil end

		insert(shieldSpec, {

			shield = {shield, shieldsize},

			banners = bannerSpec(banner, bannersize,  bannersuffix, route)

		})

	end



	return shieldSpec

end



local missingShields



local shieldExistsCache = {}



local function render(shieldEntry, scale, showLink)

	local shield = shieldEntry.shield

	local banners = shieldEntry.banners



	local size

	if shield2 then

		local width, height = mw.ustring.match(shield2], "(%d*)x?(%d*)")

		width = tonumber(width)

		height = tonumber(height)

		local sizeparts = {}

		if width then

			insert(sizeparts, format("%d", width * scale))

		end

		if height then

			insert(sizeparts, format("x%d", height * scale))

		end

		size = concat(sizeparts)

	else

		size = format("%s%d", landscape and "x" or "", defaultShieldSize * scale)

	end

	local shieldCode = format("[[File:%s|%spx|link=|alt=]]", shield1], size)

	if not banners1 then return shieldCode end



	for _,banner in ipairs(banners) do

		shieldCode = format("[[File:%s|%spx|link=|alt=]]<br>%s",

			banner1],

			defaultShieldSize,

			shieldCode)

	end

	return '<span style="display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;">' .. shieldCode .. '</span>'

end



function p.shield(route, scale, showLink, mainShield, shieldList)

	missingShields = {}



	scale = scale or 1



	local rendered = {}

	for _,entry in ipairs(shieldSpec(route, mainShield, shieldList)) do

		insert(rendered, render(entry, scale, showLink))

	end

	return concat(rendered), missingShields

end



-- Links/abbreviations

function p.link(route)

	local nolink = route.nolink

	local abbr = parser(route, 'abbr')

	if nolink then

		return abbr

	else

		local link = parser(route, 'link')

		if not link or link == '' then

			return abbr

		else

			return format("[[%s|%s]]", link, abbr)

		end

	end

end

-------------------------------------------



-- 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 = p.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

		

		return format('%s (%s)', mainText, parenText)

	else

		return routeText

	end

end



local function extra(args)

	local extraTypes = mw.loadData('Module:Road data/extra')

	local extraIcon = extraTypesstring.lower(args.extra or '')]

	if not extraIcon then return '' end

	local size = defaultShieldSize .. 'px'

	local countryIcon = extraIconargs.country or extraIcon.default

	if type(countryIcon) == 'table' then

		local localIcon = countryIconargs.state or countryIcon.default

		return string.format("[[File:%s|%s|alt=|link=]]", localIcon, size)

	else

		return string.format("[[File:%s|%s|alt=|link=]]", 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 = countryModulestate 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 = argsrouteCount * 2 - 1

		if not routeType then break end

		local route = {type = routeType, route = argsrouteCount * 2]}

		for _,v in pairs(params) do

			routev = argsv .. routeCount

		end

		

		if args.nolink then

			route.nolink = args.nolink

		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



		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 '&nbsp;/ '

end



local function addErrorMsg(catCode, msg, errorMsg)

	errorMsg.code = errorMsg.code or catCode

	insert(errorMsg, format('<span style="display: none;">Module:Jct %s</span>', msg))

end



function p._jct(args, frame)

	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 = p.shield(route)

			insert(shields, shield)

			if missingShields1 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 = '&nbsp;'

		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 args.rdt then

		-- Report deprecated "rdt" warning.

		addErrorMsg("£", 'warning: "rdt" 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('[[Category:Jct template errors|%s %s]]', 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 = '&nbsp;'

		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('[[Category:Jct template errors|%s %s]]', 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
Permanently protected module
From Wikipedia, the free encyclopedia


local p = {}

-- Change to "" upon deployment.

local moduleSuffix = ""



local parserModuleName = "Module:Road data/parser" .. moduleSuffix

local statenameModuleName = "Module:Jct/statename" .. moduleSuffix -- TODO transition

local cityModuleName = "Module:Jct/city" .. moduleSuffix



local concat = table.concat

local insert = table.insert

local format = mw.ustring.format

local trim = mw.text.trim



local parserModule = require(parserModuleName)

local parser = parserModule.parser

local util = require("Module:Road data/util")





-- Shields

local defaultShieldSize = 24



local function addContextBanner(route, name, suffix, bannerSpec)

	local bannerModule = 'Module:Road data/banners/' .. string.upper(route.country)

	local shieldfield = name .. 'shield'

	local shield = parser(route, shieldfield)

	if shield == nil then

		-- This route type does not define shield.

		-- Find shield in the default banner table.

		shield = parser(route, 'shield', name, bannerModule)

		if shield and shield ~= '' then

			if suffix == nil then

				suffix = parser(route, 'shield', 'suffix', bannerModule)

			end

			if suffix and suffix ~= '' then

				shield = shield .. " " .. suffix

			end

			shield = shield .. ".svg"

		end

	end

	if shield and shield ~= '' then

		local shieldSize = defaultShieldSize

		-- Add banner plate.

		insert(bannerSpec, {shield, shieldSize})

	end

end



local function bannerSpec(banner, bannerSize, bannerSuffix, route)

	local banners = {}

	if type(banner) == "table" then

		local bannerSizeIsNotTable = type(bannerSize) ~= "table"

		for i,filename in ipairs(banner) do

			local bannersize = bannerSizeIsNotTable and bannerSize or bannerSizei or defaultShieldSize

			insert(banners, {filename, bannersize})

		end

	elseif banner ~= '' then

		insert(banners, {banner, bannerSize})

	end



	if route.dir then

		addContextBanner(route, 'dir', bannerSuffix, banners)

	end

	if route.to then

		addContextBanner(route, 'to', bannerSuffix, banners)

	end



	return banners

end



local function shieldSpec(route, mainShield, shieldList)

	local shieldSpec = {}



	local shield

	local shieldto = parser(route, 'shieldto')

	

	if route.to then

		if not shield then shield = shieldto or parser(route, 'shield') or '' end

	else

		if not shield then shield = parser(route, 'shield') or '' end

	end

	if shield == '' then return shieldSpec end

	local orientation = parser(route, 'orientation')



	local function size(route)

		if orientation == "upright" then

			return defaultShieldSize

			else return "x" .. defaultShieldSize

		end

	end

	

	local shieldsize = size(route)

	

	local banner = parser(route, 'banner') or {}

	local bannersize = defaultShieldSize

	local bannersuffix = parser(route, 'bannersuffix')



	local bannerIsNotTable = type(banner) ~= "table"

	local bannersizeIsNotTable = type(bannersize) ~= "table"

	local bannersuffixIsNotTable = type(bannersuffix) ~= "table"



	if type(shield) == "table" then

		for i,filename in ipairs(shield) do

			local size = shieldsize or shieldsizei

			if size == "" then size = nil end

			-- banner.all describes banners that apply to all multiple shields.

			local shieldBanner = bannerIsNotTable and banner or (banneri or banner.all or {})

			-- Banner size is default if the corresponding entry

			-- in bannerSize table is not set.

			local shieldBannerSize =

				bannersizeIsNotTable and bannersize

				or (bannersizei or bannersize.all or defaultShieldSize)

			local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffixi])

			insert(shieldSpec, {

				shield = {filename, size},

				banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route)

			})

		end

	elseif shield ~= '' then

		if shieldsize == "" then shieldsize = nil end

		insert(shieldSpec, {

			shield = {shield, shieldsize},

			banners = bannerSpec(banner, bannersize,  bannersuffix, route)

		})

	end



	return shieldSpec

end



local missingShields



local shieldExistsCache = {}



local function render(shieldEntry, scale, showLink)

	local shield = shieldEntry.shield

	local banners = shieldEntry.banners



	local size

	if shield2 then

		local width, height = mw.ustring.match(shield2], "(%d*)x?(%d*)")

		width = tonumber(width)

		height = tonumber(height)

		local sizeparts = {}

		if width then

			insert(sizeparts, format("%d", width * scale))

		end

		if height then

			insert(sizeparts, format("x%d", height * scale))

		end

		size = concat(sizeparts)

	else

		size = format("%s%d", landscape and "x" or "", defaultShieldSize * scale)

	end

	local shieldCode = format("[[File:%s|%spx|link=|alt=]]", shield1], size)

	if not banners1 then return shieldCode end



	for _,banner in ipairs(banners) do

		shieldCode = format("[[File:%s|%spx|link=|alt=]]<br>%s",

			banner1],

			defaultShieldSize,

			shieldCode)

	end

	return '<span style="display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;">' .. shieldCode .. '</span>'

end



function p.shield(route, scale, showLink, mainShield, shieldList)

	missingShields = {}



	scale = scale or 1



	local rendered = {}

	for _,entry in ipairs(shieldSpec(route, mainShield, shieldList)) do

		insert(rendered, render(entry, scale, showLink))

	end

	return concat(rendered), missingShields

end



-- Links/abbreviations

function p.link(route)

	local nolink = route.nolink

	local abbr = parser(route, 'abbr')

	if nolink then

		return abbr

	else

		local link = parser(route, 'link')

		if not link or link == '' then

			return abbr

		else

			return format("[[%s|%s]]", link, abbr)

		end

	end

end

-------------------------------------------



-- 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 = p.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

		

		return format('%s (%s)', mainText, parenText)

	else

		return routeText

	end

end



local function extra(args)

	local extraTypes = mw.loadData('Module:Road data/extra')

	local extraIcon = extraTypesstring.lower(args.extra or '')]

	if not extraIcon then return '' end

	local size = defaultShieldSize .. 'px'

	local countryIcon = extraIconargs.country or extraIcon.default

	if type(countryIcon) == 'table' then

		local localIcon = countryIconargs.state or countryIcon.default

		return string.format("[[File:%s|%s|alt=|link=]]", localIcon, size)

	else

		return string.format("[[File:%s|%s|alt=|link=]]", 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 = countryModulestate 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 = argsrouteCount * 2 - 1

		if not routeType then break end

		local route = {type = routeType, route = argsrouteCount * 2]}

		for _,v in pairs(params) do

			routev = argsv .. routeCount

		end

		

		if args.nolink then

			route.nolink = args.nolink

		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



		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 '&nbsp;/ '

end



local function addErrorMsg(catCode, msg, errorMsg)

	errorMsg.code = errorMsg.code or catCode

	insert(errorMsg, format('<span style="display: none;">Module:Jct %s</span>', msg))

end



function p._jct(args, frame)

	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 = p.shield(route)

			insert(shields, shield)

			if missingShields1 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 = '&nbsp;'

		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 args.rdt then

		-- Report deprecated "rdt" warning.

		addErrorMsg("£", 'warning: "rdt" 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('[[Category:Jct template errors|%s %s]]', 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 = '&nbsp;'

		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('[[Category:Jct template errors|%s %s]]', 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

Videos

Youtube | Vimeo | Bing

Websites

Google | Yahoo | Bing

Encyclopedia

Google | Yahoo | Bing

Facebook