Module:Geography

From stencil.wiki
Revision as of 03:09, 11 January 2025 by Robertbaxter (talk | contribs)

Documentation for this module may be created at Module:Geography/doc

local p = {}

local CLASS_INFO = {
	place = {
		standard_category = "Places in @@@@"
	}, event = {
		standard_category = "Events in @@@@",
		multi_category = {
			country = "International events",
			state_province = "Multi-state/province events",
			city = "Multi-city events"
		}
	}
}

function p.geoCategories(frame)
	local args = frame.args or frame:getParent().args
	local class = args["class"]
	local country = args["country"]
	local state_province = args["state_province"]
	local city = args["city"]
	local regional = args["region"]
	
	local result = ""
	if country ~= nil then
		result = result .. geographicCategory(countryWithArticle(country), class, "country")
	end
	if state_province ~= nil then
		result = result .. geographicCategory(state_province, class, "state_province")
	end
	if city ~= nil then
		result = result .. geographicCategory(city, class, "city")
	end
	if regional and country ~= nil then
		result = result .. geographicCategory(getRegion(country), class, "region")
	end
	
	return result
end

-- DEPRECATED
function p.sharedPlace(frame)
    local args = frame.args or frame:getParent().args
    local a = ""
    local b = true
    for name in string.gmatch(args[1], "[^,]+") do
    	name = name:gsub("^%s*(.-)%s*$", "%1")
		if a == "" then
			a = name
		elseif a ~= name then
			b = false
		end
	end
	if b then return a else return "" end
end

-- If all strings in the list are identical, returns the string, otherwise
-- returns nil (ignores blank string items, if all strings are blank returns
-- the blank string).
local function sharedPlace(list)
	local result = ""
    if type(list) == string then
    	for name in string.gmatch(list, "[^,]+") do
	    	name = name:gsub("^%s*(.-)%s*$", "%1")
	    	if name ~= "" then
	    		if result == "" then
					result = name
				elseif result ~= name then
					return false
				end	
	    	end
		end
    elseif type(list) == table then
	    for name in list do
			if name ~= "" then
	    		if result == "" then
					result = name
				elseif result ~= name then
					return false
				end	
	    	end
	    end
	end
	return result
end

-- Base function to generate a category for a geographic division given a
-- data string (the name of that division or a CSV list of multiple names
-- (primarily for events taking place in multiple areas).
function geographicCategory(data, class, division)
	if data == "" then return "" end
	
	if data:match(',') then
		-- Query is a list, determine if the items in the list are identical.
		local shared = sharedPlace(data)
		if shared == false then
			-- If they are differnt, need to render a multi-category (if there
			-- is one for the specified class + division) or each unique
			-- category (if not).
			if CLASS_INFO[class]["multi-category"] ~= nil
					and CLASS_INFO[class]["multi-category"][division] ~= nil then
				return "[[Category:" .. CLASS_INFO[class]["multi-category"][division] .. "]]"
			else
				local result = ""
				local history = {}
				for name in string.gmatch(list, "[^,]+") do
					name = name:gsub("^%s*(.-)%s*$", "%1")
			    	if name ~= "" and not history[name] then
			    		history[name] = true
			    		result = result .. geographicCategory(name, class, division)
			    	end
				end
				return result
			end
		else
			-- Items in the list match, just render the category for the
			-- shared value.
			data = shared
		end
	end

	return "[[Category:" .. CLASS_INFO[class]["standard_category"].gsub("@@@@", data) .. "]]"
end

function getRegion(country)
    -- Switch on the provided country and return the region string.
end

function countryWithArticle(country)
	-- Adds the article "the" to country names that use it
	-- (e.g. "the Netherlands").
end

return p