Module:Station: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 4: | Line 4: | ||
-- Load the main railway network data | -- Load the main railway network data | ||
local data = mw.loadJsonData("Data:NguhRoutes/network.json") | local data = mw.loadJsonData("Data:NguhRoutes/network.json") | ||
-- Predefined display names for known lines | |||
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" | |||
-- Note: LKL is NOT here since it's a station code, not a line | |||
} | |||
-- Helper function to find a station by code | -- Helper function to find a station by code | ||
local function findStation(code) | local function findStation(code) | ||
return data.stations[code] | return data.stations[code] | ||
end | end | ||
| Line 20: | Line 48: | ||
for _, stop in ipairs(line.stops) do | for _, stop in ipairs(line.stops) do | ||
if type(stop) == "table" then | if type(stop) == "table" then | ||
local fullCode = (dimension == "the_nether" and "N-" or "") .. stop.code | local fullCode = (dimension == "the_nether" and "N-" or "") .. stop.code | ||
if fullCode == stationCode then | if fullCode == stationCode then | ||
servedLines[line.code] = { | servedLines[line.code] = { | ||
name = line.name, | name = line.name, | ||
| Line 44: | Line 70: | ||
end | end | ||
hexColor = hexColor:gsub("#", "") | hexColor = hexColor:gsub("#", "") | ||
-- | -- Handle 3-character hex codes | ||
if #hexColor == 3 then | |||
hexColor = hexColor:gsub("(.)", "%1%1") | |||
end | |||
local r = tonumber(hexColor:sub(1, 2), 16) or 0 | local r = tonumber(hexColor:sub(1, 2), 16) or 0 | ||
local g = tonumber(hexColor:sub(3, 4), 16) or 0 | local g = tonumber(hexColor:sub(3, 4), 16) or 0 | ||
local b = tonumber(hexColor:sub(5, 6), 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 | local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 | ||
return luminance < 0.5 and "fff" or "000" | |||
end | |||
-- Function to create a display name for any line code | |||
local function getLineDisplayName(lineCode, lineData) | |||
-- Check predefined names first | |||
if lineDisplayNames[lineCode] then | |||
return lineDisplayNames[lineCode] | |||
end | |||
-- | -- Use line name from data | ||
if lineData and lineData.name then | |||
return lineData.name | |||
end | |||
-- Default: convert code to readable name | |||
if lineCode:sub(1, 2) == "Ng" then | |||
return "Ŋ" .. lineCode:sub(3) .. " Line" | |||
end | |||
return lineCode .. " Line" | |||
end | end | ||
-- Main function to generate infobox | -- Main function to generate infobox | ||
p.infobox = function(frame) | p.infobox = function(frame) | ||
local code = frame.args[1] or frame.args.code or "" | local code = frame.args[1] or frame.args.code or "" | ||
| Line 68: | Line 117: | ||
end | end | ||
local station = findStation(code) | local station = findStation(code) | ||
| Line 75: | Line 123: | ||
end | end | ||
local servedLines = getLinesForStation(code) | local servedLines = getLinesForStation(code) | ||
local output = {} | local output = {} | ||
| Line 84: | Line 129: | ||
table.insert(output, '{{Infobox') | table.insert(output, '{{Infobox') | ||
-- Above section | -- Above section | ||
local stationName = station[1] or "Unknown Station" | local stationName = station[1] or station.name or "Unknown Station" | ||
table.insert(output, '| above = ' .. stationName) | table.insert(output, '| above = ' .. stationName) | ||
-- Header section | -- Header section | ||
local header = string.format('%s [%s]', stationName, code) | local header = string.format('%s [%s]', stationName, code) | ||
if code:sub(1, 2) == "N-" then | if code:sub(1, 2) == "N-" then | ||
header = header .. ' [[File:LeshrailSymbol.png|frameless|upright=0.3|link=Leshrail]]' | header = header .. ' [[File:LeshrailSymbol.png|frameless|upright=0.3|link=Leshrail]]' | ||
| Line 97: | Line 140: | ||
table.insert(output, '| header1 = ' .. header) | table.insert(output, '| header1 = ' .. header) | ||
-- Image section | -- Image section | ||
if station.image then | if station.image then | ||
table.insert(output, '| image = ' .. station.image) | table.insert(output, '| image = ' .. station.image) | ||
| Line 106: | Line 149: | ||
local lineCount = 1 | local lineCount = 1 | ||
-- | -- Sort line codes for consistent output | ||
local | local sortedLineCodes = {} | ||
for lineCode in pairs(servedLines) do | |||
table.insert(sortedLineCodes, lineCode) | |||
end | |||
table.sort(sortedLineCodes) | |||
-- | -- Process each line | ||
local | for _, lineCode in ipairs(sortedLineCodes) do | ||
lineCount = lineCount + 1 | |||
local lineData = servedLines[lineCode] | |||
if lineCode == "FE" then | |||
-- FERRA line (special handling) | |||
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 | |||
-- Local Line (special handling) | |||
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 | |||
local displayName = getLineDisplayName(lineCode, lineData) | |||
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 | ||
end | end | ||
-- REMOVED THE PROBLEMATIC "No lines found" MESSAGE | |||
-- If a station truly has no lines, it will just show header and image | |||
-- Close the infobox | -- Close the infobox | ||
table.insert(output, '}}') | table.insert(output, '}}') | ||
return table.concat(output, '\n') | return table.concat(output, '\n') | ||
end | end | ||
-- | -- Test function to check specific station | ||
p. | p.test = function(frame) | ||
local code = frame.args[1] | local code = frame.args[1] or "SVG" -- Default to SVG for testing | ||
local station = findStation(code) | local station = findStation(code) | ||
local servedLines = getLinesForStation(code) | local servedLines = getLinesForStation(code) | ||
local result = { "=== Station: " .. code .. " ===" | local result = { | ||
"=== Testing Station: " .. code .. " ===", | |||
"Station found: " .. tostring(station ~= nil), | |||
"" | |||
} | |||
if station | if station then | ||
result[#result + 1] = "Station name: " .. (station[1] or "No name") | |||
result[#result + 1] = "Station type: " .. type(station) | |||
result[#result + 1] = "" | |||
end | end | ||
result[#result + 1] = "Lines serving this station (" .. #servedLines .. "):" | |||
for lineCode, lineData in pairs(servedLines) do | if next(servedLines) then | ||
for lineCode, lineData in pairs(servedLines) do | |||
result[#result + 1] = string.format("- %s: %s (color: %s)", | |||
lineCode, lineData.name, lineData.color) | |||
end | |||
else | |||
result[#result + 1] = "- No lines found" | |||
end | end | ||
result[#result + 1] = "" | |||
result[#result + 1] = "=== Generated Infobox ===" | |||
result[#result + 1] = p.infobox(frame) | |||
return table.concat(result, "\n") | return table.concat(result, "\n") | ||
Revision as of 07:02, 7 January 2026
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")
-- Predefined display names for known lines
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"
-- Note: LKL is NOT here since it's a station code, not a line
}
-- Helper function to find a station by code
local function findStation(code)
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
local fullCode = (dimension == "the_nether" and "N-" or "") .. stop.code
if fullCode == stationCode then
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
hexColor = hexColor:gsub("#", "")
-- Handle 3-character hex codes
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
-- Function to create a display name for any line code
local function getLineDisplayName(lineCode, lineData)
-- Check predefined names first
if lineDisplayNames[lineCode] then
return lineDisplayNames[lineCode]
end
-- Use line name from data
if lineData and lineData.name then
return lineData.name
end
-- Default: convert code to readable name
if lineCode:sub(1, 2) == "Ng" then
return "Ŋ" .. lineCode:sub(3) .. " Line"
end
return lineCode .. " Line"
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 = {}
-- Infobox opening
table.insert(output, '{{Infobox')
-- Above section
local stationName = station[1] or station.name or "Unknown Station"
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 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 codes for consistent output
local sortedLineCodes = {}
for lineCode in pairs(servedLines) do
table.insert(sortedLineCodes, lineCode)
end
table.sort(sortedLineCodes)
-- Process each line
for _, lineCode in ipairs(sortedLineCodes) do
lineCount = lineCount + 1
local lineData = servedLines[lineCode]
if lineCode == "FE" then
-- FERRA line (special handling)
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
-- Local Line (special handling)
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
local displayName = getLineDisplayName(lineCode, lineData)
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
-- REMOVED THE PROBLEMATIC "No lines found" MESSAGE
-- If a station truly has no lines, it will just show header and image
-- Close the infobox
table.insert(output, '}}')
return table.concat(output, '\n')
end
-- Test function to check specific station
p.test = function(frame)
local code = frame.args[1] or "SVG" -- Default to SVG for testing
local station = findStation(code)
local servedLines = getLinesForStation(code)
local result = {
"=== Testing Station: " .. code .. " ===",
"Station found: " .. tostring(station ~= nil),
""
}
if station then
result[#result + 1] = "Station name: " .. (station[1] or "No name")
result[#result + 1] = "Station type: " .. type(station)
result[#result + 1] = ""
end
result[#result + 1] = "Lines serving this station (" .. #servedLines .. "):"
if next(servedLines) then
for lineCode, lineData in pairs(servedLines) do
result[#result + 1] = string.format("- %s: %s (color: %s)",
lineCode, lineData.name, lineData.color)
end
else
result[#result + 1] = "- No lines found"
end
result[#result + 1] = ""
result[#result + 1] = "=== Generated Infobox ==="
result[#result + 1] = p.infobox(frame)
return table.concat(result, "\n")
end
return p