Module:language-like: Difference between revisions

no edit summary
(Created page with "local export = {} -- Implementation of getOtherNames() for languages, etymology languages, -- families and scripts. If `onlyOtherNames` is passed in, only return -- the names...")
 
No edit summary
Line 1: Line 1:
local export = {}
local export = {}


-- Implementation of getOtherNames() for languages, etymology languages,
local string_utilities_module = "Module:string utilities"
-- families and scripts. If `onlyOtherNames` is passed in, only return
local table_module = "Module:table"
-- the names in the `otherNames` field, otherwise combine `otherNames`,
 
-- `aliases` and `varieties`.
local wikibase = mw.wikibase
function export.getOtherNames(self, onlyOtherNames)
 
local data
local category_name_has_suffix -- defined as export.categoryNameHasSuffix below
if self._extraData then
local get_entity = wikibase.getEntity
data = self._extraData
local get_entity_id_for_title = wikibase.getEntityIdForTitle
else
local gsub = string.gsub
data = self._rawData
local ipairs = ipairs
local match = string.match
local select = select
local sitelink = wikibase.sitelink
local type = type
local umatch = mw.ustring.match
 
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function case_insensitive_pattern(...)
case_insensitive_pattern = require(string_utilities_module).case_insensitive_pattern
return case_insensitive_pattern(...)
end
local function table_flatten(...)
table_flatten = require(table_module).flatten
return table_flatten(...)
end
end
if onlyOtherNames then
return data.otherNames or {}
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local content_lang
local function get_content_lang()
content_lang, get_content_lang = mw.getContentLanguage(), nil
return content_lang
end
end
-- Combine otherNames, aliases and varieties. First try to optimize and not create any
 
-- new memory. This is possible if exactly one of the three exist, and if it's `varieties`,
-- Implementation of getAliases() for languages, etymology languages,
-- there are no nested lists in `varieties`.
-- families, scripts and writing systems.
if data.otherNames and not data.aliases and not data.varieties then
function export.getAliases(self)
return data.otherNames
local aliases = self._aliases
elseif data.aliases and not data.otherNames and not data.varieties then
if aliases == nil then
return data.aliases
aliases = (self._data or self).aliases or {}
elseif data.varieties and not data.otherNames and not data.aliases then
self._aliases = aliases
local saw_table = false
for _, name in ipairs(data.varieties) do
if type(name) == "table" then
saw_table = true
break
end
end
if not saw_table then
return data.varieties
end
end
end
return aliases
end


-- Have to do it the "hard way".
-- Implementation of getVarieties() for languages, etymology languages,
local ret = {}
-- families, scripts and writing systems. If `flatten` is passed in,
if data.otherNames then
-- flatten down to a list of strings; otherwise, keep the structure.
for _, name in ipairs(data.otherNames) do
function export.getVarieties(self, flatten)
table.insert(ret, name)
local varieties = self._varieties
end
if varieties == nil then
varieties = (self._data or self).varieties or {}
self._varieties = varieties
end
end
if data.aliases then
if not flatten then
for _, name in ipairs(data.aliases) do
return varieties
table.insert(ret, name)
end
end
end
if data.varieties then
local flattened_varieties = self._flattened_varieties
for _, name in ipairs(data.varieties) do
if flattened_varieties == nil then
if type(name) == "table" then
flattened_varieties = table_flatten(varieties)
for _, n in ipairs(name) do
self._flattened_varieties = flattened_varieties
table.insert(ret, n)
end
else
table.insert(ret, name)
end
end
end
end
return ret
return flattened_varieties
end
end


-- Implementation of getOtherNames() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getOtherNames(self)
local other_names = self._otherNames
if other_names == nil then
other_names = (self._data or self).otherNames or {}
self._otherNames = other_names
end
return other_names
end


-- Implementation of getVarieties() for languages, etymology languages,
-- Implementation of getAllNames() for languages, etymology languages,
-- families and scripts. If `flatten` is passed in, flatten down to a
-- families, scripts and writing systems. If `notCanonical` is set,
-- list of stings; otherwise, keep the structure.
-- the canonical name will be excluded.
function export.getVarieties(self, flatten)
function export.getAllNames(self)
local data
local all_names = self._allNames
if self._extraData then
if all_names == nil then
data = self._extraData
all_names = table_flatten{
else
self:getCanonicalName(),
data = self._rawData
self:getAliases(),
self:getVarieties(),
self:getOtherNames(),
}
self._allNames = all_names
end
return all_names
end
 
function export.hasType(self, ...)
local n = select("#", ...)
if n == 0 then
error("Must specify at least one type.")
end
local types = self:getTypes()
if not types[...] then
return false
elseif n == 1 then
return true
end
end
if data.varieties then
local args = {...}
-- If flattening not requested, just return them.
for i = 2, n do
if not flatten then
if not types[args[i]] then
return data.varieties
return false
end
-- Check if no nested table; if so, just return the result.
local saw_table = false
for _, name in ipairs(data.varieties) do
if type(name) == "table" then
saw_table = true
break
end
end
if not saw_table then
return data.varieties
end
-- At this point, we need to flatten the varieties.
local ret = {}
for _, name in ipairs(data.varieties) do
if type(name) == "table" then
for _, n in ipairs(name) do
table.insert(ret, n)
end
else
table.insert(ret, name)
end
end
end
return ret
else
return {}
end
end
return true
end
end


-- Implementation of template-callable getByCode() function for languages,
-- Implementation of template-callable getByCode() function for languages,
Line 115: Line 125:
-- and before general-purpose processing code that works for all string
-- and before general-purpose processing code that works for all string
-- properties.
-- properties.
function export.templateGetByCode(item, args, extra_processing)
function export.templateGetByCode(args, extra_processing)
-- The item that the caller wanted to look up
-- The item that the caller wanted to look up.
local itemname = args[2] or error("Function to call (parameter 2) has not been specified.")
local item, itemname, list = args[1], args[2]
local list
if itemname == "getAllNames" then
if itemname == "getOtherNames" then
list = item:getAllNames()
elseif itemname == "getOtherNames" then
list = item:getOtherNames()
list = item:getOtherNames()
elseif itemname == "getOnlyOtherNames" then
list = item:getOtherNames(true)
elseif itemname == "getAliases" then
elseif itemname == "getAliases" then
list = item:getAliases()
list = item:getAliases()
Line 147: Line 156:
if item[itemname] then
if item[itemname] then
local ret = item[itemname](item)
local ret = item[itemname](item)
if type(ret) == "string" then
if type(ret) == "string" then
return ret
return ret
end
error("The function \"" .. itemname .. "\" did not return a string value.")
end
error("Requested invalid item name \"" .. itemname .. "\".")
end
-- Implementation of getCommonsCategory() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getWikidataItem(self)
local item = self._WikidataItem
if item == nil then
item = (self._data or self)[2]
-- If the value is nil, it's cached as false.
item = item ~= nil and (type(item) == "number" and "Q" .. item or item) or false
self._WikidataItem = item
end
return item or nil
end
do
local function get_wiki_article(self, project)
local article
-- If the project is enwiki, check the language data.
if project == "enwiki" then
article = (self._data or self).wikipedia_article
if article then
return article
end
end
-- Otherwise, check the Wikidata item for a sitelink.
local item = self:getWikidataItem()
article = item and sitelink(item, project) or false
if article then
return article
end
-- If there's still no article, try the parent (if any).
local get_parent = self.getParent
if get_parent then
local parent = get_parent(self)
if parent then
return get_wiki_article(parent, project)
end
end
return false
end
-- Implementation of getWikipediaArticle() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getWikipediaArticle(self, noCategoryFallback, project)
if project == nil then
project = "enwiki"
end
local article
if project == "enwiki" then
article = self._wikipedia_article
if article == nil then
article = get_wiki_article(self, project)
self._wikipedia_article = article
end
else
else
error("The function \"" .. itemname .. "\" did not return a string value.")
-- If the project isn't enwiki, default to no category fallback, but
-- this can be overridden by specifying the value `false`.
if noCategoryFallback == nil then
noCategoryFallback = true
end
local non_en_wikipedia_articles = self._non_en_wikipedia_articles
if non_en_wikipedia_articles == nil then
non_en_wikipedia_articles = {}
self._non_en_wikipedia_articles = non_en_wikipedia_articles
else
article = non_en_wikipedia_articles[project]
end
if article == nil then
article = get_wiki_article(self, project)
non_en_wikipedia_articles[project] = article
end
end
if article or noCategoryFallback then
return article or nil
end
return (gsub(self:getCategoryName(), "Creole language", "Creole"))
end
end
 
do
local function get_commons_cat_claim(item)
if item then
local entity = get_entity(item)
if entity then
-- P373 is the "Commons category" property.
local claim = entity:getBestStatements("P373")[1]
return claim and ("Category:" .. claim.mainsnak.datavalue.value) or nil
end
end
end
local function get_commons_cat_sitelink(item)
if item then
local commons_sitelink = sitelink(item, "commonswiki")
-- Reject any sitelinks that aren't categories.
return commons_sitelink and match(commons_sitelink, "^Category:") and commons_sitelink or nil
end
end
local function get_commons_cat(self)
-- Checks are in decreasing order of likelihood for a useful match.
-- Get the Commons Category claim from the object's item.
local lang_item = self:getWikidataItem()
local category = get_commons_cat_claim(lang_item)
if category then
return category
end
-- Otherwise, try the object's category's item.
local langcat_item = get_entity_id_for_title("Category:" .. self:getCategoryName())
category = get_commons_cat_claim(langcat_item)
if category then
return category
end
-- If there's no P373 claim, there might be a sitelink on the
-- object's category's item.
category = get_commons_cat_sitelink(langcat_item)
if category then
return category
end
-- Otherwise, try for a sitelink on the object's own item.
category = get_commons_cat_sitelink(lang_item)
if category then
return category
end
-- If there's still no category, try the parent (if any).
local get_parent = self.getParent
if get_parent then
local parent = get_parent(self)
if parent then
return get_commons_cat(parent)
end
end
return false
end
-- Implementation of getCommonsCategory() for languages, etymology
-- languages, families, scripts and writing systems.
function export.getCommonsCategory(self)
local category
category = self._commons_category
-- Nil values cached as false.
if category ~= nil then
return category or nil
end
category = get_commons_cat(self)
self._commons_category = category
return category or nil
end
end
 
function export.categoryNameHasSuffix(name, suffixes)
for _, suffix in ipairs(suffixes) do
if umatch(name, "%f[%w]" .. case_insensitive_pattern(suffix, "^.") .. "$") then
return false
end
end
end
end
return true
end
category_name_has_suffix = export.categoryNameHasSuffix


error("Requested invalid item name \"" .. itemname .. "\".")
function export.categoryNameToCode(name, suffix, data, suffixes)
local truncated = match(name, "(.*)" .. suffix .. "$")
if truncated and category_name_has_suffix(truncated, suffixes) then
local code = data[truncated] or data[(content_lang or get_content_lang()):lcfirst(truncated)]
if code ~= nil then
return code
end
end
if not category_name_has_suffix(name, suffixes) then
return data[name] or data[(content_lang or get_content_lang()):lcfirst(name)]
end
return nil
end
end


return export
return export