Module:Languages

local export = {}

local Language = {}

function Language:getCode return self._code end

function Language:getCanonicalName return self._rawData.canonicalName end

-- Commented out; I don't think anything uses this, the presence/absence of script errors should confirm --function Language:getAllNames --	return self._rawData.names --end

function Language:getOtherNames return self._rawData.otherNames or {} end

function Language:getType return self._rawData.type or "regular" end

function Language:getWikimediaLanguages if not self._wikimediaLanguageObjects then local m_wikimedia_languages = require("Module:wikimedia languages") self._wikimediaLanguageObjects = {} local wikimedia_codes = self._rawData.wikimedia_codes or {self._code} for _, wlangcode in ipairs(wikimedia_codes) do			table.insert(self._wikimediaLanguageObjects, m_wikimedia_languages.getByCode(wlangcode)) end end return self._wikimediaLanguageObjects end

function Language:getWikipediaArticle return self._rawData.wikipedia_article or self:getCategoryName end

function Language:getScripts if not self._scriptObjects then local m_scripts = require("Module:scripts") self._scriptObjects = {} for _, sc in ipairs(self._rawData.scripts or {"None"}) do			table.insert(self._scriptObjects, m_scripts.getByCode(sc)) end end return self._scriptObjects end

function Language:getFamily if self._rawData.family and not self._familyObject then self._familyObject = require("Module:families").getByCode(self._rawData.family) end return self._familyObject end

function Language:getAncestors if not self._ancestorObjects then self._ancestorObjects = {} if self._rawData.ancestors then for _, ancestor in ipairs(self._rawData.ancestors) do				table.insert(self._ancestorObjects, export.getByCode(ancestor) or require("Module:etymology languages").getByCode(ancestor)) end else local fam = self:getFamily local protoLang = fam and fam:getProtoLanguage or nil -- For the case where the current language is the proto-language -- of its family, we need to step up a level higher right from the start. if protoLang and protoLang:getCode == self:getCode then fam = fam:getFamily protoLang = fam and fam:getProtoLanguage or nil end while not protoLang and not (not fam or fam:getCode == "qfa-not") do				fam = fam:getFamily protoLang = fam and fam:getProtoLanguage or nil end table.insert(self._ancestorObjects, protoLang) end end return self._ancestorObjects end

local function iterateOverAncestorTree(node, func) for _, ancestor in ipairs(node:getAncestors) do		if ancestor then local ret = func(ancestor) or iterateOverAncestorTree(ancestor, func) if ret then return ret end end end end

function Language:getAncestorChain if not self._ancestorChain then self._ancestorChain = {} local step = #self:getAncestors == 1 and self:getAncestors[1] or nil while step do			table.insert(self._ancestorChain, 1, step) step = #step:getAncestors == 1 and step:getAncestors[1] or nil end end return self._ancestorChain end

function Language:hasAncestor(otherlang) local function compare(ancestor) return ancestor:getCode == otherlang:getCode end return iterateOverAncestorTree(self, compare) or false end

function Language:getCategoryName local name = self._rawData.canonicalName -- If the name already has "language" in it, don't add it. if name:find("[Ll]anguage$") then return name else return name .. " language" end end

function Language:getStandardCharacters return self._rawData.standardChars end

function Language:makeEntryName(text) text = mw.ustring.gsub(text, "^[¿¡]", "") text = mw.ustring.gsub(text, "(.)[؟?!;՛՜ ՞ ՟？！।॥။၊་།]$", "%1") if self._rawData.entry_name then for i, from in ipairs(self._rawData.entry_name.from) do			local to = self._rawData.entry_name.to[i] or "" text = mw.ustring.gsub(text, from, to) end end return text end

function Language:makeSortKey(name) name = mw.ustring.lower(name) -- Remove initial hyphens and * local hyphens_regex = "^[-־ـ*]+(.)" name = mw.ustring.gsub(name, hyphens_regex, "%1")

-- Remove parentheses, as long as they are either preceded or followed by something name = mw.ustring.gsub(name, "(.)[]+", "%1") name = mw.ustring.gsub(name, "[]+(.)", "%1") -- If there are language-specific rules to generate the key, use those if self._rawData.sort_key then for i, from in ipairs(self._rawData.sort_key.from) do			local to = self._rawData.sort_key.to[i] or "" name = mw.ustring.gsub(name, from, to) end end return mw.ustring.upper(name) end

function Language:transliterate(text, sc, module_override) if not ((module_override or self._rawData.translit_module) and text) then return nil end if module_override then require("Module:debug").track("module_override") end return require("Module:" .. (module_override or self._rawData.translit_module)).tr(text, self:getCode, sc and sc:getCode or nil) end

function Language:link_tr return self._rawData.link_tr and true or false end

function Language:toJSON local entryNamePatterns = nil if self._rawData.entry_name then entryNamePatterns = {} for i, from in ipairs(self._rawData.entry_name.from) do			local to = self._rawData.entry_name.to[i] or "" table.insert(entryNamePatterns, {from = from, to = to}) end end local ret = { ancestors = self._rawData.ancestors, canonicalName = self:getCanonicalName, categoryName = self:getCategoryName, code = self._code, entryNamePatterns = entryNamePatterns, family = self._rawData.family, otherNames = self:getOtherNames, scripts = self._rawData.scripts, type = self:getType, wikimediaLanguages = self._rawData.wikimedia_codes, }	return require("Module:JSON").toJSON(ret) end

-- Do NOT use this method! -- All uses should be pre-approved on the talk page! function Language:getRawData return self._rawData end

Language.__index = Language

function export.getDataModuleName(code) if code:find("^[a-z][a-z]$") then return "languages/data2" elseif code:find("^[a-z][a-z][a-z]$") then local prefix = code:sub(1, 1) return "languages/data3/" .. prefix elseif code:find("^[a-z-]+$") then return "languages/datax" else return nil end end

local function getRawLanguageData(code) local modulename = export.getDataModuleName(code) return modulename and mw.loadData("Module:" .. modulename)[code] or nil end

function export.makeObject(code, data) if data and data.deprecated then require("Module:debug").track("languages/deprecated") require("Module:debug").track("languages/deprecated/" .. code) end return data and setmetatable({ _rawData = data, _code = code }, Language) or nil end

function export.getByCode(code) return export.makeObject(code, getRawLanguageData(code)) end

function export.getByCanonicalName(name) local code = mw.loadData("Module:languages/by name")[name] if not code then return nil end return export.makeObject(code, getRawLanguageData(code)) end

function export.iterateAll mw.incrementExpensiveFunctionCount local m_data = mw.loadData("Module:languages/alldata") local func, t, var = pairs(m_data) return function local code, data = func(t, var) return export.makeObject(code, data) end end

return export