Jump to content

Module:fi-dialects

From Wiktionary, the free dictionary

Implements the basics of the Finnish dialectal data framework, including Group for dialect groups, Area for dialect areas, and Parish for parishes (pitäjä). Each area belongs to a group and each parish to an area, forming a tree structure.


local export = {}

local Group = {}

local function makeGroup(code, data)
	return data and setmetatable({ _code = code, _data = data }, Group)
end

function Group:getCode()
	return self._code
end

function Group:getFinnishName()
	return self._data.finnish or self._code
end

function Group:getEnglishName()
	return self._data.english or self._data.finnish or self._code
end

function Group:getBranch()
	return self._data.branch
end

function Group:getFormattedName()
	if self._data.english and self:getEnglishName() ~= self:getFinnishName() then
		return self:getEnglishName() .. " (" .. self:getFinnishName() .. ")"
	else
		return self:getFinnishName()
	end
end

function Group:getFormattedNameWithLink()
	if self._data.Wikipedia then
		if self._data.english then
			return "[[w:" .. self._data.Wikipedia .. "|" .. self:getEnglishName() .. "]] (" .. self:getFinnishName() .. ")"
		else
			return "[[w:" .. self._data.Wikipedia .. "|" .. self:getFinnishName() .. "]]"
		end
	else
		return self:getFormattedName()
	end
end

function Group:getWikipediaArticle()
	return self._data.Wikipedia
end

function Group:getWikidataItem()
	local item = self._data.wikidata
	if type(item) == "number" then
		return "Q" .. item
	else
		return item
	end
end

Group.__index = Group

function export.getGroup(code, nil_on_failure)
	local area_data = mw.loadData("Module:fi-dialects/data/area")
	return makeGroup(code, area_data.groups[code] or (not nil_on_failure and error("Group not found by code: " .. code) or nil))
end

local function findAreaFrom(areas, code, original_code, root, nil_on_failure)
	local area = code
	local subarea = nil
	if code:find("/") then
		local slash = code:find("/")
		area = code:sub(1, slash - 1)
		subarea = code:sub(slash + 1)
	end
	local result = areas and areas[area]
	if not result then
		if nil_on_failure then return nil end
		error("Area not found from data: " .. original_code)
	end
	if not root then
		root = result
	end
	if subarea then
		return root, findAreaFrom(result.subareas, subarea, original_code)
	end
	return root, result
end

local Area = {}

local function makeArea(code, root, data)
	return data and setmetatable({ _code = code, _root = root, _data = data }, Area)
end

function export.getArea(code, nil_on_failure)
	local area_data = mw.loadData("Module:fi-dialects/data/area")
	local subarea = nil
	if area_data.area_aliases[code] then
		code = area_data.area_aliases[code]
	end
	return makeArea(code, findAreaFrom(area_data.areas, code, code, nil, nil_on_failure))
end

function Area:getCode()
	return self._code
end

function Area:getFinnishName()
	return self._data.finnish or self._code
end

function Area:getEnglishName()
	return self._data.english or self._data.finnish or self._code
end

function Area:getFormattedName()
	if self._data.english and self:getEnglishName() ~= self:getFinnishName() then
		return self:getEnglishName() .. " (" .. self:getFinnishName() .. ")"
	else
		return self:getFinnishName()
	end
end

function Area:getFormattedNameWithLink()
	if self._data.Wikipedia then
		if self._data.english then
			return "[[w:" .. self._data.Wikipedia .. "|" .. self:getEnglishName() .. "]] (" .. self:getFinnishName() .. ")"
		else
			return "[[w:" .. self._data.Wikipedia .. "|" .. self:getFinnishName() .. "]]"
		end
	else
		return self:getFormattedName()
	end
end

function Area:getBranch()
	return self._root.branch
end

function Area:getGroupCode()
	return self._data.group or self._root.group
end

function Area:getGroup()
	return (self._data.group or self._root.group) and export.getGroup(self._data.group or self._root.group)
end

function Area:getWikipediaArticle()
	return (self._data.Wikipedia or self._root.Wikipedia)
end

function Area:getWikidataItem()
	local item = (self._data.wikidata or self._root.wikidata)
	if type(item) == "number" then
		return "Q" .. item
	else
		return item
	end
end

function Area:getSuperArea()
	if self == self._root then
		return nil
	end
	return export.getArea(mw.ustring.gsub(self._code, "/[^/]+$", ""))
end

function Area:getSubAreas()
	if self._data.subareas then
		local subareas = {}
		for key, subarea in pairs(self._data.subareas) do
			subareas[key] = makeArea(self._code .. "/" .. key, self._root, subarea)
		end
		return subareas
	end
	return {}
end

Area.__index = Area

local Parish = {}

local function makeParish(code, canonical_code, data)
	return data and setmetatable({ _code = code, _canonical = canonical_code, _data = data }, Parish)
end

function export.getParish(code, nil_on_failure)
	local parish_data = mw.loadData("Module:fi-dialects/data/parish")
	local canonical_code = parish_data.parish_aliases[code] or code
	return makeParish(code, canonical_code, parish_data.parishes[canonical_code] or (not nil_on_failure and error("Parish not found by code: " .. code) or nil))
end

function Parish:getCode()
	return self._code
end

function Parish:getCanonicalCode()
	return self._canonical
end

function Parish:getFinnishName()
	return self._data.finnish or self._canonical
end

function Parish:getEnglishName()
	return self._data.english or self._data.finnish or self._canonical
end

function Parish:getFormattedName()
	if self._data.english and self:getEnglishName() ~= self:getFinnishName() then
		return self:getEnglishName() .. " (" .. self:getFinnishName() .. ")"
	else
		return self:getFinnishName()
	end
end

function Parish:getWikipediaArticle(cheap)
	if self._data.Wikipedia or cheap then return self._data.Wikipedia end
	local item = self:getWikidataItem()
	if not item then return nil end
	local entity = mw.wikibase.getEntity(item)
	if not entity then return nil end
	return entity:getSitelink("enwiki")
end

function Parish:getWikidataItem()
	local item = self._data.wikidata
	if type(item) == "number" then
		return "Q" .. item
	else
		return item
	end
end

function Parish:getAreaCode()
	return self._data.area
end

function Parish:getArea()
	return export.getArea(self._data.area)
end

function Parish:getCoordinates()
	if self._data.latitude == nil or self._data.longitude == nil then
		return nil
	end
	return self._data.latitude, self._data.longitude
end

Parish.__index = Parish

return export