Module:MetroStationInfobox

From Tyne and Wear Metro wiki
Revision as of 08:02, 27 August 2025 by Hopperelec (talk | contribs) (Created page with "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 a...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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