Module:Adjacent stations

local yesno = require("Module:Yesno") local _style = { ['3'] = 'style="width: 30%;',	['c'] = 'style="text-align: center;', ['v'] = 'vertical-align: middle;', ['bd'] = 'border:', ['t'] = 'border-top:', ['bb'] = 'border-bottom:', ['L'] = 'border-left:', ['R'] = 'border-right:', ['n'] = 'none;', ['0'] = '0px none;', ['1'] = '1px solid #aaa;' } local style = { ['table'] = table.concat({'style="width: 55%; max-width: 50em; margin:0.5em auto; font-size:95%; clear:both;',		_style['t'], _style['0'],		'border-collapse: separate;" cellspacing="0" cellpadding="-1"'	}), ['header leftcell'] = table.concat({_style['3'], _style['v'],		_style['bd'], _style['1'],		_style['L'], _style['n'],		_style['bb'], _style['n'],		'"|'	}),	['header banner'] = table.concat({'style="',		_style['bd'], _style['n'],		_style['t'], _style['1'],		'"|'	}),	['header midcell'] = table.concat({'colspan="3" style="', _style['v'],		_style['bd'], _style['n'],		_style['t'], _style['1'],		'"|'	}),	['header rightcell'] = table.concat({_style['3'], _style['v'],		_style['bd'], _style['1'],		_style['R'], _style['n'],		_style['bb'], _style['n'],		'"|'	}), ['body leftcell'] = table.concat({_style['c'], _style['v'],		_style['L'], _style['0'],		_style['bb'], _style['0'],		_style['R'], _style['1'],		_style['t'], _style['1'],		'"|'	}),	['body banner'] = table.concat({_style['c'],		_style['L'], _style['0'],		_style['bb'], _style['0'],		_style['R'], _style['0'],		_style['t'], _style['1'],		'width: 8px; min-width: 8px; background-color: #'	}),	['body midcell'] = table.concat({_style['c'], _style['v'],		_style['bb'], _style['0'],		'"|'	}), ['body rightcell'] = table.concat({_style['c'], _style['v'],		_style['L'], _style['1'],		_style['bb'], _style['0'],		_style['R'], _style['0'],		_style['t'], _style['1'],		'"|'	}) }

local function subFormat(s) return ' ' .. s .. ' ' end

local p = {}

function p.top return table.concat({'{| class="wikitable" ', style['table']}) end

function p.line(args, index, data) local lineTitle = {} local colour = {} local left = {} local right = {} local note = {} local leftTerminus = {} local rightTerminus = {} local t = {} for i, v in ipairs(index) do		if args.system[v] then table.insert(t, table.concat({'\n|-', '\n!', style['header leftcell'], 'Preceding station', '\n!', style['header midcell'], (data[v]['system title'] or (..args.system[v]..)), '\n!', style['header rightcell'], 'Following station' }))			table.insert(t, '') table.insert(t, '') table.insert(t, '') end if args.line[v] or args.left[v] or args.right[v] then if not args.line[v] then args.line[v] = args.line[index[i-1]] end local _line = data[v]['lines'][args.line[v]] lineTitle[v] = _line['line title'] colour[v] = _line.colour or _line.color note[v] = args.note[v] or '' if type(_line['left terminus']) == 'string' then _leftTerminus = _line['left terminus'] elseif type(_line['left terminus']) == 'table' then _leftTerminus = _line['left terminus'][args.TypeL[v] or args.Type[v] or 1] end if type(_line['right terminus']) == 'string' then _rightTerminus = _line['right terminus'] elseif type(_line['right terminus']) == 'table' then _rightTerminus = _line['right terminus'][args.TypeR[v] or args.Type[v] or 1] end local function station(var) local function subst(s) if s then if string.match(s, '%[%[') then return mw.ustring.gsub(s, '%%1', var) elseif type(var) == 'string' then return table.concat({, var, }) elseif type(var) == 'table' and #var > 0 then local function _subst(k) return table.concat({mw.ustring.gsub(s, '%%1', var[k]), '|', var[k]}) end local t = {} t[1] = table.concat({, _subst(1), }) for i = 2, #var - 1 do								t[i] = table.concat({', ', _subst(i), ''}) end if #var > 1 then t[#var] = table.concat({' or ', _subst('}) end if var['via'] then t[#var + 1] = table.concat({' via ', _subst('via'), ''}) end return table.concat(t) end end end if data[v]['station format'] then return subst(data[v]['station format'][var] or data[v]['station format'][1]) or '' else return var or '' end end if not args.left[v] then left[v] = "Terminus" leftTerminus[v] = '' else left[v] = station(args.left[v]) if args.onewayL[v] == true then leftTerminus[v] = subFormat('One-way operation') elseif args.left[v] == _leftTerminus then leftTerminus[v] = subFormat('Terminus') else leftTerminus[v] = subFormat('towards ' .. station(_leftTerminus)) end end if not args.right[v] then right[v] = "Terminus" rightTerminus[v] = '' else right[v] = station(args.right[v]) if args.onewayR[v] == true then rightTerminus[v] = subFormat('One-way operation') elseif args.right[v] == _rightTerminus then rightTerminus[v] = subFormat('Terminus') else rightTerminus[v] = subFormat('towards ' .. station(_rightTerminus)) end end table.insert(t, '\n|-') table.insert(t, table.concat({'\n|', style['body leftcell'], left[v], leftTerminus[v]})) table.insert(t, table.concat({'\n|', style['body banner'], colour[v], '"|',				'\n|', style['body midcell'], lineTitle[v], ' ', note[v], ' ',				'\n|', style['body banner'], colour[v], '"|'})) table.insert(t, table.concat({'\n|', style['body rightcell'], right[v], rightTerminus[v]})) end end local function combine(t, i)		if t[i + 4] ~= '' and t[i + 4] == t[i] then t[i + 4] = '' -- The cell in the next row is deleted local rowspan = 2 while t[i + rowspan * 4] == t[i] do				t[i + rowspan * 4] = '' rowspan = rowspan + 1 end t[i] = mw.ustring.gsub(t[i], '\n|style="', table.concat({'\n|rowspan="', rowspan, '" style="'})) end end local max = #t for i = 2, max, 4 do combine(t, i) end for i = 3, max, 4 do combine(t, i) end for i = 4, max, 4 do combine(t, i) end return table.concat(t) end

function p.bottom return '\n|}' end

function p.main(frame) local _args = frame:getParent.args local args = { system = {}, line = {}, left = {}, right = {}, Type = {}, TypeL = {}, TypeR = {}, note = {}, onewayL = {}, onewayR = {}, circular = {}, circularL = {}, circularR = {} }

local _index = {} local parameters = { ['strings'] = { ['system'] = 'system', ['line'] = 'line', ['left'] = 'left', ['right'] = 'right' },		['optional strings'] = { ['note-mid'] = 'note', ['type'] = 'Type', ['type-left'] = 'TypeL', ['type-right'] = 'TypeR', --			['through'] = 'through', -- The way this would work is that it would replace either "Terminus" cell, rather than just one of them in particular. --			['through-left'] = 'throughL', --			['through-right'] = 'throughR', --			['branch'] = 'branch', --			['transfer'] = 'transfer' },		['optional boolean'] = { ['oneway-left'] = 'onewayL', ['oneway-right'] = 'onewayR', --			['round-left'] = 'roundL', --			['round-right'] = 'roundR', ['circular'] = 'circular', ['circular-left'] = 'circularL', ['circular-right'] = 'circularR', ['through-left'] = 'throughL', ['through-right'] = 'throughR' }	}	for k, v in pairs(_args) do		_args[k] = v:match('^%s*(.-)%s*$') if _args[k] and _args[k] ~= '' then local a = string.match(k, '^(.*%D)%d+$') or k			local b = tonumber(string.match(k, '^.*%D(%d+)$')) or 1 if parameters['strings'][a] then args[parameters['strings'][a]][b] = v				_index[b] = true elseif args[parameters['optional strings'][a]] then args[parameters['optional strings'][a]][b] = v			elseif args[parameters['optional boolean'][a]] then args[parameters['optional boolean'][a]][b] = yesno(v) end end end

local index = {} for k, v in pairs(_index) do		table.insert(index, k)	end table.sort(index) local data = {} for i, v in ipairs(index) do		if args.system[v] then data[v] = require('Module:Adjacent stations/' .. args.system[v]) --			data[v] = require('Module:Adjacent stations/' .. args.system[v] .. '/sandbox') else data[v] = data[index[i-1]] end end local rows = { -- Included for mixed used with S-line. ['all'] = table.concat({p.top, p.line(args, index, data), p.bottom}), ['top'] = table.concat({p.top, p.line(args, index, data)}), ['mid'] = table.concat({p.line(args, index, data)}), ['bottom'] = table.concat({p.line(args, index, data), p.bottom}) }	return rows[_args.rows] or rows['all'] end

return p