Jump to content

Module:Jcon: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Support shieldlist for Template:Shieldlist
Support new data format
Line 5: Line 5:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
local data = mw.loadData('Module:Jcon/data')
local parser = require('Module:Road data/parser').parser


local dataModuleName = 'Module:Jcon/data'
local anyTall = false -- Whether any tall shields have been found before adding MTO signs
local data = mw.loadData(dataModuleName)


-- Normalize the given road type
-- Normalize the given road type
Line 13: Line 14:
roadType = (roadType or ''):lower() -- Make the road type lowercase
roadType = (roadType or ''):lower() -- Make the road type lowercase


for index, placeType in ipairs(data.placeTypes) do
for index, placeType in ipairs(data._placeTypes) do
roadType = roadType -- Remove the place types from the road type
roadType = roadType -- Remove the place types from the road type
:gsub('^' .. placeType .. ' of ', '')
:gsub('^' .. placeType .. ' of ', '')
Line 20: Line 21:
end
end


return data.aliases[roadType] or roadType -- Transform alias into proper name
return roadType
end
end


Line 28: Line 29:
if sign then
if sign then
fileName = data.signs[fileName] -- Get the file name from the sign definition
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
else
local titleObj = mw.title.new('File:' .. fileName)
local titleObj = mw.title.new('File:' .. fileName)
Line 46: Line 42:


-- Get the first defined shield from a table
-- Get the first defined shield from a table
local function getShield(shieldTable, route, shield, to)
local function getShield(parserArgs, shield, to)
-- Shield format for "to" routes
if to and shield and shieldTable.toShield then
if to and shield then
-- Shield format for "to" routes
local res = parser(parserArgs, 'shieldtomain', nil, dataModuleName)
anyTall = anyTall or shieldTable.shieldTall
if type(res) == 'table' then return res[1] end
return shieldTable.toShield:format(route)
if res then return res end
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
-- Guide format for "to" routes
if to then
local res = parser(parserArgs, 'shieldto', nil, dataModuleName)
if type(res) == 'table' then return res[1] end
if res then return res end
end
-- Shield format (used as reassurance marker)
if shield then
local res = parser(parserArgs, 'shieldmain', nil, dataModuleName)
if type(res) == 'table' then return res[1] end
if res then return res end
end
-- Guide format (used on guide signs)
local res = parser(parserArgs, 'shield', nil, dataModuleName)
if type(res) == 'table' then return res[1] end
if res then return res end
return ''
end
end


-- Generate the wikitext for the shield
-- Generate the wikitext for the shield
local function shieldWikitext(route, roadInfo, args, prefix)
local function shieldWikitext(parserArgs, args, prefix)
return showFile(
local fileName = nil
getShield(parserArgs, yesno(args.shield), prefix == 'to'),
args
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
end


Line 102: Line 98:


-- Generate the text part of the output
-- Generate the text part of the output
local function getText(route, roadInfo, args, noSelfRedirect)
local function getText(parserArgs, args, noSelfRedirect)
local link = ''
local link = parser(parserArgs, 'link', nil, dataModuleName)
local display = ''
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
if yesno(args.fulltext) then
-- Display the full link title when requested
-- Display the full link title when requested
display = roadInfo.prefix .. ' ' .. display
display = parser(parserArgs, 'name', nil, dataModuleName)
else
display = parser(parserArgs, 'abbr', nil, dataModuleName)
end
end
Line 131: Line 119:
-- Process routes present in the provided arguments
-- Process routes present in the provided arguments
local function processRoutes(roadType, showShield, showText, args, prefix, name)
local function processRoutes(roadType, showShield, showText, args, prefix, name)
local roadInfo = data.types[roadType]
local shield = '' -- Generated shield wikitext
local shield = '' -- Generated shield wikitext
local text = '' -- Generated text/link wikitext
local text = '' -- Generated text/link wikitext
Line 142: Line 128:


while args[paramName] do
while args[paramName] do
local routeRoadInfo = roadInfo -- Local copy of the road info
local routeRoadType = roadType -- Local copy of the road info
if typeParam and args[typeParam] then
if typeParam and args[typeParam] then
-- Override the road info if one is provided
-- Override the road info if one is provided
local overrideRoadType = normalizeType(args[typeParam])
routeRoadType = normalizeType(args[typeParam])
routeRoadInfo = data.types[overrideRoadType]
end
end
-- Arguments for the road data parser
local parserArgs = {
ignoreifexists = true,
country = 'CAN',
province = 'ON',
type = routeRoadType,
route = args[paramName]
}
if showShield then
if showShield then
local routeShield = shieldWikitext(args[paramName], routeRoadInfo, args, prefix) -- Generate route shield
local routeShield = shieldWikitext(parserArgs, args, prefix) -- Generate route shield
if routeShield ~= '' then
if routeShield ~= '' then
Line 160: Line 154:
if showText then
if showText then
local routeText = getText(args[paramName], routeRoadInfo, args) -- Generate route text
local routeText = getText(parserArgs, args) -- Generate route text
if routeText ~= '' then
if routeText ~= '' then
Line 208: Line 202:
local text = nil -- Generated text/name wikitext
local text = nil -- Generated text/name wikitext
if data.signs[roadType] then
if data._signs[roadType] then
-- Handle MTO signs
-- Handle MTO signs
shield = showFile(roadType, args, true)
shield = showFile(roadType, args, true)
text = args[2] or ''
text = args[2] or ''
elseif data.types[roadType] then
elseif data[roadType] then
-- Handle numbered roads
-- Handle numbered roads
shield, text = processRoutes(roadType, showShield, showText, args, 'con', args[3])
shield, text = processRoutes(roadType, showShield, showText, args, 'con', args[3])
Line 295: Line 289:
function p.shieldlist(frame)
function p.shieldlist(frame)
local args = getArgs(frame)
local args = getArgs(frame)
local roadInfo = data.types[normalizeType(args[1])]
local type = normalizeType(args[1])
local route = args[2]
local route = args[2]
local size = args.size or '36px'
local size = args.size or '36px'
if not roadInfo then
return ''
end
-- Add table
-- Add table
Line 308: Line 298:
-- Add a table row
-- Add a table row
out = out .. '<tr>'
out = out .. '<tr>'
-- Arguments for the road data parser
local parserArgs = {
ignoreifexists = true,
country = 'CAN',
province = 'ON',
type = type,
route = route
}
-- Generate route shield
-- Generate route shield
local routeShield = shieldWikitext(route, roadInfo, { size = size, shield = true })
local routeShield = shieldWikitext(parserArgs, { size = size, shield = true })
if routeShield ~= '' then
if routeShield ~= '' then
Line 317: Line 316:
-- Generate route text
-- Generate route text
local routeText = getText(route, roadInfo, { fulltext = true }, true)
local routeText = getText(parserArgs, { fulltext = true }, true)
if routeText ~= '' then
if routeText ~= '' then

Revision as of 09:50, 24 August 2024

require('strict')

local p = {}

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local parser = require('Module:Road data/parser').parser

local dataModuleName = 'Module:Jcon/data'
local data = mw.loadData(dataModuleName)

-- 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 roadType
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
	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(parserArgs, shield, to)
	-- Shield format for "to" routes
	if to and shield then
		local res = parser(parserArgs, 'shieldtomain', nil, dataModuleName)
		if type(res) == 'table' then return res[1] end
		if res then return res end
	end
	
	-- Guide format for "to" routes
	if to then
		local res = parser(parserArgs, 'shieldto', nil, dataModuleName)
		if type(res) == 'table' then return res[1] end
		if res then return res end
	end
	
	-- Shield format (used as reassurance marker)
	if shield then
		local res = parser(parserArgs, 'shieldmain', nil, dataModuleName)
		if type(res) == 'table' then return res[1] end
		if res then return res end
	end
	
	-- Guide format (used on guide signs)
	local res = parser(parserArgs, 'shield', nil, dataModuleName)
	if type(res) == 'table' then return res[1] end
	if res then return res end
	
	return ''
end

-- Generate the wikitext for the shield
local function shieldWikitext(parserArgs, args, prefix)
	return showFile(
		getShield(parserArgs, yesno(args.shield), prefix == 'to'),
		args
	)
end

-- Display a link, accounting for presentation arguments
local function displayLink(link, display, args, followNoLink, noSelfRedirect)
	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))
			and not (noSelfRedirect and titleObj and titleObj.redirectTarget == mw.title.getCurrentTitle())
	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(parserArgs, args, noSelfRedirect)
	local link = parser(parserArgs, 'link', nil, dataModuleName)
	
	local display = ''
	if yesno(args.fulltext) then
		-- Display the full link title when requested
		display = parser(parserArgs, 'name', nil, dataModuleName)
	else
		display = parser(parserArgs, 'abbr', nil, dataModuleName)
	end
	
	return displayLink(link, display, args, true, noSelfRedirect)
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 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 routeRoadType = roadType -- Local copy of the road info
		
		if typeParam and args[typeParam] then
			-- Override the road info if one is provided
			routeRoadType = normalizeType(args[typeParam])
		end
		
		-- Arguments for the road data parser
		local parserArgs = {
			ignoreifexists = true,
			country = 'CAN',
			province = 'ON',
			type = routeRoadType,
			route = args[paramName]
		}
		
		if showShield then
			local routeShield = shieldWikitext(parserArgs, 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(parserArgs, args) -- Generate route text
			
			if routeText ~= '' then
				if text ~= '' then text = text .. '&nbsp;/ ' 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 for {{jcon}}
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[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 '&#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(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 .. '&nbsp;/ ' 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 .. '&nbsp;' 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

-- Entry function for {{shieldlist}}
function p.shieldlist(frame)
	local args = getArgs(frame)
	local type = normalizeType(args[1])
	local route = args[2]
	local size = args.size or '36px'
	
	-- Add table
	local out = '<table style="background: transparent; margin: 0; padding: 0; width: 100%; align: left;">'
	
	-- Add a table row
	out = out .. '<tr>'
	
	-- Arguments for the road data parser
	local parserArgs = {
		ignoreifexists = true,
		country = 'CAN',
		province = 'ON',
		type = type,
		route = route
	}
	
	-- Generate route shield
	local routeShield = shieldWikitext(parserArgs, { size = size, shield = true })
	
	if routeShield ~= '' then
		out = out .. '<td style="background: transparent; border: 0px; margin: 0px; padding: 0px;">' .. routeShield .. '</td>'
	end
	
	 -- Generate route text
	local routeText = getText(parserArgs, { fulltext = true }, true)
	
	if routeText ~= '' then
		out = out .. '<td style="background: transparent; border: 0px; margin: 0px; padding: 0px; text-align: center;">' .. routeText .. '</td>'
	end
	
	out = out .. '</tr></table>' -- Finish the table and table row
	
	return out
end

return p