Module:languages: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
local export = {}
local export = {}


--[=[ This function checks for things that could plausibly be a language code:
--[=[
two or three lowercase letters, two or three groups of three lowercase
Throw an error for an invalid language code or script code.
letters with hyphens between them. If such a pattern is not found,
it is likely the editor simply forgot to enter a language code. ]=]


function export.err(langCode, param, text, template_tag)
`lang_code` (required) is the bad code and can be nil or a non-string.
 
`param` (required) is the name of the parameter in which the code was contained. It can be a string, a number
(for a numeric param, in which case the param will show up in the error message as an ordinal such as
"first" or "second"), or `true` if no parameter can be clearly identified.
 
`code_desc` (optional) is text describing what the code is; by default, "language code".
 
`template_text` (optional) is a string specifying the template that generated the error, or a function
to generate this string. If given, it will be displayed in the error message.
 
`not_real_lang` (optional), if given, indicates that the code is not in the form of a language code
(e.g. it's a script code). Normally, this function checks for things that could plausibly be a language code:
two or three lowercase letters, two or three groups of three lowercase letters with hyphens between them.
If such a pattern is found, a different error message is displayed (indicating an invalid code) than otherwise
(indicating a missing code). If `not_real_lang` is given, this check is suppressed.
]=]
 
function export.err(lang_code, param, code_desc, template_tag, not_real_lang)
local ordinals = {
local ordinals = {
"first", "second", "third", "fourth", "fifth", "sixth",
"first", "second", "third", "fourth", "fifth", "sixth",
Line 14: Line 30:
}
}
text = text or "language code"
code_desc = code_desc or "language code"
if not template_tag then
if not template_tag then
Line 24: Line 40:
template_tag = " (Original template: " .. template_tag .. ")"
template_tag = " (Original template: " .. template_tag .. ")"
end
end
local paramType = type(param)
local function err(msg)
if paramType == "number" then
error(msg .. template_tag, 3)
ordinal = ordinals[param]
end
param = ordinal .. ' parameter'
local param_type = type(param)
elseif paramType == "string" then
local in_the_param
param = 'parameter "' .. param .. '"'
if param == true then
-- handled specially below
in_the_param = ""
else
else
error("The parameter name is "
if param_type == "number" then
.. (paramType == "table" and "a table" or tostring(param))
param = ordinals[param] .. " parameter"
.. ", but it should be a number or a string." .. template_tag, 2)
elseif param_type == "string" then
param = 'parameter "' .. param .. '"'
else
err("The parameter name is "
.. (param_type == "table" and "a table" or tostring(param))
.. ", but it should be a number or a string.")
end
in_the_param = " in the " .. param
end
end
if not lang_code or lang_code == "" then
if param == true then
err("The " .. code_desc .. " is missing.")
else
err("The " .. param .. " (" .. code_desc .. ") is missing.")
end
elseif type(lang_code) ~= "string" then
err("The " .. code_desc .. in_the_param .. " is supposed to be a string but is a " .. type(lang_code) .. ".")
-- Can use string.find because language codes only contain ASCII.
-- Can use string.find because language codes only contain ASCII.
if not langCode or langCode == "" then
elseif not_real_lang or lang_code:find("^%l%l%l?$")
error("The " .. param .. " (" .. text .. ") is missing." .. template_tag, 2)
or lang_code:find("^%l%l%l%-%l%l%l$")
elseif langCode:find("^%l%l%l?$")
or lang_code:find("^%l%l%l%-%l%l%l%-%l%l%l$") then
or langCode:find("^%l%l%l%-%l%l%l$")
err("The " .. code_desc .. " \"" .. lang_code .. "\"" .. in_the_param .. " is not valid.")
or langCode:find("^%l%l%l%-%l%l%l%-%l%l%l$") then
error("The " .. text .. " \"" .. langCode .. "\" is not valid." .. template_tag, 2)
else
else
error("Please enter a " .. text .. " in the " .. param .. "." .. template_tag, 2)
err("Please specify a " .. code_desc .. in_the_param .. ". The value \"" .. lang_code .. "\" is not valid.")
end
end
end
end
Line 79: Line 110:




function Language:getOtherNames()
function Language:getDisplayForm()
return self._rawData.otherNames or {}
return self:getCanonicalName()
end
 
 
function Language:getOtherNames(onlyOtherNames)
self:loadInExtraData()
return require("Module:language-like").getOtherNames(self, onlyOtherNames)
end
 
 
function Language:getAliases()
self:loadInExtraData()
return self._extraData.aliases or {}
end
 
 
function Language:getVarieties(flatten)
self:loadInExtraData()
return require("Module:language-like").getVarieties(self, flatten)
end
end


Line 122: Line 171:


function Language:getWikidataItem()
function Language:getWikidataItem()
return self._rawData[2] or self._rawData.wikidata_item
local item = self._rawData[2]
if type(item) == "number" then
return "Q" .. item
else
return item
end
end
end


Line 130: Line 185:
self._scriptObjects = {}
self._scriptObjects = {}
for _, sc in ipairs(self._rawData.scripts or { "None" }) do
for _, sc in ipairs(self:getScriptCodes()) do
table.insert(self._scriptObjects, m_scripts.getByCode(sc))
table.insert(self._scriptObjects, m_scripts.getByCode(sc))
end
end
Line 139: Line 194:


function Language:getScriptCodes()
function Language:getScriptCodes()
return self._rawData.scripts or { "None" }
return self._rawData.scripts or self._rawData[4] or { "None" }
end
end


Line 222: Line 277:




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




function Language:makeCategoryLink()
function Language:makeCategoryLink()
return "[[:Category:" .. self:getCategoryName() .. "|" .. self:getCanonicalName() .. "]]"
return "[[:Category:" .. self:getCategoryName() .. "|" .. self:getDisplayForm() .. "]]"
end
end


Line 261: Line 318:
if type(self._rawData.entry_name) == "table" then
if type(self._rawData.entry_name) == "table" then
text = do_entry_name_or_sort_key_replacements(text, self._rawData.entry_name)
text = do_entry_name_or_sort_key_replacements(text, self._rawData.entry_name)
end
return text
end
-- Return true if the language has display processing enabled, i.e. lang:makeDisplayText()
-- does non-trivial processing.
function Language:hasDisplayProcessing()
return not not self._rawData.display
end
-- Apply display-text replacements to `text`, if any.
function Language:makeDisplayText(text)
if type(self._rawData.display) == "table" then
text = do_entry_name_or_sort_key_replacements(text, self._rawData.display)
end
end
Line 352: Line 426:
ancestors = self._rawData.ancestors,
ancestors = self._rawData.ancestors,
canonicalName = self:getCanonicalName(),
canonicalName = self:getCanonicalName(),
categoryName = self:getCategoryName(),
categoryName = self:getCategoryName("nocap"),
code = self._code,
code = self._code,
entryNamePatterns = entryNamePatterns,
entryNamePatterns = entryNamePatterns,
entryNameRemoveDiacritics = entryNameRemoveDiacritics,
entryNameRemoveDiacritics = entryNameRemoveDiacritics,
family = self._rawData[3] or self._rawData.family,
family = self._rawData[3] or self._rawData.family,
otherNames = self:getOtherNames(),
otherNames = self:getOtherNames(true),
scripts = self._rawData.scripts,
aliases = self:getAliases(),
varieties = self:getVarieties(),
scripts = self._rawData.scripts or self._rawData[4],
type = self:getType(),
type = self:getType(),
wikimediaLanguages = self._rawData.wikimedia_codes,
wikimediaLanguages = self._rawData.wikimedia_codes,
Line 368: Line 444:




-- Do NOT use this method!
-- Do NOT use these methods!
-- All uses should be pre-approved on the talk page!
-- All uses should be pre-approved on the talk page!
function Language:getRawData()
function Language:getRawData()
return self._rawData
return self._rawData
end
function Language:getRawExtraData()
self:loadInExtraData()
return self._extraData
end
end


Line 385: Line 466:
elseif code:find("^[%l-]+$") then
elseif code:find("^[%l-]+$") then
return "languages/datax"
return "languages/datax"
else
return nil
end
end
function export.getExtraDataModuleName(code)
if code:find("^%l%l$") then
return "languages/extradata2"
elseif code:find("^%l%l%l$") then
local prefix = code:sub(1, 1)
return "languages/extradata3/" .. prefix
elseif code:find("^[%l-]+$") then
return "languages/extradatax"
else
else
return nil
return nil
Line 394: Line 489:
local modulename = export.getDataModuleName(code)
local modulename = export.getDataModuleName(code)
return modulename and mw.loadData("Module:" .. modulename)[code] or nil
return modulename and mw.loadData("Module:" .. modulename)[code] or nil
end
local function getRawExtraLanguageData(code)
local modulename = export.getExtraDataModuleName(code)
return modulename and mw.loadData("Module:" .. modulename)[code] or nil
end
function Language:loadInExtraData()
if not self._extraData then
-- load extra data from module and assign to meta table
-- use empty table as a fallback if extra data is nil
local meta = getmetatable(self)
meta._extraData = getRawExtraLanguageData(self._code) or {}
setmetatable(self, meta)
end
end
end




function export.makeObject(code, data)
function export.makeObject(code, data)
return data and setmetatable({ _rawData = data, _code = code }, Language) or nil
return data and setmetatable({ _rawData = data, _code = code }, Language) or nil
end
end
Line 426: Line 537:
codetext = "language code"
codetext = "language code"
end
end
if paramForError == true then
export.err(code, paramForError, codetext)
error("The " .. codetext .. " \"" .. code .. "\" is not valid.")
else
export.err(code, paramForError, codetext)
end
end
end
return retval
return retval
Line 457: Line 564:
local retval = code and export.makeObject(code, getRawLanguageData(code)) or nil
local retval = code and export.makeObject(code, getRawLanguageData(code)) or nil
if not retval and allowEtymLang then
if not retval and allowEtymLang then
retval = require("Module:etymology languages").getByCanonicalName(code)
retval = require("Module:etymology languages").getByCanonicalName(name)
end
end
if not retval and allowFamily then
if not retval and allowFamily then
retval = require("Module:families").getByCanonicalName(code)
local famname = name:match("^(.*) languages$")
famname = famname or name
retval = require("Module:families").getByCanonicalName(famname)
end
end
if not retval and errorIfInvalid then
if not retval and errorIfInvalid then