이 모듈에 대한 설명문서는 모듈:Arguments/설명문서에서 만들 수 있습니다
-- Module:StationLayout
local p = {}
local getArgs = require('Module:Arguments').getArgs
local html = mw.html
----------------------------------------------------------------------
-- 유틸
----------------------------------------------------------------------
local function split(list, sep)
sep = sep or ','
local out = {}
for item in mw.text.gsplit(list or '', sep, true) do
if item and item ~= '' then table.insert(out, mw.text.trim(item)) end
end
return out
end
local function makeColorCell(num, color, inner)
local cell = html.create('th')
:attr('scope', 'col')
:css{width = '25px', ['font-weight']='normal'}
:wikitext(inner and inner or num)
if color then
if color:match('자동다크') then
color = '{{자동다크|' .. color:gsub('자동다크,?', '') .. '}}'
end
cell
:cssText('background:' .. color .. '; color:#fff;')
end
return cell
end
----------------------------------------------------------------------
-- 상단 "선로 번호 가이드" 테이블
----------------------------------------------------------------------
local function buildTrackGuide(tracks, up, down)
local tbl = html.create('table')
:addClass('wikitable')
:css{width='125px', ['margin-left']='0'}
tbl:tag('tr')
:tag('th')
:attr('colspan', #tracks * 2 + 1)
:css('font-weight', 'normal')
:wikitext(up)
local row = tbl:tag('tr')
-- 왼쪽 완충벽
row:node(makeColorCell('|'))
for _, spec in ipairs(tracks) do
local num, color = spec.num, spec.color
row:node(makeColorCell(num, color, num))
-- 선로 사이 구분벽
row:node(makeColorCell('|'))
end
tbl:tag('tr')
:tag('th')
:attr('colspan', #tracks * 2 + 1)
:css('font-weight', 'normal')
:wikitext(down)
return tostring(tbl)
end
----------------------------------------------------------------------
-- 본문 행(row) 테이블
----------------------------------------------------------------------
local function buildMainTable(rows)
local tbl = html.create('table')
:addClass('wikitable')
for _, r in ipairs(rows) do
-- r = {range, line, icons, dest}
local tr = tbl:tag('tr')
local rangeText = r.range:gsub('-', '·') -- 3-4 → 3·4
local first, last = rangeText:match('^(%d+)·?(%d*)$')
local rowspan = 1
if last and last ~= '' and tonumber(last) > tonumber(first) then
rowspan = tonumber(last) - tonumber(first) + 1
end
tr:tag('th')
:attr('rowspan', rowspan)
:css{width='25px', background='{{자동다크|#808080}}',
color='#fff', ['font-weight']='normal'}
:wikitext(rangeText)
tr:tag('td')
:css{['min-width']='7em', ['text-align']='left', ['font-weight']='normal'}
:wikitext(r.line)
tr:tag('td')
:css{['min-width']='5em', ['text-align']='center', ['font-weight']='normal'}
:wikitext(r.icons)
tr:tag('td')
:css{['min-width']='7em', ['text-align']='left', ['font-weight']='normal'}
:wikitext(r.dest)
end
return tostring(tbl)
end
----------------------------------------------------------------------
-- 파서
----------------------------------------------------------------------
local function parseTracks(arg)
local list = split(arg or '')
local tracks = {}
for _, item in ipairs(list) do
local num, clr = item:match('^([%d%-]+)%s*%(([^%)]*)%)')
if not num then num, clr = item, nil end
table.insert(tracks, {num = num, color = clr})
end
return tracks
end
local function parseRows(args)
local rows = {}
for k, v in pairs(args) do
if k:match('^row%d+') then
local parts = split(v, ';')
table.insert(rows, {
range = parts[1] or '',
line = parts[2] or '',
icons = parts[3] or '',
dest = parts[4] or ''
})
end
end
-- 원래 입력 순서를 유지하기 위해 sort
table.sort(rows, function(a, b) return a.range < b.range end)
return rows
end
----------------------------------------------------------------------
-- 메인 엔트리
----------------------------------------------------------------------
function p.main(frame)
local args = getArgs(frame, {trim=true, removeBlanks=false})
local top = args.top or ''
local bottom = args.bottom or ''
local trackSpec = parseTracks(args.tracks)
local rows = parseRows(args)
local out = {}
table.insert(out, buildTrackGuide(trackSpec, top, bottom))
table.insert(out, buildMainTable(rows))
return table.concat(out, '\n')
end
return p