跳转到内容

模組:Expressway exit

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

local p = {}
local data = require("Module:Expressway exit/data")
local getArgs = require('Module:Arguments').getArgs
-- Parameter Name Index
local fieldList = {
    'place', 'type', 'name', 'connect', 'note',
    'highway', 'start', 'end', 'alias', 'state', 'index'
}

local function _parsePlaceArgs(args)
    local processedData = {}
	processedData.maxIndex = 0

  
	for _, field in ipairs(fieldList) do
	    for i = 1, 64 do
	        local key = field .. i
	        local value = args[key]
	        processedData[field] = processedData[field] or {}
			-- Handling special case 1: allowing unnumbered fields
	        if i == 1 and (not value or value == '') then
	            value = args[field]  -- fallback to `name`, `place`, etc.
	            processedData[field][1] = value
	        end
	        if value and value ~= '' then
	            processedData[field][i] = value
	            if i > (processedData.maxIndex or 0) then
	                processedData.maxIndex = i
	            end
	        end
	    end
	end

    processedData['place-rows'] = {}
    for i = 1, processedData.maxIndex do
        local rowKey = 'place-rows' .. i
        local rowVal = tonumber(args[rowKey])
        if rowVal then
        	if i == 1 and not rowVal then
				rowVal = tonumber(args['place-rows'])
			else
            	processedData['place-rows'][i] = math.max(1, math.min(rowVal, processedData.maxIndex))
            end
        else
            processedData['place-rows'][i] = ''
        end
    end

    return processedData
end

local function getColor(state)
    local key = string.upper(state or '')
    return data.stateColor[key] or ''
end

local function getIcon(typ)
    local result = {}
    local key = string.upper(typ or '')

    if key ~= '' and data.iconIndex[key] == true then
        for i = 1, #key do
            local c = key:sub(i, i)
            
            if c == 'S' then
                -- Special case: S for multiple fixed icons
                table.insert(result,data.icon2.S)
            else
                local entry = data.icon[c]
                if entry then
                    table.insert(result, string.format(
                        '[[File:%s|16px|link=%s|alt=%s|%s]]',
                        entry.file or '',
                        entry.link or '',
                        entry.alt or entry.text or entry.link or '',
                        entry.text or entry.link or ''
                    ))
                end
            end
        end
    end

    return table.concat(result)
end

local function _createLegendSpans()
	local container = mw.html.create() 
	local items = data.items

	for i, item in ipairs(items) do
		local outerSpan = mw.html.create("span")
			:css("margin", "0px")
			:css("font-size", "90%")

		local innerSpan = mw.html.create("span")
			:css("border", "1px solid #000")
			:css("background-color", item.color)
			:css("color", item.color)
			:wikitext("   ")

		outerSpan:node(innerSpan)
		outerSpan:wikitext(" " .. item.label)

		container:node(outerSpan)

		if i < #items then
			container:wikitext("&nbsp;&nbsp;")
		end
	end

	return container
end

local catgs = {}
local function _addcat (name)
	if name and name ~= ''then
		table.insert(catgs, string.format('[[Category:%s]]',name))
	end
end

function p.GenerateTable(processedData, args)
    local frame = mw.getCurrentFrame()
    local maxIndex = processedData.maxIndex
    -- Data default initialization
    local place         = processedData.place or {}
    local typ           = processedData['type'] or {}
    local name          = processedData.name or {}
    local connect       = processedData.connect or {}
    local note          = processedData.note or {}
    local highway       = processedData.highway or {}
    local distStart     = processedData['start'] or {}
    local distEnd       = processedData['end'] or {}
    local alias         = processedData.alias or {}
    local state         = processedData.state or {}
    local index         = processedData.index or {}
    local placeRows     = processedData['place-rows'] or {}
    local placeExist = false
    
    for _, v in pairs(place) do
		if v and v ~= '' then
			placeExist = true
			break
		end
	end

    -- header
    local html = mw.html.create('table')
		:addClass("wikitable")
		:attr('role', 'presentation')
		:cssText('margin: 0 0.5em; font-size: 90%;')
		:cssText('width:' .. (args.width or 'fit-content'))
		
    local tr = html:tag('tr')
    if placeExist then
        tr:tag('th'):wikitext('地區')
    end
    
    tr:tag('th'):wikitext('里程')
    tr:tag('th'):wikitext('類型')
    tr:tag('th'):wikitext('名稱')
    tr:tag('th'):wikitext('連接到')
    tr:tag('th')
		:cssText('width',args['note-width'] or 'inherit')
		:wikitext('備註')

    -- body part
    local placeRowIndex = 0
	local rowSpan
	local skipPlaceRowCount = 0
	
    for i = 1, maxIndex do
        -- Current data item
        local currentPlace      = place[i] or ''
        local currentType       = typ[i] or ''
        local currentName       = name[i] or ''
        local currentConnect    = connect[i] or ''
        local currentNote       = note[i] or ''
        local currentHighway    = highway[i] or ''
        local currentDistStart  = distStart[i] or ''
        local currentDistEnd    = distEnd[i] or ''
        local currentAlias      = alias[i] or ''
        local currentState      = state[i] or ''
        local currentIndex      = index[i] or ''
        local currentPlaceRow   = tonumber(placeRows[i]) or 1
        currentPlaceRow = math.max(1, math.min(currentPlaceRow, maxIndex))
		
		local alias_str = ''
		if currentAlias ~= '' then
			alias_str = '<br/><small>' .. currentAlias.. '</small>'
		end
		
		-- If the current highway is not empty, render the highway segmented lines
        if currentHighway ~= '' then
            local colspan = placeExist and 6 or 5
            html:tag('tr')
                :tag('th')
                :attr('colspan', colspan)
                :cssText('text-align: center;')
                :wikitext(currentHighway)
        end

        -- Render the main data row
        local row = html:tag('tr')
		local finalRow = currentPlaceRow
		
		if skipPlaceRowCount == 0 then
			-- Render Region column (place)
    		if currentPlace and currentPlace ~= '' then
				local placeCell = row:tag('td'):cssText('text-align: center')
				placeCell:wikitext(currentPlace)
				if finalRow > 1 then
					placeCell:attr('rowspan', finalRow)
					placeRowIndex = placeRowIndex + finalRow
					skipPlaceRowCount = finalRow - 1
				else
					placeRowIndex = placeRowIndex + 1
				end
    		elseif placeExist then
    			local placeCell = row:tag('td'):cssText('text-align: center')
    			if finalRow > 1 then
					placeCell:attr('rowspan', finalRow)
					placeRowIndex = placeRowIndex + finalRow
					skipPlaceRowCount = finalRow - 1
					placeCell:tag('span')
        			:cssText('color:red;')
        			:wikitext('?')
        		_addcat(data.catgs.general)
				else
					placeRowIndex = placeRowIndex + 1
					placeCell:wikitext('&nbsp;')
				end
	        end
	    else
			skipPlaceRowCount = skipPlaceRowCount - 1	
		end

        -- distance series
        local stateColor = getColor(currentState)
		local color = stateColor ~= '' and ('background-color:#' .. stateColor .. ';color:inherit;') or ''
        local distData = currentDistEnd ~= '' and (currentDistStart .. '/' .. currentDistEnd) or currentDistStart
        row:tag('td')
            :cssText('text-align:center;')
            :cssText('font-family:Liberation Mono,Courier New,Courier,monospace;')
            :cssText(color)
            :wikitext(distData)

        -- Type icon column
        row:tag('td')
        	:cssText(color)
        	:tag('span')
	            :cssText('display:flex; white-space:nowrap;')
	            :wikitext(currentIndex ~= '' and '(' .. currentIndex .. ')&thinsp;' or '')
	            :tag('span') 
					:cssText('margin: 0 auto;')
					:wikitext(getIcon(currentType))

        -- Name and classification list
        row:tag('td')
            :cssText(color)
            :wikitext(currentName .. alias_str)

        -- Connect column
        row:tag('td')
            :cssText(color)
            :wikitext(currentConnect)

        -- Note column (Formerly called comment)
        row:tag('td')
            :cssText(color)
            :wikitext(currentNote)
    end

    -- footer (Using existing pure wikitext content templates, there is no need to convert to Lua)
	local footerCol = placeExist and 6 or 5
	local rowFooter = html:tag('tr')
	
	local footer = mw.html.create()
	local countryCode = string.upper(args.country or '')
	
	if countryCode == 'UK' or countryCode == 'GBR' then
		local span1 = mw.html.create('span')
			:cssText('margin:0px; font-size:90%;')
			:tag('span')
				:cssText('border:none; background-color:#0079c1; color:#0079c1;')
				:wikitext('&nbsp;&nbsp;&nbsp;')
				:done()
			:wikitext('&nbsp;Highway')

		local span2 = mw.html.create('span')
			:cssText('margin:0px; font-size:90%;')
			:tag('span')
				:cssText('border:none; background-color:#00703c; color:#00703c;')
				:wikitext('&nbsp;&nbsp;&nbsp;')
				:done()
			:wikitext('&nbsp;Main road')

		local span3 = mw.html.create('span')
			:cssText('margin:0px; font-size:90%;')
			:tag('span')
				:cssText('border:1px solid #000; background-color:white; color:white;')
				:wikitext('&nbsp;&nbsp;&nbsp;')
				:done()
			:wikitext('&nbsp;Primary Road')

		footer:node(span1)
			:wikitext(' • ')
			:node(span2)
			:wikitext(' • ')
			:node(span3)
			:tag('br')
	else
		footer:wikitext('1.000 英里 = 1.609 公里;1.000 公里 = 0.621 英里')
			:tag('br')
	end
	
	
	-- Add additional key information
	if args.key and args.key ~= '' then
		footer:wikitext(footer_str):tag('br'):done():wikitext(args.key)
	else
		footer:wikitext(footer_str)
	end
	
	-- Insert footer cell
	rowFooter:tag('td')
	    :attr('colspan', footerCol)
	    :attr('align', 'center')
		:cssText('background:var(--background-color-neutral-subtle,#f2f2f2);color: inherit;')
		:node(footer)
		:node(_createLegendSpans())
    return tostring(html) .. (#catgs > 0 and table.concat(catgs) or '')
end

function p._main(args)
    local processedData = _parsePlaceArgs(args)
    local html = p.GenerateTable(processedData, args, processedData.maxIndex)
    return html
end

function p.main(frame)
    if not getArgs then
    	getArgs = require('Module:Arguments').getArgs
    end
    args = getArgs(frame, {
        parentFirst = true,
        removeBlanks = true,
        wrappers = {
            'Template:Expressway exit',
        }
    })

    return p._main(args)
end

return p