이 모듈에 대한 설명문서는 모듈: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