Module:Jcon: Difference between revisions
Appearance
Content deleted Content added
BrandonXLF (talk | contribs) Support shieldlist for Template:Shieldlist |
BrandonXLF (talk | contribs) 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 |
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. |
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 |
return roadType |
||
end |
end |
||
Line 28: | Line 29: | ||
if sign then |
if sign then |
||
fileName = data. |
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( |
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( |
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( |
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 = |
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 |
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 |
||
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( |
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( |
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. |
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 |
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 |
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( |
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( |
local routeText = getText(parserArgs, { fulltext = true }, true) |
||
if routeText ~= '' then |
if routeText ~= '' then |
Revision as of 09:50, 24 August 2024
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module depends on the following other modules: |
This module implements Template:Jcon and Template:Shieldlist.
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 .. ' / ' 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 '​' -- 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 .. ' / ' 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
-- 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