Module:Adjacent stations

local getArgs = require('Module:Arguments').getArgs local p, data, lineData = {}

local function dig(...) -- Digs through a table with sub-tables using arguments as keys, returning the value of the last key argument -- Analogous to returning a file given a file path with sub-folders -- Returns nil if any given sub-table does not exist local arg = {...} local a, i, n = arg[1], 1, select('#', ...) while a and i < n do		a = a[arg[i + 1]] i = i + 1 end if i == n then return a end end

local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame) if funcName ~= '_main' then local t = mw.title.new('Module:Adjacent stations/' .. (args.system or args[1])) data = t.exists and mw.loadData('Module:Adjacent stations/' .. (args.system or args[1])) if funcName ~= '_station' and (args.line or args[2]) then lineData = dig(data, 'lines', args.line or args[2]) or					dig(data, 'lines', dig(data, 'aliases', string.lower(args.line or args[2]))) end end return p[funcName](args, frame) end end

p.main = makeInvokeFunc('_main') function p._main(args) local renderSuccessionBox = require('Module:Adjacent stations/renderSuccessionBox') return renderSuccessionBox(args) end

p.station = makeInvokeFunc('_station') function p._station(args, frame) local station = args.station or args[2] if station then if data then local stationFormat = data['station format'] or error(i18n[lang]['error_format']) local link = stationFormat[station] or stationFormat[1] return string.match(link, '%[%[.+%]%]') and (string.gsub(link, '%%1', station)) or				table.concat({, station, }) else return frame:expandTemplate{ title = (args.system or args[1]) .. ' stations', args = { ['station'] = station, ['line'] = args.line or args[3], ['branch'] = args['type'] or args[4] }			}		end end end

p.line = makeInvokeFunc('_line') function p._line(args, frame) if data then if args['type'] or args[3] then local typ = dig(lineData, 'types', args['type'] or args[3], 'title') return table.concat({lineData['title'], ' (', typ, ')'}) else return lineData and lineData['title'] or				(string.gsub(dig(data, 'lines', '_default', 'title'), '%%1', args.line or args[2] or '_default')) end else return frame:expandTemplate{ title = (args.system or args[1]) .. ' stations', args = { args.line or args[2], ['branch'] = args['type'] or args[3] }		}	end end

p.color = makeInvokeFunc('_color') function p._color(args, frame) if data then return dig(lineData, 'types', args['type'] or args[3], 'color') or			lineData and lineData['color'] or			dig(data, 'lines', '_default', 'color') else return frame:expandTemplate{ title = (args.system or args[1]) .. ' color', args = { args.line or args[2], ['branch'] = args['type'] or args[3] }		}	end end

p.icon = makeInvokeFunc('_icon') function p._icon(args) return dig(lineData, 'types', args['type'] or args[3], 'icon') or		lineData and lineData['icon'] or		data['system icon'] end

p.box = makeInvokeFunc('_box') function p._box(args) local colour, root = p._color(args), mw.html.create('div') local style = args.style or args.inline local typeData = dig(lineData, 'types', args['type'] or args[3]) if colour then colour = string.match(colour, '#') and colour or '#' .. colour end local linkedBox = style == 'link' or		style == 'ldot' or		style == 'lsquare' or		style and string.match(style, 'route') if linkedBox then root :wikitext(string.match(p._line(args), '%[%[.+|')) end local box = root:tag('span') if style == 'dot' or		style == 'ldot' or		style == 'square' or		style == 'lsquare' then box :css('line-height', 'initial') end if style == 'dot' or		style == 'ldot' or		style == 'square' or		style == 'lsquare' or		style == 'xroute' then box :css('color', colour) else box :css('background-color', colour) end if style == nil or		style == 'link' or		style == 'inline' or style == 'yes' or		style == 'box' then box :css('border', '1px solid #000') elseif style and string.match(style, 'route') then local borderColour = typeData and typeData['border color'] or lineData and lineData['border color'] or colour box :css('border', '.075em solid ' .. borderColour) :css('padding', '0 .3em') if style ~= 'route' then box :css('border-radius', '.5em') end end if style == 'dot' or style == 'ldot' then box:wikitext('●') elseif style == 'square' or style == 'lsquare' then box:wikitext('■') elseif style and string.match(style, 'route') then box :css('color',				typeData and typeData['text color'] or				lineData and lineData['text color'] or				style == 'xroute' and colour or				'black'			) :css('font-weight', args.bold == 'no' or 'bold') :css('font-size', 'inherit') :css('white-space', 'nowrap') :wikitext(args.line or args[2]) else box :wikitext(string.rep(' ', style == 'small' and 1 or 4)) end if linkedBox then root:wikitext(']]') end if style == nil or		style == 'inline' or style == 'yes' or		style == 'small' or		style == 'dot' or		style == 'square' then root :wikitext(' ', p._line(args)) end return root end

return p