Bước tới nội dung

Mô đun:Jct

Bách khoa toàn thư mở Wikipedia
local p = {}-- Change to "" upon deployment.local moduleSuffix = ""local parserModuleName = "Module:Road data/parser" .. moduleSuffixlocal statenameModuleName = "Module:Jct/statename" .. moduleSuffix -- TODO transitionlocal cityModuleName = "Module:Jct/city" .. moduleSuffixlocal concat = table.concatlocal insert = table.insertlocal format = mw.ustring.formatlocal trim = mw.text.trimlocal parserModule = require(parserModuleName)local parser = parserModule.parserlocal util = require("Module:Road data/util")-- Shieldslocal defaultShieldSize = 24local function addContextBanner(route, name, suffix, bannerSpec)	local bannerModule = 'Module:Road data/banners/' .. string.upper(route.country)	local shieldfield = name .. 'shield'	local shield = parser(route, shieldfield)	if shield == nil then		-- This route type does not define shield.		-- Find shield in the default banner table.		shield = parser(route, 'shield', name, bannerModule)		if shield and shield ~= '' then			if suffix == nil then				suffix = parser(route, 'shield', 'suffix', bannerModule)			end			if suffix and suffix ~= '' then				shield = shield .. " " .. suffix			end			shield = shield .. ".svg"		end	end	if shield and shield ~= '' then		local shieldSize = defaultShieldSize		-- Add banner plate.		insert(bannerSpec, {shield, shieldSize})	endendlocal function bannerSpec(banner, bannerSize, bannerSuffix, route)	local banners = {}	if type(banner) == "table" then		local bannerSizeIsNotTable = type(bannerSize) ~= "table"		for i,filename in ipairs(banner) do			local bannersize = bannerSizeIsNotTable and bannerSize or bannerSize[i] or defaultShieldSize			insert(banners, {filename, bannersize})		end	elseif banner ~= '' then		insert(banners, {banner, bannerSize})	end	if route.dir then		addContextBanner(route, 'dir', bannerSuffix, banners)	end	if route.to then		addContextBanner(route, 'to', bannerSuffix, banners)	end	return bannersendlocal function shieldSpec(route, mainShield, shieldList)	local shieldSpec = {}	local shield	local shieldto = parser(route, 'shieldto')		if route.to then		if not shield then shield = shieldto or parser(route, 'shield') or '' end	else		if not shield then shield = parser(route, 'shield') or '' end	end	if shield == '' then return shieldSpec end	local orientation = parser(route, 'orientation')	local function size(route)		if orientation == "upright" then			return defaultShieldSize			else return "x" .. defaultShieldSize		end	end		local shieldsize = size(route)		local banner = parser(route, 'banner') or {}	local bannersize = defaultShieldSize	local bannersuffix = parser(route, 'bannersuffix')	local bannerIsNotTable = type(banner) ~= "table"	local bannersizeIsNotTable = type(bannersize) ~= "table"	local bannersuffixIsNotTable = type(bannersuffix) ~= "table"	if type(shield) == "table" then		for i,filename in ipairs(shield) do			local size = shieldsize or shieldsize[i]			if size == "" then size = nil end			-- banner.all describes banners that apply to all multiple shields.			local shieldBanner = bannerIsNotTable and banner or (banner[i] or banner.all or {})			-- Banner size is default if the corresponding entry			-- in bannerSize table is not set.			local shieldBannerSize =				bannersizeIsNotTable and bannersize				or (bannersize[i] or bannersize.all or defaultShieldSize)			local shieldBannerSuffix = bannersuffix and (bannersuffixIsNotTable and bannersuffix or bannersuffix[i])			insert(shieldSpec, {				shield = {filename, size},				banners = bannerSpec(shieldBanner, shieldBannerSize, shieldBannerSuffix, route)			})		end	elseif shield ~= '' then		if shieldsize == "" then shieldsize = nil end		insert(shieldSpec, {			shield = {shield, shieldsize},			banners = bannerSpec(banner, bannersize,  bannersuffix, route)		})	end	return shieldSpecendlocal missingShieldslocal shieldExistsCache = {}local function render(shieldEntry, scale, showLink)	local shield = shieldEntry.shield	local banners = shieldEntry.banners	local size	if shield[2] then		local width, height = mw.ustring.match(shield[2], "(%d*)x?(%d*)")		width = tonumber(width)		height = tonumber(height)		local sizeparts = {}		if width then			insert(sizeparts, format("%d", width * scale))		end		if height then			insert(sizeparts, format("x%d", height * scale))		end		size = concat(sizeparts)	else		size = format("%s%d", landscape and "x" or "", defaultShieldSize * scale)	end	local shieldCode = format("[[Tập tin:%s|%spx|link=|alt=]]", shield[1], size)	if not banners[1] then return shieldCode end	for _,banner in ipairs(banners) do		shieldCode = format("[[Tập tin:%s|%spx|link=|alt=]]<br>%s",			banner[1],			defaultShieldSize,			shieldCode)	end	return '<span style="display: inline-block; vertical-align: baseline; line-height: 0; text-align: center;">' .. shieldCode .. '</span>'endfunction p.shield(route, scale, showLink, mainShield, shieldList)	missingShields = {}	scale = scale or 1	local rendered = {}	for _,entry in ipairs(shieldSpec(route, mainShield, shieldList)) do		insert(rendered, render(entry, scale, showLink))	end	return concat(rendered), missingShieldsend-- Links/abbreviationsfunction p.link(route)	local nolink = route.nolink	local abbr = parser(route, 'abbr')	if nolink then		return abbr	else		local link = parser(route, 'link')		if not link or link == '' then			return abbr		else			return format("[[%s|%s]]", link, abbr)		end	endend--------------------------------------------- Links/abbreviationslocal function routeText(route, jctname, frame)	local link	local type = route.type	if not type or type == '' then		link = route.route	else		link = p.link(route)	end	local dir = route.dir and ' ' .. string.lower(route.dir) or ''	local routeText = link .. dir	local name = route.name	if name and name ~= '' then		local mainText = jctname and name or routeText		local parenText = jctname and routeText or name				return format('%s (%s)', mainText, parenText)	else		return routeText	endendlocal function extra(args)	local extraTypes = mw.loadData('Module:Road data/extra')	local extraIcon = extraTypes[string.lower(args.extra or '')]	if not extraIcon then return '' end	local size = defaultShieldSize .. 'px'	local countryIcon = extraIcon[args.country] or extraIcon.default	if type(countryIcon) == 'table' then		local localIcon = countryIcon[args.state] or countryIcon.default		return string.format("[[Tập tin:%s|%s|alt=|link=]]", localIcon, size)	else		return string.format("[[Tập tin:%s|%s|alt=|link=]]", countryIcon, size)	endendlocal function parseArgs(args)	local state = args.state or args.province or ''	args.state = state	local country	if args.country and args.country ~= '' then		country = string.upper(args.country)	else		local countryModule = mw.loadData("Module:Road data/countrymask")		country = countryModule[state] or 'UNK'	end	args.country = country	local params = {'denom', 'county', 'township', 'dab', 'nolink', 'noshield', 'to', 'dir', 'name'}	local routes = {}	local routeCount = 1	local seenTo = false	while true do		local routeType = args[routeCount * 2 - 1]		if not routeType then break end		local route = {type = routeType, route = args[routeCount * 2]}		for _,v in pairs(params) do			route[v] = args[v .. routeCount]		end				if args.nolink then			route.nolink = args.nolink		end				route.country = country		route.state = state		-- Set the first .to to true.		-- Set all following .to to ''.		if seenTo then			if route.to then				-- Report duplicate to flag.				route.toerror = true			end			route.to = ''		elseif route.to then			route.to = true			seenTo = true		end		insert(routes, route)		routeCount = routeCount + 1	end	return routesendlocal function prefix(to, num)	if to and to ~= '' then		return num == 1 and 'To ' or ' to '	end	return num == 1 and '' or '&nbsp;/ 'endlocal function addErrorMsg(catCode, msg, errorMsg)	errorMsg.code = errorMsg.code or catCode	insert(errorMsg, format('<span style="display: none;">Module:Jct %s</span>', msg))endfunction p._jct(args, frame)	local routes = parseArgs(args)	local shields = {}	local links = {}	local allMissingShields = {}	local typeErr = false	local toErr = false	frame = frame or mw.getCurrentFrame()	for num,route in ipairs(routes) do		if not (args.noshield or route.noshield) then			local shield, missingShields = p.shield(route)			insert(shields, shield)			if missingShields[1] then				insert(allMissingShields, concat(missingShields, ' / '))			end		end		local prefix = prefix(route.to, num)		if prefix ~= '' then insert(links, prefix) end		insert(links, routeText(route, args.jctname, frame))		typeErr = typeErr or route.typeerror or false		toErr = toErr or route.toerror or false	end	local graphics = concat(shields) .. extra(args) .. ' '	local linkText = concat(links)	local cities = ''	if args.city1 or args.location1 then		local citiesPrefix		if args.citiesprefix then			citiesPrefix = args.citiesprefix ~= '' and format(" %s ", args.citiesprefix) or ''		else			citiesPrefix = '&nbsp;'		end		local cityModule = require(cityModuleName)		cities = citiesPrefix .. cityModule.city(args)	end	local errorMsg = {}	-- Errors must be reported by the level of severity, most severe first.	if typeErr then		-- Report invalid type errors.		addErrorMsg("§", 'error: Invalid route type', errorMsg)	end	if #allMissingShields > 0 then		-- Report missing shield error.		-- shieldExists() would have populated missingShields if shields are missing.		addErrorMsg("¶", 'error: Missing route marker graphics: ' .. concat(allMissingShields, ' / '), errorMsg)	end	if toErr then		-- Report invalid to errors.		addErrorMsg("&", 'error: Invalid "to" argument', errorMsg)	end	if args.road then		-- Report deprecated "road" warning.		addErrorMsg("∆", 'warning: "road" parameter is deprecated', errorMsg)	end	if args.rdt then		-- Report deprecated "rdt" warning.		addErrorMsg("£", 'warning: "rdt" parameter is deprecated', errorMsg)	end	if #errorMsg > 0 then		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page's title		-- Add a category for the first, most severe error.		insert(errorMsg, format('[[Thể loại:Lỗi bản mẫu Jct|%s %s]]', errorMsg.code, page))		errorMsg = concat(errorMsg)	else		errorMsg = ''	end	return graphics .. linkText .. cities .. errorMsgendfunction p.jct(frame)	-- Import module function to work with passed arguments	local getArgs = require('Module:Arguments').getArgs	local args = getArgs(frame, {removeBlanks = false})	return p._jct(args, frame)endfunction p._roadlink(args, frame)	local routes = parseArgs(args)	local links = {}	local typeErr = false	local toErr = false	frame = frame or mw.getCurrentFrame()	for num,route in ipairs(routes) do		local prefix = prefix(route.to, num)		if prefix ~= '' then insert(links, prefix) end		insert(links, routeText(route, args.jctname, frame))		typeErr = typeErr or route.typeerror or false		toErr = toErr or route.toerror or false	end	local linkText = concat(links)	local cities = ''	if args.city1 or args.location1 then		local citiesPrefix		if args.citiesprefix then			citiesPrefix = args.citiesprefix ~= '' and format(" %s ", args.citiesprefix) or ''		else			citiesPrefix = '&nbsp;'		end		local cityModule = require(cityModuleName)		cities = citiesPrefix .. cityModule.city(args)	end	local errorMsg = {}	-- Errors must be reported by the level of severity, most severe first.	if typeErr then		-- Report invalid type errors.		addErrorMsg("2", 'error: Invalid route type', errorMsg)	end	if toErr then		-- Report invalid to errors.		addErrorMsg("3", 'error: Invalid "to" argument', errorMsg)	end	if args.road then		-- Report deprecated "road" warning.		addErrorMsg("W", 'warning: "road" parameter is deprecated', errorMsg)	end	if #errorMsg > 0 then		local page = mw.title.getCurrentTitle().prefixedText -- Get transcluding page's title		-- Add a category for the first, most severe error.		insert(errorMsg, format('[[Thể loại:Lỗi bản mẫu Jct|%s %s]]', errorMsg.code, page))		errorMsg = concat(errorMsg)	else		errorMsg = ''	end	return linkText .. citiesendfunction p.roadlink(frame)	-- Import module function to work with passed arguments	local getArgs = require('Module:Arguments').getArgs	local args = getArgs(frame, {removeBlanks = true})	return p._roadlink(args, frame)endreturn p