45,646
edits
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
local export = {} | local export = {} | ||
--[=[ | --[=[ | ||
Throw an error for an invalid language code or script code. | |||
function export.err( | `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: | ||
} | } | ||
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 | local function err(msg) | ||
if | error(msg .. template_tag, 3) | ||
end | |||
local param_type = type(param) | |||
local in_the_param | |||
if param == true then | |||
-- handled specially below | |||
in_the_param = "" | |||
else | else | ||
if param_type == "number" then | |||
param = ordinals[param] .. " parameter" | |||
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. | ||
elseif not_real_lang or lang_code:find("^%l%l%l?$") | |||
or lang_code:find("^%l%l%l%-%l%l%l$") | |||
or lang_code:find("^%l%l%l%-%l%l%l%-%l%l%l$") then | |||
or | err("The " .. code_desc .. " \"" .. lang_code .. "\"" .. in_the_param .. " is not valid.") | ||
or | |||
else | else | ||
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. | 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() | ||
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 | 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 | ||
name = name .. " language" | |||
end | |||
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: | 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 | -- 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 | ||
export.err(code, paramForError, codetext) | |||
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( | 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( | 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 |