Jump to content

Module:PUV stop

From Wikipedia, the free encyclopedia

local Arguments = require('Module:Arguments')
local PUVLine = require('Module:PUV line') -- Load the data from Module:PUV line
local yesno = require('Module:Yesno')
local data = PUVLine.data

local BUS_ROUTES_ARTICLE = "List of bus routes in Metro Manila"
local EDSA_CAROUSEL_ARTICLE = "EDSA Carousel"

local p = {}

local service_keys = {}
for k, _ in pairs(data) do
    service_keys[k] = true
end

local function trim(s)
    return (s:gsub("^%s+", ""):gsub("%s+$", ""))
end

function p.routebox(frame)
    local args = Arguments.getArgs(frame)
    local stop_name = args.name or ""
    local show_rint = yesno(args.icon, true)
    local output = {}

    -- Get all positional arguments
    local service_key = args[1]
    local route_codes = {}
    for _, code in ipairs(args) do
        -- Distinguish between route key and line key
        if code ~= "" and not service_keys[code] then
            if service_key == "bgc" then
                -- Separate letter code and stop number for BGC Bus
                local line_code = code:match("^(%a+)%d%d?$")
                if line_code then
                    table.insert(route_codes, {
                        code = line_code,
                        text = code
                    })
                end
            else
                table.insert(route_codes, {
                    code = code,
                    text = code
                })
            end
        end
    end

    -- Determine list of routes based on first positional argument
    local service_data = data[service_key]

    -- Sort in ascending order
    if #route_codes > 1 then
        table.sort(route_codes, function(a, b)
            local na, nb = tonumber(a.code), tonumber(b.code)
            if na and nb then
                return na < nb
            else
                return tostring(a.code) < tostring(b.code)
            end
        end)
    end

    -- Rail-interchange symbol
    local first_code = route_codes[1] and route_codes[1]["code"] or nil
    local line_data = (service_data and service_data["lines"]) or {}
    local stop_type = (first_code and line_data[first_code] and line_data[first_code]["type"]) or "bus"
    local stop_symbol = (stop_type == "rapid") and "rapid" or "1"

    local rint = ""
    if show_rint then
        rint = frame:expandTemplate{
            title = "rint",
            args = {"bus", stop_symbol}
        }
    end

    -- Determine wikilink based on service
    local wikilink = (service_data and service_data["article"]) or BUS_ROUTES_ARTICLE
    -- Wikilink to EDSA Carousel only for line 1 on city buses type
    if service_key == "city" and first_code == "1" then
        wikilink = EDSA_CAROUSEL_ARTICLE
    end

    -- Image that indicates which service it is
    local image_data = (service_data and service_data["image"]) or {}
    local image = ""
    if image_data[1] and image_data[2] then
        image = string.format("[[File:%s|%s|link=%s]]", image_data[1], image_data[2], wikilink)
    end

    -- RouteBox icons
    for i, tuple in ipairs(route_codes) do
        local code, text = tuple.code, tuple.text
        local line = line_data[code]
        local background_color = (line and line["background_color"]) or "black"
        local text_color = (line and line["color"]) or "white"

        local box = frame:expandTemplate{
            title = "RouteBox",
            args = {text, wikilink, background_color, text_color}
        }

        -- Adjust spacing for multiple lines
        if #route_codes >= 2 then
            if i == 1 then
                table.insert(output, rint .. " " .. image .. " " .. box)
            else
                table.insert(output, box)
            end
        else
            table.insert(output, rint .. " " .. image .. " " .. box)
        end
    end

    return trim(table.concat(output, " ") .. " " .. stop_name)
end

return p