跳转到内容

模組:重庆轨道交通

本页使用了标题或全文手工转换
维基百科,自由的百科全书

local p = {}

local _adj = require('Module:Adjacent stations')
local _data = require('Module:Adjacent stations/重庆轨道交通')

---@type fun(frame: frame, options: { trim: boolean?, removeBlanks: boolean?, valueFunc: (fun(key: any, value: any): any)?, frameOnly: boolean?, parentOnly: boolean?, parentFirst: boolean?, wrappers: string[]?, readOnly: boolean?, noOverwrite: boolean? }?): { [string]: string }
local _args = require('Module:Arguments').getArgs
local _navbox = require("Module:Navbox")._navbox
local _list = require('Module:list').makeList

local function makeInvokeFunction(funcName)
    return function(frame)
        local args = _args(frame, { parentOnly = true })
        return p[funcName](args, frame)
    end
end

local operational = {
    '0', '1', '2', '3', '4', '5', '江跳', '6', '9', '10', '18', '璧铜'
}

local construction = {
    '7', '15', '17', '24', '27', --'永川'
}

local projected = {
    '8', '12', '21'
}

local branch = {
    ['3'] = { 'a' },
    ['6'] = { 'i' },
}

local binds = {
    ['5'] = { '江跳' },
    ['江跳'] = { '5' },
    -- ['27'] = { '璧铜' },
    -- ['璧铜'] = { '27' },
}

---@param link string
---@return string
local function delinkLabel(link)
    if link:match("|") then
        return link:match("^%[%[.-|(.+)%]%]"):gsub("\n", "")
    else
        return link:match("^%[%[(.-)%]%]")
    end
end

---@param link string
---@return string
local function delinkTarget(link)
    if link:match("|") then
        return link:match("^%[%[(.-)|.*%]%]")
    else
        return link:match("^%[%[(.-)%]%]")
    end
end

---@param line string
---@return string, string?
local function parseCode(line)
    if line == '空港' or line == '3a' or line == '3z' then
        return '3', 'a'
    elseif line == '国博' or line == '6i' or line == '6z' then
        return '6', 'i'
    else
        return line, nil
    end
end

---@param frame frame
---@param l string
---@param t string?
---@return string
local function lineColor(frame, l, t)
    return '#' .. _adj._color({ '重庆轨道交通', l, t, data = _data }, frame)
end

---@param frame frame
---@param l string
---@param t string?
local function lineLink(frame, l, t)
    if l == '3' and t == 'a' then
        return '[[重庆轨道交通空港线|空港线]]'
    elseif l == '6' and t == 'i' then
        return '[[重庆轨道交通国博线|国博线]]'
    else
        return _adj._line({ '重庆轨道交通', l, t, data = _data }, frame)
    end
end

---@param frame frame
---@param l string
---@param t string?
local function lineLongLink(frame, l, t)
    return '[[' .. delinkTarget(lineLink(frame, l, t)) .. ']]'
end

---@param frame frame
---@param l string
---@param t string?
local function lineName(frame, l, t)
    return delinkLabel(lineLink(frame, l, t))
end

---@param frame frame
---@param l string
---@param t string?
local function lineLongName(frame, l, t)
    return delinkTarget(lineLink(frame, l, t))
end

---@param l string
---@param t string?
---@return boolean?
local function isNumeric(l, t)
    local num = tonumber(l)
    return num and num > 0 and not ((l == '3' and t == 'a') or (l == '6' and t == 'i'))
end

--#region [[Template:重庆轨道交通线路名]]

---@param frame frame
---@param code string
---@param nxt string
---@param style string
---@param inline 'force'?
---@param is_head boolean
---@return string
local function line(frame, code, nxt, style, inline, is_head)
    local l0, t0 = parseCode(code)
    local l1, t1
    if nxt then
        l1, t1 = parseCode(nxt)
    end
    if style == 'route' then
        return _adj._box({ '重庆轨道交通', l0, 'route', type = t0, data = _data }, frame)
    else
        local item = {}

        local color = lineColor(frame, l0, t0)
        if style == 'square' then
            table.insert(item,
                '<span class="crt-line-link-square" style="--line-color: ' .. color .. '">')
        else
            local i = inline or (not is_head and style ~= 'full')
            table.insert(item,
                '<span class="crt-line-link-' .. (i and 'inline' or 'default') ..
                '" style="border-left-color: ' .. color .. '"><span style="user-select:none;">&zwj;</span>')
        end

        if style == 'plain' then
            local compressed = nxt ~= nil and isNumeric(l0, t0) == isNumeric(l1, t1)
            local name = lineName(frame, l0, t0)
            if compressed then
                name = mw.ustring.gsub(name, '[号號支]?[线綫線]$', '')
            else
                name = mw.ustring.gsub(name, '支', '')
            end
            table.insert(item, name)
        elseif style == 'full' then
            table.insert(item, lineLongLink(frame, l0, t0))
        else
            table.insert(item, lineLink(frame, l0, t0))
        end

        table.insert(item, '</span>')
        return table.concat(item)
    end
end

---@param frame frame
---@param codes string
---@param style string
---@param inline 'force'?
---@return string
local function line_list(frame, codes, style, inline)
    local codes = mw.text.split(codes, '%s')
    local result = {}

    if style == 'r' or style == 'c' then
        style = 'route'
    elseif style == 's' then
        style = 'square'
    elseif style == 'f' or style == 'l' or style == 'long' then
        style = 'full'
    elseif style == 'p' or style == 'i' or style == 'inline' then
        style = 'plain'
    end

    for i = 1, #codes do
        result[i] = line(frame, codes[i], codes[i + 1], style, inline, i == 1)
    end

    if style == 'r' or style == 'route' or style == 'c' then
        return table.concat(result, ' ')
    elseif style == 's' or style == 'square' then
        if #result > 1 then
            result['class'] = 'inline'
            return _list('horizontal', result)
        else
            return result[1]
        end
    elseif style == 'f' or style == 'full' or style == 'l' or style == 'long' then
        return table.concat(result, '<br/>')
    else
        return table.concat(result, '<span class="crt-line-link-comma">、</span>')
    end
end

---@param frame frame
---@return string
function p.line_list(frame)
    local args = frame.args
    return line_list(frame, args[1], args[2], args['inline'])
end

--#endregion

--#region [[Template:重庆轨道交通线路]]

---@param frame frame
---@param l string
---@return string
local function stations(frame, l)
    if branch[l] then
        local subgroup_args = {
            'subgroup',
            groupstyle = 'background: var(--background-color-neutral, #eaecf0); width: 4em; text-align: center;',
            navbar     = 'plain',
            liststyle  = 'width: auto;',
            list0      = frame:expandTemplate { title = '重庆轨道交通车站/' .. lineName(frame, l) }
        }
        for i, b in ipairs(branch[l]) do
            local b_name = lineName(frame, l, b)
            b_name = mw.ustring.gsub(b_name, '支', '')
            subgroup_args['group' .. i] = b_name
            subgroup_args['list' .. i] = frame:expandTemplate { title = '重庆轨道交通车站/' .. b_name }
        end
        return _navbox(subgroup_args)
    else
        return frame:expandTemplate { title = '重庆轨道交通车站/' .. lineName(frame, l) }
    end
end

---@param color string
---@return string
local function navbox_title_border(color)
    return '-moz-box-shadow: inset calc(-1em/3) 0 0 0 ' .. color ..
        '; -webkit-box-shadow: inset calc(-1em/3) 0 0 0 ' .. color ..
        '; box-shadow: inset calc(-1em/3) 0 0 0 ' .. color .. ';'
end

---@param frame frame
---@param args { [string]: string }
---@param list string[]
local function build_navbox_groups(frame, args, list)
    for i, l in ipairs(list) do
        args['group' .. i .. 'style'] = navbox_title_border(lineColor(frame, l))
        args['group' .. i] = lineLink(frame, l)
        args['list' .. i] = stations(frame, l)
    end
end

---@param frame frame
---@return string
function p.navbox(frame)
    -- Scan args
    local args = _args(frame)
    local flags = {}
    for _, v in ipairs(args) do
        flags[mw.ustring.lower(v)] = true
    end
    local num_int = 0
    local num_arg = 0
    local single = ''
    local cats = {}

    ---@type string[]
    local list_o = {}
    ---@type string[]
    local list_c = {}
    ---@type string[]
    local list_p = {}

    if flags.construction or flags.projected then
        list_o = operational
        list_c = construction
        list_p = projected
    else
        for alias, l in pairs(_data.aliases) do
            if flags[alias] then
                flags[alias] = nil
                flags[l] = '1'
            end
        end

        for _, l in ipairs(operational) do
            if flags[l] then
                table.insert(list_o, l)
                num_int = num_int + 1
                num_arg = num_arg + 1
                single = l
                if not flags.nocat then
                    table.insert(cats, '[[Category:' .. lineLongName(frame, l) .. '车站]]')
                end
                if binds[l] then
                    for _, b in ipairs(binds[l]) do
                        if flags[b] == nil then
                            table.insert(list_o, b)
                            num_arg = num_arg + 1
                        end
                    end
                end
            end
        end
        for _, l in ipairs(construction) do
            if flags[l] then
                table.insert(list_c, l)
                num_arg = num_arg + 1
                single = l
                if not flags.nocat then
                    table.insert(cats, '[[Category:' .. lineLongName(frame, l) .. '车站]]')
                end
            end
        end
        for _, l in ipairs(projected) do
            if flags[l] then
                table.insert(list_p, l)
                num_arg = num_arg + 1
                single = l
                if not flags.nocat then
                    table.insert(cats, '[[Category:' .. lineLongName(frame, l) .. '车站]]')
                end
            end
        end
        if num_arg == 0 then
            list_o = operational
            list_c = construction
            list_p = projected
        end
    end

    -- Build navbox
    local navbox_args = {
        name       = '重庆轨道交通车站',
        state      = args.state or 'autocollapse',
        bodystyle  = 'width: 100%; vertical-align: middle;',
        titlestyle = 'background: #00843d; color: white;',
        groupstyle = 'background: var(--background-color-neutral, #eaecf0); color: inherit; width: 4em; text-align: center;',
        liststyle  = 'width: auto;'
    }

    if flags.construction or flags.projected then
        if flags.construction then
            navbox_args.title =
            '[[重庆轨道交通|<span style="color:white">重庆轨道交通</span>]]在建线路[[重庆轨道交通车站列表|<span style="color:white">车站</span>]]'
            build_navbox_groups(frame, navbox_args, list_c)
        else
            navbox_args.title =
            '[[重庆轨道交通|<span style="color:white">重庆轨道交通</span>]]规划线路[[重庆轨道交通车站列表|<span style="color:white">车站</span>]]'
            build_navbox_groups(frame, navbox_args, list_p)
        end
    else
        if num_arg > 0 then
            navbox_args.state = args.state or 'expanded'
            if num_int > 1 and not flags.nocat then
                table.insert(cats, '[[Category:重庆轨道交通换乘车站|' .. num_int .. ']]')
            end
        end
        if num_arg == 1 then
            local name = lineLongName(frame, single)
            local color = lineColor(frame, single)
            local contrast = _data.lines[single]['text color'] == '000000' and 'var(--color-base, #000000)' or '#ffffff'
            navbox_args.name = '重庆轨道交通车站/' .. lineName(frame, single)
            navbox_args.title = '[[' .. name .. '|<span style="color: ' .. contrast .. '">' .. name .. '</span>]]车站'
            navbox_args.titlestyle = 'background: ' .. color .. '; color: ' .. contrast
            navbox_args.list0 = stations(frame, single)
        else
            navbox_args.title =
            '[[重庆轨道交通|<span style="color:white">重庆轨道交通</span>]][[重庆轨道交通车站列表|<span style="color:white">车站</span>]]'
            build_navbox_groups(frame, navbox_args, list_o)
            local i = #list_o + 1
            if #list_c > 0 then
                local child_args = {
                    'child',
                    navbar     = 'plain',
                    title      = '在建线路',
                    titlestyle = 'background: var(--background-color-neutral, #eaecf0); color: var(--color-subtle, #54595d);',
                    groupstyle = 'background: var(--background-color-neutral, #eaecf0); color: inherit; width: 4em; text-align: center;',
                    liststyle  = 'width: auto;'
                }
                build_navbox_groups(frame, child_args, list_c)
                if num_arg > 0 then
                    child_args.state = 'expanded'
                end
                navbox_args['list' .. i] = _navbox(child_args)
                i = i + 1
            end
            if #list_p > 0 then
                local child_args = {
                    'child',
                    navbar     = 'plain',
                    title      = '规划线路',
                    titlestyle =
                    'background: var(--background-color-neutral, #eaecf0); color: var(--color-subtle, #54595d);',
                    groupstyle = 'background: var(--background-color-neutral, #eaecf0); color: inherit; width: 4em; text-align: center;',
                    liststyle  = 'width: auto;'
                }
                build_navbox_groups(frame, child_args, list_p)
                if num_arg > 0 then
                    child_args.state = 'expanded'
                end
                navbox_args['list' .. i] = _navbox(child_args)
                i = i + 1
            end
        end
    end

    return _navbox(navbox_args) .. table.concat(cats)
end

--#endregion

--#region [[Template:重庆轨道交通出入口]]

function p._exit_list(args, frame)
    local lines = mw.text.split(mw.text.trim(args[1]), '\n')
    local rows = {}
    local has_closed = false
    local has_photo = false
    local unknown_args = false

    for i, line in ipairs(lines) do
        local props      = mw.text.split(line, '%s*\\%s*')
        rows[i]          = {}
        rows[i]['index'] = mw.text.trim(props[1])
        rows[i]['line']  = mw.text.trim(props[2] or '')
        if props[2] and props[2] ~= '' then
            rows[i]['rowspan'] = 1
        end
        rows[i]['tags']    = mw.text.trim(props[3] or '')
        rows[i]['loc']     = mw.text.trim(props[4] or '')
        rows[i]['targets'] = mw.text.split(mw.text.trim(props[5] or ''), ',')
        if props[6] and mw.text.trim(props[6]) ~= '' then
            rows[i]['photo'] = mw.text.trim(props[6])
            has_photo = true
        end
        rows[i]['ref'] = mw.text.trim(props[7] or '')
    end

    for i = #rows - 1, 1, -1 do
        if rows[i].line and rows[i].line ~= '' and rows[i].line == rows[i + 1].line then
            rows[i].rowspan = rows[i].rowspan + rows[i + 1].rowspan
            rows[i + 1].rowspan = 0
        end
    end

    for i, row in ipairs(rows) do
        local result = { '|-' }
        if mw.ustring.find(row.tags, 'c') then
            table.insert(result,
                ' aria-describedby="crt-exit-closed" class="closed"')
            has_closed = true
        end

        table.insert(result, '\n|')

        if row.line and row.line ~= '' and row.rowspan > 0 then
            if (row.rowspan > 1) then
                table.insert(result, 'rowspan=' .. row.rowspan)
            end

            local fill
            if mw.ustring.find(row.line, ',') then
                local lines = mw.text.split(row.line, ',')
                fill = { 'repeating-linear-gradient(135deg' }
                local offset = 0
                for j, line in ipairs(lines) do
                    local color = lineColor(frame, line)
                    table.insert(fill, ', ' .. color .. ' ' .. offset .. 'em')
                    offset = offset + .5
                    table.insert(fill, ', ' .. color .. ' ' .. offset .. 'em')
                end
                table.insert(fill, ')')
                fill = table.concat(fill)
            else
                fill = lineColor(frame, row.line)
            end
            table.insert(
                result,
                ' style="width: 0.5em; padding: 0; background: ' .. fill .. '" |\n')
        elseif row.line == nil or row.line == '' then
            table.insert(result, ' colspan=2 ')
        end

        table.insert(result, '| ' .. frame:expandTemplate { title = '重庆轨道交通出口标志', args = { row.index } })
        if mw.ustring.find(row.tags, 'r') then
            table.insert(result, '&emsp14;[[File:CRT Toilet.svg|x24px|卫生间|link=]]')
        end
        if mw.ustring.find(row.tags, 'A') then
            table.insert(result, '&emsp14;[[File:CRT Accessible Ramp.svg|x24px|无障碍坡道|link=]]')
        end
        if mw.ustring.find(row.tags, 'L') then
            table.insert(result, '&emsp14;[[File:CRT Accessible Elevator-platform.svg|x24px|无障碍升降台|link=]]')
        end
        if mw.ustring.find(row.tags, 'E') then
            table.insert(result, '&emsp14;[[File:CRT Elevator.svg|x24px|无障碍电梯|link=]]')
        end
        -- if mw.ustring.find(row.tags, 't') or mw.ustring.find(row.tags, 'a') then -- 追踪兼容参数
        -- 	unknown_args = true
        -- end
        table.insert(result, row.ref .. '\n')

        if has_photo then
            if row.photo then
                table.insert(result, '| [[File:' .. row.photo .. '|140px]]\n')
            else
                table.insert(result, '|\n')
            end
        end

        table.insert(result, '| ' .. row.loc .. '\n')

        if row.targets then
            table.insert(result, '| ' .. _list('horizontal', row.targets) .. '\n')
        else
            table.insert(result, '| \n')
        end

        rows[i] = table.concat(result)
    end

    if has_closed then
        table.insert(rows, [[
|- style="font-size: small; text-align: center"
| colspan=]] .. (has_photo and '5' or '4') .. [[| <span id="crt-exit-closed" class="closed-note">未开通</span>
]])
    end

    return [[
{| class="wikitable crt-exit-list"
|- style="text-align: center; vertical-align: middle"
! style="min-width: 3em" colspan=2 | 出入口
]]
        .. (has_photo and '! 照片\n' or '') .. [[
! style="min-width: 4em" | 位置
! style="min-width: 9em" | 目的地
]] .. table.concat(rows) .. '\n|}' .. (unknown_args and '[[Category:在重庆轨道交通出入口使用未知参数的条目]]' or '')
end

p.exit_list = makeInvokeFunction('_exit_list')

--#endregion

return p