Module:Sandbox/Szqecs/L-rail

From WikiProjectMed
Jump to navigation Jump to search
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 '<div style="font-size: smaller; font-style: italic">' .. s .. '</div>'
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][1]['system title'],
				'\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][args.line[v]]
			lineTitle[v] = _line['line title']
			colour[v] = _line.colour
			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 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 1]
			end
			
			local function station(s)
				if _line['station link'] then
					return _line['station link'][s] or data[v][1]['station link'][s] or mw.ustring.gsub(_line['station link'][1] or data[v][1]['station link'][1], '%%s', s)
				else
					return data[v][1]['station link'][s] or mw.ustring.gsub(data[v][1]['station link'][1], '%%s', s)
				end
			end
			
			if not args.left[v] then
				left[v] = "''Terminus''"
				leftTerminus[v] = ''
			elseif args.left[v] == _leftTerminus then
				left[v] = station(args.left[v])
				leftTerminus[v] = subFormat('Terminus')
			else
				left[v] = station(args.left[v])
				if args.onewayL[v] == true then
					leftTerminus[v] = subFormat('One-way operation')
				else
					leftTerminus[v] = subFormat('towards ' .. station(_leftTerminus))
				end
			end
			
			if not args.right[v] then
				right[v] = "''Terminus''"
				rightTerminus[v] = ''
			elseif args.right[v] == _rightTerminus then
				right[v] = station(args.right[v])
				rightTerminus[v] = subFormat('Terminus')
			else
				right[v] = station(args.right[v])
				if args.onewayR[v] == true then
					rightTerminus[v] = subFormat('One-way operation')
				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], '<div style="font-size: smaller">', note[v], '</div>',
				'\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
			local tmp = i+4
			t[i+4] = ''
			local rowspan = 2
			while t[tmp] == t[tmp+4] do
				t[tmp+4] = ''
				rowspan = rowspan+1
				tmp = tmp+4
			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-2, 4 do combine(t, i) end
	for i = 3, max-1, 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 = {},
		TypeL = {},
		TypeR = {},
		note = {},
		onewayL = {},
		onewayR = {},
		circular = {},
		circularL = {},
		circularR = {}
	}
	
	local _index = {}
	for k, v in pairs(_args) do
		local a = string.match(k, '(%a+)%d+')
		if not a then
			a = k
		end
		local b = tonumber(string.match(k, '%a+(%d+)'))
		if not b then
			b = 1
		end
		
		if a == 'system' then
			args.system[b] = v
			_index[b] = true
		elseif a == 'line' then
			args.line[b] = v
			_index[b] = true
		elseif a == 'left' then
			args.left[b] = v
			_index[b] = true
		elseif a == 'right' then
			args.right[b] = v
			_index[b] = true
		elseif a == 'typeL' then
			args.TypeL[b] = v
		elseif a == 'typeR' then
			args.TypeR[b] = v
		elseif a == 'note' then
			args.note[b] = v
		elseif a == 'onewayL' then
			args.onewayL[b] = yesno(v)
		elseif a == 'onewayR' then
			args.onewayR[b] = yesno(v)
		elseif a == 'circular' then
			args.circular[b] = yesno(v)
		elseif a == 'circularL' then
			args.circularL[b] = yesno(v)
		elseif a == 'circularR' then
			args.circularR[b] = yesno(v)
		elseif a == 'throughL' then
			args.throughL = yesno(v)
		elseif a == 'throughR' then
			args.throughR = yesno(v)
		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:Sandbox/Szqecs/L-rail/' .. args.system[v])
		else
			data[v] = data[index[i-1]]
		end
	end
	
	local rows = { -- To be removed. Included for backwards compatibility.
		['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