Mô đun:Location map
Giao diện
Mô-đun này là loại cần được bảo vệ. Nó là một mô-đun nguy hiểm cao được sử dụng bởi một số lượng lớn các trang, hoặc là các thay thế rất thường xuyên. Bởi vì phá hoại hoặc lỗi sai khi sửa sẽ ảnh hưởng đến nhiều trang và thậm chí chỉnh sửa tầm thường có thể gây ra tải đáng kể cho các máy chủ, nó được khóa hạn chế sửa đổi. |
Mô đun Lua này được sử dụng ở khoảng 182.000 trang. Để tránh gây lỗi trên quy mô lớn và tải máy chủ không cần thiết, tất cả thay đổi cần được thử nghiệm ở trang con /sandbox, /testcases của mô đun, hoặc ở chỗ thử mô đun. Các thay đổi đã được thử nghiệm có thể thêm vào mô đun bằng một sửa đổi duy nhất. Xin hãy thảo luận các thay đổi tại trang thảo luận trước khi áp dụng sửa đổi. |
Mô đun Lua này sử dụng những tính năng phức tạp của cú pháp bản mẫu.
Bạn được khuyến khích làm quen với cấu trúc của mô đun này và các hàm cú pháp trước khi sửa đổi mô đun. Nếu sửa đổi của bạn gây ra lỗi không mong muốn, hãy sửa chữa hoặc lùi lại nhanh chóng, vì mô đun này có thể xuất hiện trên một số lượng lớn trang. |
Mô đun này phụ thuộc vào các mô đun sau: |
Usage
This module implements the {{Location map}} and {{Location map~}} templates. Please see the template pages for usage instructions.
Thể loại theo dõi/bảo trì
require('strict')
local p = {}
local argByViArg = {
khung = "border",
["chú thích"] = "caption",
["nhãn"] = "label",
["trôi"] = "float",
["rộng"] = "width",
["rộng mặc định"] = "default_width",
["địa hình nổi"] = "relief",
["BD thay thế"] = "AlternativeMap",
["hình phủ"] = "overlay_image",
["kích thước nhãn"] = "label_size",
["rộng nhãn"] = "label_width",
["điểm"] = "mark",
["kích thước điểm"] = "marksize",
["vị trí"] = "position",
["màu nền"] = "background",
["liên kết"] = "link",
["vĩ"] = "lat_dir",
["vĩ độ"] = "lat_deg",
["vĩ phút"] = "lat_min",
["vĩ giây"] = "lat_sec",
["kinh độ"] = "lon_deg",
["kinh phút"] = "lon_min",
["kinh giây"] = "lon_sec",
["kinh"] = "lon_dir",
["toàn vĩ độ"] = "lat",
["toàn kinh độ"] = "long",
}
local rawGetArgs = require('Mô đun:Arguments').getArgs
local getArgs = function (frame, options)
local args = rawGetArgs(frame, options)
if args.lon_dir == "Đ" or args.lon_dir == "đ" or args.lon_dir == "T" or args.lon_dir == "t" then
if args.lat_dir == "B" or args.lat_dir == "B" then args.lat_dir = "N"
elseif args.lat_dir == "N" or args.lat_dir == "n" then args.lat_dir = "S"
end
end
if args.lon_dir == "Đ" or args.lon_dir == "đ" then args.lon_dir = "E"
elseif args.lon_dir == "T" or args.lon_dir == "t" then args.lon_dir = "W"
end
for viArgName, argName in pairs(argByViArg) do
if args[viArgName] then
args[argName] = args[viArgName]
end
end
return args
end
local function round(n, decimals)
local pow = 10^(decimals or 0)
return math.floor(n * pow + 0.5) / pow
end
function p.getMapParams(map, frame)
if not map then
error('Cần định rõ tên của trang định rõ bản đồ định vị để sử dụng', 2)
end
local moduletitle = mw.title.new('Mô đun:Location map/data/' .. map)
if not moduletitle then
error(string.format('%q không phải là tên hợp lệ của trang định rõ bản đồ định vị', map), 2)
elseif moduletitle.exists then
local mapData = mw.loadData('Mô đun:Location map/data/' .. map)
return function(name, params)
if name == nil then
return 'Mô đun:Location map/data/' .. map
elseif mapData[name] == nil then
return ''
elseif params then
return mw.message.newRawMessage(tostring(mapData[name]), unpack(params)):plain()
else
return mapData[name]
end
end
elseif mw.title.new('Bản mẫu:Bản đồ định vị ' .. map).exists then
local cache = {}
return function(name, params)
if params then
return frame:expandTemplate{title = 'Bản đồ định vị ' .. map, args = { name, unpack(params) }}
else
if name == nil then
return 'Bản mẫu:Bản đồ định vị ' .. map
elseif cache[name] == nil then
cache[name] = frame:expandTemplate{title = 'Bản đồ định vị ' .. map, args = { name }}
end
return cache[name]
end
end
elseif mw.title.new('Bản mẫu:Location map ' .. map).exists then
local cache = {}
if type(frame) ~= 'table' or type(frame.expandTemplate) ~= 'function' then
error('Phải cung cấp khung khi sử dụng bản đồ định vị kiểu cũ')
end
return function(name, params)
if params then
return frame:expandTemplate{title = 'Location map ' .. map, args = { name, unpack(params) }}
else
if name == nil then
return 'Bản mẫu:Location map ' .. map
elseif cache[name] == nil then
cache[name] = frame:expandTemplate{title = 'Location map ' .. map, args = { name }}
end
return cache[name]
end
end
else
error('Không tìm thấy trang định rõ bản đồ định vị. "Mô đun:Location map/data/' .. map .. '", "Bản mẫu:Bản đồ định vị ' .. map .. '", và "Bản mẫu:Location map ' .. map .. '" đều không tồn tại', 2)
end
end
function p.data(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local params = {}
for k,v in ipairs(args) do
if k > 2 then
params[k-2] = v
end
end
return map(args[2], #params ~= 0 and params)
end
local hemisphereMultipliers = {
["kinh độ"] = { W = -1, w = -1, E = 1, e = 1 },
["vĩ độ"] = { S = -1, s = -1, N = 1, n = 1 }
}
local function decdeg(degrees, minutes, seconds, hemisphere, decimal, direction)
local direction_prefix = mw.ustring.gsub(direction, " độ", "")
if decimal then
if degrees then
error('Không thể đặt cả giá trị thập phân cùng giá trị độ-phút-giây cho ' .. direction, 2)
elseif minutes then
error('Chỉ có thể đặt ' .. direction_prefix .. ' phút ở dạng độ-phút-giây', 2)
elseif seconds then
error('Chỉ có thể đặt ' .. direction_prefix .. ' giây ở dạng độ-phút-giây', 2)
elseif hemisphere then
error('Chỉ có thể đặt bán cầu ở dạng độ-phút-giây cho ' .. direction, 2)
end
local retval = tonumber(decimal)
if retval then
return retval
end
error('Giá trị "' .. decimal .. '" không phải là ' .. direction .. ' hợp lệ', 2)
elseif seconds and not minutes then
error('Đã đặt ' .. direction_prefix .. ' giây mà không đặt ' .. direction_prefix .. ' phút', 2)
elseif not degrees then
if minutes then
error('Đã đặt ' .. direction_prefix .. ' phút mà không đặt ' .. direction, 2)
elseif hemisphere then
error('Đã đặt bán cầu cho ' .. direction .. ' mà không đặt ' .. direction, 2)
end
return nil
end
decimal = tonumber(degrees)
if not decimal then
error('Giá trị "' .. degrees .. '" độ trong ' .. direction .. ' không phải hợp lệ', 2)
elseif minutes and not tonumber(minutes) then
error('Giá trị "' .. minutes .. '" phút trong ' .. direction .. ' không phải hợp lệ', 2)
elseif seconds and not tonumber(seconds) then
error('Giá trị "' .. seconds .. '" giây trong ' .. direction .. ' không phải hợp lệ', 2)
end
decimal = decimal + (minutes or 0)/60 + (seconds or 0)/3600
if hemisphere then
local multiplier = hemisphereMultipliers[direction][hemisphere]
if not multiplier then
error('Bán cầu "' .. hemisphere .. '" trong ' .. direction .. ' không phải hợp lệ', 2)
end
decimal = decimal * multiplier
end
return decimal
end
-- Finds a parameter in a transclusion of {{Coord}}.
local function coord2text(para,coord)
local result = mw.text.split(mw.ustring.match(coord, '%s*%-?[%.%d]+;%s*%-?[%.%d]+%s*') or ';', '[;]')
if para == 'longitude' then result = result[2] else result = result[1] end
if not tonumber(result) then return error('Giá trị tọa độ dạng sai', 2) end
return tonumber(result)
end
-- effectively make removeBlanks false for caption and maplink, and true for everything else
-- if useWikidata is present but blank, convert it to false instead of nil
-- p.top, p.bottom, and their callers need to use this
function p.valueFunc(key, value)
if value then
value = mw.text.trim(value)
end
if value ~= '' or key == 'caption' or key == 'maplink' then
return value
elseif key == 'useWikidata' then
return false
end
end
local function getContainerImage(args, map)
if args.AlternativeMap then
return args.AlternativeMap
elseif args.relief and map('image1') ~= '' then
return map('image1')
else
return map('image')
end
end
function p.top(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local width
local default_as_number = tonumber(mw.ustring.match(tostring(args.default_width),"%d*"))
if not args.width then
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
elseif mw.ustring.sub(args.width, -2) == 'px' then
width = mw.ustring.sub(args.width, 1, -3)
else
width = args.width
end
local width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
if width_as_number == 0 then
-- check to see if width is junk. If it is, then use default calculation
width = round((default_as_number or 240) * (tonumber(map('defaultscale')) or 1))
width_as_number = tonumber(mw.ustring.match(tostring(width),"%d*")) or 0;
end
if args.max_width ~= "" and args.max_width ~= nil then
-- check to see if width bigger than max_width
local max_as_number = tonumber(mw.ustring.match(args.max_width,"%d*")) or 0;
if width_as_number>max_as_number and max_as_number>0 then
width = args.max_width;
end
end
local retval = args.float == 'center' and '<div class="center">' or ''
if args.caption and args.caption ~= '' and args.border ~= 'infobox' then
retval = retval .. '<div class="noviewer thumb '
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'tleft'
elseif args.float == '"center"' or args.float == 'center' or args.float == '"none"' or args.float == 'none' then
retval = retval .. 'tnone'
else
retval = retval .. 'tright'
end
retval = retval .. '"><div class="thumbinner" style="width:' .. (width + 2) .. 'px'
if args.border == 'none' then
retval = retval .. ';border:none'
elseif args.border then
retval = retval .. ';border-color:' .. args.border
end
retval = retval .. '"><div style="position:relative;width:' .. width .. 'px' .. (args.border ~= 'none' and ';border:1px solid lightgray">' or '">')
else
retval = retval .. '<div style="width:' .. width .. 'px;'
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'float:left;clear:left'
elseif args.float == '"center"' or args.float == 'center' then
retval = retval .. 'float:none;clear:both;margin-left:auto;margin-right:auto'
elseif args.float == '"none"' or args.float == 'none' then
retval = retval .. 'float:none;clear:none'
else
retval = retval .. 'float:right;clear:right'
end
retval = retval .. '"><div style="width:' .. width .. 'px;padding:0"><div style="position:relative;width:' .. width .. 'px">'
end
local image = getContainerImage(args, map)
local currentTitle = mw.title.getCurrentTitle()
retval = string.format(
'%s[[Tập tin:%s|%spx|%s%s]]',
retval,
image,
width,
args.alt or ((args.label or currentTitle.text) .. ' trên bản đồ ' .. map('name')),
args.maplink and ('|link=' .. args.maplink) or ''
)
if args.caption and args.caption ~= '' then
if (currentTitle.namespace == 0) and mw.ustring.find(args.caption, '##') then
retval = retval .. '[[Thể loại:Trang có hai dấu thăng trong chú thích bản đồ định vị]]'
end
end
if args.overlay_image then
return retval .. '<div style="position:absolute;top:0;left:0">[[Tập tin:' .. args.overlay_image .. '|' .. width .. 'px]]</div>'
else
return retval
end
end
function p.bottom(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local retval = '</div>'
local currentTitle = mw.title.getCurrentTitle()
if not args.caption or args.border == 'infobox' then
if args.border then
retval = retval .. '<div>'
else
retval = retval .. '<div style="font-size:90%;padding-top:3px">'
end
retval = retval
.. (args.caption or (args.label or currentTitle.text) .. ' (' .. map('name') .. ')')
.. '</div>'
elseif args.caption ~= '' then
-- This is not the pipe trick. We're creating a link with no text on purpose, so that CSS can give us a nice image
retval = retval .. '<div class="thumbcaption"><div class="magnify">[[:Tập tin:' .. getContainerImage(args, map) .. '| ]]</div>' .. args.caption .. '</div>'
end
if args.switcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">' .. args.switcherLabel .. '</span>'
elseif args.autoSwitcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">Xem bản đồ ' .. map('name') .. '</span>'
end
retval = retval .. '</div></div>'
if args.caption_undefined then
mw.log('Removed parameter caption_undefined used.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
retval = retval .. '[[Thể loại:Bản đồ định vị có tham số dời|caption_undefined]]'
end
end
if map('skew') ~= '' or map('lat_skew') ~= '' or map('crosses180') ~= '' or map('type') ~= '' then
mw.log('Removed parameter used in map definition ' .. map())
if currentTitle.namespace == 0 then
local key = (map('skew') ~= '' and 'skew' or '') ..
(map('lat_skew') ~= '' and 'lat_skew' or '') ..
(map('crosses180') ~= '' and 'crosses180' or '') ..
(map('type') ~= '' and 'type' or '')
retval = retval .. '[[Thể loại:Bản đồ định vị có tham số dời|' .. key .. ' ]]'
end
end
if string.find(map('name'), '|', 1, true) then
mw.log('Pipe used in name of map definition ' .. map())
if currentTitle.namespace == 0 then
retval = retval .. '[[Thể loại:Bản đồ định vị có dấu sổ thẳng trong tên]]'
end
end
if args.float == 'center' then
retval = retval .. '</div>'
end
return retval
end
local function markOuterDiv(x, y, imageDiv, labelDiv)
return mw.html.create('div')
:cssText('position:absolute;top:' .. round(y, 3) .. '%;left:' .. round(x, 3) .. '%')
:node(imageDiv)
:node(labelDiv)
end
local function markImageDiv(mark, marksize, label, link, alt, title)
local builder = mw.html.create('div')
:cssText('position:absolute;left:-' .. round(marksize / 2) .. 'px;top:-' .. round(marksize / 2) .. 'px;line-height:0')
:attr('title', title)
if marksize ~= 0 then
builder:wikitext(string.format(
'[[Tập tin:%s|%dx%dpx|%s|link=%s%s]]',
mark,
marksize,
marksize,
label,
link,
alt and ('|alt=' .. alt) or ''
))
end
return builder
end
local function markLabelDiv(label, label_size, label_width, position, background, x, marksize)
if tonumber(label_size) == 0 then
return mw.html.create('div'):cssText('font-size:0%;position:absolute'):wikitext(label)
end
local builder = mw.html.create('div')
:cssText('font-size:' .. label_size .. '%;line-height:110%;position:absolute;width:' .. label_width .. 'em')
local distance = round(marksize / 2 + 1)
local spanCss
if position == 'top' then -- specified top
builder:cssText('bottom:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em;text-align:center')
elseif position == 'bottom' then -- specified bottom
builder:cssText('top:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em;text-align:center')
elseif position == 'left' or (tonumber(x) > 70 and position ~= 'right') then -- specified left or autodetected to left
builder:cssText('top:-0.75em;right:' .. distance .. 'px;text-align:right')
spanCss = 'float:right'
else -- specified right or autodetected to right
builder:cssText('top:-0.75em;left:' .. distance .. 'px;text-align:left')
spanCss = 'float:left'
end
builder = builder:tag('div')
:css('display', 'inline')
:cssText('padding:1px')
:cssText(spanCss)
:wikitext(label)
if background then
builder:cssText('background-color:' .. background)
end
return builder:done()
end
local function getX(longitude, left, right)
local width = (right - left) % 360
if width == 0 then
width = 360
end
local distanceFromLeft = (longitude - left) % 360
-- the distance needed past the map to the right equals distanceFromLeft - width. the distance needed past the map to the left equals 360 - distanceFromLeft. to minimize page stretching, go whichever way is shorter
if distanceFromLeft - width / 2 >= 180 then
distanceFromLeft = distanceFromLeft - 360
end
return 100 * distanceFromLeft / width
end
local function getY(latitude, top, bottom)
return 100 * (top - latitude) / (top - bottom)
end
function p.mark(frame, args, map)
if not args then
args = getArgs(frame, {wrappers = 'Bản mẫu:Bản đồ định vị~'})
end
local mapnames = {}
if not map then
if args[1] then
map = {}
for mapname in mw.text.gsplit(args[1], '#', true) do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
mapnames[#mapnames + 1] = mapname
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('Thế giới', frame)
args[1] = 'Thế giới'
end
end
if type(map) == 'table' then
local outputs = {}
local oldargs = args[1]
for k,v in ipairs(map) do
args[1] = mapnames[k]
outputs[k] = tostring(p.mark(frame, args, v))
end
args[1] = oldargs
return table.concat(outputs, '#PlaceList#') .. '#PlaceList#'
end
local x, y, longitude, latitude
longitude = decdeg(args.lon_deg, args.lon_min, args.lon_sec, args.lon_dir, args.long, 'kinh độ')
latitude = decdeg(args.lat_deg, args.lat_min, args.lat_sec, args.lat_dir, args.lat, 'vĩ độ')
if args.excludefrom then
-- If this mark is to be excluded from certain maps entirely (useful in the context of multiple maps)
for exclusionmap in mw.text.gsplit(args.excludefrom, '#', true) do
-- Check if this map is excluded. If so, return an empty string.
if args[1] == exclusionmap then
return ''
end
end
end
local builder = mw.html.create()
local currentTitle = mw.title.getCurrentTitle()
if args.coordinates then
-- Temporarily removed to facilitate infobox conversion. See [[:en:Wikipedia:Coordinates in infoboxes]]
-- if longitude or latitude then
-- error('Tọa độ từ [[Mô đun:Coordinates]] và tọa độ riêng lẻ không thể cả hai đều được cung cấp')
-- end
longitude = coord2text('longitude', args.coordinates)
latitude = coord2text('latitude', args.coordinates)
elseif not longitude and not latitude and args.useWikidata then
-- If they didn't provide either coordinate, try Wikidata. If they provided one but not the other, don't.
local entity = mw.wikibase.getEntity()
if entity and entity.claims and entity.claims.P625 and entity.claims.P625[1].mainsnak.snaktype == 'value' then
local value = entity.claims.P625[1].mainsnak.datavalue.value
longitude, latitude = value.longitude, value.latitude
end
if args.link and (currentTitle.namespace == 0) then
builder:wikitext('[[Thể loại:Bản đồ định vị có ghim được liên kết lấy tọa độ từ Wikidata]]')
end
end
if not longitude then
error('Không có giá trị kinh độ')
elseif not latitude then
error('Không có giá trị vĩ độ')
end
if currentTitle.namespace > 0 then
if (not args.lon_deg) ~= (not args.lat_deg) then
builder:wikitext('[[Thể loại:Bản đồ định vị có độ chính xác kinh độ và vĩ độ khác nhau|Độ]]')
elseif (not args.lon_min) ~= (not args.lat_min) then
builder:wikitext('[[Thể loại:Bản đồ định vị có độ chính xác kinh độ và vĩ độ khác nhau|Phút]]')
elseif (not args.lon_sec) ~= (not args.lat_sec) then
builder:wikitext('[[Thể loại:Bản đồ định vị có độ chính xác kinh độ và vĩ độ khác nhau|Giây]]')
elseif (not args.lon_dir) ~= (not args.lat_dir) then
builder:wikitext('[[Thể loại:Bản đồ định vị có độ chính xác kinh độ và vĩ độ khác nhau|Bán cầu]]')
elseif (not args.long) ~= (not args.lat) then
builder:wikitext('[[Thể loại:Bản đồ định vị có độ chính xác kinh độ và vĩ độ khác nhau|Thập phân]]')
end
end
if args.skew or args.lon_shift or args.markhigh then
mw.log('Removed parameter used in invocation.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = (args.skew and 'skew' or '') ..
(args.lon_shift and 'lon_shift' or '') ..
(args.markhigh and 'markhigh' or '')
builder:wikitext('[[Thể loại:Bản đồ định vị có tham số dời|' .. key ..' ]]')
end
end
if map('x') ~= '' then
x = tonumber(mw.ext.ParserFunctions.expr(map('x', { latitude, longitude })))
else
x = tonumber(getX(longitude, map('left'), map('right')))
end
if map('y') ~= '' then
y = tonumber(mw.ext.ParserFunctions.expr(map('y', { latitude, longitude })))
else
y = tonumber(getY(latitude, map('top'), map('bottom')))
end
if (x < 0 or x > 100 or y < 0 or y > 100) and not args.outside then
mw.log('Mark placed outside map boundaries without outside flag set. x = ' .. x .. ', y = ' .. y)
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
if currentTitle.namespace == 0 then
local key = frame:preprocess('{{FULLPAGENAME}}')
builder:wikitext('[[Thể loại:Bản đồ định vị không định trước rằng ghim nằm ngoài bản đồ|' .. key .. ' ]]')
end
end
local mark = args.mark or map('mark')
if mark == '' then
mark = 'Red pog.svg'
end
local marksize = tonumber(args.marksize) or tonumber(map('marksize')) or 8
local imageDiv = markImageDiv(mark, marksize, args.label or mw.title.getCurrentTitle().text, args.link or '', args.alt, args[2])
local labelDiv
if args.label and args.position ~= 'none' then
labelDiv = markLabelDiv(args.label, args.label_size or 90, args.label_width or 6, args.position, args.background, x, marksize)
end
return builder:node(markOuterDiv(x, y, imageDiv, labelDiv))
end
local function switcherSeparate(s)
if s == nil then return {} end
local retval = {}
for i in string.gmatch(s .. '#', '([^#]*)#') do
i = mw.text.trim(i)
retval[#retval + 1] = (i ~= '' and i)
end
return retval
end
function p.main(frame, args, map)
local caption_list = {}
if not args then
args = getArgs(frame, {wrappers = 'Bản mẫu:Bản đồ định vị', valueFunc = p.valueFunc})
end
if args.useWikidata == nil then
args.useWikidata = true
end
if not map then
if args[1] then
map = {}
for mapname in string.gmatch(args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mw.ustring.gsub(mapname, '^%s*(.-)%s*$', '%1'), frame)
end
if args['caption'] then
if args['caption'] == "" then
while #caption_list < #map do
caption_list[#caption_list + 1] = args['caption']
end
else
for caption in mw.text.gsplit(args['caption'], '##', true) do
caption_list[#caption_list + 1] = caption
end
end
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('Thế giới', frame)
end
end
if type(map) == 'table' then
local altmaps = switcherSeparate(args.AlternativeMap)
if #altmaps > #map then
error(string.format('Đã cung cấp %d AlternativeMap nhưng chỉ cung cấp %d bản đồ', #altmaps, #map))
end
local overlays = switcherSeparate(args.overlay_image)
if #overlays > #map then
error(string.format('Đã cung cấp %d overlay_image nhưng chỉ cung cấp %d bản đồ', #overlays, #map))
end
if #caption_list > #map then
error(string.format('Đã cung cấp %d chú thích nhưng chỉ cung cấp %d bản đồ', #caption_list, #map))
end
local outputs = {}
args.autoSwitcherLabel = true
for k,v in ipairs(map) do
args.AlternativeMap = altmaps[k]
args.overlay_image = overlays[k]
args.caption = caption_list[k]
outputs[k] = p.main(frame, args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, args, map) .. tostring( p.mark(frame, args, map) ) .. p.bottom(frame, args, map)
end
end
return p