Module:Station
Documentation for this module may be created at Module:Station/doc
-- Module:InfoboxStation
-- Updated to use Module:Data/Cenrail/Lines for line data
local p = {}
-- Load data from different sources
local stationsData = mw.loadJsonData("Data:NguhRoutes/network.json")
local linesModule = require("Module:Data/Cenrail/Lines")
local countriesModule = require("Module:Places") -- Keep for country info if needed
-- Helper function to find a station by code
local function findStation(code)
return stationsData.stations[code]
end
-- Helper to get display name for a line
local function getLineDisplayName(lineKey)
local displayNames = {
central = "Central Line",
transversal = "Transversal Line",
southern = "Southern Line"
-- Add more as more lines are defined in the module
}
return displayNames[lineKey] or lineKey:gsub("^%l", string.upper) .. " Line"
end
-- Helper to determine which lines serve a station
local function getLinesForStation(stationCode)
local servedLines = {}
-- Check each line in the lines module
for lineKey, lineData in pairs(linesModule) do
if type(lineData) == "table" and lineData.stops then
-- Check if this station is in the line's stops
for _, stopCode in ipairs(lineData.stops) do
if stopCode == stationCode then
servedLines[lineKey] = {
name = getLineDisplayName(lineKey),
color = lineData.color or "#000000",
key = lineKey
}
break -- Found it, move to next line
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
hexColor = hexColor:gsub("#", "")
if #hexColor == 3 then
hexColor = hexColor:gsub("(.)", "%1%1")
end
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
if not r or not g or not b then
return "000"
end
local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
return luminance < 0.5 and "fff" or "000"
end
-- Main function to generate infobox
p.infobox = function(frame)
local code = frame.args[1] or frame.args.code or ""
if code == "" then
return "'''Error: No station code provided'''"
end
local station = findStation(code)
if not station then
return "'''Error: Station '" .. code .. "' not found in dataset'''"
end
local servedLines = getLinesForStation(code)
local output = {}
-- Build wikitext
table.insert(output, '{{Infobox')
-- Get station name (handles different data structures)
local stationName
if type(station) == "table" then
stationName = station[1] or station.name or "Unknown Station"
else
stationName = tostring(station)
end
-- Above section
table.insert(output, '| above = ' .. stationName)
-- Header section
local header = string.format('%s [%s]', stationName, code)
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 available)
if type(station) == "table" and 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
-- Sort line keys for consistent output
local sortedLineKeys = {}
for lineKey in pairs(servedLines) do
table.insert(sortedLineKeys, lineKey)
end
table.sort(sortedLineKeys)
-- Special handling for specific line types
local specialLines = {
FE = function(lineCount)
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))
end,
LL = function(lineCount)
local localLineName = (type(station) == "table" and 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))
end
}
-- Process each line
for _, lineKey in ipairs(sortedLineKeys) do
lineCount = lineCount + 1
local lineData = servedLines[lineKey]
-- Check if it's a special line
if specialLines[lineKey] then
specialLines[lineKey](lineCount)
else
-- Regular line
local displayName = lineData.name
local wikiLinkName = displayName:gsub(" Line", ""):gsub(" ", "_")
local textColor = getTextColor(lineData.color)
local bgColor = lineData.color:gsub("#", "")
table.insert(output, string.format('| header%d = {{Colorlink|%s|Cenrail#%s|%s}}',
lineCount, textColor, wikiLinkName, displayName))
table.insert(output, string.format('| header%dstyle = background:#%s',
lineCount, bgColor))
end
end
-- If no lines found, add a placeholder (optional)
if lineCount == 1 then
lineCount = lineCount + 1
table.insert(output, string.format('| header%d = (No railway lines)', lineCount))
end
table.insert(output, '}}')
local wikitext = table.concat(output, '\n')
-- Try to parse the wikitext
if frame.preprocess then
return frame:preprocess(wikitext)
else
return wikitext
end
end
-- Debug function to show station information
p.debug = function(frame)
local code = frame.args[1] or frame.args.code or ""
if code == "" then
return "No station code provided"
end
local station = findStation(code)
local servedLines = getLinesForStation(code)
local result = {
"=== DEBUG: Station " .. code .. " ===",
""
}
-- Station info
table.insert(result, "Station found: " .. tostring(station ~= nil))
if station then
table.insert(result, "Station type: " .. type(station))
if type(station) == "table" then
table.insert(result, "Station data:")
for k, v in pairs(station) do
table.insert(result, " " .. tostring(k) .. ": " .. tostring(v))
end
else
table.insert(result, "Station value: " .. tostring(station))
end
end
table.insert(result, "")
table.insert(result, "=== Lines serving this station ===")
if next(servedLines) then
for lineKey, lineData in pairs(servedLines) do
table.insert(result, string.format("- %s: %s (color: %s)",
lineKey, lineData.name, lineData.color))
end
else
table.insert(result, "- No lines found")
-- Show available lines for debugging
table.insert(result, "")
table.insert(result, "=== Available lines in Module ===")
for lineKey, lineData in pairs(linesModule) do
if type(lineData) == "table" then
table.insert(result, string.format("- %s: %d stops",
lineKey, #(lineData.stops or {})))
end
end
end
return table.concat(result, "\n")
end
-- Test function for specific station
p.test = function(frame)
local code = frame.args[1] or "KCC" -- Default to KCC (in both central and transversal lines)
local station = findStation(code)
local servedLines = getLinesForStation(code)
local result = {
"=== Test for station: " .. code .. " ===",
"Station name: " .. (station and (station[1] or station.name or "Unknown") or "Not found"),
"Number of lines serving: " .. (next(servedLines) and tostring(tablelength(servedLines)) or "0"),
""
}
if next(servedLines) then
table.insert(result, "Lines:")
for lineKey, lineData in pairs(servedLines) do
table.insert(result, "- " .. lineData.name .. " (key: " .. lineKey .. ")")
end
end
table.insert(result, "")
table.insert(result, "=== Generated Infobox ===")
table.insert(result, p.infobox(frame))
return table.concat(result, "\n")
end
-- Helper function
local function tablelength(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
return p