Module:Railway
Documentation for this module may be created at Module:Railway/doc
local p = {}
local function adjacentStations(id, lang, interchange)
return require("Module:Wikidata").claim({
lang = lang,
item = id,
formatting = 'table',
property = 'P197', -- adjacent station
qualifier = 'P1192 OR P81 OR /P81', -- connecting service or connecting line as qualifier or property
qualifier2 = 'P5051 OR P560', -- towards or direction
case = 'infoboxdata', -- fixes in local language, i.e. remove 'Station' from label
colformat1 = 'raw',
separator = '<station>',
rowformat = '$0<qualifier>$1<qualifier>$2<qualifier>' .. interchange
})
end
function p._station(args)
local id = args.item
local lang = args.lang or require("Module:Wikidata").lang()
--fetch data
local data_raw = adjacentStations(id, lang, 'false')
local interchange_id = require("Module:Wikidata").claim({
lang = lang,
item = id,
formatting = 'raw',
property = 'P833', -- interchange station
separator = '<interchange>'
})
if interchange_id then
for qid in mw.text.gsplit(interchange_id, '<interchange>', true) do
data_raw = (data_raw or '') .. '<station>' .. (adjacentStations(qid, lang, 'true') or '')
end
end
if data_raw == nil then return end
-- fill a table with data
local data = {} -- {station, line, towards, interchange}
local novalue = mw.message.new('Wikibase-snakview-snaktypeselector-novalue'):inLanguage(lang):plain()
local terminus = mw.wikibase.getLabel('Q20202072')
for station in mw.text.gsplit(data_raw, '<station>', true) do
if #station > 0 then
local station_data = mw.text.split(station, '<qualifier>', true)
if station_data[1] == novalue then
station_data[1] = terminus
end
for line in mw.text.gsplit(station_data[2], ', ', true) do
if line ~= '' then
table.insert(data, {station_data[1], line, station_data[3], station_data[4]})
end
end
end
end
-- group by line
local conn_line = {} -- {line_label, {line, part_of, part_of_label, interchange, adjacent1, towards1, adjacent2, towards2}}
for _, v in ipairs(data) do
local line_label = mw.wikibase.getLabel(v[2])
if conn_line[line_label] == nil then
-- new line, fetch data
local line_part = require("Module:Wikidata").claim({
lang = lang,
item = v[2],
property = 'P361', -- part of
qualifier = 'P361/P2910 OR P361/P154', -- icon or logo image from part of
qualifier2 = 'P361',
colformat2 = 'label',
formatting = 'table',
list = 'false',
rowformat = '$1$0<label>$2',
rowsubformat1 = '[[File:$1|20x20px|link=]] '
})
local line_part_label = ''
if line_part then
line_part_label = mw.text.split(line_part, '<label>', true)[2]
line_part = mw.text.split(line_part, '<label>', true)[1]
else
line_part = ''
end
local line_icon = mw.wikibase.getBestStatements(v[2], 'P2910')
if #line_icon == 0 then
line_icon = mw.wikibase.getBestStatements(v[2], 'P154') -- logo image
end
local line_sitelink = mw.wikibase.getSitelink(v[2]) or ('d:' .. v[2])
local line_linked = ''
if #line_icon > 0 then
line_linked = '[[File:' .. mw.wikibase.renderSnak(line_icon[1]['mainsnak']) .. '|20x20px|'
.. '|alt=' .. line_label .. '|link=' .. line_sitelink .. ']]'
else
line_icon = mw.wikibase.getBestStatements(v[2], 'P465') -- sRGB color hex triplet
if #line_icon > 0 then
line_linked = '<div style="line-height: .5; background-color: #'
.. mw.wikibase.renderSnak(line_icon[1]['mainsnak'])
.. ';"> </div>'
end
line_linked = line_linked .. '[[' .. line_sitelink .. '|' .. line_label .. ']]'
end
conn_line[line_label] = {}
conn_line[line_label]["line"] = line_linked
conn_line[line_label]["part"] = line_part
conn_line[line_label]["part_label"] = line_part_label
conn_line[line_label]["interchange"] = v[4] == 'true'
conn_line[line_label]["adj1"] = v[1]
conn_line[line_label]["tow1"] = v[3]
else
conn_line[line_label]["adj2"] = v[1]
conn_line[line_label]["tow2"] = v[3]
end
end
-- sorting by part of and line
local sortingkeys = {}
for k in pairs(conn_line) do
sortingkeys[#sortingkeys + 1] = conn_line[k]["part_label"] .. '<line>' .. k
end
table.sort(sortingkeys,
function(a, b)
local num_a = string.match(mw.text.split(a, '<line>', true)[2], '%d+')
local num_b = string.match(mw.text.split(b, '<line>', true)[2], '%d+')
if num_a and num_b then
local part_a = mw.text.split(a, '<line>', true)[1]
local part_b = mw.text.split(b, '<line>', true)[1]
return part_a .. string.format("%04d", num_a) < part_b .. string.format("%04d", num_b)
else
return a < b
end
end)
-- fill a sorted table to format
local ret_table = {}
for i, v in ipairs(sortingkeys) do
local v_line = mw.text.split(v, '<line>', true)[2]
ret_table[i] = {['line'] = conn_line[v_line]['line'],
['part'] = conn_line[v_line]['part'], ['interchange'] = conn_line[v_line]['interchange'],
['adjacent1'] = conn_line[v_line]["adj1"], ['towards1'] = conn_line[v_line]["tow1"],
['adjacent2'] = conn_line[v_line]["adj2"] or terminus, ['towards2'] = conn_line[v_line]["tow2"] or ''}
end
return require('Module:Railway/format').station(ret_table)
end
function p.station(frame)
local args = require('Module:Arguments').getArgs(frame)
return p._station(args)
end
return p