Jump to content

Module:country flags

From Wiktionary, the free dictionary

Generates the list in Wiktionary:Language flags list and the table in Wiktionary:Language flags.


local export = {}

local Array = require "Module:array"

local function normalize_language_name(language_name)
	return language_name:gsub("_", " "):gsub("\\'", "'")
end

function export.show_list(frame)
	local language_names = require "Module:languages/canonical names"
	local input = frame.args[1]
	local raw_list = assert(
		input,
		"expected raw list in first parameter")
	local output = Array()
	local invalid_lines = Array()
	local invalid_language_names = Array()
	for line in raw_list:gmatch "[^\n]+" do
		local language, rest = line:match("^(.-): (.+)$")
		if not language then
			invalid_lines:insert(line)
		else
			local language_with_spaces = normalize_language_name(language)
			if not language_names[language_with_spaces] then
				invalid_language_names:insert(language_with_spaces)
			end
			local image, pixels = rest:match("^(.+) (%d+px)$")
			if not image then
				image = rest
			end
			pixels = pixels or "45px"
			output:insert(("* %s: [[File:%s|border|%s]]"):format(language, image, pixels))
		end
	end
	if #invalid_lines > 0 then
		local invalid_lines_printed = invalid_lines
			:map(function(line)
				return "<code>" .. mw.text.nowiki(line) .. "<code>"
			end)
			:concat ", "
		output:insert(1, ("The following line%s invalid syntax: %s")
			:format(
				#invalid_lines == 1 and " has" or "s have",
				invalid_lines_printed))
	end
	if #invalid_language_names > 0 then
		local language_names_printed = invalid_language_names
			:map(function(name)
				return "“" .. name .. "”"
			end)
			:concat(", ")
		output:insert(1, ("The following language name%s not found in the "
			.. "[[:Category:Language data modules|language data modules]]: %s."):format(
			#invalid_language_names == 1 and " was" or "s were",
			language_names_printed))
	end
	return output:concat "\n"
end

local function normalize_file_name(file_name)
	return mw.uri.decode(file_name:gsub("_", " "), "PATH")
end

local function compare_language_names(a, b)
	if a == "Translingual" or b == "Translingual" then
		return a == "Translingual"
	elseif a == "English" or b == "English" then
		return a == "English"
	else
		return a < b
	end
end

local function parse_flag_list(raw_flag_list)
	local flag_map = {}
	local image_size = {}
	for line in raw_flag_list:gmatch "[^\n]+" do
		local language, rest = line:match("^(.-): (.+)$")
		if language then -- ignore invalid lines
			local image, pixels = rest:match("^(.+) (%d+px)$")
			if not image then
				image = rest
			end
			language = normalize_language_name(language)
			image = normalize_file_name(image)
			flag_map[language] = image
			image_size[image] = pixels
		end
	end
	return flag_map, image_size
end

local function parse_image_info(raw_image_info)
	local image_order = Array()
	local image_info = {}
	local invalid_lines = Array()
	local duplicate_info = Array()
	for line in raw_image_info:gmatch "[^\n]+" do
		local image, info = line:match("^(.-): (.+)$")
		if not image then
			invalid_lines:insert(line)
		else
			image = normalize_file_name(image)
			if image_info[image] then
				duplicate_info:insert(line)
			else
				image_info[image] = info
			end
		end
	end
	return image_info, invalid_lines, duplicate_info
end

function export.show_info(frame)
	local flag_list_title = frame.args[1]
	local raw_image_info = frame.args[2]
	
	local flag_list_page = assert(mw.title.new(flag_list_title))
	local flag_list_page_content = assert(flag_list_page:getContent())
	local raw_flag_list = assert(flag_list_page_content:match("<!%-%- start list %-%->%s*(.-)%s*<!%-%- end list %-%->"))
	
	local image_info, invalid_lines, duplicate_info = parse_image_info(raw_image_info)
	
	local flag_map, image_size = parse_flag_list(raw_flag_list)
	
	if #duplicate_info > 0 then
		mw.log("Duplicate image info:\n" .. duplicate_info:concat "\n")
	end
	
	if #invalid_lines > 0 then
		mw.log("Invalid lines:\n" .. invalid_lines:concat "\n")
	end
	
	local output = Array([[
{| class="wikitable"
! Language
! Flag
! Represents]])
	for language, image in require "Module:table".sortedPairs(flag_map, compare_language_names) do
		local row = Array()
		row:insert("| " .. language)
		row:insert(("| [[File:%s|border|%s]]"):format(image, image_size[image] or "45px"))
		row:insert("| " .. (image_info[image] or "?"))
		output:insert(row:concat "\n")
	end
	return output:concat "\n|-\n" .. "\n|}"
		.. "\n\n==Flags without a description==\n"
		.. export.show_images_with_missing_info(frame)
end

function export.sort_raw_image_info(frame)
	local raw_image_info = frame.args[1]
	local lines = Array(mw.text.split(raw_image_info))
		:filter(function(line) return not line:match "^%s*" end)
	local flag_of = Array {
		"Flag of the prince-bishopric of ",
		"Flag of the ",
		"Flag of ",
		"Bandeira do ",
		"Bandeira-de-",
		"Zastava ",
	}:map(require "Module:string utilities".pattern_escape)
	
	local function key(line)
		local image = line:match "[^:]+"
		local flag
		for _, prefix in ipairs(flag_of) do
			local res, count = image:gsub("^" .. prefix, "")
			if count == 1 then
				flag = res
				break
			end
		end
		return (flag or image):lower()
	end
	
	lines:sort(function(a, b) return key(a) < key(b) end)
	
	return lines:concat "\n"
end

function export.show_images_with_missing_info(frame)
	local flag_list_title = frame.args[1]
	local raw_image_info = frame.args[2]
	
	local flag_list_page = assert(mw.title.new(flag_list_title))
	local flag_list_page_content = assert(flag_list_page:getContent())
	local raw_flag_list = assert(flag_list_page_content:match("<!%-%- start list %-%->%s*(.-)%s*<!%-%- end list %-%->"))
	
	local image_info, invalid_lines, duplicate_info = parse_image_info(raw_image_info)
	
	local flag_map, image_size = parse_flag_list(raw_flag_list)
	
	if #duplicate_info > 0 then
		mw.log("Duplicate image info:\n" .. duplicate_info:concat "\n")
	end
	
	if #invalid_lines > 0 then
		mw.log("Invalid lines:\n" .. invalid_lines:concat "\n")
	end
	
	local output = Array()
	for language, image in require "Module:table".sortedPairs(flag_map, compare_language_names) do
		if not image_info[image] then
			output:insert(image .. ":\n")
		end
	end
	
	return require "Module:debug".highlight(output:concat(), { lang = "text" })
end

return export