Module:Station
Documentation for this module may be created at Module:Station/doc
-- Module:InfoboxStation
local p = {}
-- Load the main railway network data
local data = mw.loadJsonData("Data:NguhRoutes/network.json")
-- Helper function to find a station by code
local function findStation(code)
-- Direct lookup in stations table
return data.stations[code]
end
-- Helper function to determine which lines serve this station
local function getLinesForStation(stationCode)
local servedLines = {}
-- Check both overworld and nether lines
for dimension, lines in pairs(data.lines) do
for _, line in ipairs(lines) do
for _, stop in ipairs(line.stops) do
if type(stop) == "table" then
-- Check if this stop matches our station
local fullCode = (dimension == "the_nether" and "N-" or "") .. stop.code
if fullCode == stationCode then
-- This line serves our station
servedLines[line.code] = {
name = line.name,
color = line.color or "#000000",
dimension = dimension
}
end
end
end
end
end
return servedLines
end
-- Function to convert hex color to text color (light/dark)
local function getTextColor(hexColor)
if not hexColor or hexColor == "" then
return "000"
end
-- Remove # if present
hexColor = hexColor:gsub("#", "")
-- Convert to RGB
local r = tonumber(hexColor:sub(1, 2), 16) or 0
local g = tonumber(hexColor:sub(3, 4), 16) or 0
local b = tonumber(hexColor:sub(5, 6), 16) or 0
-- Calculate relative luminance
local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
-- Return white text for dark backgrounds, black for light
return luminance < 0.5 and "fff" or "000"
end
-- Main function to generate infobox
p.infobox = function(frame)
-- Get the station code from the first parameter
local code = frame.args[1] or frame.args.code or ""
if code == "" then
return "'''Error: No station code provided'''"
end
-- Find the station in the dataset
local station = findStation(code)
if not station then
return "'''Error: Station '" .. code .. "' not found in dataset'''"
end
-- Determine which lines serve this station
local servedLines = getLinesForStation(code)
-- Start building the infobox
local output = {}
-- Infobox opening
table.insert(output, '{{Infobox')
-- Above section with station name
local stationName = station[1] or "Unknown Station"
table.insert(output, '| above = ' .. stationName)
-- Header section with code and optional Leshrail symbol
local header = string.format('%s [%s]', stationName, code)
-- Check if this is a Leshrail station (Nether station)
if code:sub(1, 2) == "N-" then
header = header .. ' [[File:LeshrailSymbol.png|frameless|upright=0.3|link=Leshrail]]'
end
table.insert(output, '| header1 = ' .. header)
-- Image section (if station has image data)
if station.image then
table.insert(output, '| image = ' .. station.image)
table.insert(output, '| caption = ' .. (station.caption or stationName))
end
-- Add lines that serve this station
local lineCount = 1
-- Mapping of line codes to display names
local lineDisplayNames = {
CN = "Central Line",
ZY = "Zyrian Line",
AQ = "Aquatic Line",
NO = "Northern Line",
LC = "Line of Chaos",
MT = "Mountain Line",
WE = "Western Line",
OL = "Olympic Line",
AR = "Archipelago Line",
TR = "Traeth Line",
TV = "Transversal Line",
FR = "Forest Line",
CR = "Crystal Line",
SO = "Southern Line",
LQ = "Lautseq Line",
NgE = "Ŋerlin Line",
CU = "Cuban Line",
CO = "Corner Line",
TF = "Transfortunate Line",
NgA = "Ŋafrican Line",
MI = "Mitosis Line",
SL = "Slab Line",
LL = "Local Line",
FE = "FERRA" -- Special case, handled separately
}
-- Check each possible line
local lineOrder = {"CN", "ZY", "AQ", "NO", "LC", "MT", "WE", "OL", "AR", "TR",
"TV", "FR", "CR", "SO", "LQ", "NgE", "CU", "CO", "TF",
"NgA", "MI", "SL", "LL", "FE"}
for _, lineCode in ipairs(lineOrder) do
if servedLines[lineCode] then
lineCount = lineCount + 1
if lineCode == "FE" then
-- Special handling for FERRA
table.insert(output, string.format('| header%d = [[File:FERRAlogo.png|frameless|upright=0.3|link=FERRA]]',
lineCount))
table.insert(output, string.format('| header%dstyle = background:#a4a4c6',
lineCount))
elseif lineCode == "LL" then
-- Special handling for Local Line
local localLineName = station.local_line_name or "Local Rail Services"
table.insert(output, string.format('| header%d = {{colorlink|FFF|Cenrail#Local_Rail_Services|%s}}',
lineCount, localLineName))
table.insert(output, string.format('| header%dstyle = background:#555',
lineCount))
else
-- Regular line handling
local lineData = servedLines[lineCode]
local displayName = lineDisplayNames[lineCode] or lineCode .. " Line"
local textColor = getTextColor(lineData.color)
local bgColor = lineData.color:gsub("#", "")
table.insert(output, string.format('| header%d = {{Colorlink|%s|Cenrail#%s|%s}}',
lineCount, textColor, displayName:gsub(" ", "_"), displayName))
table.insert(output, string.format('| header%dstyle = background:#%s',
lineCount, bgColor))
end
end
end
-- Close the infobox
table.insert(output, '}}')
-- Return the complete infobox wikitext
return table.concat(output, '\n')
end
-- Alternative function that returns data for debugging
p.getStationInfo = function(frame)
local code = frame.args[1] or frame.args.code or ""
if code == "" then
return "No code provided"
end
local station = findStation(code)
if not station then
return "Station not found: " .. code
end
local servedLines = getLinesForStation(code)
local result = { "=== Station: " .. code .. " ===" }
table.insert(result, "Name: " .. (station[1] or "Unknown"))
if station.image then
table.insert(result, "Image: " .. station.image)
end
if station.caption then
table.insert(result, "Caption: " .. station.caption)
end
table.insert(result, "")
table.insert(result, "=== Lines serving this station ===")
for lineCode, lineData in pairs(servedLines) do
table.insert(result, string.format("- %s: %s (Color: %s)",
lineCode, lineData.name, lineData.color))
end
if next(servedLines) == nil then
table.insert(result, "No lines found for this station")
end
return table.concat(result, "\n")
end
return p