Modulu:Railway

Wikipedia, Entziklopedia askea

Documentation for this module may be created at Modulu:Railway/dok

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=]]&nbsp;'
				})
			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']) 
						.. ';">&nbsp;</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