Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:ISO 3166/sandbox

From Wikipedia, the free encyclopedia
-- to enable us to replicate the current functioning of Country extract, we need to deal with:
-- 2 {{<name>}} DONE!
-- 3 [[<name>]] DONE!
-- 4 [[<name>|<junk>]] DONE!
-- 5 [[image:flag of <country>.[svg|gif|png|jpg]|\d+px]] DONE!

local p = {}
local getArgs = require("Module:Arguments").getArgs
local data = mw.loadData("Module:ISO 3166/data/National/sandbox")

--[[----------C A T S----------]]--												-- Assign error categories
local function cats(cat, args)
	if not (args.nocat and args.nocat == 'true') and mw.title.getCurrentTitle().namespace == 0 then
		if cat == 'nocountry' then
			return '[[Category:Wikipedia articles with obscure country]]'
		elseif cat == 'nosubdivision' then
			return '[[Category:Wikipedia articles with obscure subdivision]]'
		end
	end
	return ''
end

--[[----------F I N D N A M E----------]]--										-- Finds the name in the database

local function findname(code,cdata,qry)
	local sqry = p.strip(qry)
	if cdata["name"] and sqry==p.strip(cdata["name"])
		or cdata["isoname"] and sqry==p.strip(cdata["isoname"])
		or not cdata["nocode"] and sqry==code
		or sqry==cdata["alpha3"] or sqry==cdata["numeric"]
		then
		return true
	end
	for _,tname in pairs(cdata["isonames"] or {}) do
		if sqry==p.strip(tname) then
			return true
		end
	end
	for _,tname in pairs(cdata["altnames"] or {}) do
		if sqry==p.strip(tname) then
			return true
		end
	end
	return false
end

--[[----------I S O N A M E----------]]--										-- Find the ISO name of a country/region

local function isoname(isodata,code,lang)
	if isodata[code]["isonames"] then
		local name = isodata[code]["isodisplaynames"] and isodata[code]["isodisplaynames"][lang]
			 or isodata[code]["isonames"][lang]
			 or isodata[code]["isodisplaynames"] and isodata[code]["isodisplaynames"][isodata[code]["defaultlang"] or isodata["defaultlang"]]
			 or isodata[code]["isonames"][isodata[code]["defaultlang"] or isodata["defaultlang"]]
			 or isodata[code]["isodisplaynames"] and isodata[code]["isodisplaynames"]["en"]
			 or isodata[code]["isonames"]["en"]
		if name then return name end
		for _,iname in pairs(isodata[code]["isonames"]) do return iname end
		return isodata[code]["isodisplayname"] or isodata[code]["isoname"]
	else
		return isodata[code]["isodisplayname"] or isodata[code]["isoname"]
	end
end

--[[----------S T R I P----------]]--											-- Removes junk from the input

function p.strip(text)
	if not text then return nil end
	
	local accents = {["À"]="A",["Á"]="A",["Â"]="A",["Ã"]="A",["Ä"]="A",
		["Å"]="A",["Æ"]="AE",["Ç"]="C",["È"]="E",["É"]="E",["Ê"]="E",["Ë"]="E",
		["Ì"]="I",["Í"]="I",["Î"]="I",["Ï"]="I",["Ð"]="D",["Ñ"]="N",["Ò"]="O",
		["Ó"]="O",["Ô"]="O",["Õ"]="O",["Ö"]="O",["Ø"]="O",["Ù"]="U",["Ú"]="U",
		["Û"]="U",["Ü"]="U",["Ý"]="Y",["Þ"]="TH",["Ā"]="A",["Ă"]="A",["Ą"]="A",
		["Ć"]="C",["Ĉ"]="C",["Ċ"]="C",["Č"]="C",["Ď"]="D",["Đ"]="D",["Ē"]="E",
		["Ĕ"]="E",["Ė"]="E",["Ę"]="E",["Ě"]="E",["Ĝ"]="G",["Ğ"]="G",["Ġ"]="G",
		["Ģ"]="G",["Ĥ"]="H",["Ħ"]="H",["Ĩ"]="I",["Ī"]="I",["Ĭ"]="I",["Į"]="I",
		["İ"]="I",["IJ"]="IJ",["Ĵ"]="J",["Ķ"]="K",["Ĺ"]="L",["Ļ"]="L",["Ľ"]="L",
		["Ŀ"]="L",["Ł"]="L",["Ń"]="N",["Ņ"]="N",["Ň"]="N",["Ŋ"]="N",["Ō"]="O",
		["Ŏ"]="O",["Ő"]="O",["Œ"]="OE",["Ŕ"]="R",["Ŗ"]="R",["Ř"]="R",["Ś"]="S",
		["Ŝ"]="S",["Ş"]="S",["Š"]="S",["Ţ"]="T",["Ť"]="T",["Ŧ"]="T",["Ũ"]="U",
		["Ū"]="U",["Ŭ"]="U",["Ů"]="U",["Ű"]="U",["Ų"]="U",["Ŵ"]="W",["Ŷ"]="Y",
		["Ÿ"]="Y",["Ź"]="Z",["Ż"]="Z",["Ž"]="Z",["Ɓ"]="B",["Ƃ"]="B",["Ɔ"]="C",
		["Ƈ"]="C",["Ɖ"]="D",["Ɗ"]="D",["Ƌ"]="D",["Ǝ"]="E",["Ə"]="E",["Ɛ"]="E",
		["Ƒ"]="F",["Ɠ"]="G",["Ɣ"]="G",["Ɩ"]="I",["Ɨ"]="I",["Ƙ"]="K",["Ɯ"]="M",
		["Ɲ"]="N",["Ɵ"]="O",["Ơ"]="O",["Ƣ"]="OI",["Ƥ"]="P",["Ʃ"]="SH",["Ƭ"]="T",
		["Ʈ"]="T",["Ư"]="U",["Ʊ"]="U",["Ʋ"]="V",["Ƴ"]="Y",["Ƶ"]="Z",["Ʒ"]="Z",
		["Ƹ"]="Z",["DŽ"]="DZ",["LJ"]="LJ",["NJ"]="NJ",["Ǎ"]="A",["Ǐ"]="I",
		["Ǒ"]="O",["Ǔ"]="U",["Ǖ"]="U",["Ǘ"]="U",["Ǚ"]="U",["Ǜ"]="U",["Ǟ"]="A",
		["Ǡ"]="A",["Ǣ"]="AE",["Ǥ"]="G",["Ǧ"]="G",["Ǩ"]="K",["Ǫ"]="O",["Ǭ"]="O",
		["Ǯ"]="Z",["DZ"]="DZ",["Ǵ"]="G",["Ƕ"]="HV",["Ƿ"]="W",["Ǹ"]="N",["Ǻ"]="A",
		["Ǽ"]="AE",["Ǿ"]="O",["Ȁ"]="A",["Ȃ"]="A",["Ȅ"]="E",["Ȇ"]="E",["Ȉ"]="I",
		["Ȋ"]="I",["Ȍ"]="O",["Ȏ"]="O",["Ȑ"]="R",["Ȓ"]="R",["Ȕ"]="U",["Ȗ"]="U",
		["Ș"]="S",["Ț"]="T",["Ȝ"]="Z",["Ȟ"]="H",["Ƞ"]="N",["Ȣ"]="OU",["Ȥ"]="Z",
		["Ȧ"]="A",["Ȩ"]="E",["Ȫ"]="O",["Ȭ"]="O",["Ȯ"]="O",["Ȱ"]="O",["Ȳ"]="Y",
		["Ⱥ"]="A",["Ȼ"]="C",["Ƚ"]="L",["Ⱦ"]="T",["Ƀ"]="B",["Ʉ"]="U",["Ʌ"]="V",
		["Ɇ"]="E",["Ɉ"]="J",["Ɋ"]="Q",["Ɍ"]="R",["Ɏ"]="Y",
	}
	local remove = {"COUNTRY OF ", "COUNTY ", " COUNTY$", "FLAG OF ", " FLAG$",	-- text to be removed list
		" GOVERNORATE$", "KINGDOM OF ", "NATION OF ", "PROVINCE OF ",
		" PROVINCE$", "STATE OF ", " STATE$", "TERRITORY OF ",
	}
	local patterns = {"(%a)%.(%a)%.", ".+:", "|.+", "%(.-%)", "%.%S.*",			-- patterns to follow (order may matter)
		"^%s*THE ", "_", "%-", "%d%d?%d?PX", "%s+"
	}
	local replacements = {["(%a)%.(%a)%."]="%1%2",								-- Replacements for patterns above (order does not matter)
		[".+:"]="", ["|.+"]="", ["%(.-%)"]="",									
		["%.%S.*"]="", ["^%s*THE "]="", ["_"]=" ", ["%-"]=" ",
		["%d%d?%d?PX"]="", ["%s+"]=" "
	}
	
	text = mw.text.decode(text)                                                 -- Decode HTML entities (passed from wikidata?)
	text = mw.text.killMarkers(text)											-- Remove <nowiki> and <ref> tags
	text = mw.ustring.upper(text)												-- Case insensitivity
	text = mw.ustring.gsub(text,"[À-Ɏ]",accents)								-- Deaccent
	
	for _,pattern in ipairs(patterns) do										-- Follow patterns
		text = mw.ustring.gsub(text,pattern,replacements[pattern]) 
	end
	
	for _,words in pairs(remove) do												-- Remove unneeded words
		text = mw.ustring.gsub(text,words,"") 
	end

	text = mw.ustring.gsub(text,"^%s*THE ","")									-- Final "The" replacement
	
	text = mw.ustring.gsub(text,"%W","")										-- Remove non alpha-numeric
	
	return text
	
end

--[[----------P . C A L L S T R I P ---------]]--								-- Calls P.strip but using Module:Arguments

function p.callstrip(frame)
	
	local args = getArgs(frame)
	
	return p.strip(args[1]) or ""

end

--[[----------P . L U A C O D E---------]]--									-- Makes the ISO code of a country

function p.luacode(args)
	args[1], args[2] = args[1] or '', args[2] or ''
	local code1 = p.strip(args[1])
	local code2 = p.strip(args[2])

	if args["codetype"]=="3" then args["codetype"]="alpha3" end
	
	local eot = args.error or ""
	
	if code1 == "" then
		mw.addWarning((args[1] ~= "" and ('Invalid parameter "' .. args[1] .. '"') or 'No parameter') ..
			' for the country given ([[Module:ISO 3166]]).')
		return cats('nocountry', args), '<span style="font-size:100%" class="error">"No parameter for the country given"</span>'
	end

	local notRecognized ='%s ("%s") is not a recognized %s in [[ISO 3166-%s]] ([[Module:ISO 3166]]).'
	
	if code2 == "" then													--3166-1 code
		for alpha2,cdata in pairs(data) do
			if findname(alpha2,cdata,code1) then
				if args["codetype"]=="numeric" or args["codetype"]=="alpha3" then
					return cdata[args["codetype"]]
				else
					return alpha2
				end
			end
		end
		if string.find(args[1],"%-") then
			args[1], args[2] = string.match(args[1],"^([^%-]*)%-(.*)$")
			if args[2] then return p.luacode(args) end
		end
		mw.addWarning(string.format(notRecognized, code1, args[1], 'country', '1'))
		return cats('nocountry', args)
	else																		--3166-2 code
		for alpha2,cdata in pairs(data) do                                       
			if findname(alpha2,cdata,code1) then
				if mw.ustring.match(alpha2,"GB") then							-- For England, Wales etc.
					alpha2 = "GB"
				end
				local sdata = mw.loadData("Module:ISO 3166/data/"..alpha2)
				local empty = true
				for scode,scdata in pairs(sdata) do
					if type(scdata)=="table" then
						empty = false
						if findname(scode,scdata,code2) then
							return alpha2.."-"..scode
						end
					end
				end
				if string.find(args[2] or '',"%-") then
					code1, args[2] = string.match(args[2] or '',"^([^%-]*)%-(.*)$")
					args[1] = args[1].."-"..code1
					return p.luacode(args)
				end
				mw.addWarning(string.format(notRecognized, code2, args[2], 'subdivision', '2:' .. alpha2))
				return cats('nosubdivision', args)
			end
		end
		if string.find(args[1],"%-") then
			args[1] = string.match(args[1],"^([^%-]*)%-(.*)$")
			return p.luacode(args)
		end
		mw.addWarning(string.format(notRecognized, code1, args[1], 'country', '1'))
		return cats('nocountry', args)
	end
	mw.addWarning(string.format(notRecognized, code1, args[1], 'country', '1'))
	return cats('nocountry', args)
end

--[[----------P . C O D E---------]]--											-- Calls P.Luacode but using Module:Arguments

function p.code(frame)

	return p.luacode(getArgs(frame)) or ""

end

--[[----------P . N U M E R I C---------]]--									-- Calls P.Luacode but using Module:Arguments and setting it to output a numeric value

function p.numeric(frame)

	local args = getArgs(frame)
	
	args["codetype"]="numeric"
	
	return p.luacode(args) or ""
	
end
	
--[[----------P . L U A N A M E---------]]--									-- Makes the ISO/common name of a country
	
function p.luaname(args)

	local code1 = p.luacode(args)
	local code2 = ''
		
	if string.find(code1,"%-") then
		code1, code2 = string.match(code1,"^([^%-]*)%-(.*)$")
	end
	
	if string.find(code1,"^%u%u$") then
		if code2=="" then														--3166-1 alpha-2 code
			if data[code1] then
				return (args.isoname or args.lang) and isoname(data,code1,args.lang)
					or (data[code1]["displayname"] or data[code1]["name"])
			else
				return cats('nocountry', args)
			end
		else																	--3166-2 code
			local sdata
			if data[code1] then
				sdata = mw.loadData("Module:ISO 3166/data/"..code1)
			else
				return cats('nocountry', args)
			end
			if sdata[code2] then
				return (args.isoname or args.lang) and isoname(sdata,code2,args.lang)
					or (sdata[code2]["displayname"] or sdata[code2]["name"])
			else
				return cats('nocountry', args)
			end
		end
	elseif args.notfound then
		return args.notfound
	end
	
end

--[[----------P . N A M E---------]]--											-- Calls P.Luaname but using Module:Arguments

function p.name(frame)

	return p.luaname(getArgs(frame)) or ""

end
	
--[[----------P . G E O C O O R D I N S E R T---------]]--						-- Wrapper for Module:Coordinates.coordinsert
function p.geocoordinsert(frame)
	-- {{#invoke:ISO 3166|geocoordinsert|{{coord|...}}
	-- |country=..|subdivision1=...|subdivision2=...
	-- |type=...|scale=...|dim=...|source=...|globe=...
	-- }}
	local args = frame.args
	local subdivisionqueried = false
	local tracking = ''
	local targs = {}
	targs[1] = args[1] or ''
	for i, v in pairs(args) do
		if i == 'country' and not mw.ustring.find(targs[1], 'region:') then
			local country = v
			local k, region = 1, ''
			-- look for a valid subdivision
			while region == '' and k < 3 do
				local subdivision = args['subdivision' .. k] or ''
				if subdivision ~= '' then
					region = p.luacode({country, subdivision, nocat = 'true'})
					subdivisionqueried = true
				end
				k = k + 1
			end
			-- subdivision lookup failed or never attempted, try country only
			if region == '' then
				region = p.luacode({country, nocat = 'true'})
				if region == '' then
					tracking = tracking .. cats('nocountry', args)
				elseif subdivisionqueried == true then
					tracking = tracking .. cats('nosubdivision', args)
				end
			end
			-- something worked, add it to the targs
			if region ~= '' then
				targs[#targs + 1] = 'region:' .. region
			end
		elseif i == 'type' or i == 'scale' or i == 'dim' 
				or i == 'source' or i == 'globe' then
			targs[#targs + 1] = i .. ':' .. v
		end
	end
	-- call Module:Coordinates.coordinsert if there is something to insert
	if #targs > 1 then
		local coordinsert = require('Module:Coordinates').coordinsert
		return coordinsert({args = targs}) .. tracking
	end
	-- otherwise, just return the coordinates
	return targs[1] .. tracking
end

return p