模組: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(" ")
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(' ')
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 .. ') ' 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(' ')
:done()
:wikitext(' Highway')
local span2 = mw.html.create('span')
:cssText('margin:0px; font-size:90%;')
:tag('span')
:cssText('border:none; background-color:#00703c; color:#00703c;')
:wikitext(' ')
:done()
:wikitext(' 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(' ')
:done()
:wikitext(' 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