Module:MetroStationInfobox
From Tyne and Wear Metro wiki
Documentation for this module may be created at Module:MetroStationInfobox/doc
local p = {}
local LENGTH_555 = 59.9
local LENGTH_METROCAR = 55.6
function smwAnnotatePlatform(platform)
return '[[Has platform::' ..
(platform.num or '') .. ';' ..
(platform.route or '') .. ';' ..
(platform.len and (platform.len .. ' m') or '') .. '|' ..
platform.display .. ']]'
end
function p.main(frame)
local args = frame:getParent().args
-- Aliases
args['Nexus code'] = args['Nexus code'] or args['Code']
args['Coordinates'] = args['Coordinates'] or args['Coords']
local tableElement = mw.html.create( 'table' ):addClass( 'infobox' )
tableElement:tag( 'caption' )
:wikitext( '[[Has station name::' .. ( args['Name'] or mw.title.getCurrentTitle().text ) .. ']]' )
local pillsRow = mw.html.create( 'tr' )
local pillsList = pillsRow
:tag( 'td' ):attr( 'colspan', '2' )
:tag( 'ul' ):addClass( 'pills' )
local thereArePills = false
local function createPill()
thereArePills = true
return pillsList:tag( 'li' )
end
if args['Is on green line'] then
createPill()
:css( 'background-color', '#0f0' ):css( 'border-color', '#0a0' )
:wikitext( '[[Is on green line::true| ]][[GRN]]' )
end
if args['Is on yellow line'] then
createPill()
:css( 'background-color', '#ff0' ):css( 'border-color', '#aa0' )
:wikitext( '[[Is on yellow line::true| ]][[YEL]]' )
end
if args['Fare zones'] then
local zones = {
A = { bg = '#FEF797', accent = '#FAAA4D' },
B = { bg = '#B3DBB4', accent = '#FEFEFE' },
C = { bg = '#F9D5E5', accent = '#ED008C' },
D = { bg = '#D4E7F7', accent = '#0081EA' },
}
for zone in mw.text.gsplit(args['Fare zones'], ',') do
zone = mw.text.trim(zone):upper()
if zones[zone] then
createPill():addClass( 'zone' )
:attr( 'title', "Zone" .. zone )
:wikitext( '[[Has Metro fare zone::' .. zone .. ']]' )
-- Can't use CSS variables with TemplateStyles
:css( 'background-color', zones[zone].bg )
:css( 'border-color', zones[zone].accent )
:css( 'color', zones[zone].accent )
end
end
end
if args['Nexus code'] then
createPill()
:attr( 'title', 'Nexus code' )
:wikitext( '[[Image:Nexus_icon.svg|link=Nexus]][[Has Nexus code::' .. args['Nexus code'] .. ']]' )
end
if args['Alternative codes'] then
for code in mw.text.gsplit(args['alternative codes'], ',') do
code = mw.text.trim(code)
if code ~= '' then
createPill():addClass( 'alternative-code' )
:attr( 'title', 'Alternative code' )
:wikitext( '[[Image:Nexus_icon.svg|link=Nexus]]' .. args['Nexus code'] )
end
end
end
if args['CRS code'] then
createPill()
:attr( 'title', 'CRS code' )
:wikitext( '[[Image:National_Rail_logo.svg|alt=National Rail logo]][[Has CRS code::' .. args['CRS code'] .. ']]' )
end
if args['Has bus interchange'] then
createPill()
:attr( 'title', 'Bus interchange' )
:wikitext( '[[Has bus interchange::true| ]]🚍' )
end
if args['Has rail interchange'] then
createPill()
:attr( 'title', 'Rail interchange' )
:wikitext( '[[Has rail interchange::true| ]][[Image:National_Rail_logo.svg|alt=National Rail logo]]' )
end
if args['Car parking spaces'] then
createPill()
:attr( 'title', args['Car parking spaces'] .. ' car parking spaces' )
:wikitext( '🅿️×[[Has car parking spaces' .. args['Car parking spaces'] .. ']]' )
end
if args['Cycle parking spaces'] then
createPill()
:attr( 'title', args['Cycle parking spaces'] .. ' cycle parking spaces' )
:wikitext( '🅿️×[[Has cycle parking spaces' .. args['Cycle parking spaces'] .. ']]' )
end
if thereArePills then
tableElement:node(pillsRow)
end
if args['Image'] then
tableElement:tag( 'tr' )
:tag( 'td' ):attr( 'colspan', '2' )
:wikitext( '[[Has primary image::File:' .. args['Image'] .. '|300px]]' )
end
if args['Coordinates'] then
local lat, lon = args['Coordinates']:match("([-%d.]+),([-%d.]+)")
if lat and lon then
tableElement:tag( 'tr' ):addClass( 'coordinates' )
:tag( 'td' ):attr( 'colspan', '2' )
:wikitext(
'[[Has coordinates::' .. args['Coordinates'] .. '| ]]' ..
'[https://www.openstreetmap.org/#map=19/' .. lat .. '/' .. lon .. ' 🗺️ View on OpenStreetMap]'
)
end
end
if args['Address'] then
tableElement:tag( 'tr' )
:tag( 'td' ):attr( 'colspan', '2' )
:wikitext( '[[Has address::' .. args['Address'] .. ']]')
end
if args['Distance from datum'] then
tableElement:tag( 'tr' )
:tag( 'td' ):attr( 'colspan', '2' )
:wikitext( '[[Has distance from Gosforth datum::' .. args['Address'] .. ']] from Gosforth datum' )
end
local dates = {}
if args['Date originally opened'] then
table.insert(dates, 'Originally opened [[Has date opened::' .. args['Date originally opened'] .. ']]')
end
if args['Date closed before Metro'] then
table.insert(dates, 'Closed before Metro [[Has date closed before Metro::' .. args['Date closed before Metro'] .. ']]')
end
if args['Date opened for Metro'] then
table.insert(dates, 'Opened for Metro [[Has date opened for Metro::' .. args['Date opened for Metro'] .. ']]')
end
if args['Other key dates'] then
local parts = mw.text.split(args['Other key dates'], ';')
for i = 1, #parts, 2 do
if parts[i+1] then
table.insert(dates, mw.text.trim(parts[i]) .. ' ' .. mw.text.trim(parts[i+1]))
end
end
end
if #dates == 1 then
tableElement:tag( 'tr' )
:tag( 'td' ):attr( 'colspan', '2' )
:wikitext( dates[1] )
elseif #dates > 1 then
local row = tableElement:tag( 'tr' )
row:tag( 'th' ):attr( 'scope', 'row' ):wikitext( 'Key dates' )
local list = row:tag( 'td' )
:tag( 'ul' ):addClass( 'key-dates' )
for _, date in ipairs(dates) do
list:tag('li'):wikitext(date)
end
end
if args['Platforms'] then
local parsedPlatforms = {}
local anyHaveLength = false
local maxLength = math.max(LENGTH_555, LENGTH_METROCAR)
for pStr in mw.text.gsplit(args['Platforms'], ';') do
pStr = mw.text.trim(pStr)
if pStr ~= '' then
local pData = mw.text.split(pStr, ',')
local platform = {
num = tonumber(mw.text.trim(pData[1])),
route = tonumber(mw.text.trim(pData[2])),
len = tonumber(mw.text.trim(pData[3]))
}
local extras = {}
if platform.route then
table.insert(extras, 'route code ' .. platform.route)
end
if platform.len then
table.insert(extras, platform.len .. ' m')
end
platform.display = 'P' .. (platform.num or '?')
if #extras > 0 then
platform.display = platform.display .. ' (' .. table.concat(extras, ', ') .. ')'
end
if platform.len then
anyHaveLength = true
if platform.len > maxLength then
maxLength = platform.len
end
end
table.insert(parsedPlatforms, platform)
end
end
if #parsedPlatforms > 0 then
local row = tableElement:tag( 'tr' )
row:tag( 'th' ):attr( 'scope', 'row' ):wikitext( 'Platforms' )
if anyHaveLength then
local list = row:tag( 'td' )
:tag( 'ul' ):addClass( 'platforms-visualizer' )
list:tag( 'li' ):addClass( 'reference-train' ):addClass( 'reference-555' )
:css( 'width', (LENGTH_555/maxLength*100) .. '%' )
:wikitext( '[[Class 555|Class 555 for reference]]' )
list:tag( 'li' ):addClass( 'reference-train' ):addClass( 'reference-metrocar' )
:css( 'width', (LENGTH_METROCAR/maxLength*100) .. '%' )
:wikitext( '[[Metrocar|Metrocar for reference]]' )
for _, platform in ipairs(parsedPlatforms) do
local annotatedDisplay = smwAnnotatePlatform(platform)
if platform.len and platform.len > 0 then
local width = platform.len / maxLength * 100
list:tag('li'):addClass('reference-platform')
:css('width', (platform.len/maxLength*100) .. '%')
:attr('title', platform.display)
:wikitext(annotatedDisplay)
else
list:tag('li'):attr('title', platform.display)
:wikitext(annotatedDisplay)
end
end
else
local texts = {}
for _, platform in ipairs(parsedPlatforms) do
platform.display = mw.ustring.gsub(platform.display, ' ', ' ') -- non-breaking space
table.insert(texts, smwAnnotatePlatform(platform))
end
row:tag( 'td' ):wikitext(table.concat(texts, ', '))
end
end
end
return tableElement
end
return p