Wiktionary bjnwiktionary https://bjn.wiktionary.org/wiki/Laman_Tatambaian MediaWiki 1.47.0-wmf.10 case-sensitive Media Istimiwa Pamandiran Pamakai Pamandiran Pamakai Wikikamus Pamandiran Wikikamus Barakas Pamandiran Barakas MediaWiki Pamandiran MediaWiki Citakan Pamandiran Citakan Patulung Pamandiran Patulung Tumbung Pamandiran Tumbung TimedText TimedText talk Modul Pembicaraan Modul Acara Pembicaraan Acara Modul:utilities 828 2493 26547 23983 2026-04-14T13:38:41Z id>Swarabakti 0 26547 Scribunto text/plain local export = {} local headword_data_module = "Module:headword/data" local languages_module = "Module:languages" local links_module = "Module:links" local load_module = "Module:load" local pages_module = "Module:pages" local script_utilities_module = "Module:script utilities" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local utilities_data_module = "Module:utilities/data" local mw = mw local anchor_encode = mw.uri.anchorEncode local concat = table.concat local format_categories -- Defined below. local ipairs = ipairs local require = require local type = type local unstrip = mw.text.unstrip --[==[ 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function is_content_page(...) is_content_page = require(pages_module).is_content_page return is_content_page(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function remove_links(...) remove_links = require(links_module).remove_links return remove_links(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end --[==[ 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 catfix_scripts local function get_catfix_scripts() catfix_scripts, get_catfix_scripts = load_data(utilities_data_module).catfix_scripts, nil return catfix_scripts end local current_title local function get_current_title() current_title, get_current_title = mw.title.getCurrentTitle(), nil return current_title end local defaultsort local function get_defaultsort() defaultsort, get_defaultsort = load_data(headword_data_module).page.pagename_defaultsort, nil return defaultsort end local pagename local function get_pagename() pagename, get_pagename = load_data(headword_data_module).page.encoded_pagename, nil return pagename end local und local function get_und() und, get_und = require(languages_module).getByCode("und"), nil return und end do local function handle_url(capture) return capture:match("https?://[^%s%]]+%s([^%]]+)") or "" end --[==[ A helper function to strip wiki markup, giving the plaintext of what is displayed on the page.]==] function export.get_plaintext(text) text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Remove strip markers and HTML tags. text = unstrip(text):gsub("<[^<>\1\2]+>", "") -- Parse internal links for the display text, and remove categories. text = remove_links(text) -- Remove files. text = text:gsub("\1[Ff][Ii][Ll][Ee]:[^\1\2]+\2", "") :gsub("\1[Ii][Mm][Aa][Gg][Ee]:[^\1\2]+\2", "") -- Parse external links for the display text. text = text:gsub("%[(https?://[^%[%]]+)%]", handle_url) -- Any remaining square brackets aren't involved in links, but must be escaped to avoid creating new links. :gsub("\1", "&#91;&#91;") :gsub("\2", "&#93;&#93;") :gsub("%[", "&#91;") :gsub("]", "&#93;") -- Strip bold, italics and soft hyphens. :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") -- Get any HTML entities and trim. -- Note: don't decode URL percent encoding, as it shouldn't be used in display text and may cause problems if % is used. return trim(decode_entities(text)) end end do local function generate_sortkey(lang, sc, sort_key, sort_base) -- If the sort key is "-", treat the language as undetermined (the default). This is desirable when categorising (e.g.) translation requests, as the pages to be categorised are always in English/Translingual. if sort_key == "-" then lang, sort_key = und or get_und(), nil elseif not lang then lang = und or get_und() end -- Generate the automatic sort key. local auto = lang:makeSortKey(sort_base or pagename or get_pagename(), sc) -- Use the page defaultsort if necessary. Try hard to avoid empty sort key, which causes categories to be -- displayed as raw text; fall back to pagename if necessary. if not auto or auto == "" then auto = defaultsort or get_defaultsort() end if not auto or auto == "" then auto = sort_base end if not auto or auto == "" then auto = pagename or get_pagename() end -- If not sort key specified, use the automatic one. if not sort_key or sort_key == "" then return auto -- Otherwise, if the language is not "und", categorize the manual sort key as either redundant or non-redundant. -- FIXME: we should do this for "und" as well, but "Undetermined terms..." does not make sense for translations etc. elseif lang:getCode() ~= "und" then return sort_key, "[[Category:" .. lang:getFullName() .. " terms with " .. ( uupper(sort_key) == auto and "redundant" or "non-redundant non-automated" ) .. " sortkeys|" .. sort_key .. "]]" end return sort_key end --[==[ Format the categories with the appropriate sort key. * `cat` can take two forms: ** A string (the full category, minus the {"Category:"} prefix); ** A list of categories. Each category in the list can be either: *** A string in the same format as above; *** An object with the fields: **** `cat`: a string in the same format as above (required); **** `lang`: an optional language object to override the overall `lang`; **** `sc`: an optional script object to override the overall `sc`. **** `sort_key`: an optional sort key to override the overall `sort_key`; **** `sort_base`: an optional sort base to override the overall `sort_base`; * `lang` is an object encapsulating a language; if {nil}, the object for language code {"und"} (undetermined) will be used. `lang` is used when computing the sort key (either from the subpage name or sort base). * `sort_key` is placed in the category invocation, and indicates how the page will sort in the respective category. Normally '''do not use this'''. Instead, leave it {nil}, and if you need to a control the sort order, use {sort_base}, so that language-specific normalization is applied on top of the specified sort base. If neither {sort_key} nor {sort_base} is specified, the default is to apply language-specific normalization to the subpage name; see below. * `sort_base` lets you override the default sort key while still maintaining appropriate language-specific normalization. If {nil} is specified, this defaults to the subpage name, which is the portion of the full pagename after subtracting the namespace prefix (and, in certain namespaces such as {User:}, but notably not in the mainspace, after subtracting anything up through the final slash). The actual sort key is derived from the sort base approximately by lowercasing, applying language-specific normalization and then uppercasing; note that the same process is applied in deriving the sort key when no sort base is specified. For example, for French, Spanish, etc. the normalization process maps accented letters to their unaccented equivalents, so that e.g. in French, {{m|fr|ça}} sorts after {{m|fr|ca}} (instead of after the default Wikimedia sort order, which is approximately based on Unicode sort order and places ç after z) and {{m|fr|côté}} sorts after {{m|fr|coté}} (instead of between c and d). Similarly, in Russian the normalization process converts Cyrillic ё to a string consisting of Cyrillic е followed by U+10FFFF, so that effectively ё sorts after е instead of the default Wikimedia sort, which (I think) puts ё after я, the last letter of the Cyrillic alphabet. * `force_output` forces normal output in all namespaces. Normally, nothing is output if the page isn't in the main, Appendix:, Thesaurus:, Reconstruction: or Citations: namespaces. * `sc` is a script object; if nil, the default will be derived from the sort base (or its default value, the subpage name) by calling {lang:findBestScript()}. The value of `sc` is used during the sort base normalization process; for example, languages with multiple scripts will often have script-specific normalization processes.]==] function export.format_categories(cat, lang, sort_key, sort_base, force_output, sc) if not ( force_output or is_content_page(current_title or get_current_title()) or current_title.prefixedText == "Wiktionary:Sandbox" ) then return "" elseif type(cat) == "string" then local this_sort_key, extra = generate_sortkey(lang, sc, sort_key, sort_base) return "[[Category:" .. cat .. "|" .. this_sort_key .. "]]" .. (extra or "") end local ret, i, n, default = {}, 0, 0 -- Iterate over all categories in `cat`. while true do i = i + 1 local category = cat[i] if category == nil then return concat(ret) end local this_sort_key, extra -- If the category type is a table, use any custom options in it. if type(category) == "table" then category, this_sort_key, extra = category.cat, generate_sortkey( category.lang or lang, category.sc or sc, category.sort_key or sort_key, category.sort_base or sort_base ) -- If `default` has already been determined, use it. elseif default then this_sort_key = default -- Otherwise, calculate `default` and use it. else this_sort_key, extra = generate_sortkey(lang, sc, sort_key, sort_base) default = this_sort_key end n = n + 1 ret[n] = "[[Category:" .. category .. "|" .. this_sort_key .. "]]" .. (extra or "") end end format_categories = export.format_categories end --[==[ Add a "catfix", which is used on language-specific category pages to add language attributes and often script classes to all entry names. The addition of language attributes and script classes makes the entry names display better (using the language- or script-specific styles specified in [[MediaWiki:Common.css]]), which is particularly important for non-English languages that do not have consistent font support in browsers. Language attributes are added for all languages, but script classes are only added for languages with one script listed in their data file, or for languages that have a default script listed in the {catfix_script} list in [[Module:utilities/data]]. Some languages clearly have a default script, but still have other scripts listed in their data file. If those other scripts are not simply scripts like {{cd|Brai}} (Braille), their default script needs to be specified. Others do not have a default script. * Serbo-Croatian is regularly written in both the Latin and Cyrillic scripts. Because it uses two scripts, Serbo-Croatian cannot have a script class applied to entries in its category pages, as only one script class can be specified at a time. * German is usually written in the Latin script ({{cd|Latn}}), but Fraktur ({{cd|Latf}}) is also listed in its data file. So German needs an entry in the {catfix_script} list, so that the {{cd|Latn}} (Latin) script class will be applied to entries in its category pages. To find the scripts listed for a language, go to [[Module:languages]] and use the search box to find the data file for the language. To find out what a script code means, search the script code in [[Module:scripts/data]].]==] function export.catfix(lang, sc) if not lang or not lang.getCanonicalName then error('The first argument to the function "catfix" should be a language object from [[Module:languages]] or [[Module:etymology languages]].') end if sc and not sc.getCode then error('The second argument to the function "catfix" should be a script object from [[Module:scripts]].') end -- To add script classes to links on pages created by category boilerplate templates. if not sc then local code = (catfix_scripts or get_catfix_scripts())[lang:getCode()] or catfix_scripts[lang:getFullCode()] if code then sc = get_script(code) end end -- If the language only has a single valid candidate script, apply it as the default. if not sc then local scripts = lang:getScripts() if #scripts == 1 then sc = scripts[1] else -- Iterate over scripts. If there is only one when ignoring -- scripts like Brai, then pick that one. for _, script in ipairs(scripts) do if script:getCode() ~= "Brai" then if sc then -- Multiple candidates - fail. sc = nil break else sc = script end end end end end -- Hack: using a <ul> tag prevents the parser from automatically generating a <p> tag around the catfix element. return "<ul class=\"catfix\" data-anchor=\"" .. anchor_encode(lang:getFullName()) .. "\">" .. tag_text("", lang, sc) .. "</ul>" .. format_categories("Pages using catfix", nil, nil, nil, true) end --[==[ Given a type (as a string) and an arbitrary number of entities, checks whether all of those entities are language, family, script, writing system or Wikimedia language objects. Useful for error handling in functions that require one of these kinds of object. If `noErr` is set, the function returns false instead of throwing an error, which allows customised error handling to be done in the calling function.]==] function export.check_object(typ, noErr, ...) if ... == nil then if noErr then return false end error("Must provide at least one object to check.", 2) end for _, obj in ipairs{...} do if type(obj) ~= "table" or type(obj.hasType) ~= "function" then if noErr then return false end error("Function expected a " .. typ .. " object, but received a " .. type(obj) .. " instead.", 2) elseif not (typ == "object" or obj:hasType(typ)) then for _, wrong_type in ipairs{"family", "language", "script", "Wikimedia language", "writing system"} do if obj:hasType(wrong_type) then if noErr then return false end error("Function expected a " .. typ .. " object, but received a " .. wrong_type .. " object instead.", 2) end end if noErr then return false end error("Function expected a " .. typ .. " object, but received another type of object instead.", 2) end end return true end return export szkevg9xl5j9wpvvgbzhwuqjxjznt9y 26548 26547 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Modul:utilities]] 26547 Scribunto text/plain local export = {} local headword_data_module = "Module:headword/data" local languages_module = "Module:languages" local links_module = "Module:links" local load_module = "Module:load" local pages_module = "Module:pages" local script_utilities_module = "Module:script utilities" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local utilities_data_module = "Module:utilities/data" local mw = mw local anchor_encode = mw.uri.anchorEncode local concat = table.concat local format_categories -- Defined below. local ipairs = ipairs local require = require local type = type local unstrip = mw.text.unstrip --[==[ 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function is_content_page(...) is_content_page = require(pages_module).is_content_page return is_content_page(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function remove_links(...) remove_links = require(links_module).remove_links return remove_links(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end --[==[ 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 catfix_scripts local function get_catfix_scripts() catfix_scripts, get_catfix_scripts = load_data(utilities_data_module).catfix_scripts, nil return catfix_scripts end local current_title local function get_current_title() current_title, get_current_title = mw.title.getCurrentTitle(), nil return current_title end local defaultsort local function get_defaultsort() defaultsort, get_defaultsort = load_data(headword_data_module).page.pagename_defaultsort, nil return defaultsort end local pagename local function get_pagename() pagename, get_pagename = load_data(headword_data_module).page.encoded_pagename, nil return pagename end local und local function get_und() und, get_und = require(languages_module).getByCode("und"), nil return und end do local function handle_url(capture) return capture:match("https?://[^%s%]]+%s([^%]]+)") or "" end --[==[ A helper function to strip wiki markup, giving the plaintext of what is displayed on the page.]==] function export.get_plaintext(text) text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Remove strip markers and HTML tags. text = unstrip(text):gsub("<[^<>\1\2]+>", "") -- Parse internal links for the display text, and remove categories. text = remove_links(text) -- Remove files. text = text:gsub("\1[Ff][Ii][Ll][Ee]:[^\1\2]+\2", "") :gsub("\1[Ii][Mm][Aa][Gg][Ee]:[^\1\2]+\2", "") -- Parse external links for the display text. text = text:gsub("%[(https?://[^%[%]]+)%]", handle_url) -- Any remaining square brackets aren't involved in links, but must be escaped to avoid creating new links. :gsub("\1", "&#91;&#91;") :gsub("\2", "&#93;&#93;") :gsub("%[", "&#91;") :gsub("]", "&#93;") -- Strip bold, italics and soft hyphens. :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") -- Get any HTML entities and trim. -- Note: don't decode URL percent encoding, as it shouldn't be used in display text and may cause problems if % is used. return trim(decode_entities(text)) end end do local function generate_sortkey(lang, sc, sort_key, sort_base) -- If the sort key is "-", treat the language as undetermined (the default). This is desirable when categorising (e.g.) translation requests, as the pages to be categorised are always in English/Translingual. if sort_key == "-" then lang, sort_key = und or get_und(), nil elseif not lang then lang = und or get_und() end -- Generate the automatic sort key. local auto = lang:makeSortKey(sort_base or pagename or get_pagename(), sc) -- Use the page defaultsort if necessary. Try hard to avoid empty sort key, which causes categories to be -- displayed as raw text; fall back to pagename if necessary. if not auto or auto == "" then auto = defaultsort or get_defaultsort() end if not auto or auto == "" then auto = sort_base end if not auto or auto == "" then auto = pagename or get_pagename() end -- If not sort key specified, use the automatic one. if not sort_key or sort_key == "" then return auto -- Otherwise, if the language is not "und", categorize the manual sort key as either redundant or non-redundant. -- FIXME: we should do this for "und" as well, but "Undetermined terms..." does not make sense for translations etc. elseif lang:getCode() ~= "und" then return sort_key, "[[Category:" .. lang:getFullName() .. " terms with " .. ( uupper(sort_key) == auto and "redundant" or "non-redundant non-automated" ) .. " sortkeys|" .. sort_key .. "]]" end return sort_key end --[==[ Format the categories with the appropriate sort key. * `cat` can take two forms: ** A string (the full category, minus the {"Category:"} prefix); ** A list of categories. Each category in the list can be either: *** A string in the same format as above; *** An object with the fields: **** `cat`: a string in the same format as above (required); **** `lang`: an optional language object to override the overall `lang`; **** `sc`: an optional script object to override the overall `sc`. **** `sort_key`: an optional sort key to override the overall `sort_key`; **** `sort_base`: an optional sort base to override the overall `sort_base`; * `lang` is an object encapsulating a language; if {nil}, the object for language code {"und"} (undetermined) will be used. `lang` is used when computing the sort key (either from the subpage name or sort base). * `sort_key` is placed in the category invocation, and indicates how the page will sort in the respective category. Normally '''do not use this'''. Instead, leave it {nil}, and if you need to a control the sort order, use {sort_base}, so that language-specific normalization is applied on top of the specified sort base. If neither {sort_key} nor {sort_base} is specified, the default is to apply language-specific normalization to the subpage name; see below. * `sort_base` lets you override the default sort key while still maintaining appropriate language-specific normalization. If {nil} is specified, this defaults to the subpage name, which is the portion of the full pagename after subtracting the namespace prefix (and, in certain namespaces such as {User:}, but notably not in the mainspace, after subtracting anything up through the final slash). The actual sort key is derived from the sort base approximately by lowercasing, applying language-specific normalization and then uppercasing; note that the same process is applied in deriving the sort key when no sort base is specified. For example, for French, Spanish, etc. the normalization process maps accented letters to their unaccented equivalents, so that e.g. in French, {{m|fr|ça}} sorts after {{m|fr|ca}} (instead of after the default Wikimedia sort order, which is approximately based on Unicode sort order and places ç after z) and {{m|fr|côté}} sorts after {{m|fr|coté}} (instead of between c and d). Similarly, in Russian the normalization process converts Cyrillic ё to a string consisting of Cyrillic е followed by U+10FFFF, so that effectively ё sorts after е instead of the default Wikimedia sort, which (I think) puts ё after я, the last letter of the Cyrillic alphabet. * `force_output` forces normal output in all namespaces. Normally, nothing is output if the page isn't in the main, Appendix:, Thesaurus:, Reconstruction: or Citations: namespaces. * `sc` is a script object; if nil, the default will be derived from the sort base (or its default value, the subpage name) by calling {lang:findBestScript()}. The value of `sc` is used during the sort base normalization process; for example, languages with multiple scripts will often have script-specific normalization processes.]==] function export.format_categories(cat, lang, sort_key, sort_base, force_output, sc) if not ( force_output or is_content_page(current_title or get_current_title()) or current_title.prefixedText == "Wiktionary:Sandbox" ) then return "" elseif type(cat) == "string" then local this_sort_key, extra = generate_sortkey(lang, sc, sort_key, sort_base) return "[[Category:" .. cat .. "|" .. this_sort_key .. "]]" .. (extra or "") end local ret, i, n, default = {}, 0, 0 -- Iterate over all categories in `cat`. while true do i = i + 1 local category = cat[i] if category == nil then return concat(ret) end local this_sort_key, extra -- If the category type is a table, use any custom options in it. if type(category) == "table" then category, this_sort_key, extra = category.cat, generate_sortkey( category.lang or lang, category.sc or sc, category.sort_key or sort_key, category.sort_base or sort_base ) -- If `default` has already been determined, use it. elseif default then this_sort_key = default -- Otherwise, calculate `default` and use it. else this_sort_key, extra = generate_sortkey(lang, sc, sort_key, sort_base) default = this_sort_key end n = n + 1 ret[n] = "[[Category:" .. category .. "|" .. this_sort_key .. "]]" .. (extra or "") end end format_categories = export.format_categories end --[==[ Add a "catfix", which is used on language-specific category pages to add language attributes and often script classes to all entry names. The addition of language attributes and script classes makes the entry names display better (using the language- or script-specific styles specified in [[MediaWiki:Common.css]]), which is particularly important for non-English languages that do not have consistent font support in browsers. Language attributes are added for all languages, but script classes are only added for languages with one script listed in their data file, or for languages that have a default script listed in the {catfix_script} list in [[Module:utilities/data]]. Some languages clearly have a default script, but still have other scripts listed in their data file. If those other scripts are not simply scripts like {{cd|Brai}} (Braille), their default script needs to be specified. Others do not have a default script. * Serbo-Croatian is regularly written in both the Latin and Cyrillic scripts. Because it uses two scripts, Serbo-Croatian cannot have a script class applied to entries in its category pages, as only one script class can be specified at a time. * German is usually written in the Latin script ({{cd|Latn}}), but Fraktur ({{cd|Latf}}) is also listed in its data file. So German needs an entry in the {catfix_script} list, so that the {{cd|Latn}} (Latin) script class will be applied to entries in its category pages. To find the scripts listed for a language, go to [[Module:languages]] and use the search box to find the data file for the language. To find out what a script code means, search the script code in [[Module:scripts/data]].]==] function export.catfix(lang, sc) if not lang or not lang.getCanonicalName then error('The first argument to the function "catfix" should be a language object from [[Module:languages]] or [[Module:etymology languages]].') end if sc and not sc.getCode then error('The second argument to the function "catfix" should be a script object from [[Module:scripts]].') end -- To add script classes to links on pages created by category boilerplate templates. if not sc then local code = (catfix_scripts or get_catfix_scripts())[lang:getCode()] or catfix_scripts[lang:getFullCode()] if code then sc = get_script(code) end end -- If the language only has a single valid candidate script, apply it as the default. if not sc then local scripts = lang:getScripts() if #scripts == 1 then sc = scripts[1] else -- Iterate over scripts. If there is only one when ignoring -- scripts like Brai, then pick that one. for _, script in ipairs(scripts) do if script:getCode() ~= "Brai" then if sc then -- Multiple candidates - fail. sc = nil break else sc = script end end end end end -- Hack: using a <ul> tag prevents the parser from automatically generating a <p> tag around the catfix element. return "<ul class=\"catfix\" data-anchor=\"" .. anchor_encode(lang:getFullName()) .. "\">" .. tag_text("", lang, sc) .. "</ul>" .. format_categories("Pages using catfix", nil, nil, nil, true) end --[==[ Given a type (as a string) and an arbitrary number of entities, checks whether all of those entities are language, family, script, writing system or Wikimedia language objects. Useful for error handling in functions that require one of these kinds of object. If `noErr` is set, the function returns false instead of throwing an error, which allows customised error handling to be done in the calling function.]==] function export.check_object(typ, noErr, ...) if ... == nil then if noErr then return false end error("Must provide at least one object to check.", 2) end for _, obj in ipairs{...} do if type(obj) ~= "table" or type(obj.hasType) ~= "function" then if noErr then return false end error("Function expected a " .. typ .. " object, but received a " .. type(obj) .. " instead.", 2) elseif not (typ == "object" or obj:hasType(typ)) then for _, wrong_type in ipairs{"family", "language", "script", "Wikimedia language", "writing system"} do if obj:hasType(wrong_type) then if noErr then return false end error("Function expected a " .. typ .. " object, but received a " .. wrong_type .. " object instead.", 2) end end if noErr then return false end error("Function expected a " .. typ .. " object, but received another type of object instead.", 2) end end return true end return export szkevg9xl5j9wpvvgbzhwuqjxjznt9y panggulu 0 3000 26603 23887 2026-07-08T00:11:50Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26603 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{suara|bjn|LL-Q33151 (bjn)-Volstand-panggulu.wav|q=Banjar Hulu}} : {{suara|bjn|LL-Q33151 (bjn)-Muhammad Faisal Ansari-pinggulu.wav|q=Banjar Kuala}} {{-ragam-}} * [[pinggulu]] (''Banjar Kuala'') {{-n-|bjn}} panggulu # dahal awak manusia (atawa binatang) nang manyambungakan kapala ka awak nang lain {{-n-|bjn}} # panghulu , patugas agama nang mancatat urang Islam nang bapangantinan #*''lawas sudah si Anu jadi panggulu'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. [[Tumbung:WikiPandir]] 9k3ptz7clva4th5nc9umo8cckv7f91i métér 0 3406 26607 21839 2026-07-08T00:15:18Z Swarabakti 404 /* {{basa|bjn}} */ 26607 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{suara|bjn|LL-Q33151 (bjn)-Volstand-mitir.wav|q=Banjar Hulu}} : {{suara|bjn|LL-Q33151 (bjn)-Muhammad Faisal Ansari-meter.wav|q=Banjar Kuala}} {{-ragam-}} * [[mitir]] (''Banjar Hulu'') {{-n-|bjn}} # {{label|bjn|Kuala}} satuan asan maukur panjang [[Tumbung:WikiPandir]] hyrvt1t5593aarucvxv2kmqfmw6zl6r 26615 26607 2026-07-08T01:46:02Z Sibiru45 115 /* Basa Banjar */ 26615 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{suara|bjn|LL-Q33151 (bjn)-Volstand-mitir.wav|q=Banjar Hulu}} : {{suara|bjn|LL-Q33151 (bjn)-Muhammad Faisal Ansari-meter.wav|q=Banjar Kuala}} {{-ragam-}} * {{label|bjn|Hulu}}: [[mitir]] {{-n-|bjn}} # {{label|bjn|Kuala}} satuan asan maukur panjang [[Tumbung:WikiPandir]] kpa6idl570hzw7hayezi1ljk0sn1uju 26618 26615 2026-07-08T04:25:21Z Sibiru45 115 /* {{basa|bjn}} */ 26618 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{suara|bjn|LL-Q33151 (bjn)-Volstand-mitir.wav|q=Banjar Hulu}} : {{suara|bjn|LL-Q33151 (bjn)-Muhammad Faisal Ansari-meter.wav|q=Banjar Kuala}} {{-ragam-}} * Banjar Hulu: [[mitir]] {{-n-|bjn}} # {{label|bjn|Kuala}} satuan asan maukur panjang [[Tumbung:WikiPandir]] 75w98qx357txbevfz91jmpqhkthycru 26619 26618 2026-07-08T04:26:00Z Sibiru45 115 /* {{basa|bjn}} */ 26619 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{suara|bjn|LL-Q33151 (bjn)-Volstand-mitir.wav|q=Banjar Hulu}} : {{suara|bjn|LL-Q33151 (bjn)-Muhammad Faisal Ansari-meter.wav|q=Banjar Kuala}} {{-ragam-}} * Banjar Hulu: [[mitir]] {{-n-|bjn}} # {{label|bjn|Kuala}} satuan gasan maukur panjang [[Tumbung:WikiPandir]] 7jsekvck1deonmwkju4votjfz3xu8aq Citakan:l 10 3684 26549 2022-05-24T03:41:28Z id>Mbee-wiki 0 26549 wikitext text/x-wiki {{#invoke:links/templates|l_term_t<noinclude>|demo=term</noinclude>}}<!-- -->{{#ifeq:{{PAGENAME}}|RecentChanges||<!-- -->{{#ifeq:{{{1|}}}|und|[[Kategori:Pranala tanpa kode bahasa]]}}<!-- -->}}<!-- -->{{redlink category|{{{1|}}}|{{{2|}}}|template=l}}<!-- --><noinclude>{{dokumentasi}}</noinclude> l9qcz51qiagixsfsrxoerihmnx3g9wz 26550 20144 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Templat:l]] 20144 wikitext text/x-wiki #ALIH[[Citakan:pranala]] 6qp0efc5oql3cxsd7v99i9b4nvskyst Modul:links 828 3686 26535 24231 2026-04-10T19:00:15Z id>Swarabakti 0 mutakhirkan 26535 Scribunto text/plain local export = {} --[=[ [[Unsupported titles]], pages with high memory usage, extraction modules and part-of-speech names are listed at [[Module:links/data]]. Other modules used: [[Module:script utilities]] [[Module:scripts]] [[Module:languages]] and its submodules [[Module:gender and number]] [[Module:debug/track]] ]=] local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local form_of_module = "Module:form of" local gender_and_number_module = "Module:gender and number" local languages_module = "Module:languages" local load_module = "Module:load" local memoize_module = "Module:memoize" local pages_module = "Module:pages" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local script_utilities_module = "Module:script utilities" local string_encode_entities_module = "Module:string/encode entities" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local concat = table.concat local find = string.find local get_current_title = mw.title.getCurrentTitle local insert = table.insert local ipairs = ipairs local match = string.match local new_title = mw.title.new local pairs = pairs local remove = table.remove local sub = string.sub local toNFC = mw.ustring.toNFC local tostring = tostring local type = type local unstrip = mw.text.unstrip local NAMESPACE = get_current_title().nsText local function anchor_encode(...) anchor_encode = require(memoize_module)(mw.uri.anchorEncode, true) return anchor_encode(...) end local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function decode_uri(...) decode_uri = require(string_utilities_module).decode_uri return decode_uri(...) end -- Can't yet replace, as the [[Module:string utilities]] version no longer has automatic double-encoding prevention, which requires changes here to account for. local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_genders(...) format_genders = require(gender_and_number_module).format_genders return format_genders(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function get_current_L2(...) get_current_L2 = require(pages_module).get_current_L2 return get_current_L2(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function request_script(...) request_script = require(script_utilities_module).request_script return request_script(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function tag_translit(...) tag_translit = require(script_utilities_module).tag_translit return tag_translit(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local m_headword_data local function get_headword_data() m_headword_data = load_data("Module:headword/data") return m_headword_data end local function track(page, code) local tracking_page = "links/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function selective_trim(...) -- Unconditionally trimmed charset. local always_trim = "\194\128-\194\159" .. -- U+0080-009F (C1 control characters) "\194\173" .. -- U+00AD (soft hyphen) "\226\128\170-\226\128\174" .. -- U+202A-202E (directionality formatting characters) "\226\129\166-\226\129\169" -- U+2066-2069 (directionality formatting characters) -- Standard trimmed charset. local standard_trim = "%s" .. -- (default whitespace charset) "\226\128\139-\226\128\141" .. -- U+200B-200D (zero-width spaces) always_trim -- If there are non-whitespace characters, trim all characters in `standard_trim`. -- Otherwise, only trim the characters in `always_trim`. selective_trim = function(text) if text == "" then return text end local trimmed = trim(text, standard_trim) if trimmed ~= "" then return trimmed end return trim(text, always_trim) end return selective_trim(...) end local function escape(text, str) local rep repeat text, rep = text:gsub("\\\\(\\*" .. str .. ")", "\5%1") until rep == 0 return (text:gsub("\\" .. str, "\6")) end local function unescape(text, str) return (text :gsub("\5", "\\") :gsub("\6", str)) end -- Remove bold, italics, soft hyphens, strip markers and HTML tags. local function remove_formatting(str) str = str :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") return (unstrip(str) :gsub("<[^<>]+>", "")) end --[==[Takes an input and splits on a double slash (taking account of escaping backslashes).]==] function export.split_on_slashes(text) if text:find("\\", nil, true) then track("escaped", "split_on_slashes") end text = split(escape(text, "//"), "//", true) or {} for i, v in ipairs(text) do text[i] = unescape(v, "//") if v == "" then text[i] = false end end return text end --[==[Takes a wikilink and outputs the link target and display text. By default, the link target will be returned as a title object, but if `allow_bad_target` is set it will be returned as a string, and no check will be performed as to whether it is a valid link target.]==] function export.get_wikilink_parts(text, allow_bad_target) -- TODO: replace `allow_bad_target` with `allow_unsupported`, with support for links to unsupported titles, including escape sequences. if ( -- Filters out anything but "[[...]]" with no intermediate "[[" or "]]". not match(text, "^()%[%[") or -- Faster than sub(text, 1, 2) ~= "[[". find(text, "[[", 3, true) or find(text, "]]", 3, true) ~= #text - 1 ) then return nil, nil end local pipe, title, display = find(text, "|", 3, true) if pipe then title, display = sub(text, 3, pipe - 1), sub(text, pipe + 1, -3) else title = sub(text, 3, -3) display = title end if allow_bad_target then return title, display end title = new_title(title) -- No title object means the target is invalid. if title == nil then return nil, nil -- If the link target starts with "#" then mw.title.new returns a broken -- title object, so grab the current title and give it the correct fragment. elseif title.prefixedText == "" then local fragment = title.fragment if fragment == "" then -- [[#]] isn't valid return nil, nil end title = get_current_title() title.fragment = fragment end return title, display end -- Does the work of export.get_fragment, but can be called directly to avoid unnecessary checks for embedded links. local function get_fragment(text) text = escape(text, "#") -- Replace numeric character references with the corresponding character (&#39; → '), -- as they contain #, which causes the numeric character reference to be -- misparsed (wa'a → wa&#39;a → pagename wa&, fragment 39;a). text = decode_entities(text) local target, fragment = text:match("^(.-)#(.+)$") target = target or text target = unescape(target, "#") fragment = fragment and unescape(fragment, "#") return target, fragment end --[==[Takes a link target and outputs the actual target and the fragment (if any).]==] function export.get_fragment(text) if text:find("\\", nil, true) then track("escaped", "get_fragment") end -- If there are no embedded links, process input. local open = find(text, "[[", nil, true) if not open then return get_fragment(text) end local close = find(text, "]]", open + 2, true) if not close then return get_fragment(text) -- If there is one, but it's redundant (i.e. encloses everything with no pipe), remove and process. elseif open == 1 and close == #text - 1 and not find(text, "|", 3, true) then return get_fragment(sub(text, 3, -3)) end -- Otherwise, return the input. return text end --[==[ Given a link target as passed to `full_link()`, get the actual page that the target refers to. This removes bold, italics, strip markets and HTML; calls `makeEntryName()` for the language in question; converts targets beginning with `*` to the Reconstruction namespace; and converts appendix-constructed languages to the Appendix namespace. Returns up to three values: # the actual page to link to, or {nil} to not link to anything; # how the target should be displayed as, if the user didn't explicitly specify any display text; generally the same as the original target, but minus any anti-asterisk !!; # the value `true` if the target had a backslash-escaped * in it (FIXME: explain this more clearly). ]==] function export.get_link_page_with_auto_display(target, lang, sc, plain) local orig_target = target if not target then return nil elseif target:find("\\", nil, true) then track("escaped", "get_link_page") end target = remove_formatting(target) if target:sub(1, 1) == ":" then track("initial colon") -- FIXME, the auto_display (second return value) should probably remove the colon return target:sub(2), orig_target end local prefix = target:match("^(.-):") -- Convert any escaped colons target = target:gsub("\\:", ":") if prefix then -- If this is an a link to another namespace or an interwiki link, ensure there's an initial colon and then -- return what we have (so that it works as a conventional link, and doesn't do anything weird like add the term -- to a category.) prefix = ulower(trim(prefix)) if prefix ~= "" and ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then return target, orig_target end end -- Check if the term is reconstructed and remove any asterisk. Also check for anti-asterisk (!!). -- Otherwise, handle the escapes. local reconstructed, escaped, anti_asterisk if not plain then target, reconstructed = target:gsub("^%*(.)", "%1") if reconstructed == 0 then target, anti_asterisk = target:gsub("^!!(.)", "%1") if anti_asterisk == 1 then -- Remove !! from original. FIXME! We do it this way because the call to remove_formatting() above -- may cause non-initial !! to be interpreted as anti-asterisks. We should surely move the -- remove_formatting() call later. orig_target = orig_target:gsub("^!!", "") end end end target, escaped = target:gsub("^(\\-)\\%*", "%1*") if not (sc and sc:getCode() ~= "None") then sc = lang:findBestScript(target) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). if (not sc:hasCapitalization()) and sc:isTransliterated() and target:match("%^") then target = escape(target, "^") :gsub("%^", "") target = unescape(target, "^") end -- Get the entry name for the language. target = lang:makeEntryName(target, sc, reconstructed == 1 or lang:hasType("appendix-constructed")) -- If the link contains unexpanded template parameters, then don't create a link. if target:match("{{{.-}}}") then -- FIXME: Should we return the original target as the default display value (second return value)? return nil end -- Link to appendix for reconstructed terms and terms in appendix-only languages. Plain links interpret * -- literally, however. if reconstructed == 1 then if lang:getFullCode() == "und" then -- Return the original target as default display value. If we don't do this, we wrongly get -- [Term?] displayed instead. return nil, orig_target end target = "Lampiran:Rekonstruksi " .. lang:getCanonicalNameLower() .. "/" .. target -- Reconstructed languages and substrates require an initial *. elseif anti_asterisk ~= 1 and (lang:hasType("reconstructed") or lang:getFamilyCode() == "qfa-sub") then error(("The specified language %s is unattested, while the term '%s' does not begin with '*' to indicate that it is reconstructed.") : format(lang:getCanonicalName(), orig_target)) elseif lang:hasType("appendix-constructed") then target = "Lampiran:" .. lang:getFullName() .. "/" .. target else target = target end return target, orig_target, escaped > 0 end function export.get_link_page(target, lang, sc, plain) local target, auto_display, escaped = export.get_link_page_with_auto_display(target, lang, sc, plain) return target, escaped end -- Make a link from a given link's parts local function make_link(link, lang, sc, id, isolated, cats, no_alt_ast, plain) -- Convert percent encoding to plaintext. link.target = link.target and decode_uri(link.target, "PATH") link.fragment = link.fragment and decode_uri(link.fragment, "PATH") -- Find fragments (if one isn't already set). -- Prevents {{l|en|word#Etymology 2|word}} from linking to [[word#Etymology 2#English]]. -- # can be escaped as \#. if link.target and link.fragment == nil then link.target, link.fragment = get_fragment(link.target) end -- Process the target local auto_display, escaped link.target, auto_display, escaped = export.get_link_page_with_auto_display(link.target, lang, sc, plain) -- Create a default display form. -- If the target is "" then it's a link like [[#English]], which refers to the current page. if auto_display == "" then auto_display = (m_headword_data or get_headword_data()).pagename end -- If the display is the target and the reconstruction * has been escaped, remove the escaping backslash. if escaped then auto_display = auto_display:gsub("\\([^\\]*%*)", "%1", 1) end -- Process the display form. if link.display then local orig_display = link.display link.display = lang:makeDisplayText(link.display, sc, true) if cats then auto_display = lang:makeDisplayText(auto_display, sc) -- If the alt text is the same as what would have been automatically generated, then the alt parameter is redundant (e.g. {{l|en|foo|foo}}, {{l|en|w:foo|foo}}, but not {{l|en|w:foo|w:foo}}). -- If they're different, but the alt text could have been entered as the term parameter without it affecting the target page, then the target parameter is redundant (e.g. {{l|ru|фу|фу́}}). -- If `no_alt_ast` is true, use pcall to catch the error which will be thrown if this is a reconstructed lang and the alt text doesn't have *. if link.display == auto_display then insert(cats, lang:getCode() .. ":Istilah dengan parameter alt lewah") else local ok, check if no_alt_ast then ok, check = pcall(export.get_link_page, orig_display, lang, sc, plain) else ok = true check = export.get_link_page(orig_display, lang, sc, plain) end if ok and link.target == check then insert(cats, lang:getCode() .. ":Istilah dengan parameter sasaran lewah") end end end else link.display = lang:makeDisplayText(auto_display, sc) end if not link.target then return link.display end -- If the target is the same as the current page, there is no sense id -- and either the language code is "und" or the current L2 is the current -- language then return a "self-link" like the software does. if link.target == get_current_title().prefixedText then local fragment, current_L2 = link.fragment, get_current_L2() if ( fragment and fragment == current_L2 or not (id or fragment) and (lang:getFullCode() == "und" or lang:getFullName() == current_L2) ) then return tostring(mw.html.create("strong") :addClass("selflink") :wikitext(link.display)) end end -- Add fragment. Do not add a section link to "Undetermined", as such sections do not exist and are invalid. -- TabbedLanguages handles links without a section by linking to the "last visited" section, but adding -- "Undetermined" would break that feature. For localized prefixes that make syntax error, please use the -- format: ["xyz"] = true. local prefix = link.target:match("^:*([^:]+):") prefix = prefix and ulower(prefix) if prefix ~= "category" and not (prefix and load_data("Module:data/interwikis")[prefix]) then if (link.fragment or link.target:sub(-1) == "#") and not plain then track("fragment", lang:getFullCode()) if cats then insert(cats, lang:getCode() .. ":Istilah dengan fragmen manual") end end if not link.fragment then if id then link.fragment = lang:getFullCode() == "und" and anchor_encode(id) or language_anchor(lang, id) elseif lang:getFullCode() ~= "und" and not (link.target:match("^Lampiran:") or link.target:match("^Wikikamus:")) then link.fragment = anchor_encode(lang:getFullName()) end end end -- Put inward-facing square brackets around a link to isolated spacing character(s). if isolated and #link.display > 0 and not umatch(decode_entities(link.display), "%S") then link.display = "&#x5D;" .. link.display .. "&#x5B;" end link.target = link.target:gsub("^(:?)(.*)", function(m1, m2) return m1 .. encode_entities(m2, "#%&+/:<=>@[\\]_{|}") end) link.fragment = link.fragment and encode_entities(remove_formatting(link.fragment), "#%&+/:<=>@[\\]_{|}") return "[[" .. link.target:gsub("^[^:]", ":%0") .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]" end -- Split a link into its parts local function parse_link(linktext) local link = { target = linktext } local target = link.target link.target, link.display = target:match("^(..-)|(.+)$") if not link.target then link.target = target link.display = target end -- There's no point in processing these, as they aren't real links. local target_lower = link.target:lower() for _, false_positive in ipairs({ "category", "cat", "file", "image" }) do if target_lower:match("^" .. false_positive .. ":") then return nil end end link.display = decode_entities(link.display) link.target, link.fragment = get_fragment(link.target) -- So that make_link does not look for a fragment again. if not link.fragment then link.fragment = false end return link end local function check_params_ignored_when_embedded(alt, lang, id, cats) if alt then track("alt-ignored") if cats then insert(cats, lang:getCode() .. ":Istilah dengan parameter alt tak diacuhkan") end end if id then track("id-ignored") if cats then insert(cats, lang:getCode() .. "Istilah dengan parameter id tak diacuhkan") end end end -- Find embedded links and ensure they link to the correct section. local function process_embedded_links(text, alt, lang, sc, id, cats, no_alt_ast, plain) -- Process the non-linked text. text = lang:makeDisplayText(text, sc, true) -- If the text begins with * and another character, then act as if each link begins with *. However, don't do this if the * is contained within a link at the start. E.g. `|*[[foo]]` would set all_reconstructed to true, while `|[[*foo]]` would not. local all_reconstructed = false if not plain then -- anchor_encode removes links etc. if anchor_encode(text):sub(1, 1) == "*" then all_reconstructed = true end -- Otherwise, handle any escapes. text = text:gsub("^(\\-)\\%*", "%1*") end check_params_ignored_when_embedded(alt, lang, id, cats) local function process_link(space1, linktext, space2) local capture = "[[" .. linktext .. "]]" local link = parse_link(linktext) -- Return unprocessed false positives untouched (e.g. categories). if not link then return capture end if all_reconstructed then if link.target:find("^!!") then -- Check for anti-asterisk !! at the beginning of a target, indicating that a reconstructed term -- wants a part of the term to link to a non-reconstructed term, e.g. Old English -- {{ang-noun|m|head=*[[!!Crist|Cristes]] [[!!mæsseǣfen]]}}. link.target = link.target:sub(3) -- Also remove !! from the display, which may have been copied from the target (as in mæsseǣfen in -- the example above). link.display = link.display:gsub("^!!", "") elseif not link.target:match("^%*") then link.target = "*" .. link.target end end linktext = make_link(link, lang, sc, id, false, nil, no_alt_ast, plain) :gsub("^%[%[", "\3") :gsub("%]%]$", "\4") return space1 .. linktext .. space2 end -- Use chars 1 and 2 as temporary substitutions, so that we can use charsets. These are converted to chars 3 and 4 by process_link, which means we can convert any remaining chars 1 and 2 back to square brackets (i.e. those not part of a link). text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- If the script uses ^ to capitalize transliterations, make sure that any carets preceding links are on the inside, so that they get processed with the following text. if ( text:find("^", nil, true) and not sc:hasCapitalization() and sc:isTransliterated() ) then text = escape(text, "^") :gsub("%^\1", "\1%^") text = unescape(text, "^") end text = text:gsub("\1(%s*)([^\1\2]-)(%s*)\2", process_link) -- Remove the extra * at the beginning of a language link if it's immediately followed by a link whose display begins with * too. if all_reconstructed then text = text:gsub("^%*\3([^|\1-\4]+)|%*", "\3%1|*") end return (text :gsub("[\1\3]", "[[") :gsub("[\2\4]", "]]") ) end local function simple_link(term, fragment, alt, lang, sc, id, cats, no_alt_ast, srwc) local plain if lang == nil then lang, plain = get_lang("und"), true end -- Get the link target and display text. If the term is the empty string, treat the input as a link to the current page. if term == "" then term = get_current_title().prefixedText elseif term then local new_term, new_alt = export.get_wikilink_parts(term, true) if new_term then check_params_ignored_when_embedded(alt, lang, id, cats) -- [[|foo]] links are treated as plaintext "[[|foo]]". -- FIXME: Pipes should be handled via a proper escape sequence, as they can occur in unsupported titles. if new_term == "" then term, alt = nil, term else local title = new_title(new_term) if title then local ns = title.namespace -- File: and Category: links should be returned as-is. if ns == 6 or ns == 14 then return term end end term, alt = new_term, new_alt if cats then if not (srwc and srwc(term, alt)) then insert(cats, lang:getCode() .. ":Istilah dengan pranala wiki lewah") end end end end end if alt then alt = selective_trim(alt) if alt == "" then alt = nil end end -- If there's nothing to process, return nil. if not (term or alt) then return nil end -- If there is no script, get one. if not sc then sc = lang:findBestScript(alt or term) end -- Embedded wikilinks need to be processed individually. if term then local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, alt, lang, sc, id, cats, no_alt_ast, plain) end term = selective_trim(term) end -- If not, make a link using the parameters. return make_link({ target = term, display = alt, fragment = fragment }, lang, sc, id, true, cats, no_alt_ast, plain) end --[==[Creates a basic link to the given term. It links to the language section (such as <code>==English==</code>), but it does not add language and script wrappers, so any code that uses this function should call the <code class="n">[[Module:script utilities#tag_text|tag_text]]</code> from [[Module:script utilities]] to add such wrappers itself at some point. The first argument, <code class="n">data</code>, may contain the following items, a subset of the items used in the <code class="n">data</code> argument of <code class="n">full_link</code>. If any other items are included, they are ignored. { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, id = sense_id, } } ; <code class="n">term</code> : Text to turn into a link. This is generally the name of a page. The text can contain wikilinks already embedded in it. These are processed individually just like a single link would be. The <code class="n">alt</code> argument is ignored in this case. ; <code class="n">alt</code> (''optional'') : The alternative display for the link, if different from the linked page. If this is {{code|lua|nil}}, the <code class="n">text</code> argument is used instead (much like regular wikilinks). If <code class="n">text</code> contains wikilinks in it, this argument is ignored and has no effect. (Links in which the alt is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/alt-ignored}}.) ; <code class="n">lang</code> : The [[Module:languages#Language objects|language object]] for the term being linked. If this argument is defined, the function will determine the language's canonical name (see [[Template:language data documentation]]), and point the link or links in the <code class="n">term</code> to the language's section of an entry, or to a language-specific senseid if the <code class="n">id</code> argument is defined. ; <code class="n">id</code> (''optional'') : Sense id string. If this argument is defined, the link will point to a language-specific sense id ({{ll|en|identifier|id=HTML}}) created by the template {{temp|senseid}}. A sense id consists of the language's canonical name, a hyphen (<code>-</code>), and the string that was supplied as the <code class="n">id</code> argument. This is useful when a term has more than one sense in a language. If the <code class="n">term</code> argument contains wikilinks, this argument is ignored. (Links in which the sense id is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/id-ignored}}.) The second argument is as follows: ; <code class="n">allow_self_link</code> : If {{code|lua|true}}, the function will also generate links to the current page. The default ({{code|lua|false}}) will not generate a link but generate a bolded "self link" instead. The following special options are processed for each link (both simple text and with embedded wikilinks): * The target page name will be processed to generate the correct entry name. This is done by the [[Module:languages#makeEntryName|makeEntryName]] function in [[Module:languages]], using the <code class="n">entry_name</code> replacements in the language's data file (see [[Template:language data documentation]] for more information). This function is generally used to automatically strip dictionary-only diacritics that are not part of the normal written form of a language. * If the text starts with <code class="n">*</code>, then the term is considered a reconstructed term, and a link to the Reconstruction: namespace will be created. If the text contains embedded wikilinks, then <code class="n">*</code> is automatically applied to each one individually, while preserving the displayed form of each link as it was given. This allows linking to phrases containing multiple reconstructed terms, while only showing the * once at the beginning. * If the text starts with <code class="n">:</code>, then the link is treated as "raw" and the above steps are skipped. This can be used in rare cases where the page name begins with <code class="n">*</code> or if diacritics should not be stripped. For example: ** {{temp|l|en|*nix}} links to the nonexistent page [[Reconstruction:English/nix]] (<code class="n">*</code> is interpreted as a reconstruction), but {{temp|l|en|:*nix}} links to [[*nix]]. ** {{temp|l|sl|Franche-Comté}} links to the nonexistent page [[Franche-Comte]] (<code>é</code> is converted to <code>e</code> by <code class="n">makeEntryName</code>), but {{temp|l|sl|:Franche-Comté}} links to [[Franche-Comté]].]==] function export.language_link(data) if type(data) ~= "table" then error( "The first argument to the function language_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "language_link") end -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Pranala bahasa tak ditentukan") end return simple_link( data.term, data.fragment, data.alt, lang, data.sc, data.id, cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end function export.plain_link(data) if type(data) ~= "table" then error( "The first argument to the function plain_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "plain_link") end return simple_link( data.term, data.fragment, data.alt, nil, data.sc, data.id, data.cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end --[==[Replace any links with links to the correct section, but don't link the whole text if no embedded links are found. Returns the display text form.]==] function export.embedded_language_links(data) if type(data) ~= "table" then error( "The first argument to the function embedded_language_links must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "embedded_language_links") end local term, lang, sc = data.term, data.lang, data.sc -- If we don't have a script, get one. if not sc then sc = lang:findBestScript(term) end -- Do we have embedded wikilinks? If so, they need to be processed individually. local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, data.alt, lang, sc, data.id, data.cats, data.no_alt_ast) end -- If not, return the display text. term = selective_trim(term) -- FIXME: Double-escape any percent-signs, because we don't want to treat non-linked text as having percent-encoded characters. This is a hack: percent-decoding should come out of [[Module:languages]] and only dealt with in this module, as it's specific to links. term = term:gsub("%%", "%%25") return lang:makeDisplayText(term, sc, true) end function export.mark(text, item_type, face, lang) local tag = { "", "" } if item_type == "gloss" then tag = { '<span class="mention-gloss-double-quote">“</span><span class="mention-gloss">', '</span><span class="mention-gloss-double-quote">”</span>' } if type(text) == "string" and text:match("^''[^'].*''$") then -- Temporary tracking for mention glosses that are entirely italicized or bolded, which is probably -- wrong. (Note that this will also find bolded mention glosses since they use triple apostrophes.) track("italicized-mention-gloss", lang and lang:getFullCode() or nil) end elseif item_type == "tr" then if face == "term" then tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr mention-tr Latn">', '</span>' } else tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr Latn">', '</span>' } end elseif item_type == "ts" then -- \226\129\160 = word joiner (zero-width non-breaking space) U+2060 tag = { '<span class="ts mention-ts Latn">/\226\129\160', '\226\129\160/</span>' } elseif item_type == "pos" then tag = { '<span class="ann-pos">', '</span>' } elseif item_type == "non-gloss" then tag = { '<span class="ann-non-gloss">', '</span>' } elseif item_type == "annotations" then tag = { '<span class="mention-gloss-paren annotation-paren">(</span>', '<span class="mention-gloss-paren annotation-paren">)</span>' } elseif item_type == "infl" then tag = { '<span class="ann-infl">', '</span>' } end if type(text) == "string" then return tag[1] .. text .. tag[2] else return "" end end local pos_tags --[==[Formats the annotations that are displayed with a link created by {{code|lua|full_link}}. Annotations are the extra bits of information that are displayed following the linked term, and include things such as gender, transliteration, gloss and so on. * The first argument is a table possessing some or all of the following keys: *:; <code class="n">genders</code> *:: Table containing a list of gender specifications in the style of [[Module:gender and number]]. *:; <code class="n">tr</code> *:: Transliteration. *:; <code class="n">gloss</code> *:: Gloss that translates the term in the link, or gives some other descriptive information. *:; <code class="n">pos</code> *:: Part of speech of the linked term. If the given argument matches one of the aliases in `pos_aliases` in [[Module:headword/data]], or consists of a part of speech or alias followed by `f` (for a non-lemma form), expand it appropriately. Otherwise, just show the given text as it is. *:; <code class="n">ng</code> *:: Arbitrary non-gloss descriptive text for the link. This should be used in preference to putting descriptive text in `gloss` or `pos`. *:; <code class="n">lit</code> *:: Literal meaning of the term, if the usual meaning is figurative or idiomatic. *:; <code class="n">infl</code> *:: Table containing a list of grammar tags in the style of [[Module:form of]] `tagged_inflections`. *:Any of the above values can be omitted from the <code class="n">info</code> argument. If a completely empty table is given (with no annotations at all), then an empty string is returned. * The second argument is a string. Valid values are listed in [[Module:script utilities/data]] "data.translit" table.]==] function export.format_link_annotations(data, face) local output = {} -- Interwiki link if data.interwiki then insert(output, data.interwiki) end -- Genders if type(data.genders) ~= "table" then data.genders = { data.genders } end if data.genders and #data.genders > 0 then local genders, gender_cats = format_genders(data.genders, data.lang) insert(output, "&nbsp;" .. genders) if gender_cats then local cats = data.cats if cats then extend(cats, gender_cats) end end end local annotations = {} -- Transliteration and transcription if data.tr and data.tr[1] or data.ts and data.ts[1] then local kind if face == "term" then kind = face else kind = "default" end if data.tr[1] and data.ts[1] then insert(annotations, tag_translit(data.tr[1], data.lang, kind) .. " " .. export.mark(data.ts[1], "ts")) elseif data.ts[1] then insert(annotations, export.mark(data.ts[1], "ts")) else insert(annotations, tag_translit(data.tr[1], data.lang, kind)) end end -- Gloss/translation if data.gloss then insert(annotations, export.mark(data.gloss, "gloss")) end -- Part of speech if data.pos then -- debug category for pos= containing transcriptions if data.pos:match("/[^><]-/") then data.pos = data.pos .. "[[Kategori:Pranala mengandung transkripsi pada kelas kata]]" end -- Canonicalize part of speech aliases as well as non-lemma aliases like 'nf' or 'nounf' for "noun form". pos_tags = pos_tags or (m_headword_data or get_headword_data()).pos_aliases local pos = pos_tags[data.pos] if not pos and data.pos:find("f$") then local pos_form = data.pos:sub(1, -2) -- We only expand something ending in 'f' if the result is a recognized non-lemma POS. pos_form = (pos_tags[pos_form] or pos_form) .. " form" if (m_headword_data or get_headword_data()).nonlemmas[pos_form .. "s"] then pos = pos_form end end insert(annotations, export.mark(pos or data.pos, "pos")) end -- Inflection data if data.infl then local m_form_of = require(form_of_module) -- Split tag sets manually, since tagged_inflections creates a numbered list, and we do not want that. local infl_outputs = {} local tag_sets = m_form_of.split_tag_set(data.infl) for _, tag_set in ipairs(tag_sets) do table.insert(infl_outputs, m_form_of.tagged_inflections({ tags = tag_set, lang = data.lang, nocat = true, nolink = true, nowrap = true })) end insert(annotations, export.mark(table.concat(infl_outputs, "; "), "infl")) end -- Non-gloss text if data.ng then insert(annotations, export.mark(data.ng, "non-gloss")) end -- Literal/sum-of-parts meaning if data.lit then insert(annotations, "literally " .. export.mark(data.lit, "gloss")) end -- Provide a hook to insert additional annotations such as nested inflections. if data.postprocess_annotations then data.postprocess_annotations { data = data, annotations = annotations } end if #annotations > 0 then insert(output, " " .. export.mark(concat(annotations, ", "), "annotations")) end return concat(output) end -- Encode certain characters to avoid various delimiter-related issues at various stages. We need to encode < and > -- because they end up forming part of CSS class names inside of <span ...> and will interfere with finding the end -- of the HTML tag. I first tried converting them to URL encoding, i.e. %3C and %3E; they then appear in the URL as -- %253C and %253E, which get mapped back to %3C and %3E when passed to [[Module:accel]]. But mapping them to &lt; -- and &gt; somehow works magically without any further work; they appear in the URL as < and >, and get passed to -- [[Module:accel]] as < and >. I have no idea who along the chain of calls is doing the encoding and decoding. If -- someone knows, please modify this comment appropriately! local accel_char_map local function get_accel_char_map() accel_char_map = { ["%"] = ".", [" "] = "_", ["_"] = u(0xFFF0), ["<"] = "&lt;", [">"] = "&gt;", } return accel_char_map end local function encode_accel_param_chars(param) return (param:gsub("[% <>_]", accel_char_map or get_accel_char_map())) end local function encode_accel_param(prefix, param) if not param then return "" end if type(param) == "table" then local filled_params = {} -- There may be gaps in the sequence, especially for translit params. local maxindex = 0 for k in pairs(param) do if type(k) == "number" and k > maxindex then maxindex = k end end for i = 1, maxindex do filled_params[i] = param[i] or "" end -- [[Module:accel]] splits these up again. param = concat(filled_params, "*~!") end -- This is decoded again by [[WT:ACCEL]]. return prefix .. encode_accel_param_chars(param) end local function insert_if_not_blank(list, item) if item == "" then return end insert(list, item) end local function get_class(lang, tr, accel, nowrap) if not accel and not nowrap then return "" end local classes = {} if accel then insert(classes, "form-of lang-" .. lang:getFullCode()) local form = accel.form if form then insert(classes, encode_accel_param_chars(form) .. "-form-of") end insert_if_not_blank(classes, encode_accel_param("gender-", accel.gender)) insert_if_not_blank(classes, encode_accel_param("pos-", accel.pos)) insert_if_not_blank(classes, encode_accel_param("transliteration-", accel.translit or (tr ~= "-" and tr or nil))) insert_if_not_blank(classes, encode_accel_param("target-", accel.target)) insert_if_not_blank(classes, encode_accel_param("origin-", accel.lemma)) insert_if_not_blank(classes, encode_accel_param("origin_transliteration-", accel.lemma_translit)) if accel.no_store then insert(classes, "form-of-nostore") end end if nowrap then insert(classes, nowrap) end return concat(classes, " ") end -- Add any left or right regular or accent qualifiers, labels or references to a formatted term. `data` is the object -- specifying the term, which should optionally contain: -- * a language object in `lang`; required if any accent qualifiers or labels are given; -- * left regular qualifiers in `q` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * right regular qualifiers in `qq` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * left accent qualifiers in `a` (an array of strings); an empty array will be ignored; -- * right accent qualifiers in `aa` (an array of strings); an empty array will be ignored; -- * left labels in `l` (an array of strings); an empty array will be ignored; -- * right labels in `ll` (an array of strings); an empty array will be ignored; -- * references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text` -- (formatted reference text) and optionally `name` and/or `group`. -- `formatted` is the formatted version of the term itself. local function add_qualifiers_and_refs_to_term(data, formatted) local q = data.q if type(q) == "string" then q = { q } end local qq = data.qq if type(qq) == "string" then qq = { qq } end if q and q[1] or qq and qq[1] or data.a and data.a[1] or data.aa and data.aa[1] or data.l and data.l[1] or data.ll and data.ll[1] or data.refs and data.refs[1] then formatted = format_qualifiers { lang = data.lang, text = formatted, q = q, qq = qq, a = data.a, aa = data.aa, l = data.l, ll = data.ll, refs = data.refs, } end return formatted end --[==[ Creates a full link, with annotations (see `[[#format_link_annotations|format_link_annotations]]`), in the style of {{tl|l}} or {{tl|m}}. The first argument, `data`, must be a table. It contains the various elements that can be supplied as parameters to {{tl|l}} or {{tl|m}}: { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, sc = script_object, track_sc = boolean, no_nonstandard_sc_cat = boolean, fragment = link_fragment, id = sense_id, genders = { "gender1", "gender2", ... }, tr = transliteration, respect_link_tr = boolean, ts = transcription, gloss = gloss, pos = part_of_speech_tag, ng = non-gloss text, lit = literal_translation, infl = { "form_of_grammar_tag1", "form_of_grammar_tag2", ... }, no_alt_ast = boolean, accel = {accelerated_creation_tags}, interwiki = interwiki, pretext = "text_at_beginning" or nil, posttext = "text_at_end" or nil, q = { "left_qualifier1", "left_qualifier2", ...} or "left_qualifier", qq = { "right_qualifier1", "right_qualifier2", ...} or "right_qualifier", l = { "left_label1", "left_label2", ...}, ll = { "right_label1", "right_label2", ...}, a = { "left_accent_qualifier1", "left_accent_qualifier2", ...}, aa = { "right_accent_qualifier1", "right_accent_qualifier2", ...}, refs = { "formatted_ref1", "formatted_ref2", ...} or { {text = "text", name = "name", group = "group"}, ... }, show_qualifiers = boolean, } } Any one of the items in the `data` table may be {nil}, but an error will be shown if neither `term` nor `alt` nor `tr` is present. Thus, calling {full_link{ term = term, lang = lang, sc = sc }}, where `term` is the page to link to (which may have diacritics that will be stripped and/or embedded bracketed links) and `lang` is a [[Module:languages#Language objects|language object]] from [[Module:languages]], will give a plain link similar to the one produced by the template {{tl|l}}, and calling {full_link( { term = term, lang = lang, sc = sc }, "term" )} will give a link similar to the one produced by the template {{tl|m}}. The function will: * Try to determine the script, based on the characters found in the `term` or `alt` argument, if the script was not given. If a script is given and `track_sc` is {true}, it will check whether the input script is the same as the one which would have been automatically generated and add the category [[:Category:LANG terms with redundant script codes]] if yes, or [[:Category:LANG terms with non-redundant manual script codes]] if no. This should be used when the input script object is directly determined by a template's `sc` parameter. * Call `[[#language_link|language_link]]` on the `term` or `alt` forms, to remove diacritics in the page name, process any embedded wikilinks and create links to Reconstruction or Appendix pages when necessary. * Call `[[Module:script utilities#tag_text]]` to add the appropriate language and script tags to the term and italicize terms written in the Latin script if necessary. Accelerated creation tags, as used by [[WT:ACCEL]], are included. * Generate a transliteration, based on the `alt` or `term` arguments, if the script is not Latin, no transliteration was provided in `tr` and the combination of the term's language and script support automatic transliteration. The transliteration itself will be linked if both `.respect_link_tr` is specified and the language of the term has the `link_tr` property set for the script of the term; but not otherwise. * Add the annotations (transliteration, gender, gloss, etc.) after the link. * If `no_alt_ast` is specified, then the `alt` text does not need to contain an asterisk if the language is reconstructed. This should only be used by modules which really need to allow links to reconstructions that don't display asterisks (e.g. number boxes). * If `pretext` or `posttext` is specified, this is text to (respectively) prepend or append to the output, directly before processing qualifiers, labels and references. This can be used to add arbitrary extra text inside of the qualifiers, labels and references. * If `show_qualifiers` is specified or the `show_qualifiers` argument is given, then left and right qualifiers, accent qualifiers, labels and references will be displayed, otherwise they will be ignored. (This is because a fair amount of code stores qualifiers, labels and/or references in these fields and displays them itself, rather than expecting {full_link()} to display them.)]==] function export.full_link(data, face, allow_self_link, show_qualifiers) if type(data) ~= "table" then error("The first argument to the function full_link must be a table. " .. "See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "full_link") end -- Prevent data from being destructively modified. local data = shallow_copy(data) -- FIXME: this shouldn't be added to `data`, as that means the input table needs to be cloned. data.cats = {} -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Undetermined language links") end local terms = { true } -- Generate multiple forms if applicable. for _, param in ipairs { "term", "alt" } do if type(data[param]) == "string" and data[param]:find("//", nil, true) then data[param] = export.split_on_slashes(data[param]) elseif type(data[param]) == "string" and not (type(data.term) == "string" and data.term:find("//", nil, true)) then if not data.no_generate_forms then data[param] = lang:generateForms(data[param]) else data[param] = { data[param] } end else data[param] = {} end end for _, param in ipairs { "sc", "tr", "ts" } do data[param] = { data[param] } end for _, param in ipairs { "term", "alt", "sc", "tr", "ts" } do for i in pairs(data[param]) do terms[i] = true end end -- Create the link local output = {} local id, no_alt_ast, srwc, accel, nevercalltr = data.id, data.no_alt_ast, data.suppress_redundant_wikilink_cat, data.accel, data.never_call_transliteration_module local link_tr = data.respect_link_tr and lang:link_tr(data.sc[1]) for i in ipairs(terms) do local link -- Is there any text to show? if (data.term[i] or data.alt[i]) then -- Try to detect the script if it was not provided local display_term = data.alt[i] or data.term[i] local best = lang:findBestScript(display_term) -- no_nonstandard_sc_cat is intended for use in [[Module:interproject]] if ( not data.no_nonstandard_sc_cat and best:getCode() == "None" and find_best_script_without_lang(display_term):getCode() ~= "None" ) then insert(cats, lang:getCode() .. ":Istilah dengan aksara tak lazim") end if not data.sc[i] then data.sc[i] = best -- Track uses of sc parameter. elseif data.track_sc then if data.sc[i]:getCode() == best:getCode() then insert(cats, lang:getCode() .. ":Istilah dengan kode aksara lewah") else insert(cats, lang:getCode() .. ":Istilah dengan kode aksara manual tak lewah") end end -- If using a discouraged character sequence, add to maintenance category if data.sc[i]:hasNormalizationFixes() == true then if (data.term[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.term[i])) ~= toNFC(data.term[i])) or (data.alt[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.alt[i])) ~= toNFC(data.alt[i])) then insert(cats, "Pages using discouraged character sequences") end end link = simple_link( data.term[i], data.fragment, data.alt[i], lang, data.sc[i], id, cats, no_alt_ast, srwc ) end -- simple_link can return nil, so check if a link has been generated. if link then -- Add "nowrap" class to prefixes in order to prevent wrapping after the hyphen local nowrap local display_term = data.alt[i] or data.term[i] if display_term and (display_term:find("^%-") or display_term:find("^־")) then -- Hebrew maqqef -- FIXME, use hyphens from [[Module:affix]] nowrap = "nowrap" end link = tag_text(link, lang, data.sc[i], face, get_class(lang, data.tr[i], accel, nowrap)) else --[[ No term to show. Is there at least a transliteration we can work from? ]] link = request_script(lang, data.sc[i]) -- No link to show, and no transliteration either. Show a term request (unless it's a substrate, as they rarely take terms). if (link == "" or (not data.tr[i]) or data.tr[i] == "-") and lang:getFamilyCode() ~= "qfa-sub" then -- If there are multiple terms, break the loop instead. if i > 1 then remove(output) break elseif NAMESPACE ~= "Templat" then insert(cats, lang:getCode() .. ":Permintaan istilah") end link = "<small>[Term?]</small>" end end insert(output, link) if i < #terms then insert(output, "<span class=\"Zsym mention\" style=\"font-size:100%;\">&nbsp;/ </span>") end end -- When suppress_tr is true, do not show or generate any transliteration if data.suppress_tr then data.tr[1] = nil else -- TODO: Currently only handles the first transliteration, pending consensus on how to handle multiple translits for multiple forms, as this is not always desirable (e.g. traditional/simplified Chinese). if data.tr[1] == "" or data.tr[1] == "-" then data.tr[1] = nil else local phonetic_extraction = load_data("Module:links/data").phonetic_extraction phonetic_extraction = phonetic_extraction[lang:getCode()] or phonetic_extraction[lang:getFullCode()] if phonetic_extraction then data.tr[1] = data.tr[1] or require(phonetic_extraction).getTranslit(export.remove_links(data.alt[1] or data.term[1])) elseif (data.term[1] or data.alt[1]) and data.sc[1]:isTransliterated() then -- Track whenever there is manual translit. The categories below like 'terms with redundant transliterations' -- aren't sufficient because they only work with reference to automatic translit and won't operate at all in -- languages without any automatic translit, like Persian and Hebrew. if data.tr[1] then local full_code = lang:getFullCode() track("manual-tr", full_code) end if not nevercalltr then -- Try to generate a transliteration. local text = data.alt[1] or data.term[1] if not link_tr then text = export.remove_links(text, true) end local automated_tr = lang:transliterate(text, data.sc[1]) if automated_tr then local manual_tr = data.tr[1] if manual_tr then if export.remove_links(manual_tr) == export.remove_links(automated_tr) then insert(cats, lang:getCode() .. ":Istilah dengan alih aksara lewah") else -- Prevents Arabic root categories from flooding the tracking categories. if NAMESPACE ~= "Kategori" then insert(cats, lang:getCode() .. ":Istilah dengan alih aksara manual tak lewah") end end end if not manual_tr or lang:overrideManualTranslit(data.sc[1]) then data.tr[1] = automated_tr end end end end end end -- Link to the transliteration entry for languages that require this if data.tr[1] and link_tr and not data.tr[1]:match("%[%[(.-)%]%]") then data.tr[1] = simple_link( data.tr[1], nil, nil, lang, get_script("Latn"), nil, cats, no_alt_ast, srwc ) elseif data.tr[1] and not link_tr then -- Remove the pseudo-HTML tags added by remove_links. data.tr[1] = data.tr[1]:gsub("</?link>", "") end if data.tr[1] and not umatch(data.tr[1], "[^%s%p]") then data.tr[1] = nil end insert(output, export.format_link_annotations(data, face)) if data.pretext then insert(output, 1, data.pretext) end if data.posttext then insert(output, data.posttext) end local categories = cats[1] and format_categories(cats, lang, "-", nil, nil, data.sc) or "" output = concat(output) if show_qualifiers or data.show_qualifiers then output = add_qualifiers_and_refs_to_term(data, output) end return output .. categories end --[==[Replaces all wikilinks with their displayed text, and removes any categories. This function can be invoked either from a template or from another module. -- Strips links: deletes category links, the targets of piped links, and any double square brackets involved in links (other than file links, which are untouched). If `tag` is set, then any links removed will be given pseudo-HTML tags, which allow the substitution functions in [[Module:languages]] to properly subdivide the text in order to reduce the chance of substitution failures in modules which scrape pages like [[Module:zh-translit]]. -- FIXME: This is quite hacky. We probably want this to be integrated into [[Module:languages]], but we can't do that until we know that nothing is pushing pipe linked transliterations through it for languages which don't have link_tr set. * <code><nowiki>[[page|displayed text]]</nowiki></code> &rarr; <code><nowiki>displayed text</nowiki></code> * <code><nowiki>[[page and displayed text]]</nowiki></code> &rarr; <code><nowiki>page and displayed text</nowiki></code> * <code><nowiki>[[Kategori:id:Lema|WORD]]</nowiki></code> &rarr; ''(nothing)'']==] function export.remove_links(text, tag) if type(text) == "table" then text = text.args[1] end if not text or text == "" then return "" end text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Parse internal links for the display text. text = text:gsub("(\1)([^\1\2]-)(\2)", function(c1, c2, c3) -- Don't remove files. for _, false_positive in ipairs({ "file", "image" }) do if c2:lower():match("^" .. false_positive .. ":") then return c1 .. c2 .. c3 end end -- Remove categories completely. for _, false_positive in ipairs({ "category", "cat" }) do if c2:lower():match("^" .. false_positive .. ":") then return "" end end -- In piped links, remove all text before the pipe, unless it's the final character (i.e. the pipe trick), in which case just remove the pipe. c2 = c2:match("^[^|]*|(.+)") or c2:match("([^|]+)|$") or c2 if tag then return "<link>" .. c2 .. "</link>" else return c2 end end) text = text :gsub("\1", "[[") :gsub("\2", "]]") return text end function export.section_link(link) if type(link) ~= "string" then error("The first argument to section_link was a " .. type(link) .. ", but it should be a string.") elseif link:find("\\", nil, true) then track("escaped", "section_link") end local target, section = get_fragment((link:gsub("_", " "))) if not section then error("No \"#\" delineating a section name") end return simple_link( target, section, target .. " §&nbsp;" .. section ) end return export eoxg2nqf378ifvy2vd9s9wh15y2r7b7 26536 26535 2026-07-07T21:53:34Z Sibiru45 115 1 ralatan matan [[:id:Modul:links]] 26535 Scribunto text/plain local export = {} --[=[ [[Unsupported titles]], pages with high memory usage, extraction modules and part-of-speech names are listed at [[Module:links/data]]. Other modules used: [[Module:script utilities]] [[Module:scripts]] [[Module:languages]] and its submodules [[Module:gender and number]] [[Module:debug/track]] ]=] local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local form_of_module = "Module:form of" local gender_and_number_module = "Module:gender and number" local languages_module = "Module:languages" local load_module = "Module:load" local memoize_module = "Module:memoize" local pages_module = "Module:pages" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local script_utilities_module = "Module:script utilities" local string_encode_entities_module = "Module:string/encode entities" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local concat = table.concat local find = string.find local get_current_title = mw.title.getCurrentTitle local insert = table.insert local ipairs = ipairs local match = string.match local new_title = mw.title.new local pairs = pairs local remove = table.remove local sub = string.sub local toNFC = mw.ustring.toNFC local tostring = tostring local type = type local unstrip = mw.text.unstrip local NAMESPACE = get_current_title().nsText local function anchor_encode(...) anchor_encode = require(memoize_module)(mw.uri.anchorEncode, true) return anchor_encode(...) end local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function decode_uri(...) decode_uri = require(string_utilities_module).decode_uri return decode_uri(...) end -- Can't yet replace, as the [[Module:string utilities]] version no longer has automatic double-encoding prevention, which requires changes here to account for. local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_genders(...) format_genders = require(gender_and_number_module).format_genders return format_genders(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function get_current_L2(...) get_current_L2 = require(pages_module).get_current_L2 return get_current_L2(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function request_script(...) request_script = require(script_utilities_module).request_script return request_script(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function tag_translit(...) tag_translit = require(script_utilities_module).tag_translit return tag_translit(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local m_headword_data local function get_headword_data() m_headword_data = load_data("Module:headword/data") return m_headword_data end local function track(page, code) local tracking_page = "links/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function selective_trim(...) -- Unconditionally trimmed charset. local always_trim = "\194\128-\194\159" .. -- U+0080-009F (C1 control characters) "\194\173" .. -- U+00AD (soft hyphen) "\226\128\170-\226\128\174" .. -- U+202A-202E (directionality formatting characters) "\226\129\166-\226\129\169" -- U+2066-2069 (directionality formatting characters) -- Standard trimmed charset. local standard_trim = "%s" .. -- (default whitespace charset) "\226\128\139-\226\128\141" .. -- U+200B-200D (zero-width spaces) always_trim -- If there are non-whitespace characters, trim all characters in `standard_trim`. -- Otherwise, only trim the characters in `always_trim`. selective_trim = function(text) if text == "" then return text end local trimmed = trim(text, standard_trim) if trimmed ~= "" then return trimmed end return trim(text, always_trim) end return selective_trim(...) end local function escape(text, str) local rep repeat text, rep = text:gsub("\\\\(\\*" .. str .. ")", "\5%1") until rep == 0 return (text:gsub("\\" .. str, "\6")) end local function unescape(text, str) return (text :gsub("\5", "\\") :gsub("\6", str)) end -- Remove bold, italics, soft hyphens, strip markers and HTML tags. local function remove_formatting(str) str = str :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") return (unstrip(str) :gsub("<[^<>]+>", "")) end --[==[Takes an input and splits on a double slash (taking account of escaping backslashes).]==] function export.split_on_slashes(text) if text:find("\\", nil, true) then track("escaped", "split_on_slashes") end text = split(escape(text, "//"), "//", true) or {} for i, v in ipairs(text) do text[i] = unescape(v, "//") if v == "" then text[i] = false end end return text end --[==[Takes a wikilink and outputs the link target and display text. By default, the link target will be returned as a title object, but if `allow_bad_target` is set it will be returned as a string, and no check will be performed as to whether it is a valid link target.]==] function export.get_wikilink_parts(text, allow_bad_target) -- TODO: replace `allow_bad_target` with `allow_unsupported`, with support for links to unsupported titles, including escape sequences. if ( -- Filters out anything but "[[...]]" with no intermediate "[[" or "]]". not match(text, "^()%[%[") or -- Faster than sub(text, 1, 2) ~= "[[". find(text, "[[", 3, true) or find(text, "]]", 3, true) ~= #text - 1 ) then return nil, nil end local pipe, title, display = find(text, "|", 3, true) if pipe then title, display = sub(text, 3, pipe - 1), sub(text, pipe + 1, -3) else title = sub(text, 3, -3) display = title end if allow_bad_target then return title, display end title = new_title(title) -- No title object means the target is invalid. if title == nil then return nil, nil -- If the link target starts with "#" then mw.title.new returns a broken -- title object, so grab the current title and give it the correct fragment. elseif title.prefixedText == "" then local fragment = title.fragment if fragment == "" then -- [[#]] isn't valid return nil, nil end title = get_current_title() title.fragment = fragment end return title, display end -- Does the work of export.get_fragment, but can be called directly to avoid unnecessary checks for embedded links. local function get_fragment(text) text = escape(text, "#") -- Replace numeric character references with the corresponding character (&#39; → '), -- as they contain #, which causes the numeric character reference to be -- misparsed (wa'a → wa&#39;a → pagename wa&, fragment 39;a). text = decode_entities(text) local target, fragment = text:match("^(.-)#(.+)$") target = target or text target = unescape(target, "#") fragment = fragment and unescape(fragment, "#") return target, fragment end --[==[Takes a link target and outputs the actual target and the fragment (if any).]==] function export.get_fragment(text) if text:find("\\", nil, true) then track("escaped", "get_fragment") end -- If there are no embedded links, process input. local open = find(text, "[[", nil, true) if not open then return get_fragment(text) end local close = find(text, "]]", open + 2, true) if not close then return get_fragment(text) -- If there is one, but it's redundant (i.e. encloses everything with no pipe), remove and process. elseif open == 1 and close == #text - 1 and not find(text, "|", 3, true) then return get_fragment(sub(text, 3, -3)) end -- Otherwise, return the input. return text end --[==[ Given a link target as passed to `full_link()`, get the actual page that the target refers to. This removes bold, italics, strip markets and HTML; calls `makeEntryName()` for the language in question; converts targets beginning with `*` to the Reconstruction namespace; and converts appendix-constructed languages to the Appendix namespace. Returns up to three values: # the actual page to link to, or {nil} to not link to anything; # how the target should be displayed as, if the user didn't explicitly specify any display text; generally the same as the original target, but minus any anti-asterisk !!; # the value `true` if the target had a backslash-escaped * in it (FIXME: explain this more clearly). ]==] function export.get_link_page_with_auto_display(target, lang, sc, plain) local orig_target = target if not target then return nil elseif target:find("\\", nil, true) then track("escaped", "get_link_page") end target = remove_formatting(target) if target:sub(1, 1) == ":" then track("initial colon") -- FIXME, the auto_display (second return value) should probably remove the colon return target:sub(2), orig_target end local prefix = target:match("^(.-):") -- Convert any escaped colons target = target:gsub("\\:", ":") if prefix then -- If this is an a link to another namespace or an interwiki link, ensure there's an initial colon and then -- return what we have (so that it works as a conventional link, and doesn't do anything weird like add the term -- to a category.) prefix = ulower(trim(prefix)) if prefix ~= "" and ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then return target, orig_target end end -- Check if the term is reconstructed and remove any asterisk. Also check for anti-asterisk (!!). -- Otherwise, handle the escapes. local reconstructed, escaped, anti_asterisk if not plain then target, reconstructed = target:gsub("^%*(.)", "%1") if reconstructed == 0 then target, anti_asterisk = target:gsub("^!!(.)", "%1") if anti_asterisk == 1 then -- Remove !! from original. FIXME! We do it this way because the call to remove_formatting() above -- may cause non-initial !! to be interpreted as anti-asterisks. We should surely move the -- remove_formatting() call later. orig_target = orig_target:gsub("^!!", "") end end end target, escaped = target:gsub("^(\\-)\\%*", "%1*") if not (sc and sc:getCode() ~= "None") then sc = lang:findBestScript(target) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). if (not sc:hasCapitalization()) and sc:isTransliterated() and target:match("%^") then target = escape(target, "^") :gsub("%^", "") target = unescape(target, "^") end -- Get the entry name for the language. target = lang:makeEntryName(target, sc, reconstructed == 1 or lang:hasType("appendix-constructed")) -- If the link contains unexpanded template parameters, then don't create a link. if target:match("{{{.-}}}") then -- FIXME: Should we return the original target as the default display value (second return value)? return nil end -- Link to appendix for reconstructed terms and terms in appendix-only languages. Plain links interpret * -- literally, however. if reconstructed == 1 then if lang:getFullCode() == "und" then -- Return the original target as default display value. If we don't do this, we wrongly get -- [Term?] displayed instead. return nil, orig_target end target = "Lampiran:Rekonstruksi " .. lang:getCanonicalNameLower() .. "/" .. target -- Reconstructed languages and substrates require an initial *. elseif anti_asterisk ~= 1 and (lang:hasType("reconstructed") or lang:getFamilyCode() == "qfa-sub") then error(("The specified language %s is unattested, while the term '%s' does not begin with '*' to indicate that it is reconstructed.") : format(lang:getCanonicalName(), orig_target)) elseif lang:hasType("appendix-constructed") then target = "Lampiran:" .. lang:getFullName() .. "/" .. target else target = target end return target, orig_target, escaped > 0 end function export.get_link_page(target, lang, sc, plain) local target, auto_display, escaped = export.get_link_page_with_auto_display(target, lang, sc, plain) return target, escaped end -- Make a link from a given link's parts local function make_link(link, lang, sc, id, isolated, cats, no_alt_ast, plain) -- Convert percent encoding to plaintext. link.target = link.target and decode_uri(link.target, "PATH") link.fragment = link.fragment and decode_uri(link.fragment, "PATH") -- Find fragments (if one isn't already set). -- Prevents {{l|en|word#Etymology 2|word}} from linking to [[word#Etymology 2#English]]. -- # can be escaped as \#. if link.target and link.fragment == nil then link.target, link.fragment = get_fragment(link.target) end -- Process the target local auto_display, escaped link.target, auto_display, escaped = export.get_link_page_with_auto_display(link.target, lang, sc, plain) -- Create a default display form. -- If the target is "" then it's a link like [[#English]], which refers to the current page. if auto_display == "" then auto_display = (m_headword_data or get_headword_data()).pagename end -- If the display is the target and the reconstruction * has been escaped, remove the escaping backslash. if escaped then auto_display = auto_display:gsub("\\([^\\]*%*)", "%1", 1) end -- Process the display form. if link.display then local orig_display = link.display link.display = lang:makeDisplayText(link.display, sc, true) if cats then auto_display = lang:makeDisplayText(auto_display, sc) -- If the alt text is the same as what would have been automatically generated, then the alt parameter is redundant (e.g. {{l|en|foo|foo}}, {{l|en|w:foo|foo}}, but not {{l|en|w:foo|w:foo}}). -- If they're different, but the alt text could have been entered as the term parameter without it affecting the target page, then the target parameter is redundant (e.g. {{l|ru|фу|фу́}}). -- If `no_alt_ast` is true, use pcall to catch the error which will be thrown if this is a reconstructed lang and the alt text doesn't have *. if link.display == auto_display then insert(cats, lang:getCode() .. ":Istilah dengan parameter alt lewah") else local ok, check if no_alt_ast then ok, check = pcall(export.get_link_page, orig_display, lang, sc, plain) else ok = true check = export.get_link_page(orig_display, lang, sc, plain) end if ok and link.target == check then insert(cats, lang:getCode() .. ":Istilah dengan parameter sasaran lewah") end end end else link.display = lang:makeDisplayText(auto_display, sc) end if not link.target then return link.display end -- If the target is the same as the current page, there is no sense id -- and either the language code is "und" or the current L2 is the current -- language then return a "self-link" like the software does. if link.target == get_current_title().prefixedText then local fragment, current_L2 = link.fragment, get_current_L2() if ( fragment and fragment == current_L2 or not (id or fragment) and (lang:getFullCode() == "und" or lang:getFullName() == current_L2) ) then return tostring(mw.html.create("strong") :addClass("selflink") :wikitext(link.display)) end end -- Add fragment. Do not add a section link to "Undetermined", as such sections do not exist and are invalid. -- TabbedLanguages handles links without a section by linking to the "last visited" section, but adding -- "Undetermined" would break that feature. For localized prefixes that make syntax error, please use the -- format: ["xyz"] = true. local prefix = link.target:match("^:*([^:]+):") prefix = prefix and ulower(prefix) if prefix ~= "category" and not (prefix and load_data("Module:data/interwikis")[prefix]) then if (link.fragment or link.target:sub(-1) == "#") and not plain then track("fragment", lang:getFullCode()) if cats then insert(cats, lang:getCode() .. ":Istilah dengan fragmen manual") end end if not link.fragment then if id then link.fragment = lang:getFullCode() == "und" and anchor_encode(id) or language_anchor(lang, id) elseif lang:getFullCode() ~= "und" and not (link.target:match("^Lampiran:") or link.target:match("^Wikikamus:")) then link.fragment = anchor_encode(lang:getFullName()) end end end -- Put inward-facing square brackets around a link to isolated spacing character(s). if isolated and #link.display > 0 and not umatch(decode_entities(link.display), "%S") then link.display = "&#x5D;" .. link.display .. "&#x5B;" end link.target = link.target:gsub("^(:?)(.*)", function(m1, m2) return m1 .. encode_entities(m2, "#%&+/:<=>@[\\]_{|}") end) link.fragment = link.fragment and encode_entities(remove_formatting(link.fragment), "#%&+/:<=>@[\\]_{|}") return "[[" .. link.target:gsub("^[^:]", ":%0") .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]" end -- Split a link into its parts local function parse_link(linktext) local link = { target = linktext } local target = link.target link.target, link.display = target:match("^(..-)|(.+)$") if not link.target then link.target = target link.display = target end -- There's no point in processing these, as they aren't real links. local target_lower = link.target:lower() for _, false_positive in ipairs({ "category", "cat", "file", "image" }) do if target_lower:match("^" .. false_positive .. ":") then return nil end end link.display = decode_entities(link.display) link.target, link.fragment = get_fragment(link.target) -- So that make_link does not look for a fragment again. if not link.fragment then link.fragment = false end return link end local function check_params_ignored_when_embedded(alt, lang, id, cats) if alt then track("alt-ignored") if cats then insert(cats, lang:getCode() .. ":Istilah dengan parameter alt tak diacuhkan") end end if id then track("id-ignored") if cats then insert(cats, lang:getCode() .. "Istilah dengan parameter id tak diacuhkan") end end end -- Find embedded links and ensure they link to the correct section. local function process_embedded_links(text, alt, lang, sc, id, cats, no_alt_ast, plain) -- Process the non-linked text. text = lang:makeDisplayText(text, sc, true) -- If the text begins with * and another character, then act as if each link begins with *. However, don't do this if the * is contained within a link at the start. E.g. `|*[[foo]]` would set all_reconstructed to true, while `|[[*foo]]` would not. local all_reconstructed = false if not plain then -- anchor_encode removes links etc. if anchor_encode(text):sub(1, 1) == "*" then all_reconstructed = true end -- Otherwise, handle any escapes. text = text:gsub("^(\\-)\\%*", "%1*") end check_params_ignored_when_embedded(alt, lang, id, cats) local function process_link(space1, linktext, space2) local capture = "[[" .. linktext .. "]]" local link = parse_link(linktext) -- Return unprocessed false positives untouched (e.g. categories). if not link then return capture end if all_reconstructed then if link.target:find("^!!") then -- Check for anti-asterisk !! at the beginning of a target, indicating that a reconstructed term -- wants a part of the term to link to a non-reconstructed term, e.g. Old English -- {{ang-noun|m|head=*[[!!Crist|Cristes]] [[!!mæsseǣfen]]}}. link.target = link.target:sub(3) -- Also remove !! from the display, which may have been copied from the target (as in mæsseǣfen in -- the example above). link.display = link.display:gsub("^!!", "") elseif not link.target:match("^%*") then link.target = "*" .. link.target end end linktext = make_link(link, lang, sc, id, false, nil, no_alt_ast, plain) :gsub("^%[%[", "\3") :gsub("%]%]$", "\4") return space1 .. linktext .. space2 end -- Use chars 1 and 2 as temporary substitutions, so that we can use charsets. These are converted to chars 3 and 4 by process_link, which means we can convert any remaining chars 1 and 2 back to square brackets (i.e. those not part of a link). text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- If the script uses ^ to capitalize transliterations, make sure that any carets preceding links are on the inside, so that they get processed with the following text. if ( text:find("^", nil, true) and not sc:hasCapitalization() and sc:isTransliterated() ) then text = escape(text, "^") :gsub("%^\1", "\1%^") text = unescape(text, "^") end text = text:gsub("\1(%s*)([^\1\2]-)(%s*)\2", process_link) -- Remove the extra * at the beginning of a language link if it's immediately followed by a link whose display begins with * too. if all_reconstructed then text = text:gsub("^%*\3([^|\1-\4]+)|%*", "\3%1|*") end return (text :gsub("[\1\3]", "[[") :gsub("[\2\4]", "]]") ) end local function simple_link(term, fragment, alt, lang, sc, id, cats, no_alt_ast, srwc) local plain if lang == nil then lang, plain = get_lang("und"), true end -- Get the link target and display text. If the term is the empty string, treat the input as a link to the current page. if term == "" then term = get_current_title().prefixedText elseif term then local new_term, new_alt = export.get_wikilink_parts(term, true) if new_term then check_params_ignored_when_embedded(alt, lang, id, cats) -- [[|foo]] links are treated as plaintext "[[|foo]]". -- FIXME: Pipes should be handled via a proper escape sequence, as they can occur in unsupported titles. if new_term == "" then term, alt = nil, term else local title = new_title(new_term) if title then local ns = title.namespace -- File: and Category: links should be returned as-is. if ns == 6 or ns == 14 then return term end end term, alt = new_term, new_alt if cats then if not (srwc and srwc(term, alt)) then insert(cats, lang:getCode() .. ":Istilah dengan pranala wiki lewah") end end end end end if alt then alt = selective_trim(alt) if alt == "" then alt = nil end end -- If there's nothing to process, return nil. if not (term or alt) then return nil end -- If there is no script, get one. if not sc then sc = lang:findBestScript(alt or term) end -- Embedded wikilinks need to be processed individually. if term then local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, alt, lang, sc, id, cats, no_alt_ast, plain) end term = selective_trim(term) end -- If not, make a link using the parameters. return make_link({ target = term, display = alt, fragment = fragment }, lang, sc, id, true, cats, no_alt_ast, plain) end --[==[Creates a basic link to the given term. It links to the language section (such as <code>==English==</code>), but it does not add language and script wrappers, so any code that uses this function should call the <code class="n">[[Module:script utilities#tag_text|tag_text]]</code> from [[Module:script utilities]] to add such wrappers itself at some point. The first argument, <code class="n">data</code>, may contain the following items, a subset of the items used in the <code class="n">data</code> argument of <code class="n">full_link</code>. If any other items are included, they are ignored. { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, id = sense_id, } } ; <code class="n">term</code> : Text to turn into a link. This is generally the name of a page. The text can contain wikilinks already embedded in it. These are processed individually just like a single link would be. The <code class="n">alt</code> argument is ignored in this case. ; <code class="n">alt</code> (''optional'') : The alternative display for the link, if different from the linked page. If this is {{code|lua|nil}}, the <code class="n">text</code> argument is used instead (much like regular wikilinks). If <code class="n">text</code> contains wikilinks in it, this argument is ignored and has no effect. (Links in which the alt is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/alt-ignored}}.) ; <code class="n">lang</code> : The [[Module:languages#Language objects|language object]] for the term being linked. If this argument is defined, the function will determine the language's canonical name (see [[Template:language data documentation]]), and point the link or links in the <code class="n">term</code> to the language's section of an entry, or to a language-specific senseid if the <code class="n">id</code> argument is defined. ; <code class="n">id</code> (''optional'') : Sense id string. If this argument is defined, the link will point to a language-specific sense id ({{ll|en|identifier|id=HTML}}) created by the template {{temp|senseid}}. A sense id consists of the language's canonical name, a hyphen (<code>-</code>), and the string that was supplied as the <code class="n">id</code> argument. This is useful when a term has more than one sense in a language. If the <code class="n">term</code> argument contains wikilinks, this argument is ignored. (Links in which the sense id is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/id-ignored}}.) The second argument is as follows: ; <code class="n">allow_self_link</code> : If {{code|lua|true}}, the function will also generate links to the current page. The default ({{code|lua|false}}) will not generate a link but generate a bolded "self link" instead. The following special options are processed for each link (both simple text and with embedded wikilinks): * The target page name will be processed to generate the correct entry name. This is done by the [[Module:languages#makeEntryName|makeEntryName]] function in [[Module:languages]], using the <code class="n">entry_name</code> replacements in the language's data file (see [[Template:language data documentation]] for more information). This function is generally used to automatically strip dictionary-only diacritics that are not part of the normal written form of a language. * If the text starts with <code class="n">*</code>, then the term is considered a reconstructed term, and a link to the Reconstruction: namespace will be created. If the text contains embedded wikilinks, then <code class="n">*</code> is automatically applied to each one individually, while preserving the displayed form of each link as it was given. This allows linking to phrases containing multiple reconstructed terms, while only showing the * once at the beginning. * If the text starts with <code class="n">:</code>, then the link is treated as "raw" and the above steps are skipped. This can be used in rare cases where the page name begins with <code class="n">*</code> or if diacritics should not be stripped. For example: ** {{temp|l|en|*nix}} links to the nonexistent page [[Reconstruction:English/nix]] (<code class="n">*</code> is interpreted as a reconstruction), but {{temp|l|en|:*nix}} links to [[*nix]]. ** {{temp|l|sl|Franche-Comté}} links to the nonexistent page [[Franche-Comte]] (<code>é</code> is converted to <code>e</code> by <code class="n">makeEntryName</code>), but {{temp|l|sl|:Franche-Comté}} links to [[Franche-Comté]].]==] function export.language_link(data) if type(data) ~= "table" then error( "The first argument to the function language_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "language_link") end -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Pranala bahasa tak ditentukan") end return simple_link( data.term, data.fragment, data.alt, lang, data.sc, data.id, cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end function export.plain_link(data) if type(data) ~= "table" then error( "The first argument to the function plain_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "plain_link") end return simple_link( data.term, data.fragment, data.alt, nil, data.sc, data.id, data.cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end --[==[Replace any links with links to the correct section, but don't link the whole text if no embedded links are found. Returns the display text form.]==] function export.embedded_language_links(data) if type(data) ~= "table" then error( "The first argument to the function embedded_language_links must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "embedded_language_links") end local term, lang, sc = data.term, data.lang, data.sc -- If we don't have a script, get one. if not sc then sc = lang:findBestScript(term) end -- Do we have embedded wikilinks? If so, they need to be processed individually. local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, data.alt, lang, sc, data.id, data.cats, data.no_alt_ast) end -- If not, return the display text. term = selective_trim(term) -- FIXME: Double-escape any percent-signs, because we don't want to treat non-linked text as having percent-encoded characters. This is a hack: percent-decoding should come out of [[Module:languages]] and only dealt with in this module, as it's specific to links. term = term:gsub("%%", "%%25") return lang:makeDisplayText(term, sc, true) end function export.mark(text, item_type, face, lang) local tag = { "", "" } if item_type == "gloss" then tag = { '<span class="mention-gloss-double-quote">“</span><span class="mention-gloss">', '</span><span class="mention-gloss-double-quote">”</span>' } if type(text) == "string" and text:match("^''[^'].*''$") then -- Temporary tracking for mention glosses that are entirely italicized or bolded, which is probably -- wrong. (Note that this will also find bolded mention glosses since they use triple apostrophes.) track("italicized-mention-gloss", lang and lang:getFullCode() or nil) end elseif item_type == "tr" then if face == "term" then tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr mention-tr Latn">', '</span>' } else tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr Latn">', '</span>' } end elseif item_type == "ts" then -- \226\129\160 = word joiner (zero-width non-breaking space) U+2060 tag = { '<span class="ts mention-ts Latn">/\226\129\160', '\226\129\160/</span>' } elseif item_type == "pos" then tag = { '<span class="ann-pos">', '</span>' } elseif item_type == "non-gloss" then tag = { '<span class="ann-non-gloss">', '</span>' } elseif item_type == "annotations" then tag = { '<span class="mention-gloss-paren annotation-paren">(</span>', '<span class="mention-gloss-paren annotation-paren">)</span>' } elseif item_type == "infl" then tag = { '<span class="ann-infl">', '</span>' } end if type(text) == "string" then return tag[1] .. text .. tag[2] else return "" end end local pos_tags --[==[Formats the annotations that are displayed with a link created by {{code|lua|full_link}}. Annotations are the extra bits of information that are displayed following the linked term, and include things such as gender, transliteration, gloss and so on. * The first argument is a table possessing some or all of the following keys: *:; <code class="n">genders</code> *:: Table containing a list of gender specifications in the style of [[Module:gender and number]]. *:; <code class="n">tr</code> *:: Transliteration. *:; <code class="n">gloss</code> *:: Gloss that translates the term in the link, or gives some other descriptive information. *:; <code class="n">pos</code> *:: Part of speech of the linked term. If the given argument matches one of the aliases in `pos_aliases` in [[Module:headword/data]], or consists of a part of speech or alias followed by `f` (for a non-lemma form), expand it appropriately. Otherwise, just show the given text as it is. *:; <code class="n">ng</code> *:: Arbitrary non-gloss descriptive text for the link. This should be used in preference to putting descriptive text in `gloss` or `pos`. *:; <code class="n">lit</code> *:: Literal meaning of the term, if the usual meaning is figurative or idiomatic. *:; <code class="n">infl</code> *:: Table containing a list of grammar tags in the style of [[Module:form of]] `tagged_inflections`. *:Any of the above values can be omitted from the <code class="n">info</code> argument. If a completely empty table is given (with no annotations at all), then an empty string is returned. * The second argument is a string. Valid values are listed in [[Module:script utilities/data]] "data.translit" table.]==] function export.format_link_annotations(data, face) local output = {} -- Interwiki link if data.interwiki then insert(output, data.interwiki) end -- Genders if type(data.genders) ~= "table" then data.genders = { data.genders } end if data.genders and #data.genders > 0 then local genders, gender_cats = format_genders(data.genders, data.lang) insert(output, "&nbsp;" .. genders) if gender_cats then local cats = data.cats if cats then extend(cats, gender_cats) end end end local annotations = {} -- Transliteration and transcription if data.tr and data.tr[1] or data.ts and data.ts[1] then local kind if face == "term" then kind = face else kind = "default" end if data.tr[1] and data.ts[1] then insert(annotations, tag_translit(data.tr[1], data.lang, kind) .. " " .. export.mark(data.ts[1], "ts")) elseif data.ts[1] then insert(annotations, export.mark(data.ts[1], "ts")) else insert(annotations, tag_translit(data.tr[1], data.lang, kind)) end end -- Gloss/translation if data.gloss then insert(annotations, export.mark(data.gloss, "gloss")) end -- Part of speech if data.pos then -- debug category for pos= containing transcriptions if data.pos:match("/[^><]-/") then data.pos = data.pos .. "[[Kategori:Pranala mengandung transkripsi pada kelas kata]]" end -- Canonicalize part of speech aliases as well as non-lemma aliases like 'nf' or 'nounf' for "noun form". pos_tags = pos_tags or (m_headword_data or get_headword_data()).pos_aliases local pos = pos_tags[data.pos] if not pos and data.pos:find("f$") then local pos_form = data.pos:sub(1, -2) -- We only expand something ending in 'f' if the result is a recognized non-lemma POS. pos_form = (pos_tags[pos_form] or pos_form) .. " form" if (m_headword_data or get_headword_data()).nonlemmas[pos_form .. "s"] then pos = pos_form end end insert(annotations, export.mark(pos or data.pos, "pos")) end -- Inflection data if data.infl then local m_form_of = require(form_of_module) -- Split tag sets manually, since tagged_inflections creates a numbered list, and we do not want that. local infl_outputs = {} local tag_sets = m_form_of.split_tag_set(data.infl) for _, tag_set in ipairs(tag_sets) do table.insert(infl_outputs, m_form_of.tagged_inflections({ tags = tag_set, lang = data.lang, nocat = true, nolink = true, nowrap = true })) end insert(annotations, export.mark(table.concat(infl_outputs, "; "), "infl")) end -- Non-gloss text if data.ng then insert(annotations, export.mark(data.ng, "non-gloss")) end -- Literal/sum-of-parts meaning if data.lit then insert(annotations, "literally " .. export.mark(data.lit, "gloss")) end -- Provide a hook to insert additional annotations such as nested inflections. if data.postprocess_annotations then data.postprocess_annotations { data = data, annotations = annotations } end if #annotations > 0 then insert(output, " " .. export.mark(concat(annotations, ", "), "annotations")) end return concat(output) end -- Encode certain characters to avoid various delimiter-related issues at various stages. We need to encode < and > -- because they end up forming part of CSS class names inside of <span ...> and will interfere with finding the end -- of the HTML tag. I first tried converting them to URL encoding, i.e. %3C and %3E; they then appear in the URL as -- %253C and %253E, which get mapped back to %3C and %3E when passed to [[Module:accel]]. But mapping them to &lt; -- and &gt; somehow works magically without any further work; they appear in the URL as < and >, and get passed to -- [[Module:accel]] as < and >. I have no idea who along the chain of calls is doing the encoding and decoding. If -- someone knows, please modify this comment appropriately! local accel_char_map local function get_accel_char_map() accel_char_map = { ["%"] = ".", [" "] = "_", ["_"] = u(0xFFF0), ["<"] = "&lt;", [">"] = "&gt;", } return accel_char_map end local function encode_accel_param_chars(param) return (param:gsub("[% <>_]", accel_char_map or get_accel_char_map())) end local function encode_accel_param(prefix, param) if not param then return "" end if type(param) == "table" then local filled_params = {} -- There may be gaps in the sequence, especially for translit params. local maxindex = 0 for k in pairs(param) do if type(k) == "number" and k > maxindex then maxindex = k end end for i = 1, maxindex do filled_params[i] = param[i] or "" end -- [[Module:accel]] splits these up again. param = concat(filled_params, "*~!") end -- This is decoded again by [[WT:ACCEL]]. return prefix .. encode_accel_param_chars(param) end local function insert_if_not_blank(list, item) if item == "" then return end insert(list, item) end local function get_class(lang, tr, accel, nowrap) if not accel and not nowrap then return "" end local classes = {} if accel then insert(classes, "form-of lang-" .. lang:getFullCode()) local form = accel.form if form then insert(classes, encode_accel_param_chars(form) .. "-form-of") end insert_if_not_blank(classes, encode_accel_param("gender-", accel.gender)) insert_if_not_blank(classes, encode_accel_param("pos-", accel.pos)) insert_if_not_blank(classes, encode_accel_param("transliteration-", accel.translit or (tr ~= "-" and tr or nil))) insert_if_not_blank(classes, encode_accel_param("target-", accel.target)) insert_if_not_blank(classes, encode_accel_param("origin-", accel.lemma)) insert_if_not_blank(classes, encode_accel_param("origin_transliteration-", accel.lemma_translit)) if accel.no_store then insert(classes, "form-of-nostore") end end if nowrap then insert(classes, nowrap) end return concat(classes, " ") end -- Add any left or right regular or accent qualifiers, labels or references to a formatted term. `data` is the object -- specifying the term, which should optionally contain: -- * a language object in `lang`; required if any accent qualifiers or labels are given; -- * left regular qualifiers in `q` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * right regular qualifiers in `qq` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * left accent qualifiers in `a` (an array of strings); an empty array will be ignored; -- * right accent qualifiers in `aa` (an array of strings); an empty array will be ignored; -- * left labels in `l` (an array of strings); an empty array will be ignored; -- * right labels in `ll` (an array of strings); an empty array will be ignored; -- * references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text` -- (formatted reference text) and optionally `name` and/or `group`. -- `formatted` is the formatted version of the term itself. local function add_qualifiers_and_refs_to_term(data, formatted) local q = data.q if type(q) == "string" then q = { q } end local qq = data.qq if type(qq) == "string" then qq = { qq } end if q and q[1] or qq and qq[1] or data.a and data.a[1] or data.aa and data.aa[1] or data.l and data.l[1] or data.ll and data.ll[1] or data.refs and data.refs[1] then formatted = format_qualifiers { lang = data.lang, text = formatted, q = q, qq = qq, a = data.a, aa = data.aa, l = data.l, ll = data.ll, refs = data.refs, } end return formatted end --[==[ Creates a full link, with annotations (see `[[#format_link_annotations|format_link_annotations]]`), in the style of {{tl|l}} or {{tl|m}}. The first argument, `data`, must be a table. It contains the various elements that can be supplied as parameters to {{tl|l}} or {{tl|m}}: { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, sc = script_object, track_sc = boolean, no_nonstandard_sc_cat = boolean, fragment = link_fragment, id = sense_id, genders = { "gender1", "gender2", ... }, tr = transliteration, respect_link_tr = boolean, ts = transcription, gloss = gloss, pos = part_of_speech_tag, ng = non-gloss text, lit = literal_translation, infl = { "form_of_grammar_tag1", "form_of_grammar_tag2", ... }, no_alt_ast = boolean, accel = {accelerated_creation_tags}, interwiki = interwiki, pretext = "text_at_beginning" or nil, posttext = "text_at_end" or nil, q = { "left_qualifier1", "left_qualifier2", ...} or "left_qualifier", qq = { "right_qualifier1", "right_qualifier2", ...} or "right_qualifier", l = { "left_label1", "left_label2", ...}, ll = { "right_label1", "right_label2", ...}, a = { "left_accent_qualifier1", "left_accent_qualifier2", ...}, aa = { "right_accent_qualifier1", "right_accent_qualifier2", ...}, refs = { "formatted_ref1", "formatted_ref2", ...} or { {text = "text", name = "name", group = "group"}, ... }, show_qualifiers = boolean, } } Any one of the items in the `data` table may be {nil}, but an error will be shown if neither `term` nor `alt` nor `tr` is present. Thus, calling {full_link{ term = term, lang = lang, sc = sc }}, where `term` is the page to link to (which may have diacritics that will be stripped and/or embedded bracketed links) and `lang` is a [[Module:languages#Language objects|language object]] from [[Module:languages]], will give a plain link similar to the one produced by the template {{tl|l}}, and calling {full_link( { term = term, lang = lang, sc = sc }, "term" )} will give a link similar to the one produced by the template {{tl|m}}. The function will: * Try to determine the script, based on the characters found in the `term` or `alt` argument, if the script was not given. If a script is given and `track_sc` is {true}, it will check whether the input script is the same as the one which would have been automatically generated and add the category [[:Category:LANG terms with redundant script codes]] if yes, or [[:Category:LANG terms with non-redundant manual script codes]] if no. This should be used when the input script object is directly determined by a template's `sc` parameter. * Call `[[#language_link|language_link]]` on the `term` or `alt` forms, to remove diacritics in the page name, process any embedded wikilinks and create links to Reconstruction or Appendix pages when necessary. * Call `[[Module:script utilities#tag_text]]` to add the appropriate language and script tags to the term and italicize terms written in the Latin script if necessary. Accelerated creation tags, as used by [[WT:ACCEL]], are included. * Generate a transliteration, based on the `alt` or `term` arguments, if the script is not Latin, no transliteration was provided in `tr` and the combination of the term's language and script support automatic transliteration. The transliteration itself will be linked if both `.respect_link_tr` is specified and the language of the term has the `link_tr` property set for the script of the term; but not otherwise. * Add the annotations (transliteration, gender, gloss, etc.) after the link. * If `no_alt_ast` is specified, then the `alt` text does not need to contain an asterisk if the language is reconstructed. This should only be used by modules which really need to allow links to reconstructions that don't display asterisks (e.g. number boxes). * If `pretext` or `posttext` is specified, this is text to (respectively) prepend or append to the output, directly before processing qualifiers, labels and references. This can be used to add arbitrary extra text inside of the qualifiers, labels and references. * If `show_qualifiers` is specified or the `show_qualifiers` argument is given, then left and right qualifiers, accent qualifiers, labels and references will be displayed, otherwise they will be ignored. (This is because a fair amount of code stores qualifiers, labels and/or references in these fields and displays them itself, rather than expecting {full_link()} to display them.)]==] function export.full_link(data, face, allow_self_link, show_qualifiers) if type(data) ~= "table" then error("The first argument to the function full_link must be a table. " .. "See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "full_link") end -- Prevent data from being destructively modified. local data = shallow_copy(data) -- FIXME: this shouldn't be added to `data`, as that means the input table needs to be cloned. data.cats = {} -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Undetermined language links") end local terms = { true } -- Generate multiple forms if applicable. for _, param in ipairs { "term", "alt" } do if type(data[param]) == "string" and data[param]:find("//", nil, true) then data[param] = export.split_on_slashes(data[param]) elseif type(data[param]) == "string" and not (type(data.term) == "string" and data.term:find("//", nil, true)) then if not data.no_generate_forms then data[param] = lang:generateForms(data[param]) else data[param] = { data[param] } end else data[param] = {} end end for _, param in ipairs { "sc", "tr", "ts" } do data[param] = { data[param] } end for _, param in ipairs { "term", "alt", "sc", "tr", "ts" } do for i in pairs(data[param]) do terms[i] = true end end -- Create the link local output = {} local id, no_alt_ast, srwc, accel, nevercalltr = data.id, data.no_alt_ast, data.suppress_redundant_wikilink_cat, data.accel, data.never_call_transliteration_module local link_tr = data.respect_link_tr and lang:link_tr(data.sc[1]) for i in ipairs(terms) do local link -- Is there any text to show? if (data.term[i] or data.alt[i]) then -- Try to detect the script if it was not provided local display_term = data.alt[i] or data.term[i] local best = lang:findBestScript(display_term) -- no_nonstandard_sc_cat is intended for use in [[Module:interproject]] if ( not data.no_nonstandard_sc_cat and best:getCode() == "None" and find_best_script_without_lang(display_term):getCode() ~= "None" ) then insert(cats, lang:getCode() .. ":Istilah dengan aksara tak lazim") end if not data.sc[i] then data.sc[i] = best -- Track uses of sc parameter. elseif data.track_sc then if data.sc[i]:getCode() == best:getCode() then insert(cats, lang:getCode() .. ":Istilah dengan kode aksara lewah") else insert(cats, lang:getCode() .. ":Istilah dengan kode aksara manual tak lewah") end end -- If using a discouraged character sequence, add to maintenance category if data.sc[i]:hasNormalizationFixes() == true then if (data.term[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.term[i])) ~= toNFC(data.term[i])) or (data.alt[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.alt[i])) ~= toNFC(data.alt[i])) then insert(cats, "Pages using discouraged character sequences") end end link = simple_link( data.term[i], data.fragment, data.alt[i], lang, data.sc[i], id, cats, no_alt_ast, srwc ) end -- simple_link can return nil, so check if a link has been generated. if link then -- Add "nowrap" class to prefixes in order to prevent wrapping after the hyphen local nowrap local display_term = data.alt[i] or data.term[i] if display_term and (display_term:find("^%-") or display_term:find("^־")) then -- Hebrew maqqef -- FIXME, use hyphens from [[Module:affix]] nowrap = "nowrap" end link = tag_text(link, lang, data.sc[i], face, get_class(lang, data.tr[i], accel, nowrap)) else --[[ No term to show. Is there at least a transliteration we can work from? ]] link = request_script(lang, data.sc[i]) -- No link to show, and no transliteration either. Show a term request (unless it's a substrate, as they rarely take terms). if (link == "" or (not data.tr[i]) or data.tr[i] == "-") and lang:getFamilyCode() ~= "qfa-sub" then -- If there are multiple terms, break the loop instead. if i > 1 then remove(output) break elseif NAMESPACE ~= "Templat" then insert(cats, lang:getCode() .. ":Permintaan istilah") end link = "<small>[Term?]</small>" end end insert(output, link) if i < #terms then insert(output, "<span class=\"Zsym mention\" style=\"font-size:100%;\">&nbsp;/ </span>") end end -- When suppress_tr is true, do not show or generate any transliteration if data.suppress_tr then data.tr[1] = nil else -- TODO: Currently only handles the first transliteration, pending consensus on how to handle multiple translits for multiple forms, as this is not always desirable (e.g. traditional/simplified Chinese). if data.tr[1] == "" or data.tr[1] == "-" then data.tr[1] = nil else local phonetic_extraction = load_data("Module:links/data").phonetic_extraction phonetic_extraction = phonetic_extraction[lang:getCode()] or phonetic_extraction[lang:getFullCode()] if phonetic_extraction then data.tr[1] = data.tr[1] or require(phonetic_extraction).getTranslit(export.remove_links(data.alt[1] or data.term[1])) elseif (data.term[1] or data.alt[1]) and data.sc[1]:isTransliterated() then -- Track whenever there is manual translit. The categories below like 'terms with redundant transliterations' -- aren't sufficient because they only work with reference to automatic translit and won't operate at all in -- languages without any automatic translit, like Persian and Hebrew. if data.tr[1] then local full_code = lang:getFullCode() track("manual-tr", full_code) end if not nevercalltr then -- Try to generate a transliteration. local text = data.alt[1] or data.term[1] if not link_tr then text = export.remove_links(text, true) end local automated_tr = lang:transliterate(text, data.sc[1]) if automated_tr then local manual_tr = data.tr[1] if manual_tr then if export.remove_links(manual_tr) == export.remove_links(automated_tr) then insert(cats, lang:getCode() .. ":Istilah dengan alih aksara lewah") else -- Prevents Arabic root categories from flooding the tracking categories. if NAMESPACE ~= "Kategori" then insert(cats, lang:getCode() .. ":Istilah dengan alih aksara manual tak lewah") end end end if not manual_tr or lang:overrideManualTranslit(data.sc[1]) then data.tr[1] = automated_tr end end end end end end -- Link to the transliteration entry for languages that require this if data.tr[1] and link_tr and not data.tr[1]:match("%[%[(.-)%]%]") then data.tr[1] = simple_link( data.tr[1], nil, nil, lang, get_script("Latn"), nil, cats, no_alt_ast, srwc ) elseif data.tr[1] and not link_tr then -- Remove the pseudo-HTML tags added by remove_links. data.tr[1] = data.tr[1]:gsub("</?link>", "") end if data.tr[1] and not umatch(data.tr[1], "[^%s%p]") then data.tr[1] = nil end insert(output, export.format_link_annotations(data, face)) if data.pretext then insert(output, 1, data.pretext) end if data.posttext then insert(output, data.posttext) end local categories = cats[1] and format_categories(cats, lang, "-", nil, nil, data.sc) or "" output = concat(output) if show_qualifiers or data.show_qualifiers then output = add_qualifiers_and_refs_to_term(data, output) end return output .. categories end --[==[Replaces all wikilinks with their displayed text, and removes any categories. This function can be invoked either from a template or from another module. -- Strips links: deletes category links, the targets of piped links, and any double square brackets involved in links (other than file links, which are untouched). If `tag` is set, then any links removed will be given pseudo-HTML tags, which allow the substitution functions in [[Module:languages]] to properly subdivide the text in order to reduce the chance of substitution failures in modules which scrape pages like [[Module:zh-translit]]. -- FIXME: This is quite hacky. We probably want this to be integrated into [[Module:languages]], but we can't do that until we know that nothing is pushing pipe linked transliterations through it for languages which don't have link_tr set. * <code><nowiki>[[page|displayed text]]</nowiki></code> &rarr; <code><nowiki>displayed text</nowiki></code> * <code><nowiki>[[page and displayed text]]</nowiki></code> &rarr; <code><nowiki>page and displayed text</nowiki></code> * <code><nowiki>[[Kategori:id:Lema|WORD]]</nowiki></code> &rarr; ''(nothing)'']==] function export.remove_links(text, tag) if type(text) == "table" then text = text.args[1] end if not text or text == "" then return "" end text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Parse internal links for the display text. text = text:gsub("(\1)([^\1\2]-)(\2)", function(c1, c2, c3) -- Don't remove files. for _, false_positive in ipairs({ "file", "image" }) do if c2:lower():match("^" .. false_positive .. ":") then return c1 .. c2 .. c3 end end -- Remove categories completely. for _, false_positive in ipairs({ "category", "cat" }) do if c2:lower():match("^" .. false_positive .. ":") then return "" end end -- In piped links, remove all text before the pipe, unless it's the final character (i.e. the pipe trick), in which case just remove the pipe. c2 = c2:match("^[^|]*|(.+)") or c2:match("([^|]+)|$") or c2 if tag then return "<link>" .. c2 .. "</link>" else return c2 end end) text = text :gsub("\1", "[[") :gsub("\2", "]]") return text end function export.section_link(link) if type(link) ~= "string" then error("The first argument to section_link was a " .. type(link) .. ", but it should be a string.") elseif link:find("\\", nil, true) then track("escaped", "section_link") end local target, section = get_fragment((link:gsub("_", " "))) if not section then error("No \"#\" delineating a section name") end return simple_link( target, section, target .. " §&nbsp;" .. section ) end return export eoxg2nqf378ifvy2vd9s9wh15y2r7b7 Modul:links/data 828 3687 26543 8018 2025-12-26T23:07:49Z id>Swarabakti 0 mutakhirkan dari enwikt; walaupun idwikt belum memiliki halaman yang terlalu panjang untuk saat ini 26543 Scribunto text/plain local data = {} local unpack = unpack or table.unpack -- Lua 5.2 compatibility local u = require("Module:string utilities").char data.phonetic_extraction = { ["th"] = "Module:th", ["km"] = "Module:km", } data.ignored_prefixes = { ["cat"] = true, ["category"] = true, ["file"] = true, ["image"] = true } -- Scheme for using unsupported characters in titles. data.unsupported_characters = { ["#"] = "`num`", ["%"] = "`percnt`", -- only escaped in percent encoding ["&"] = "`amp`", -- only escaped in HTML entities ["."] = "`period`", -- only escaped in dot-slash notation ["<"] = "`lt`", [">"] = "`gt`", ["["] = "`lsqb`", ["]"] = "`rsqb`", ["_"] = "`lowbar`", ["`"] = "`grave`", -- used to enclose unsupported characters in the scheme, so a raw use in an unsupported title must be escaped to prevent interference ["{"] = "`lcub`", ["|"] = "`vert`", ["}"] = "`rcub`", ["~"] = "`tilde`", -- only escaped when 3 or more are consecutive ["\239\191\189"] = "`repl`" -- replacement character U+FFFD, which can't be typed directly here due to an abuse filter } -- Manually specified unsupported titles. Only put titles here if there is a different reason why they are unsupported, and not just because they contain one of the unsupported characters above. data.unsupported_titles = { [" "] = "Space", ["&amp;"] = "`amp`amp;", ["λοπαδοτεμαχοσελαχογαλεοκρανιολειψανοδριμυποτριμματοσιλφιοκαραβομελιτοκατακεχυμενοκιχλεπικοσσυφοφαττοπεριστεραλεκτρυονοπτοκεφαλλιοκιγκλοπελειολαγῳοσιραιοβαφητραγανοπτερύγων"] = "Ancient Greek dish", ["กรุงเทพมหานคร อมรรัตนโกสินทร์ มหินทรายุธยา มหาดิลกภพ นพรัตนราชธานีบูรีรมย์ อุดมราชนิเวศน์มหาสถาน อมรพิมานอวตารสถิต สักกะทัตติยวิษณุกรรมประสิทธิ์"] = "Thai name of Bangkok", [u(0x1680)] = "Ogham space", [u(0x3000)] = "Ideographic space" } -- Mammoth pages contain only Translingual and English entries, if present. The remaining L2s are placed on subpages. -- The same subpage titles are used across all mammoth pages for the convenience of bot and script operators. -- Assuming that most mammoth pages will be Latin-script terms, the subpage groupings are determined by dividing the -- list of Latin-script languages known to Wiktionary into two (three, ...) roughly equal alphabetic divisions. This is -- easily done by looking at Petscan's output: -- https://petscan.wmcloud.org/?sortby=title&language=en&ns%5B14%5D=1&categories=Latin+script+languages&project=wiktionary&doit= -- This data structure contains types of splits, each of which is a list of names of splits and Lua patterns applied to -- the decomposed L2 name (with apostrophes and double quotes removed and certain other transformations applied; see -- get_L2_sort_key() in [[Module:headword/page]]), or "true" for the final catch-all subpage (which includes anything -- not beginning with a Latin letter after the transformations are applied; this includes e.g. ǃKung but not 'Are'are, -- which sorts with A, and not Àhàn, which likewise sorts with A). The patterns must be suitable for use with plain -- string functions, not their mw.ustring equivalents. data.mammoth_page_subpage_types = { twos = { {"languages A to L", "^[A-L]"}, {"languages M to Z", true}, }, threes = { {"languages A to I", "^[A-I]"}, {"languages J to Q", "^[J-Q]"}, {"languages R to Z", true}, }, CJK = { {"languages A to C", "^[A-C]"}, -- Translingual and Chinese on one page {"languages D to Z", true}, -- all the remainder (mostly Japanese, Korean, Vietnamese) on the other }, } -- "Mammoth pages" are pages whose entries cannot be housed on a single page because of MediaWiki limits. The key is -- the page and the value is the subpage type, as defined above in `mammoth_page_subpage_types`. data.mammoth_pages = { ["a"] = "twos", -- FIXME: change to threes ["mammoth page test"] = "twos", -- required for testing purposes - please leave here } return data q02q3zllkyysivftvjq4h2gli665cgv 26544 26543 2026-07-07T21:53:35Z Sibiru45 115 1 ralatan matan [[:id:Modul:links/data]] 26543 Scribunto text/plain local data = {} local unpack = unpack or table.unpack -- Lua 5.2 compatibility local u = require("Module:string utilities").char data.phonetic_extraction = { ["th"] = "Module:th", ["km"] = "Module:km", } data.ignored_prefixes = { ["cat"] = true, ["category"] = true, ["file"] = true, ["image"] = true } -- Scheme for using unsupported characters in titles. data.unsupported_characters = { ["#"] = "`num`", ["%"] = "`percnt`", -- only escaped in percent encoding ["&"] = "`amp`", -- only escaped in HTML entities ["."] = "`period`", -- only escaped in dot-slash notation ["<"] = "`lt`", [">"] = "`gt`", ["["] = "`lsqb`", ["]"] = "`rsqb`", ["_"] = "`lowbar`", ["`"] = "`grave`", -- used to enclose unsupported characters in the scheme, so a raw use in an unsupported title must be escaped to prevent interference ["{"] = "`lcub`", ["|"] = "`vert`", ["}"] = "`rcub`", ["~"] = "`tilde`", -- only escaped when 3 or more are consecutive ["\239\191\189"] = "`repl`" -- replacement character U+FFFD, which can't be typed directly here due to an abuse filter } -- Manually specified unsupported titles. Only put titles here if there is a different reason why they are unsupported, and not just because they contain one of the unsupported characters above. data.unsupported_titles = { [" "] = "Space", ["&amp;"] = "`amp`amp;", ["λοπαδοτεμαχοσελαχογαλεοκρανιολειψανοδριμυποτριμματοσιλφιοκαραβομελιτοκατακεχυμενοκιχλεπικοσσυφοφαττοπεριστεραλεκτρυονοπτοκεφαλλιοκιγκλοπελειολαγῳοσιραιοβαφητραγανοπτερύγων"] = "Ancient Greek dish", ["กรุงเทพมหานคร อมรรัตนโกสินทร์ มหินทรายุธยา มหาดิลกภพ นพรัตนราชธานีบูรีรมย์ อุดมราชนิเวศน์มหาสถาน อมรพิมานอวตารสถิต สักกะทัตติยวิษณุกรรมประสิทธิ์"] = "Thai name of Bangkok", [u(0x1680)] = "Ogham space", [u(0x3000)] = "Ideographic space" } -- Mammoth pages contain only Translingual and English entries, if present. The remaining L2s are placed on subpages. -- The same subpage titles are used across all mammoth pages for the convenience of bot and script operators. -- Assuming that most mammoth pages will be Latin-script terms, the subpage groupings are determined by dividing the -- list of Latin-script languages known to Wiktionary into two (three, ...) roughly equal alphabetic divisions. This is -- easily done by looking at Petscan's output: -- https://petscan.wmcloud.org/?sortby=title&language=en&ns%5B14%5D=1&categories=Latin+script+languages&project=wiktionary&doit= -- This data structure contains types of splits, each of which is a list of names of splits and Lua patterns applied to -- the decomposed L2 name (with apostrophes and double quotes removed and certain other transformations applied; see -- get_L2_sort_key() in [[Module:headword/page]]), or "true" for the final catch-all subpage (which includes anything -- not beginning with a Latin letter after the transformations are applied; this includes e.g. ǃKung but not 'Are'are, -- which sorts with A, and not Àhàn, which likewise sorts with A). The patterns must be suitable for use with plain -- string functions, not their mw.ustring equivalents. data.mammoth_page_subpage_types = { twos = { {"languages A to L", "^[A-L]"}, {"languages M to Z", true}, }, threes = { {"languages A to I", "^[A-I]"}, {"languages J to Q", "^[J-Q]"}, {"languages R to Z", true}, }, CJK = { {"languages A to C", "^[A-C]"}, -- Translingual and Chinese on one page {"languages D to Z", true}, -- all the remainder (mostly Japanese, Korean, Vietnamese) on the other }, } -- "Mammoth pages" are pages whose entries cannot be housed on a single page because of MediaWiki limits. The key is -- the page and the value is the subpage type, as defined above in `mammoth_page_subpage_types`. data.mammoth_pages = { ["a"] = "twos", -- FIXME: change to threes ["mammoth page test"] = "twos", -- required for testing purposes - please leave here } return data q02q3zllkyysivftvjq4h2gli665cgv Modul:links/templates 828 3688 26553 8019 2025-11-08T21:10:16Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26553 Scribunto text/plain -- Prevent substitution. if mw.isSubsting() then return require("Module:unsubst") end local export = {} local links_module = "Module:links" local process_params = require("Module:parameters").process local remove = table.remove local upper = require("Module:string utilities").upper --[=[ Modules used: [[Module:links]] [[Module:languages]] [[Module:scripts]] [[Module:parameters]] [[Module:debug]] ]=] do local function get_args(frame) -- `compat` is a compatibility mode for {{term}}. -- If given a nonempty value, the function uses lang= to specify the -- language, and all the positional parameters shift one number lower. local iargs = frame.args iargs.compat = iargs.compat and iargs.compat ~= "" iargs.langname = iargs.langname and iargs.langname ~= "" iargs.notself = iargs.notself and iargs.notself ~= "" local alias_of_4 = {alias_of = 4} local boolean = {type = "boolean"} local params = { [1] = {required = true, type = "language", default = "und"}, [2] = true, [3] = true, [4] = true, g = {list = true, type = "genders", flatten = true}, gloss = alias_of_4, id = true, lit = true, ng = true, pos = true, sc = {type = "script"}, t = alias_of_4, tr = true, ts = true, q = {type = "qualifier"}, qq = {type = "qualifier"}, l = {type = "labels"}, ll = {type = "labels"}, ref = {type = "references"}, ["accel-form"] = true, ["accel-translit"] = true, ["accel-lemma"] = true, ["accel-lemma-translit"] = true, ["accel-gender"] = true, ["accel-nostore"] = boolean, } if iargs.compat then params.lang = {type = "language", default = "und"} remove(params, 1) alias_of_4.alias_of = 3 end if iargs.langname then params.w = boolean end return process_params(frame:getParent().args, params), iargs end -- Used in [[Template:l]] and [[Template:m]]. function export.l_term_t(frame) local args, iargs = get_args(frame) local compat = iargs.compat local lang = args[compat and "lang" or 1] -- Tracking for und. if not compat and lang:getCode() == "und" then require("Module:debug").track("link/und") end local term = args[(compat and 1 or 2)] local alt = args[(compat and 2 or 3)] term = term ~= "" and term or nil if not term and not alt and iargs.demo then term = iargs.demo end local langname = iargs.langname and ( args.w and lang:makeWikipediaLink() or lang:getCanonicalName() ) or nil if langname and term == "-" then return langname end -- Forward the information to full_link return (langname and langname .. " " or "") .. require(links_module).full_link( { lang = lang, sc = args.sc, track_sc = true, term = term, alt = alt, gloss = args[4], id = args.id, tr = args.tr, ts = args.ts, genders = args.g, pos = args.pos, ng = args.ng, lit = args.lit, q = args.q, qq = args.qq, l = args.l, ll = args.ll, refs = args.ref, show_qualifiers = true, accel = args["accel-form"] and { form = args["accel-form"], translit = args["accel-translit"], lemma = args["accel-lemma"], lemma_translit = args["accel-lemma-translit"], gender = args["accel-gender"], nostore = args["accel-nostore"], } or nil }, iargs.face, not iargs.notself ) end -- Used in [[Template:link-annotations]]. function export.l_annotations_t(frame) local args, iargs = get_args(frame) -- Forward the information to format_link_annotations return require(links_module).format_link_annotations( { lang = args[1], tr = { args.tr }, ts = { args.ts }, genders = args.g, pos = args.pos, ng = args.ng, lit = args.lit }, iargs.face ) end end -- Used in [[Template:ll]]. do local function get_args(frame) return process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, [2] = {allow_empty = true}, [3] = true, id = true, sc = {type = "script"}, }) end function export.ll(frame) local args = get_args(frame) local lang = args[1] local sc = args.sc local term = args[2] term = term ~= "" and term or nil return require(links_module).language_link{ lang = lang, sc = sc, term = term, alt = args[3], id = args.id } or "<small>[Term?]</small>" .. require("Module:utilities").format_categories( {lang:getFullName() .. " term requests"}, lang, "-", nil, nil, sc ) end end function export.def_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, }) local face = frame.args.face local ret = require("Module:script utilities").tag_definition(require(links_module).embedded_language_links{ term = args[1], lang = require("Module:languages").getByCode("en"), sc = require("Module:scripts").getByCode("Latn") }, face) if face == "non-gloss" then return ret end return '<span class="mention-gloss-paren">(</span>' .. ret .. '<span class="mention-gloss-paren">)</span>' end function export.linkify_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, }) args[1] = mw.text.trim(args[1]) if args[1] == "" or args[1]:find("[[", nil, true) then return args[1] end return "[[" .. args[1] .. "]]" end function export.cap_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true}, [2] = true, lang = {type = "language", default = "en"}, }) local term = args[1] return require(links_module).full_link{ lang = args.lang, term = term, alt = term:gsub("^.[\128-\191]*", upper) .. (args[2] or "") } end function export.section_link_t(frame) local args = process_params(frame:getParent().args, { [1] = {}, }) return require(links_module).section_link(args[1]) end return export 49ywpqwyhc1meeszxumsw7m3fxck38v 26554 26553 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Modul:links/templates]] 26553 Scribunto text/plain -- Prevent substitution. if mw.isSubsting() then return require("Module:unsubst") end local export = {} local links_module = "Module:links" local process_params = require("Module:parameters").process local remove = table.remove local upper = require("Module:string utilities").upper --[=[ Modules used: [[Module:links]] [[Module:languages]] [[Module:scripts]] [[Module:parameters]] [[Module:debug]] ]=] do local function get_args(frame) -- `compat` is a compatibility mode for {{term}}. -- If given a nonempty value, the function uses lang= to specify the -- language, and all the positional parameters shift one number lower. local iargs = frame.args iargs.compat = iargs.compat and iargs.compat ~= "" iargs.langname = iargs.langname and iargs.langname ~= "" iargs.notself = iargs.notself and iargs.notself ~= "" local alias_of_4 = {alias_of = 4} local boolean = {type = "boolean"} local params = { [1] = {required = true, type = "language", default = "und"}, [2] = true, [3] = true, [4] = true, g = {list = true, type = "genders", flatten = true}, gloss = alias_of_4, id = true, lit = true, ng = true, pos = true, sc = {type = "script"}, t = alias_of_4, tr = true, ts = true, q = {type = "qualifier"}, qq = {type = "qualifier"}, l = {type = "labels"}, ll = {type = "labels"}, ref = {type = "references"}, ["accel-form"] = true, ["accel-translit"] = true, ["accel-lemma"] = true, ["accel-lemma-translit"] = true, ["accel-gender"] = true, ["accel-nostore"] = boolean, } if iargs.compat then params.lang = {type = "language", default = "und"} remove(params, 1) alias_of_4.alias_of = 3 end if iargs.langname then params.w = boolean end return process_params(frame:getParent().args, params), iargs end -- Used in [[Template:l]] and [[Template:m]]. function export.l_term_t(frame) local args, iargs = get_args(frame) local compat = iargs.compat local lang = args[compat and "lang" or 1] -- Tracking for und. if not compat and lang:getCode() == "und" then require("Module:debug").track("link/und") end local term = args[(compat and 1 or 2)] local alt = args[(compat and 2 or 3)] term = term ~= "" and term or nil if not term and not alt and iargs.demo then term = iargs.demo end local langname = iargs.langname and ( args.w and lang:makeWikipediaLink() or lang:getCanonicalName() ) or nil if langname and term == "-" then return langname end -- Forward the information to full_link return (langname and langname .. " " or "") .. require(links_module).full_link( { lang = lang, sc = args.sc, track_sc = true, term = term, alt = alt, gloss = args[4], id = args.id, tr = args.tr, ts = args.ts, genders = args.g, pos = args.pos, ng = args.ng, lit = args.lit, q = args.q, qq = args.qq, l = args.l, ll = args.ll, refs = args.ref, show_qualifiers = true, accel = args["accel-form"] and { form = args["accel-form"], translit = args["accel-translit"], lemma = args["accel-lemma"], lemma_translit = args["accel-lemma-translit"], gender = args["accel-gender"], nostore = args["accel-nostore"], } or nil }, iargs.face, not iargs.notself ) end -- Used in [[Template:link-annotations]]. function export.l_annotations_t(frame) local args, iargs = get_args(frame) -- Forward the information to format_link_annotations return require(links_module).format_link_annotations( { lang = args[1], tr = { args.tr }, ts = { args.ts }, genders = args.g, pos = args.pos, ng = args.ng, lit = args.lit }, iargs.face ) end end -- Used in [[Template:ll]]. do local function get_args(frame) return process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, [2] = {allow_empty = true}, [3] = true, id = true, sc = {type = "script"}, }) end function export.ll(frame) local args = get_args(frame) local lang = args[1] local sc = args.sc local term = args[2] term = term ~= "" and term or nil return require(links_module).language_link{ lang = lang, sc = sc, term = term, alt = args[3], id = args.id } or "<small>[Term?]</small>" .. require("Module:utilities").format_categories( {lang:getFullName() .. " term requests"}, lang, "-", nil, nil, sc ) end end function export.def_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, }) local face = frame.args.face local ret = require("Module:script utilities").tag_definition(require(links_module).embedded_language_links{ term = args[1], lang = require("Module:languages").getByCode("en"), sc = require("Module:scripts").getByCode("Latn") }, face) if face == "non-gloss" then return ret end return '<span class="mention-gloss-paren">(</span>' .. ret .. '<span class="mention-gloss-paren">)</span>' end function export.linkify_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, }) args[1] = mw.text.trim(args[1]) if args[1] == "" or args[1]:find("[[", nil, true) then return args[1] end return "[[" .. args[1] .. "]]" end function export.cap_t(frame) local args = process_params(frame:getParent().args, { [1] = {required = true}, [2] = true, lang = {type = "language", default = "en"}, }) local term = args[1] return require(links_module).full_link{ lang = args.lang, term = term, alt = term:gsub("^.[\128-\191]*", upper) .. (args[2] or "") } end function export.section_link_t(frame) local args = process_params(frame:getParent().args, { [1] = {}, }) return require(links_module).section_link(args[1]) end return export 49ywpqwyhc1meeszxumsw7m3fxck38v Modul:parameters/data 828 3689 26624 23988 2026-04-13T00:08:09Z id>Swarabakti 0 26624 Scribunto text/plain local list_to_set = require("Module:table").listToSet local alias_of_2 = {alias_of = 2} local boolean = {type = "boolean"} local empty_list = {} local list = {list = true} local list_allow_holes_separate_no_index = {list = true, allow_holes = true, separate_no_index = true} local required = {required = true} local required_default_ = {required = true, default = ""} local required_lang_default_und = {required = true, type = "language", default = "und"} local type_labels = {type = "labels"} local type_qualifier = {type = "qualifier"} local type_references = {type = "references"} local m = {} -- [[Module:anchors]] m["anchor"] = { [1] = {required = true, list = true, disallow_holes = true}, } m["senseid"] = { [1] = required_lang_default_und, [2] = required_default_, id = alias_of_2, tag = {set = list_to_set{"li", "p"}, default = "li"}, } m["etymid"] = { [1] = required_lang_default_und, [2] = required_default_, id = alias_of_2, } -- [[Module:etymon]] m["etymon"] = { [1] = required_lang_default_und, [2] = {list = true, disallow_holes = true}, id = required, title = true, tree = boolean, text = true, exnihilo = boolean, etydate = true, pos = true, } -- [[Module:transclude]] m["transclude"] = { [1] = {required = true, type = "language"}, [2] = {list = true, required = true}, id = true, sort = true, nogloss = {default = false, type = "boolean"}, no_truncate_gloss = boolean, include_place_extra_info = boolean, place_translation_follows = boolean, place_addl = true, lb = true, nolb = true, nocat = boolean, to = boolean, t = list, indent = true, dot = boolean, pagename = true, } -- [[Module:translations]] m["translation"] = { [1] = required_lang_default_und, [2] = true, [3] = list, alt = true, id = true, sc = {type = "script"}, tr = true, ts = true, lit = true, file = true, l = type_labels, ll = type_labels, q = type_qualifier, qq = type_qualifier, ref = type_references, } m["t-needed"] = { [1] = required_lang_default_und, [2] = {set = list_to_set{"usex", "quote"}}, nocat = boolean, sort = true, } m["trans-top"] = { [1] = true, id = true, ["column-width"] = true, } m["trans-top-also"] = { [1] = required, [2] = list, id = list_allow_holes_separate_no_index, ["column-width"] = true, } m["checktrans-top"] = { [1] = true, ["column-width"] = true, } m["trans-bottom"] = empty_list m["trans-see"] = { [1] = required, [2] = list, id = list_allow_holes_separate_no_index, } m["translation subpage"] = empty_list m["no equivalent translation"] = { [1] = required_lang_default_und, noend = boolean, } m["no attested translation"] = { [1] = required_lang_default_und, noend = boolean, sort = true, } m["not used"] = { [1] = required_lang_default_und, [2] = true, } return m 2vm2y8p3hylggpnx2arc8unfx1b7pd9 26625 26624 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Modul:parameters/data]] 26624 Scribunto text/plain local list_to_set = require("Module:table").listToSet local alias_of_2 = {alias_of = 2} local boolean = {type = "boolean"} local empty_list = {} local list = {list = true} local list_allow_holes_separate_no_index = {list = true, allow_holes = true, separate_no_index = true} local required = {required = true} local required_default_ = {required = true, default = ""} local required_lang_default_und = {required = true, type = "language", default = "und"} local type_labels = {type = "labels"} local type_qualifier = {type = "qualifier"} local type_references = {type = "references"} local m = {} -- [[Module:anchors]] m["anchor"] = { [1] = {required = true, list = true, disallow_holes = true}, } m["senseid"] = { [1] = required_lang_default_und, [2] = required_default_, id = alias_of_2, tag = {set = list_to_set{"li", "p"}, default = "li"}, } m["etymid"] = { [1] = required_lang_default_und, [2] = required_default_, id = alias_of_2, } -- [[Module:etymon]] m["etymon"] = { [1] = required_lang_default_und, [2] = {list = true, disallow_holes = true}, id = required, title = true, tree = boolean, text = true, exnihilo = boolean, etydate = true, pos = true, } -- [[Module:transclude]] m["transclude"] = { [1] = {required = true, type = "language"}, [2] = {list = true, required = true}, id = true, sort = true, nogloss = {default = false, type = "boolean"}, no_truncate_gloss = boolean, include_place_extra_info = boolean, place_translation_follows = boolean, place_addl = true, lb = true, nolb = true, nocat = boolean, to = boolean, t = list, indent = true, dot = boolean, pagename = true, } -- [[Module:translations]] m["translation"] = { [1] = required_lang_default_und, [2] = true, [3] = list, alt = true, id = true, sc = {type = "script"}, tr = true, ts = true, lit = true, file = true, l = type_labels, ll = type_labels, q = type_qualifier, qq = type_qualifier, ref = type_references, } m["t-needed"] = { [1] = required_lang_default_und, [2] = {set = list_to_set{"usex", "quote"}}, nocat = boolean, sort = true, } m["trans-top"] = { [1] = true, id = true, ["column-width"] = true, } m["trans-top-also"] = { [1] = required, [2] = list, id = list_allow_holes_separate_no_index, ["column-width"] = true, } m["checktrans-top"] = { [1] = true, ["column-width"] = true, } m["trans-bottom"] = empty_list m["trans-see"] = { [1] = required, [2] = list, id = list_allow_holes_separate_no_index, } m["translation subpage"] = empty_list m["no equivalent translation"] = { [1] = required_lang_default_und, noend = boolean, } m["no attested translation"] = { [1] = required_lang_default_und, noend = boolean, sort = true, } m["not used"] = { [1] = required_lang_default_und, [2] = true, } return m 2vm2y8p3hylggpnx2arc8unfx1b7pd9 Modul:scripts 828 3693 26537 8024 2025-11-08T17:33:07Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26537 Scribunto text/plain local export = {} local combining_classes_module = "Module:Unicode data/combining classes" local json_module = "Module:JSON" local language_like_module = "Module:language-like" local load_module = "Module:load" local scripts_canonical_names_module = "Module:scripts/canonical names" local scripts_chartoscript_module = "Module:scripts/charToScript" local scripts_data_module = "Module:scripts/data" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local writing_systems_module = "Module:writing systems" local writing_systems_data_module = "Module:writing systems/data" local concat = table.concat local get_by_code -- Defined below. local gmatch = string.gmatch local insert = table.insert local make_object -- Defined below. local match = string.match local require = require local select = select local setmetatable = setmetatable local toNFC = mw.ustring.toNFC local toNFD = mw.ustring.toNFD local toNFKC = mw.ustring.toNFKC local toNFKD = mw.ustring.toNFKD local type = type --[==[ 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 category_name_has_suffix(...) category_name_has_suffix = require(language_like_module).categoryNameHasSuffix return category_name_has_suffix(...) end local function category_name_to_code(...) category_name_to_code = require(language_like_module).categoryNameToCode return category_name_to_code(...) end local function deep_copy(...) deep_copy = require(table_module).deepCopy return deep_copy(...) end local function explode(...) explode = require(string_utilities_module).explode_utf8 return explode(...) end local function get_writing_system(...) get_writing_system = require(writing_systems_module).getByCode return get_writing_system(...) end local function keys_to_list(...) keys_to_list = require(table_module).keysToList return keys_to_list(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function to_json(...) to_json = require(json_module).toJSON return to_json(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end --[==[ 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 scripts_canonical_names local function get_scripts_canonical_names() scripts_canonical_names, get_scripts_canonical_names = load_data(scripts_canonical_names_module), nil return scripts_canonical_names end local scripts_data local function get_scripts_data() scripts_data, get_scripts_data = load_data(scripts_data_module), nil return scripts_data end local scripts_suffixes local function get_scripts_suffixes() scripts_suffixes, get_scripts_suffixes = { "script", "code", "notation", "letters", "numerals", "semaphore", }, nil for _, v in pairs(load_data(writing_systems_data_module)) do insert(scripts_suffixes, v[1]) end return scripts_suffixes end local Script = {} Script.__index = Script --[==[Returns the script code of the script. Example: {{lua|"Cyrl"}} for Cyrillic.]==] function Script:getCode() return self._code end --[==[Returns the canonical name of the script. This is the name used to represent that script on Wiktionary. Example: {{lua|"Cyrillic"}} for Cyrillic.]==] function Script:getCanonicalName() return self._data[1] end --[==[Returns the display form of the script. For scripts, this is the same as the value returned by <code>:getCategoryName("nocap")</code>, i.e. it reads "NAME script" (e.g. {{lua|"Arabic script"}}). The displayed text used in <code>:makeCategoryLink</code> is always the same as the display form.]==] function Script:getDisplayForm() return self:getCategoryName("nocap") end function Script:getAliases() Script.getAliases = require(language_like_module).getAliases return self:getAliases() end function Script:getVarieties(flatten) Script.getVarieties = require(language_like_module).getVarieties return self:getVarieties(flatten) end function Script:getOtherNames() Script.getOtherNames = require(language_like_module).getOtherNames return self:getOtherNames() end function Script:getAllNames() Script.getAllNames = require(language_like_module).getAllNames return self:getAllNames() end --[==[Returns the {{w|IETF language tag#Syntax of language tags|IETF subtag}} used for the script, which should always be a valid {{w|ISO 15924}} script code. This is used when constructing HTML {{code|html|lang{{=}}}} tags. The {{lua|ietf_subtag}} value from the script's data file is used, if present; otherwise, the script code is used. For script codes which contain a hyphen, only the part after the hyphen is used (e.g. {{lua|"fa-Arab"}} becomes {{lua|"Arab"}}).]==] function Script:getIETFSubtag() local code = self._ietf_subtag if code == nil then code = self._data.ietf_subtag or match(self:getCode(), "[^%-]+$") self._ietf_subtag = code end return code end --[==[Returns a script object for the parent of the script, such as {"Arab"} for {"fa-Arab"}. It returns {nil} for scripts without a parent, like {"Latn"}, {"Grek"}, etc.]==] function Script:getParent() local parent = self._parentObject if parent == nil then parent = self:getParentCode() -- If the value is nil, it's cached as false. parent = parent and get_by_code(parent) or false self._parentObject = parent end return parent or nil end --[==[Returns the script code of the parent of the script, such as {"Arab"} for {"fa-Arab"}. It returns {nil} for scripts without a parent, like {"Latn"}, {"Grek"}, etc.]==] function Script:getParentCode() local parent = self._parentCode if parent == nil then -- If the value is nil, it's cached as false. parent = self._data.parent or false self._parentCode = parent end return parent or nil end function Script:getSystemCodes() if not self._systemCodes then local system_codes = self._data[3] if type(system_codes) == "table" then self._systemCodes = system_codes elseif type(system_codes) == "string" then self._systemCodes = split(system_codes, ",", true, true) else self._systemCodes = {} end end return self._systemCodes end function Script:getSystems() if not self._systemObjects then self._systemObjects = {} for _, system in ipairs(self:getSystemCodes()) do insert(self._systemObjects, get_writing_system(system)) end end return self._systemObjects end --[==[Check whether the script is of type `system`, which can be a writing system code or object. If multiple systems are passed, return true if the script is any of the specified systems.]==] function Script:isSystem(...) for _, system in ipairs{...} do if type(system) == "table" then system = system:getCode() end for _, s in ipairs(self:getSystemCodes()) do if system == s then return true end end end return false end --[==[Returns a table of types as a lookup table (with the types as keys). Currently, the only possible type is {script}.]==] function Script:getTypes() local types = self._types if types == nil then types = {script = true} local rawtypes = self._data.type if rawtypes then for t in gmatch(rawtypes, "[^,]+") do types[t] = true end end self._types = types end return types end --[==[Given a list of types as strings, returns true if the script has all of them. Use {{lua|hasType("script")}} to determine if an object that may be a language, family or script is a script.]==] function Script:hasType(...) Script.hasType = require(language_like_module).hasType return self:hasType(...) end --[==[Returns the name of the main category of that script. Example: {{lua|"Cyrillic script"}} for Cyrillic, whose category is at [[:Category:Cyrillic script]]. Unless optional argument <code>nocap</code> is given, the script name at the beginning of the returned value will be capitalized. This capitalization is correct for category names, but not if the script name is lowercase and the returned value of this function is used in the middle of a sentence. (For example, the script with the code <code>Semap</code> has the name <code>"flag semaphore"</code>, which should remain lowercase when used as part of the category name [[:Category:Translingual letters in flag semaphore]] but should be capitalized in [[:Category:Flag semaphore templates]].) If you are considering using <code>getCategoryName("nocap")</code>, use <code>getDisplayForm()</code> instead.]==] function Script:getCategoryName(nocap) local name = self:getCanonicalName() if category_name_has_suffix(name, scripts_suffixes or get_scripts_suffixes()) then name = name .. " script" end if not nocap then name = mw.getContentLanguage():ucfirst(name) end return name end function Script:makeCategoryLink() return "[[:Category:" .. self:getCategoryName() .. "|" .. self:getDisplayForm() .. "]]" end --[==[Returns the Wikidata item id for the script or <code>nil</code>. This corresponds to the the second field in the data modules.]==] function Script:getWikidataItem() Script.getWikidataItem = require(language_like_module).getWikidataItem return self:getWikidataItem() end --[==[ Returns the name of the Wikipedia article for the script. `project` specifies the language and project to retrieve the article from, defaulting to {"enwiki"} for the English Wikipedia. Normally if specified it should be the project code for a specific-language Wikipedia e.g. "zhwiki" for the Chinese Wikipedia, but it can be any project, including non-Wikipedia ones. If the project is the English Wikipedia and the property {wikipedia_article} is present in the data module it will be used first. In all other cases, a sitelink will be generated from {:getWikidataItem} (if set). The resulting value (or lack of value) is cached so that subsequent calls are fast. If no value could be determined, and `noCategoryFallback` is {false}, {:getCategoryName} is used as fallback; otherwise, {nil} is returned. Note that if `noCategoryFallback` is {nil} or omitted, it defaults to {false} if the project is the English Wikipedia, otherwise to {true}. In other words, under normal circumstances, if the English Wikipedia article couldn't be retrieved, the return value will fall back to a link to the script's category, but this won't normally happen for any other project. ]==] function Script:getWikipediaArticle(noCategoryFallback, project) Script.getWikipediaArticle = require(language_like_module).getWikipediaArticle return self:getWikipediaArticle(noCategoryFallback, project) end --[==[Returns the name of the Wikimedia Commons category page for the script.]==] function Script:getCommonsCategory() Script.getCommonsCategory = require(language_like_module).getCommonsCategory return self:getCommonsCategory() end --[==[Returns the charset defining the script's characters from the script's data file. This can be used to search for words consisting only of this script, but see the warning above.]==] function Script:getCharacters() return self.characters or nil end --[==[Returns the number of characters in the text that are part of this script. '''Note:''' You should never assume that text consists entirely of the same script. Strings may contain spaces, punctuation and even wiki markup or HTML tags. HTML tags will skew the counts, as they contain Latin-script characters. So it's best to avoid them.]==] function Script:countCharacters(text) local charset = self._data.characters if charset == nil then return 0 end return select(2, ugsub(text, "[" .. charset .. "]", "")) end function Script:hasCapitalization() return not not self._data.capitalized end function Script:hasSpaces() return self._data.spaces ~= false end function Script:isTransliterated() return self._data.translit ~= false end --[==[Returns true if the script is (sometimes) sorted by scraping page content, meaning that it is sensitive to changes in capitalization during sorting.]==] function Script:sortByScraping() return not not self._data.sort_by_scraping end --[==[Returns the text direction. Horizontal scripts return {{lua|"ltr"}} (left-to-right) or {{lua|"rtl"}} (right-to-left), while vertical scripts return {{lua|"vertical-ltr"}} (vertical left-to-right) or {{lua|"vertical-rtl"}} (vertical right-to-left).]==] function Script:getDirection() return self._data.direction or "ltr" end function Script:getData() return self._data end --[==[Returns the name of the module containing the script's data. Currently, this is always [[Module:scripts/data]].]==] function Script:getDataModuleName() return scripts_data_module end --[==[Returns {{lua|true}} if the script contains characters that require fixes to Unicode normalization under certain circumstances, {{lua|false}} if it doesn't.]==] function Script:hasNormalizationFixes() return not not self._data.normalizationFixes end --[==[Corrects discouraged sequences of Unicode characters to the encouraged equivalents.]==] function Script:fixDiscouragedSequences(text) if self:hasNormalizationFixes() then local norm_fixes = self._data.normalizationFixes local to = norm_fixes.to if to then for i, v in ipairs(norm_fixes.from) do text = ugsub(text, v, to[i] or "") end end end return text end do local combining_classes -- Obtain the list of default combining classes. local function get_combining_classes() combining_classes, get_combining_classes = load_data(combining_classes_module), nil return combining_classes end -- Implements a modified form of Unicode normalization for instances where there are identified deficiencies in the default Unicode combining classes. local function fixNormalization(text, self) if not self:hasNormalizationFixes() then return text end local norm_fixes = self._data.normalizationFixes local new_classes = norm_fixes.combiningClasses if not (new_classes and umatch(text, "[" .. norm_fixes.combiningClassCharacters .. "]")) then return text end text = explode(text) -- Manual sort based on new combining classes. -- We can't use table.sort, as it compares the first/last values in an array as a shortcut, which messes things up. for i = 2, #text do local char = text[i] local class = new_classes[char] or (combining_classes or get_combining_classes())[char] if class then repeat i = i - 1 local prev = text[i] if (new_classes[prev] or (combining_classes or get_combining_classes())[prev] or 0) < class then break end text[i], text[i + 1] = char, prev until i == 1 end end return concat(text) end function Script:toFixedNFC(text) return fixNormalization(toNFC(text), self) end function Script:toFixedNFD(text) return fixNormalization(toNFD(text), self) end function Script:toFixedNFKC(text) return fixNormalization(toNFKC(text), self) end function Script:toFixedNFKD(text) return fixNormalization(toNFKD(text), self) end end function Script:toJSON(opts) local ret = { canonicalName = self:getCanonicalName(), categoryName = self:getCategoryName("nocap"), code = self:getCode(), parent = self:getParentCode(), systems = self:getSystemCodes(), aliases = self:getAliases(), varieties = self:getVarieties(), otherNames = self:getOtherNames(), type = keys_to_list(self:getTypes()), direction = self:getDirection(), characters = self:getCharacters(), ietfSubtag = self:getIETFSubtag(), wikidataItem = self:getWikidataItem(), wikipediaArticle = self:getWikipediaArticle(true), } -- Use `deep_copy` when returning a table, so that there are no editing restrictions imposed by `mw.loadData`. return opts and opts.lua_table and deep_copy(ret) or to_json(ret, opts) end function export.makeObject(code, data) local data_type = type(data) if data_type ~= "table" then error(("bad argument #2 to 'makeObject' (table expected, got %s)"):format(data_type)) end return setmetatable({_data = data, _code = code, characters = data.characters}, Script) end make_object = export.makeObject --[==[ Finds the script whose code matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}.]==] function export.getByCode(code) local data = (scripts_data or get_scripts_data())[code] return data ~= nil and make_object(code, data) or nil end get_by_code = export.getByCode --[==[ Look for the script whose canonical name (the name used to represent that script on Wiktionary) matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}. The canonical name of scripts should always be unique (it is an error for two scripts on Wiktionary to share the same canonical name), so this is guaranteed to give at most one result.]==] function export.getByCanonicalName(name) if name == nil then return nil end local code = (scripts_canonical_names or get_scripts_canonical_names())[name] if code == nil then return nil end return get_by_code(code) end --[==[ Look for the script whose category name (the name used in categories for that script) matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}. In almost all cases, the category name for a script is its canonical name plus the word "script", e.g. "Cyrillic" has the category name "Cyrillic script". Where a canonical name ends with "script", "code" or "semaphore", the category name is identical to the canonical name.]==] function export.getByCategoryName(name) if name == nil then return nil end local code = category_name_to_code( name, " script", scripts_canonical_names or get_scripts_canonical_names(), scripts_suffixes or get_scripts_suffixes() ) if code == nil then return nil end return get_by_code(code) end --[==[ Takes a codepoint or a character and finds the script code (if any) that is appropriate for it based on the codepoint, using the data module [[Module:scripts/recognition data]]. The data module was generated from the patterns in [[Module:scripts/data]] using [[Module:User:Erutuon/script recognition]]. Converts the character to a codepoint. Returns a script code if the codepoint is in the list of individual characters, or if it is in one of the defined ranges in the 4096-character block that it belongs to, else returns "None". ]==] function export.charToScript(char) export.charToScript = require(scripts_chartoscript_module).charToScript return export.charToScript(char) end --[==[ Returns the code for the script that has the greatest number of characters in `text`. Useful for script tagging text that is unspecified for language. Uses [[Module:scripts/recognition data]] to determine a script code for a character language-agnostically. Specifically, it works as follows: Convert each character to a codepoint. Increment the counter for the script code if the codepoint is in the list of individual characters, or if it is in one of the defined ranges in the 4096-character block that it belongs to. Each script has a two-part counter, for primary and secondary matches. Primary matches are when the script is the first one listed; otherwise, it's a secondary match. When comparing scripts, first the total of both are compared (i.e. the overall number of matches). If these are the same, the number of primary and then secondary matches are used as tiebreakers. For example, this is used to ensure that `Grek` takes priority over `Polyt` if no characters which exclusively match `Polyt` are found, as `Grek` is a subset of `Polyt`. If `none_is_last_resort_only` is specified, this will never return {"None"} if any characters in `text` belong to a script. Otherwise, it will return {"None"} if there are more characters that don't belong to a script than belong to any individual script. (FIXME: This behavior is probably wrong, and `none_is_last_resort_only` should probably become the default.) ]==] function export.findBestScriptWithoutLang(text, none_is_last_resort_only) export.findBestScriptWithoutLang = require(scripts_chartoscript_module).findBestScriptWithoutLang return export.findBestScriptWithoutLang(text, none_is_last_resort_only) end return export anyowy4owrrtgbmxfr38n4p05s6iamd 26538 24277 2026-07-07T21:53:35Z Sibiru45 115 1 ralatan matan [[:id:Modul:scripts]] 24277 Scribunto text/plain local export = {} local combining_classes_module = "Module:Unicode data/combining classes" local json_module = "Module:JSON" local language_like_module = "Module:language-like" local load_module = "Module:load" local scripts_canonical_names_module = "Module:scripts/canonical names" local scripts_chartoscript_module = "Module:scripts/charToScript" local scripts_data_module = "Module:scripts/data" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local writing_systems_module = "Module:writing systems" local writing_systems_data_module = "Module:writing systems/data" local concat = table.concat local get_by_code -- Defined below. local gmatch = string.gmatch local insert = table.insert local make_object -- Defined below. local match = string.match local require = require local select = select local setmetatable = setmetatable local toNFC = mw.ustring.toNFC local toNFD = mw.ustring.toNFD local toNFKC = mw.ustring.toNFKC local toNFKD = mw.ustring.toNFKD local type = type --[==[ 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 category_name_has_suffix(...) category_name_has_suffix = require(language_like_module).categoryNameHasSuffix return category_name_has_suffix(...) end local function category_name_to_code(...) category_name_to_code = require(language_like_module).categoryNameToCode return category_name_to_code(...) end local function deep_copy(...) deep_copy = require(table_module).deepCopy return deep_copy(...) end local function explode(...) explode = require(string_utilities_module).explode_utf8 return explode(...) end local function get_writing_system(...) get_writing_system = require(writing_systems_module).getByCode return get_writing_system(...) end local function keys_to_list(...) keys_to_list = require(table_module).keysToList return keys_to_list(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function to_json(...) to_json = require(json_module).toJSON return to_json(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end --[==[ 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 scripts_canonical_names local function get_scripts_canonical_names() scripts_canonical_names, get_scripts_canonical_names = load_data(scripts_canonical_names_module), nil return scripts_canonical_names end local scripts_data local function get_scripts_data() scripts_data, get_scripts_data = load_data(scripts_data_module), nil return scripts_data end local scripts_suffixes local function get_scripts_suffixes() scripts_suffixes, get_scripts_suffixes = { "script", "code", "notation", "letters", "numerals", "semaphore", }, nil for _, v in pairs(load_data(writing_systems_data_module)) do insert(scripts_suffixes, v[1]) end return scripts_suffixes end local Script = {} Script.__index = Script --[==[Returns the script code of the script. Example: {{lua|"Cyrl"}} for Cyrillic.]==] function Script:getCode() return self._code end --[==[Returns the canonical name of the script. This is the name used to represent that script on Wiktionary. Example: {{lua|"Cyrillic"}} for Cyrillic.]==] function Script:getCanonicalName() return self._data[1] end --[==[Returns the display form of the script. For scripts, this is the same as the value returned by <code>:getCategoryName("nocap")</code>, i.e. it reads "NAME script" (e.g. {{lua|"Arabic script"}}). The displayed text used in <code>:makeCategoryLink</code> is always the same as the display form.]==] function Script:getDisplayForm() return self:getCategoryName("nocap") end function Script:getAliases() Script.getAliases = require(language_like_module).getAliases return self:getAliases() end function Script:getVarieties(flatten) Script.getVarieties = require(language_like_module).getVarieties return self:getVarieties(flatten) end function Script:getOtherNames() Script.getOtherNames = require(language_like_module).getOtherNames return self:getOtherNames() end function Script:getAllNames() Script.getAllNames = require(language_like_module).getAllNames return self:getAllNames() end --[==[Returns the {{w|IETF language tag#Syntax of language tags|IETF subtag}} used for the script, which should always be a valid {{w|ISO 15924}} script code. This is used when constructing HTML {{code|html|lang{{=}}}} tags. The {{lua|ietf_subtag}} value from the script's data file is used, if present; otherwise, the script code is used. For script codes which contain a hyphen, only the part after the hyphen is used (e.g. {{lua|"fa-Arab"}} becomes {{lua|"Arab"}}).]==] function Script:getIETFSubtag() local code = self._ietf_subtag if code == nil then code = self._data.ietf_subtag or match(self:getCode(), "[^%-]+$") self._ietf_subtag = code end return code end --[==[Returns a script object for the parent of the script, such as {"Arab"} for {"fa-Arab"}. It returns {nil} for scripts without a parent, like {"Latn"}, {"Grek"}, etc.]==] function Script:getParent() local parent = self._parentObject if parent == nil then parent = self:getParentCode() -- If the value is nil, it's cached as false. parent = parent and get_by_code(parent) or false self._parentObject = parent end return parent or nil end --[==[Returns the script code of the parent of the script, such as {"Arab"} for {"fa-Arab"}. It returns {nil} for scripts without a parent, like {"Latn"}, {"Grek"}, etc.]==] function Script:getParentCode() local parent = self._parentCode if parent == nil then -- If the value is nil, it's cached as false. parent = self._data.parent or false self._parentCode = parent end return parent or nil end function Script:getSystemCodes() if not self._systemCodes then local system_codes = self._data[3] if type(system_codes) == "table" then self._systemCodes = system_codes elseif type(system_codes) == "string" then self._systemCodes = split(system_codes, ",", true, true) else self._systemCodes = {} end end return self._systemCodes end function Script:getSystems() if not self._systemObjects then self._systemObjects = {} for _, system in ipairs(self:getSystemCodes()) do insert(self._systemObjects, get_writing_system(system)) end end return self._systemObjects end --[==[Check whether the script is of type `system`, which can be a writing system code or object. If multiple systems are passed, return true if the script is any of the specified systems.]==] function Script:isSystem(...) for _, system in ipairs{...} do if type(system) == "table" then system = system:getCode() end for _, s in ipairs(self:getSystemCodes()) do if system == s then return true end end end return false end --[==[Returns a table of types as a lookup table (with the types as keys). Currently, the only possible type is {script}.]==] function Script:getTypes() local types = self._types if types == nil then types = {script = true} local rawtypes = self._data.type if rawtypes then for t in gmatch(rawtypes, "[^,]+") do types[t] = true end end self._types = types end return types end --[==[Given a list of types as strings, returns true if the script has all of them. Use {{lua|hasType("script")}} to determine if an object that may be a language, family or script is a script.]==] function Script:hasType(...) Script.hasType = require(language_like_module).hasType return self:hasType(...) end --[==[Returns the name of the main category of that script. Example: {{lua|"Cyrillic script"}} for Cyrillic, whose category is at [[:Category:Cyrillic script]]. Unless optional argument <code>nocap</code> is given, the script name at the beginning of the returned value will be capitalized. This capitalization is correct for category names, but not if the script name is lowercase and the returned value of this function is used in the middle of a sentence. (For example, the script with the code <code>Semap</code> has the name <code>"flag semaphore"</code>, which should remain lowercase when used as part of the category name [[:Category:Translingual letters in flag semaphore]] but should be capitalized in [[:Category:Flag semaphore templates]].) If you are considering using <code>getCategoryName("nocap")</code>, use <code>getDisplayForm()</code> instead.]==] function Script:getCategoryName(nocap) local name = self:getCanonicalName() if category_name_has_suffix(name, scripts_suffixes or get_scripts_suffixes()) then name = name .. " script" end if not nocap then name = mw.getContentLanguage():ucfirst(name) end return name end function Script:makeCategoryLink() return "[[:Category:" .. self:getCategoryName() .. "|" .. self:getDisplayForm() .. "]]" end --[==[Returns the Wikidata item id for the script or <code>nil</code>. This corresponds to the the second field in the data modules.]==] function Script:getWikidataItem() Script.getWikidataItem = require(language_like_module).getWikidataItem return self:getWikidataItem() end --[==[ Returns the name of the Wikipedia article for the script. `project` specifies the language and project to retrieve the article from, defaulting to {"enwiki"} for the English Wikipedia. Normally if specified it should be the project code for a specific-language Wikipedia e.g. "zhwiki" for the Chinese Wikipedia, but it can be any project, including non-Wikipedia ones. If the project is the English Wikipedia and the property {wikipedia_article} is present in the data module it will be used first. In all other cases, a sitelink will be generated from {:getWikidataItem} (if set). The resulting value (or lack of value) is cached so that subsequent calls are fast. If no value could be determined, and `noCategoryFallback` is {false}, {:getCategoryName} is used as fallback; otherwise, {nil} is returned. Note that if `noCategoryFallback` is {nil} or omitted, it defaults to {false} if the project is the English Wikipedia, otherwise to {true}. In other words, under normal circumstances, if the English Wikipedia article couldn't be retrieved, the return value will fall back to a link to the script's category, but this won't normally happen for any other project. ]==] function Script:getWikipediaArticle(noCategoryFallback, project) Script.getWikipediaArticle = require(language_like_module).getWikipediaArticle return self:getWikipediaArticle(noCategoryFallback, project) end --[==[Returns the name of the Wikimedia Commons category page for the script.]==] function Script:getCommonsCategory() Script.getCommonsCategory = require(language_like_module).getCommonsCategory return self:getCommonsCategory() end --[==[Returns the charset defining the script's characters from the script's data file. This can be used to search for words consisting only of this script, but see the warning above.]==] function Script:getCharacters() return self.characters or nil end --[==[Returns the number of characters in the text that are part of this script. '''Note:''' You should never assume that text consists entirely of the same script. Strings may contain spaces, punctuation and even wiki markup or HTML tags. HTML tags will skew the counts, as they contain Latin-script characters. So it's best to avoid them.]==] function Script:countCharacters(text) local charset = self._data.characters if charset == nil then return 0 end return select(2, ugsub(text, "[" .. charset .. "]", "")) end function Script:hasCapitalization() return not not self._data.capitalized end function Script:hasSpaces() return self._data.spaces ~= false end function Script:isTransliterated() return self._data.translit ~= false end --[==[Returns true if the script is (sometimes) sorted by scraping page content, meaning that it is sensitive to changes in capitalization during sorting.]==] function Script:sortByScraping() return not not self._data.sort_by_scraping end --[==[Returns the text direction. Horizontal scripts return {{lua|"ltr"}} (left-to-right) or {{lua|"rtl"}} (right-to-left), while vertical scripts return {{lua|"vertical-ltr"}} (vertical left-to-right) or {{lua|"vertical-rtl"}} (vertical right-to-left).]==] function Script:getDirection() return self._data.direction or "ltr" end function Script:getData() return self._data end --[==[Returns the name of the module containing the script's data. Currently, this is always [[Module:scripts/data]].]==] function Script:getDataModuleName() return scripts_data_module end --[==[Returns {{lua|true}} if the script contains characters that require fixes to Unicode normalization under certain circumstances, {{lua|false}} if it doesn't.]==] function Script:hasNormalizationFixes() return not not self._data.normalizationFixes end --[==[Corrects discouraged sequences of Unicode characters to the encouraged equivalents.]==] function Script:fixDiscouragedSequences(text) if self:hasNormalizationFixes() then local norm_fixes = self._data.normalizationFixes local to = norm_fixes.to if to then for i, v in ipairs(norm_fixes.from) do text = ugsub(text, v, to[i] or "") end end end return text end do local combining_classes -- Obtain the list of default combining classes. local function get_combining_classes() combining_classes, get_combining_classes = load_data(combining_classes_module), nil return combining_classes end -- Implements a modified form of Unicode normalization for instances where there are identified deficiencies in the default Unicode combining classes. local function fixNormalization(text, self) if not self:hasNormalizationFixes() then return text end local norm_fixes = self._data.normalizationFixes local new_classes = norm_fixes.combiningClasses if not (new_classes and umatch(text, "[" .. norm_fixes.combiningClassCharacters .. "]")) then return text end text = explode(text) -- Manual sort based on new combining classes. -- We can't use table.sort, as it compares the first/last values in an array as a shortcut, which messes things up. for i = 2, #text do local char = text[i] local class = new_classes[char] or (combining_classes or get_combining_classes())[char] if class then repeat i = i - 1 local prev = text[i] if (new_classes[prev] or (combining_classes or get_combining_classes())[prev] or 0) < class then break end text[i], text[i + 1] = char, prev until i == 1 end end return concat(text) end function Script:toFixedNFC(text) return fixNormalization(toNFC(text), self) end function Script:toFixedNFD(text) return fixNormalization(toNFD(text), self) end function Script:toFixedNFKC(text) return fixNormalization(toNFKC(text), self) end function Script:toFixedNFKD(text) return fixNormalization(toNFKD(text), self) end end function Script:toJSON(opts) local ret = { canonicalName = self:getCanonicalName(), categoryName = self:getCategoryName("nocap"), code = self:getCode(), parent = self:getParentCode(), systems = self:getSystemCodes(), aliases = self:getAliases(), varieties = self:getVarieties(), otherNames = self:getOtherNames(), type = keys_to_list(self:getTypes()), direction = self:getDirection(), characters = self:getCharacters(), ietfSubtag = self:getIETFSubtag(), wikidataItem = self:getWikidataItem(), wikipediaArticle = self:getWikipediaArticle(true), } -- Use `deep_copy` when returning a table, so that there are no editing restrictions imposed by `mw.loadData`. return opts and opts.lua_table and deep_copy(ret) or to_json(ret, opts) end function export.makeObject(code, data) local data_type = type(data) if data_type ~= "table" then error(("bad argument #2 to 'makeObject' (table expected, got %s)"):format(data_type)) end return setmetatable({_data = data, _code = code, characters = data.characters}, Script) end make_object = export.makeObject --[==[ Finds the script whose code matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}.]==] function export.getByCode(code) local data = (scripts_data or get_scripts_data())[code] return data ~= nil and make_object(code, data) or nil end get_by_code = export.getByCode --[==[ Look for the script whose canonical name (the name used to represent that script on Wiktionary) matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}. The canonical name of scripts should always be unique (it is an error for two scripts on Wiktionary to share the same canonical name), so this is guaranteed to give at most one result.]==] function export.getByCanonicalName(name) if name == nil then return nil end local code = (scripts_canonical_names or get_scripts_canonical_names())[name] if code == nil then return nil end return get_by_code(code) end --[==[ Look for the script whose category name (the name used in categories for that script) matches the one provided. If it exists, it returns a {Script} object representing the script. Otherwise, it returns {nil}. In almost all cases, the category name for a script is its canonical name plus the word "script", e.g. "Cyrillic" has the category name "Cyrillic script". Where a canonical name ends with "script", "code" or "semaphore", the category name is identical to the canonical name.]==] function export.getByCategoryName(name) if name == nil then return nil end local code = category_name_to_code( name, " script", scripts_canonical_names or get_scripts_canonical_names(), scripts_suffixes or get_scripts_suffixes() ) if code == nil then return nil end return get_by_code(code) end --[==[ Takes a codepoint or a character and finds the script code (if any) that is appropriate for it based on the codepoint, using the data module [[Module:scripts/recognition data]]. The data module was generated from the patterns in [[Module:scripts/data]] using [[Module:User:Erutuon/script recognition]]. Converts the character to a codepoint. Returns a script code if the codepoint is in the list of individual characters, or if it is in one of the defined ranges in the 4096-character block that it belongs to, else returns "None". ]==] function export.charToScript(char) export.charToScript = require(scripts_chartoscript_module).charToScript return export.charToScript(char) end --[==[ Returns the code for the script that has the greatest number of characters in `text`. Useful for script tagging text that is unspecified for language. Uses [[Module:scripts/recognition data]] to determine a script code for a character language-agnostically. Specifically, it works as follows: Convert each character to a codepoint. Increment the counter for the script code if the codepoint is in the list of individual characters, or if it is in one of the defined ranges in the 4096-character block that it belongs to. Each script has a two-part counter, for primary and secondary matches. Primary matches are when the script is the first one listed; otherwise, it's a secondary match. When comparing scripts, first the total of both are compared (i.e. the overall number of matches). If these are the same, the number of primary and then secondary matches are used as tiebreakers. For example, this is used to ensure that `Grek` takes priority over `Polyt` if no characters which exclusively match `Polyt` are found, as `Grek` is a subset of `Polyt`. If `none_is_last_resort_only` is specified, this will never return {"None"} if any characters in `text` belong to a script. Otherwise, it will return {"None"} if there are more characters that don't belong to a script than belong to any individual script. (FIXME: This behavior is probably wrong, and `none_is_last_resort_only` should probably become the default.) ]==] function export.findBestScriptWithoutLang(text, none_is_last_resort_only) export.findBestScriptWithoutLang = require(scripts_chartoscript_module).findBestScriptWithoutLang return export.findBestScriptWithoutLang(text, none_is_last_resort_only) end return export anyowy4owrrtgbmxfr38n4p05s6iamd Modul:script utilities 828 3695 26541 8026 2025-11-08T18:58:48Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26541 Scribunto text/plain local export = {} local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local links_module = "Module:links" local munge_text_module = "Module:munge text" local parameters_module = "Module:parameters" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local utilities_module = "Module:utilities" local concat = table.concat local insert = table.insert local require = require local toNFD = mw.ustring.toNFD local dump = mw.dumpObject --[==[ 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 embedded_language_links(...) embedded_language_links = require(links_module).embedded_language_links return embedded_language_links(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function munge_text(...) munge_text = require(munge_text_module) return munge_text(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end local function track(...) track = require(debug_track_module) return track(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end --[==[ 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 m_data local function get_data() m_data, get_data = mw.loadData("Module:script utilities/data"), nil return m_data end --[=[ Modules used: [[Module:script utilities/data]] [[Module:scripts]] [[Module:anchors]] (only when IDs present) [[Module:string utilities]] (only when hyphens in Korean text or spaces in vertical text) [[Module:languages]] [[Module:parameters]] [[Module:utilities]] [[Module:debug/track]] ]=] function export.is_Latin_script(sc) -- Latn, Latf, Latg, pjt-Latn return sc:getCode():find("Lat") and true or false end --[==[{{temp|#invoke:script utilities|lang_t}} This is used by {{temp|lang}} to wrap portions of text in a language tag. See there for more information.]==] do local function get_args(frame) return process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, [2] = {required = true, allow_empty = true, default = ""}, ["sc"] = {type = "script"}, ["face"] = true, ["class"] = true, }) end function export.lang_t(frame) local args = get_args(frame) local lang = args[1] local sc = args["sc"] local text = args[2] local cats = {} if sc then -- Track uses of sc parameter. if sc:getCode() == lang:findBestScript(text):getCode() then insert(cats, lang:getFullName() .. " terms with redundant script codes") else insert(cats, lang:getFullName() .. " terms with non-redundant manual script codes") end else sc = lang:findBestScript(text) end text = embedded_language_links{ term = text, lang = lang, sc = sc } cats = #cats > 0 and format_categories(cats, lang, "-", nil, nil, sc) or "" local face = args["face"] local class = args["class"] return export.tag_text(text, lang, sc, face, class) .. cats end end -- Ustring turns on the codepoint-aware string matching. The basic string function -- should be used for simple sequences of characters, Ustring function for -- sets – []. local function trackPattern(text, pattern, tracking) if pattern and umatch(text, pattern) then track("script/" .. tracking) end end local function track_text(text, lang, sc) if lang and text then local langCode = lang:getFullCode() -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/ang/acute]] if langCode == "ang" then local decomposed = toNFD(text) local acute = u(0x301) trackPattern(decomposed, acute, "ang/acute") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-phi]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-theta]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-kappa]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-rho]] ϑ, ϰ, ϱ, ϕ should generally be replaced with θ, κ, ρ, φ. ]=] elseif langCode == "el" or langCode == "grc" then trackPattern(text, "ϑ", "Greek/wrong-theta") trackPattern(text, "ϰ", "Greek/wrong-kappa") trackPattern(text, "ϱ", "Greek/wrong-rho") trackPattern(text, "ϕ", "Greek/wrong-phi") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/spacing-coronis]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/spacing-smooth-breathing]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/wrong-apostrophe]] When spacing coronis and spacing smooth breathing are used as apostrophes, they should be replaced with right single quotation marks (’). ]=] if langCode == "grc" then trackPattern(text, u(0x1FBD), "Ancient Greek/spacing-coronis") trackPattern(text, u(0x1FBF), "Ancient Greek/spacing-smooth-breathing") trackPattern(text, "[" .. u(0x1FBD) .. u(0x1FBF) .. "]", "Ancient Greek/wrong-apostrophe", true) end -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/Russian/grave-accent]] elseif langCode == "ru" then local decomposed = toNFD(text) trackPattern(decomposed, u(0x300), "Russian/grave-accent") -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/Tibetan/trailing-punctuation]] elseif langCode == "bo" then trackPattern(text, "[་།]$", "Tibetan/trailing-punctuation") trackPattern(text, "[་།]%]%]$", "Tibetan/trailing-punctuation") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/broken-am]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/wrong-rue-lue]] ]=] elseif langCode == "th" then trackPattern(text, "เ".."เ", "Thai/broken-ae") trackPattern(text, "ํ[่้๊๋]?า", "Thai/broken-am") trackPattern(text, "[ฤฦ]า", "Thai/wrong-rue-lue") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/broken-am]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-no]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-mo]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-lo]] ]=] elseif langCode == "lo" then trackPattern(text, "ເ".."ເ", "Lao/broken-ae") trackPattern(text, "ໍ[່້໊໋]?າ", "Lao/broken-am") trackPattern(text, "ຫນ", "Lao/possible-broken-ho-no") trackPattern(text, "ຫມ", "Lao/possible-broken-ho-mo") trackPattern(text, "ຫລ", "Lao/possible-broken-ho-lo") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lü/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lü/possible-wrong-sequence]] ]=] elseif langCode == "khb" then trackPattern(text, "ᦵ".."ᦵ", "Lü/broken-ae") trackPattern(text, "[ᦀ-ᦫ][ᦵᦶᦷᦺ]", "Lü/possible-wrong-sequence") end end end local function Kore_ruby(txt) return (ugsub(txt, "([%-".. get_script("Hani"):getCharacters() .. "]+)%(([%-" .. get_script("Hang"):getCharacters() .. "]+)%)", "<ruby>%1<rp>(</rp><rt>%2</rt><rp>)</rp></ruby>")) end --[==[Wraps the given text in HTML tags with appropriate CSS classes (see [[WT:CSS]]) for the [[Module:languages#Language objects|language]] and script. This is required for all non-English text on Wiktionary. The actual tags and CSS classes that are added are determined by the <code>face</code> parameter. It can be one of the following: ; {{code|lua|"term"}} : The text is wrapped in {{code|html|2=<i class="(sc) mention" lang="(lang)">...</i>}}. ; {{code|lua|"head"}} : The text is wrapped in {{code|html|2=<strong class="(sc) headword" lang="(lang)">...</strong>}}. ; {{code|lua|"hypothetical"}} : The text is wrapped in {{code|html|2=<span class="hypothetical-star">*</span><i class="(sc) hypothetical" lang="(lang)">...</i>}}. ; {{code|lua|"bold"}} : The text is wrapped in {{code|html|2=<b class="(sc)" lang="(lang)">...</b>}}. ; {{code|lua|nil}} : The text is wrapped in {{code|html|2=<span class="(sc)" lang="(lang)">...</span>}}. The optional <code>class</code> parameter can be used to specify an additional CSS class to be added to the tag.]==] function export.tag_text(text, lang, sc, face, class, id) if not sc then if lang then sc = lang:findBestScript(text) else sc = find_best_script_without_lang(text) end end track_text(text, lang, sc) -- Replace space characters with newlines in Mongolian-script text, which is written top-to-bottom. if sc:getDirection():find("vertical", nil, true) and text:find(" ", nil, true) then text = munge_text(text, function(txt) -- having extra parentheses makes sure only the first return value gets through return (txt:gsub(" +", "<br>")) end) end -- Hack Korean script text to remove hyphens. -- FIXME: This should be handled in a more general fashion, but needs to -- be efficient by not doing anything if no hyphens are present, and currently this is the only -- language needing such processing. -- 20220221: Also convert 漢字(한자) to ruby, instead of needing [[Template:Ruby]]. if sc:getCode() == "Kore" and text:match("[%-()g]") then local title, display = require("Module:links").get_wikilink_parts(text, true) if title ~= nil then -- special case that the text is a single link, do not munge and preserve affix hyphens if lang and lang:getCode() == "okm" then -- Middle Korean code from [[User:Chom.kwoy]] -- Comment from [[User:Lunabunn]]: -- In Middle Korean orthography, syllable formation is phonemic as opposed to morpheme-boundary-based a la -- modern Korean. As such, for example, if you were to write nam-i, it would be rendered as na.mi so if you -- then put na-mi to indicate particle boundaries as in modern Korean, the hyphen would be misplaced. -- Previously, this was alleviated by specialcasing na--mi but [[User:Theknightwho]] made that resolve to - -- in the Hangul (previously we used to just delete all -s in Hangul processing), so it broke. -- [[User:Chom.kwoy]] implemented a different solution, which is writing -> instead using however many >s to -- shift the hyphen by that number of letters in the romanization. -- By the time we are called, > signs have been converted to &gt; by a call to encode_entities() in -- make_link() in [[Module:links]] (near the bottom of the function). display = display:gsub("&gt;", "") -- 'g' in Middle Korean is a special sign to treat the following ㅇ sign as /G/ instead of null. display = display:gsub("g", "") end if display:find("<") then display = munge_text(display, function(txt) txt = txt:gsub("(.)%-(%-?)(.)", "%1%2%3") txt = Kore_ruby(txt) return txt end) else display = display:gsub("(.)%-(%-?)(.)", "%1%2%3") display = Kore_ruby(display) end text = "[[" .. title .. "|" .. display .. "]]" else text = munge_text(text, function(txt) if lang and lang:getCode() == "okm" then txt = txt:gsub("&gt;", "") txt = txt:gsub("g", "") end if txt == text then -- special case for the entire text being plain txt = txt:gsub("(.)%-(%-?)(.)", "%1%2%3") else txt = txt:gsub("%-(%-?)", "%1") end txt = Kore_ruby(txt) return txt end) end end if sc:getCode() == "Image" then face = nil end if face == "hypothetical" then -- [[Special:WhatLinksHere/Wiktionary:Tracking/script-utilities/face/hypothetical]] track("script-utilities/face/hypothetical") end local data = (m_data or get_data()).faces[face or "plain"] if data == nil then error('Invalid script face "' .. face .. '".') end local tag = data.tag local opening_tag = {tag} if lang and id then insert(opening_tag, 'id="' .. language_anchor(lang, id) .. '"') end local classes = {data.class} -- if the script code is hyphenated (i.e. language code-script code, add the last component as a class as well) -- e.g. ota-Arab adds both Arab and ota-Arab as classes if sc:getCode():find("-", nil, true) then insert(classes, 1, (ugsub(sc:getCode(), ".+%-", ""))) insert(classes, 2, sc:getCode()) else insert(classes, 1, sc:getCode()) end if class and class ~= '' then insert(classes, class) end insert(opening_tag, 'class="' .. concat(classes, ' ') .. '"') -- FIXME: Is it OK to insert the etymology-only lang code and have it fall back to the first part of the -- lang code (by chopping off the '-...' part)? It seems the :lang() selector does this; not sure about -- [lang=...] attributes. if lang then insert(opening_tag, 'lang="' .. lang:getFullCode() .. '"') end -- Add a script wrapper return (data.prefix or "") .. "<" .. concat(opening_tag, " ") .. ">" .. text .. "</" .. tag .. ">" end --[==[Tags the transliteration for given text {translit} and language {lang}. It will add the language, script subtag (as defined in [https://www.rfc-editor.org/rfc/bcp/bcp47.txt BCP 47 2.2.3]) and [https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir dir] (directional) attributes as needed. The optional <code>kind</code> parameter can be one of the following: ; {{code|lua|"term"}} : tag transliteration for {{temp|mention}} ; {{code|lua|"usex"}} : tag transliteration for {{temp|usex}} ; {{code|lua|"head"}} : tag transliteration for {{temp|head}} ; {{code|lua|"default"}} : default The optional <code>attributes</code> parameter is used to specify additional HTML attributes for the tag.]==] function export.tag_translit(translit, lang, kind, attributes, is_manual) if type(lang) == "table" then -- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt lang = lang.getFullCode and lang:getFullCode() or error("Second argument to tag_translit should be a language code or language object.") end local data = (m_data or get_data()).translit[kind or "default"] local tag = data.tag local opening_tag = {tag} local class = data.class if lang == "ja" then insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. (is_manual and "manual-tr " or "") .. 'tr"') else insert(opening_tag, 'lang="' .. lang .. '-Latn"') insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. (is_manual and "manual-tr " or "") .. 'tr Latn"') end local dir = data.dir if dir then insert(opening_tag, 'dir="' .. dir .. '"') end if attributes then track("tag_translit/attributes") insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. translit .. "</" .. tag .. ">" end function export.tag_transcription(transcription, lang, kind, attributes) if type(lang) == "table" then -- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt lang = lang.getFullCode and lang:getFullCode() or error("Second argument to tag_transcription should be a language code or language object.") end local data = (m_data or get_data()).transcription[kind or "default"] local tag = data.tag local opening_tag = {tag} local class = data.class if lang == "ja" then insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. 'ts"') else insert(opening_tag, 'lang="' .. lang .. '-Latn"') insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. 'ts Latn"') end local dir = data.dir if dir then insert(opening_tag, 'dir="' .. dir .. '"') end if attributes then track("tag_transcription/attributes") insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. transcription .. "</" .. tag .. ">" end --[==[Tags {def} as a definition. The <code>def</code> parameter must be one of the following: ; {{code|lua|"gloss"}} : The text is wrapped in {{code|html|2=<span class="(mention-gloss">...</span>}}. ; {{code|lua|"non-gloss"}} : The text is wrapped in {{code|html|2=<span class="use-with-mention">...</span>}}. The optional <code>attributes</code> parameter is used to specify additional HTML attributes for the tag.]==] function export.tag_definition(def, kind, attributes) local data = (m_data or get_data()).definition[kind] if data == nil then error("Second argument to tag_definition should specify the kind of definition from the list in [[Module:script utilities/data]].") end local tag = data.tag local opening_tag = {tag} local class = data.class if class then insert(opening_tag, 'class="' .. class .. '"') end if attributes then insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. def .. "</" .. tag .. ">" end --[==[Generates a request to provide a term in its native script, if it is missing. This is used by the {{temp|rfscript}} template as well as by the functions in [[Module:links]]. The function will add entries to one of the subcategories of [[:Category:Requests for native script by language]], and do several checks on the given language and script. In particular: * If the script was given, a subcategory named "Requests for (script) script" is added, but only if the language has more than one script. Otherwise, the main "Requests for native script" category is used. * Nothing is added at all if the language has no scripts other than Latin and its varieties.]==] function export.request_script(lang, sc, usex, nocat, sort_key) local scripts = lang.getScripts and lang:getScripts() or error('The language "' .. lang:getCode() .. '" does not have the method getScripts. It may be unwritten.') -- By default, request for "native" script local cat_script = "native" local disp_script = "script" -- If the script was not specified, and the language has only one script, use that. if not sc and #scripts == 1 then sc = scripts[1] end -- Is the script known? if sc and sc:getCode() ~= "None" then -- If the script is Latin, return nothing. if export.is_Latin_script(sc) then return "" end if (not scripts[1]) or sc:getCode() ~= scripts[1]:getCode() then disp_script = sc:getCanonicalName() end -- The category needs to be specific to script only if there is chance of ambiguity. This occurs when when the language has multiple scripts (or with codes such as "und"). if (not scripts[1]) or scripts[2] then cat_script = sc:getCanonicalName() end else -- The script is not known. -- Does the language have at least one non-Latin script in its list? local has_nonlatin = false for _, val in ipairs(scripts) do if not export.is_Latin_script(val) then has_nonlatin = true break end end -- If there are no non-Latin scripts, return nothing. if not has_nonlatin and lang:getCode() ~= "und" then return "" end end -- Etymology languages have their own categories, whose parents are the regular language. return "<small>[" .. disp_script .. " needed]</small>" .. (nocat and "" or format_categories("Requests for " .. cat_script .. " script " .. (usex and "in" or "for") .. " " .. lang:getCanonicalName() .. " " .. (usex == "quote" and "quotations" or usex and "usage examples" or "terms"), lang, sort_key ) ) end --[==[This is used by {{temp|rfscript}}. See there for more information.]==] function export.template_rfscript(frame) local boolean = {type = "boolean"} local args = process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, ["sc"] = {type = "script"}, ["usex"] = boolean, ["quote"] = boolean, ["nocat"] = boolean, ["sort"] = true, }) local ret = export.request_script(args[1], args["sc"], args.quote and "quote" or args.usex, args.nocat, args.sort) if ret == "" then error("This language is written in the Latin alphabet. It does not need a native script.") end return ret end function export.checkScript(text, scriptCode, result) local scriptObject = get_script(scriptCode) if not scriptObject then error('The script code "' .. scriptCode .. '" is not recognized.') end local originalText = text -- Remove non-letter characters. text = ugsub(text, "%A+", "") -- Remove all characters of the script in question. text = ugsub(text, "[" .. scriptObject:getCharacters() .. "]+", "") if text ~= "" then if type(result) == "string" then error(result) else error('The text "' .. originalText .. '" contains the letters "' .. text .. '" that do not belong to the ' .. scriptObject:getDisplayForm() .. '.', 2) end end end return export 1wjllfinzt8gb85kslqiauicz2xdv7i 26542 26541 2026-07-07T21:53:35Z Sibiru45 115 1 ralatan matan [[:id:Modul:script_utilities]] 26541 Scribunto text/plain local export = {} local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local links_module = "Module:links" local munge_text_module = "Module:munge text" local parameters_module = "Module:parameters" local scripts_module = "Module:scripts" local string_utilities_module = "Module:string utilities" local utilities_module = "Module:utilities" local concat = table.concat local insert = table.insert local require = require local toNFD = mw.ustring.toNFD local dump = mw.dumpObject --[==[ 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 embedded_language_links(...) embedded_language_links = require(links_module).embedded_language_links return embedded_language_links(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function munge_text(...) munge_text = require(munge_text_module) return munge_text(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end local function track(...) track = require(debug_track_module) return track(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end --[==[ 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 m_data local function get_data() m_data, get_data = mw.loadData("Module:script utilities/data"), nil return m_data end --[=[ Modules used: [[Module:script utilities/data]] [[Module:scripts]] [[Module:anchors]] (only when IDs present) [[Module:string utilities]] (only when hyphens in Korean text or spaces in vertical text) [[Module:languages]] [[Module:parameters]] [[Module:utilities]] [[Module:debug/track]] ]=] function export.is_Latin_script(sc) -- Latn, Latf, Latg, pjt-Latn return sc:getCode():find("Lat") and true or false end --[==[{{temp|#invoke:script utilities|lang_t}} This is used by {{temp|lang}} to wrap portions of text in a language tag. See there for more information.]==] do local function get_args(frame) return process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, [2] = {required = true, allow_empty = true, default = ""}, ["sc"] = {type = "script"}, ["face"] = true, ["class"] = true, }) end function export.lang_t(frame) local args = get_args(frame) local lang = args[1] local sc = args["sc"] local text = args[2] local cats = {} if sc then -- Track uses of sc parameter. if sc:getCode() == lang:findBestScript(text):getCode() then insert(cats, lang:getFullName() .. " terms with redundant script codes") else insert(cats, lang:getFullName() .. " terms with non-redundant manual script codes") end else sc = lang:findBestScript(text) end text = embedded_language_links{ term = text, lang = lang, sc = sc } cats = #cats > 0 and format_categories(cats, lang, "-", nil, nil, sc) or "" local face = args["face"] local class = args["class"] return export.tag_text(text, lang, sc, face, class) .. cats end end -- Ustring turns on the codepoint-aware string matching. The basic string function -- should be used for simple sequences of characters, Ustring function for -- sets – []. local function trackPattern(text, pattern, tracking) if pattern and umatch(text, pattern) then track("script/" .. tracking) end end local function track_text(text, lang, sc) if lang and text then local langCode = lang:getFullCode() -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/ang/acute]] if langCode == "ang" then local decomposed = toNFD(text) local acute = u(0x301) trackPattern(decomposed, acute, "ang/acute") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-phi]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-theta]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-kappa]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Greek/wrong-rho]] ϑ, ϰ, ϱ, ϕ should generally be replaced with θ, κ, ρ, φ. ]=] elseif langCode == "el" or langCode == "grc" then trackPattern(text, "ϑ", "Greek/wrong-theta") trackPattern(text, "ϰ", "Greek/wrong-kappa") trackPattern(text, "ϱ", "Greek/wrong-rho") trackPattern(text, "ϕ", "Greek/wrong-phi") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/spacing-coronis]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/spacing-smooth-breathing]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Ancient Greek/wrong-apostrophe]] When spacing coronis and spacing smooth breathing are used as apostrophes, they should be replaced with right single quotation marks (’). ]=] if langCode == "grc" then trackPattern(text, u(0x1FBD), "Ancient Greek/spacing-coronis") trackPattern(text, u(0x1FBF), "Ancient Greek/spacing-smooth-breathing") trackPattern(text, "[" .. u(0x1FBD) .. u(0x1FBF) .. "]", "Ancient Greek/wrong-apostrophe", true) end -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/Russian/grave-accent]] elseif langCode == "ru" then local decomposed = toNFD(text) trackPattern(decomposed, u(0x300), "Russian/grave-accent") -- [[Special:WhatLinksHere/Wiktionary:Tracking/script/Tibetan/trailing-punctuation]] elseif langCode == "bo" then trackPattern(text, "[་།]$", "Tibetan/trailing-punctuation") trackPattern(text, "[་།]%]%]$", "Tibetan/trailing-punctuation") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/broken-am]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Thai/wrong-rue-lue]] ]=] elseif langCode == "th" then trackPattern(text, "เ".."เ", "Thai/broken-ae") trackPattern(text, "ํ[่้๊๋]?า", "Thai/broken-am") trackPattern(text, "[ฤฦ]า", "Thai/wrong-rue-lue") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/broken-am]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-no]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-mo]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lao/possible-broken-ho-lo]] ]=] elseif langCode == "lo" then trackPattern(text, "ເ".."ເ", "Lao/broken-ae") trackPattern(text, "ໍ[່້໊໋]?າ", "Lao/broken-am") trackPattern(text, "ຫນ", "Lao/possible-broken-ho-no") trackPattern(text, "ຫມ", "Lao/possible-broken-ho-mo") trackPattern(text, "ຫລ", "Lao/possible-broken-ho-lo") --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lü/broken-ae]] [[Special:WhatLinksHere/Wiktionary:Tracking/script/Lü/possible-wrong-sequence]] ]=] elseif langCode == "khb" then trackPattern(text, "ᦵ".."ᦵ", "Lü/broken-ae") trackPattern(text, "[ᦀ-ᦫ][ᦵᦶᦷᦺ]", "Lü/possible-wrong-sequence") end end end local function Kore_ruby(txt) return (ugsub(txt, "([%-".. get_script("Hani"):getCharacters() .. "]+)%(([%-" .. get_script("Hang"):getCharacters() .. "]+)%)", "<ruby>%1<rp>(</rp><rt>%2</rt><rp>)</rp></ruby>")) end --[==[Wraps the given text in HTML tags with appropriate CSS classes (see [[WT:CSS]]) for the [[Module:languages#Language objects|language]] and script. This is required for all non-English text on Wiktionary. The actual tags and CSS classes that are added are determined by the <code>face</code> parameter. It can be one of the following: ; {{code|lua|"term"}} : The text is wrapped in {{code|html|2=<i class="(sc) mention" lang="(lang)">...</i>}}. ; {{code|lua|"head"}} : The text is wrapped in {{code|html|2=<strong class="(sc) headword" lang="(lang)">...</strong>}}. ; {{code|lua|"hypothetical"}} : The text is wrapped in {{code|html|2=<span class="hypothetical-star">*</span><i class="(sc) hypothetical" lang="(lang)">...</i>}}. ; {{code|lua|"bold"}} : The text is wrapped in {{code|html|2=<b class="(sc)" lang="(lang)">...</b>}}. ; {{code|lua|nil}} : The text is wrapped in {{code|html|2=<span class="(sc)" lang="(lang)">...</span>}}. The optional <code>class</code> parameter can be used to specify an additional CSS class to be added to the tag.]==] function export.tag_text(text, lang, sc, face, class, id) if not sc then if lang then sc = lang:findBestScript(text) else sc = find_best_script_without_lang(text) end end track_text(text, lang, sc) -- Replace space characters with newlines in Mongolian-script text, which is written top-to-bottom. if sc:getDirection():find("vertical", nil, true) and text:find(" ", nil, true) then text = munge_text(text, function(txt) -- having extra parentheses makes sure only the first return value gets through return (txt:gsub(" +", "<br>")) end) end -- Hack Korean script text to remove hyphens. -- FIXME: This should be handled in a more general fashion, but needs to -- be efficient by not doing anything if no hyphens are present, and currently this is the only -- language needing such processing. -- 20220221: Also convert 漢字(한자) to ruby, instead of needing [[Template:Ruby]]. if sc:getCode() == "Kore" and text:match("[%-()g]") then local title, display = require("Module:links").get_wikilink_parts(text, true) if title ~= nil then -- special case that the text is a single link, do not munge and preserve affix hyphens if lang and lang:getCode() == "okm" then -- Middle Korean code from [[User:Chom.kwoy]] -- Comment from [[User:Lunabunn]]: -- In Middle Korean orthography, syllable formation is phonemic as opposed to morpheme-boundary-based a la -- modern Korean. As such, for example, if you were to write nam-i, it would be rendered as na.mi so if you -- then put na-mi to indicate particle boundaries as in modern Korean, the hyphen would be misplaced. -- Previously, this was alleviated by specialcasing na--mi but [[User:Theknightwho]] made that resolve to - -- in the Hangul (previously we used to just delete all -s in Hangul processing), so it broke. -- [[User:Chom.kwoy]] implemented a different solution, which is writing -> instead using however many >s to -- shift the hyphen by that number of letters in the romanization. -- By the time we are called, > signs have been converted to &gt; by a call to encode_entities() in -- make_link() in [[Module:links]] (near the bottom of the function). display = display:gsub("&gt;", "") -- 'g' in Middle Korean is a special sign to treat the following ㅇ sign as /G/ instead of null. display = display:gsub("g", "") end if display:find("<") then display = munge_text(display, function(txt) txt = txt:gsub("(.)%-(%-?)(.)", "%1%2%3") txt = Kore_ruby(txt) return txt end) else display = display:gsub("(.)%-(%-?)(.)", "%1%2%3") display = Kore_ruby(display) end text = "[[" .. title .. "|" .. display .. "]]" else text = munge_text(text, function(txt) if lang and lang:getCode() == "okm" then txt = txt:gsub("&gt;", "") txt = txt:gsub("g", "") end if txt == text then -- special case for the entire text being plain txt = txt:gsub("(.)%-(%-?)(.)", "%1%2%3") else txt = txt:gsub("%-(%-?)", "%1") end txt = Kore_ruby(txt) return txt end) end end if sc:getCode() == "Image" then face = nil end if face == "hypothetical" then -- [[Special:WhatLinksHere/Wiktionary:Tracking/script-utilities/face/hypothetical]] track("script-utilities/face/hypothetical") end local data = (m_data or get_data()).faces[face or "plain"] if data == nil then error('Invalid script face "' .. face .. '".') end local tag = data.tag local opening_tag = {tag} if lang and id then insert(opening_tag, 'id="' .. language_anchor(lang, id) .. '"') end local classes = {data.class} -- if the script code is hyphenated (i.e. language code-script code, add the last component as a class as well) -- e.g. ota-Arab adds both Arab and ota-Arab as classes if sc:getCode():find("-", nil, true) then insert(classes, 1, (ugsub(sc:getCode(), ".+%-", ""))) insert(classes, 2, sc:getCode()) else insert(classes, 1, sc:getCode()) end if class and class ~= '' then insert(classes, class) end insert(opening_tag, 'class="' .. concat(classes, ' ') .. '"') -- FIXME: Is it OK to insert the etymology-only lang code and have it fall back to the first part of the -- lang code (by chopping off the '-...' part)? It seems the :lang() selector does this; not sure about -- [lang=...] attributes. if lang then insert(opening_tag, 'lang="' .. lang:getFullCode() .. '"') end -- Add a script wrapper return (data.prefix or "") .. "<" .. concat(opening_tag, " ") .. ">" .. text .. "</" .. tag .. ">" end --[==[Tags the transliteration for given text {translit} and language {lang}. It will add the language, script subtag (as defined in [https://www.rfc-editor.org/rfc/bcp/bcp47.txt BCP 47 2.2.3]) and [https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir dir] (directional) attributes as needed. The optional <code>kind</code> parameter can be one of the following: ; {{code|lua|"term"}} : tag transliteration for {{temp|mention}} ; {{code|lua|"usex"}} : tag transliteration for {{temp|usex}} ; {{code|lua|"head"}} : tag transliteration for {{temp|head}} ; {{code|lua|"default"}} : default The optional <code>attributes</code> parameter is used to specify additional HTML attributes for the tag.]==] function export.tag_translit(translit, lang, kind, attributes, is_manual) if type(lang) == "table" then -- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt lang = lang.getFullCode and lang:getFullCode() or error("Second argument to tag_translit should be a language code or language object.") end local data = (m_data or get_data()).translit[kind or "default"] local tag = data.tag local opening_tag = {tag} local class = data.class if lang == "ja" then insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. (is_manual and "manual-tr " or "") .. 'tr"') else insert(opening_tag, 'lang="' .. lang .. '-Latn"') insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. (is_manual and "manual-tr " or "") .. 'tr Latn"') end local dir = data.dir if dir then insert(opening_tag, 'dir="' .. dir .. '"') end if attributes then track("tag_translit/attributes") insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. translit .. "</" .. tag .. ">" end function export.tag_transcription(transcription, lang, kind, attributes) if type(lang) == "table" then -- FIXME: Do better support for etym languages; see https://www.rfc-editor.org/rfc/bcp/bcp47.txt lang = lang.getFullCode and lang:getFullCode() or error("Second argument to tag_transcription should be a language code or language object.") end local data = (m_data or get_data()).transcription[kind or "default"] local tag = data.tag local opening_tag = {tag} local class = data.class if lang == "ja" then insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. 'ts"') else insert(opening_tag, 'lang="' .. lang .. '-Latn"') insert(opening_tag, 'class="' .. (class and (class .. " ") or "") .. 'ts Latn"') end local dir = data.dir if dir then insert(opening_tag, 'dir="' .. dir .. '"') end if attributes then track("tag_transcription/attributes") insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. transcription .. "</" .. tag .. ">" end --[==[Tags {def} as a definition. The <code>def</code> parameter must be one of the following: ; {{code|lua|"gloss"}} : The text is wrapped in {{code|html|2=<span class="(mention-gloss">...</span>}}. ; {{code|lua|"non-gloss"}} : The text is wrapped in {{code|html|2=<span class="use-with-mention">...</span>}}. The optional <code>attributes</code> parameter is used to specify additional HTML attributes for the tag.]==] function export.tag_definition(def, kind, attributes) local data = (m_data or get_data()).definition[kind] if data == nil then error("Second argument to tag_definition should specify the kind of definition from the list in [[Module:script utilities/data]].") end local tag = data.tag local opening_tag = {tag} local class = data.class if class then insert(opening_tag, 'class="' .. class .. '"') end if attributes then insert(opening_tag, attributes) end return "<" .. concat(opening_tag, " ") .. ">" .. def .. "</" .. tag .. ">" end --[==[Generates a request to provide a term in its native script, if it is missing. This is used by the {{temp|rfscript}} template as well as by the functions in [[Module:links]]. The function will add entries to one of the subcategories of [[:Category:Requests for native script by language]], and do several checks on the given language and script. In particular: * If the script was given, a subcategory named "Requests for (script) script" is added, but only if the language has more than one script. Otherwise, the main "Requests for native script" category is used. * Nothing is added at all if the language has no scripts other than Latin and its varieties.]==] function export.request_script(lang, sc, usex, nocat, sort_key) local scripts = lang.getScripts and lang:getScripts() or error('The language "' .. lang:getCode() .. '" does not have the method getScripts. It may be unwritten.') -- By default, request for "native" script local cat_script = "native" local disp_script = "script" -- If the script was not specified, and the language has only one script, use that. if not sc and #scripts == 1 then sc = scripts[1] end -- Is the script known? if sc and sc:getCode() ~= "None" then -- If the script is Latin, return nothing. if export.is_Latin_script(sc) then return "" end if (not scripts[1]) or sc:getCode() ~= scripts[1]:getCode() then disp_script = sc:getCanonicalName() end -- The category needs to be specific to script only if there is chance of ambiguity. This occurs when when the language has multiple scripts (or with codes such as "und"). if (not scripts[1]) or scripts[2] then cat_script = sc:getCanonicalName() end else -- The script is not known. -- Does the language have at least one non-Latin script in its list? local has_nonlatin = false for _, val in ipairs(scripts) do if not export.is_Latin_script(val) then has_nonlatin = true break end end -- If there are no non-Latin scripts, return nothing. if not has_nonlatin and lang:getCode() ~= "und" then return "" end end -- Etymology languages have their own categories, whose parents are the regular language. return "<small>[" .. disp_script .. " needed]</small>" .. (nocat and "" or format_categories("Requests for " .. cat_script .. " script " .. (usex and "in" or "for") .. " " .. lang:getCanonicalName() .. " " .. (usex == "quote" and "quotations" or usex and "usage examples" or "terms"), lang, sort_key ) ) end --[==[This is used by {{temp|rfscript}}. See there for more information.]==] function export.template_rfscript(frame) local boolean = {type = "boolean"} local args = process_params(frame:getParent().args, { [1] = {required = true, type = "language", default = "und"}, ["sc"] = {type = "script"}, ["usex"] = boolean, ["quote"] = boolean, ["nocat"] = boolean, ["sort"] = true, }) local ret = export.request_script(args[1], args["sc"], args.quote and "quote" or args.usex, args.nocat, args.sort) if ret == "" then error("This language is written in the Latin alphabet. It does not need a native script.") end return ret end function export.checkScript(text, scriptCode, result) local scriptObject = get_script(scriptCode) if not scriptObject then error('The script code "' .. scriptCode .. '" is not recognized.') end local originalText = text -- Remove non-letter characters. text = ugsub(text, "%A+", "") -- Remove all characters of the script in question. text = ugsub(text, "[" .. scriptObject:getCharacters() .. "]+", "") if text ~= "" then if type(result) == "string" then error(result) else error('The text "' .. originalText .. '" contains the letters "' .. text .. '" that do not belong to the ' .. scriptObject:getDisplayForm() .. '.', 2) end end end return export 1wjllfinzt8gb85kslqiauicz2xdv7i Modul:script utilities/data 828 3696 26545 8027 2025-11-08T19:04:23Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26545 Scribunto text/plain local data = {} local translit = { ["term"] = { --[=[ can't be done until Kana transliterations are correctly parsed by [[Module:links]] ["tag"] = "i", ]=] ["class"] = "mention-tr", }, ["usex"] = { ["tag"] = "i", ["class"] = "e-transliteration", }, ["head"] = { ["class"] = "headword-tr", ["dir"] = "ltr", }, ["default"] = {}, } for _, v in next, translit do if not v.tag then v.tag = "span" end end data.translit = translit data.transcription = { ["head"] = { ["tag"] = "span", ["class"] = "headword-ts", ["dir"] = "ltr", }, ["usex"] = { ["tag"] = "span", ["class"] = "e-transcription", }, ["default"] = {}, } data.definition = { ["gloss"] = { ["tag"] = "span", ["class"] = "mention-gloss", }, ["non-gloss"] = { ["tag"] = "span", ["class"] = "use-with-mention", }, } local faces = { ["term"] = { ["tag"] = "i", ["class"] = "mention", }, ["head"] = { ["tag"] = "strong", ["class"] = "headword", }, ["hypothetical"] = { ["prefix"] = '<span class="hypothetical-star">*</span>', ["tag"] = "i", ["class"] = "hypothetical", }, ["bold"] = { ["tag"] = "b", }, ["plain"] = { ["tag"] = "span", } } faces["translation"] = faces["plain"] data.faces = faces return data glatf44lq0ipqkut0sozbs72zba142n 26546 26545 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Modul:script_utilities/data]] 26545 Scribunto text/plain local data = {} local translit = { ["term"] = { --[=[ can't be done until Kana transliterations are correctly parsed by [[Module:links]] ["tag"] = "i", ]=] ["class"] = "mention-tr", }, ["usex"] = { ["tag"] = "i", ["class"] = "e-transliteration", }, ["head"] = { ["class"] = "headword-tr", ["dir"] = "ltr", }, ["default"] = {}, } for _, v in next, translit do if not v.tag then v.tag = "span" end end data.translit = translit data.transcription = { ["head"] = { ["tag"] = "span", ["class"] = "headword-ts", ["dir"] = "ltr", }, ["usex"] = { ["tag"] = "span", ["class"] = "e-transcription", }, ["default"] = {}, } data.definition = { ["gloss"] = { ["tag"] = "span", ["class"] = "mention-gloss", }, ["non-gloss"] = { ["tag"] = "span", ["class"] = "use-with-mention", }, } local faces = { ["term"] = { ["tag"] = "i", ["class"] = "mention", }, ["head"] = { ["tag"] = "strong", ["class"] = "headword", }, ["hypothetical"] = { ["prefix"] = '<span class="hypothetical-star">*</span>', ["tag"] = "i", ["class"] = "hypothetical", }, ["bold"] = { ["tag"] = "b", }, ["plain"] = { ["tag"] = "span", } } faces["translation"] = faces["plain"] data.faces = faces return data glatf44lq0ipqkut0sozbs72zba142n Modul:languages/data 828 3698 26559 8032 2025-11-08T17:18:23Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26559 Scribunto text/plain local m_scripts = require("Module:scripts") local table = table local insert = table.insert local u = require("Module:string/char") local export = {} -- UTF-8 encoded strings for some commonly-used diacritics. local c = { prime = u(0x02B9), grave = u(0x0300), acute = u(0x0301), circ = u(0x0302), tilde = u(0x0303), macron = u(0x0304), overline = u(0x0305), breve = u(0x0306), dotabove = u(0x0307), diaer = u(0x0308), ringabove = u(0x030A), dacute = u(0x030B), caron = u(0x030C), lineabove = u(0x030D), dgrave = u(0x030F), invbreve = u(0x0311), turnedcommaabove = u(0x0312), commaabove = u(0x0313), revcommaabove = u(0x0314), dotbelow = u(0x0323), diaerbelow = u(0x0324), ringbelow = u(0x0325), cedilla = u(0x0327), ogonek = u(0x0328), brevebelow = u(0x032E), macronbelow = u(0x0331), perispomeni = u(0x0342), ypogegrammeni = u(0x0345), CGJ = u(0x034F), -- combining grapheme joiner zigzag = u(0x035B), dbrevebelow = u(0x035C), dmacron = u(0x035E), dtilde = u(0x0360), dinvbreve = u(0x0361), small_a = u(0x0363), small_e = u(0x0364), small_i = u(0x0365), small_o = u(0x0366), small_u = u(0x0367), keraia = u(0x0374), lowerkeraia = u(0x0375), tonos = u(0x0384), palatalization = u(0x0484), dasiapneumata = u(0x0485), psilipneumata = u(0x0486), kashida = u(0x0640), fathatan = u(0x064B), dammatan = u(0x064C), kasratan = u(0x064D), fatha = u(0x064E), damma = u(0x064F), kasra = u(0x0650), shadda = u(0x0651), sukun = u(0x0652), hamzaabove = u(0x0654), nunghunna = u(0x0658), zwarakay = u(0x0659), smallv = u(0x065A), superalef = u(0x0670), udatta = u(0x0951), anudatta = u(0x0952), dottedgrave = u(0x1DC0), dottedacute = u(0x1DC1), coronis = u(0x1FBD), psili = u(0x1FBF), dasia = u(0x1FEF), ZWNJ = u(0x200C), -- zero width non-joiner ZWJ = u(0x200D), -- zero width joiner RSQuo = u(0x2019), -- right single quote kavyka = u(0xA67C), VS01 = u(0xFE00), -- variation selector 1 -- Punctuation for the standardChars field. -- Note: characters are literal (i.e. no magic characters). punc = " ',-‐‑‒–—…∅", -- Range covering all diacritics. diacritics = u(0x300) .. "-" .. u(0x34E) .. u(0x350) .. "-" .. u(0x36F) .. u(0x1AB0) .. "-" .. u(0x1ACE) .. u(0x1DC0) .. "-" .. u(0x1DFF) .. u(0x20D0) .. "-" .. u(0x20F0) .. u(0xFE20) .. "-" .. u(0xFE2F), } -- Braille characters for the standardChars field. local braille = {} for i = 0x2800, 0x28FF do insert(braille, u(i)) end c.braille = table.concat(braille) export.chars = c -- PUA characters, generally used in sortkeys. -- Note: if the limit needs to be increased, do so in powers of 2 (due to the way memory is allocated for tables). local p = {} for i = 1, 32 do p[i] = u(0xF000+i-1) end export.puaChars = p local s = {} -- These values are placed here to make it possible to synchronise a group of languages without the need for a dedicated function module. -- cau do local cau_remove_diacritics = c.grave .. c.acute .. c.macron local cau_from = {"[IlΙІӀᴴ]"} local cau_to = {{ ["l"] = "ӏ", ["Ι"] = "ӏ", ["І"] = "ӏ", ["Ӏ"] = "ӏ", ["ᴴ"] = "ᵸ", }} s["cau-Cyrl-displaytext"] = { from = cau_from, to = cau_to, } s["cau-Cyrl-entryname"] = { remove_diacritics = cau_remove_diacritics, from = cau_from, to = cau_to, } s["cau-Latn-entryname"] = {remove_diacritics = cau_remove_diacritics} end -- Cyrs do local Cyrs_remove_diacritics = c.grave .. c.acute .. c.dotabove .. c.diaer .. c.invbreve .. c.palatalization .. c.dasiapneumata .. c.psilipneumata .. c.dottedgrave .. c.dottedacute .. c.kavyka s["Cyrs-entryname"] = {remove_diacritics = Cyrs_remove_diacritics} s["Cyrs-sortkey"] = { remove_diacritics = Cyrs_remove_diacritics, from = { "ї", "оу", -- 2 chars "[ґꙣєѕꙃꙅꙁіꙇђꙉѻꙩꙫꙭꙮꚙꚛꙋѡѿꙍѽꙑѣꙗѥꙕѧꙙѩꙝꙛѫѭѯѱѳѵҁ]" }, to = { "и" .. p[1], "у", { ["ґ"] = "г" .. p[1], ["ꙣ"] = "д" .. p[1], ["є"] = "е", ["ѕ"] = "ж" .. p[1], ["ꙃ"] = "ж" .. p[1], ["ꙅ"] = "ж" .. p[1], ["ꙁ"] = "з", ["і"] = "и" .. p[1], ["ꙇ"] = "и" .. p[1], ["ђ"] = "и" .. p[2], ["ꙉ"] = "и" .. p[2], ["ѻ"] = "о", ["ꙩ"] = "о", ["ꙫ"] = "о", ["ꙭ"] = "о", ["ꙮ"] = "о", ["ꚙ"] = "о", ["ꚛ"] = "о", ["ꙋ"] = "у", ["ѡ"] = "х" .. p[1], ["ѿ"] = "х" .. p[1], ["ꙍ"] = "х" .. p[1], ["ѽ"] = "х" .. p[1], ["ꙑ"] = "ы", ["ѣ"] = "ь" .. p[1], ["ꙗ"] = "ь" .. p[2], ["ѥ"] = "ь" .. p[3], ["ꙕ"] = "ю", ["ѧ"] = "я", ["ꙙ"] = "я", ["ѩ"] = "я" .. p[1], ["ꙝ"] = "я" .. p[1], ["ꙛ"] = "я" .. p[2], ["ѫ"] = "я" .. p[3], ["ѭ"] = "я" .. p[4], ["ѯ"] = "я" .. p[5], ["ѱ"] = "я" .. p[6], ["ѳ"] = "я" .. p[7], ["ѵ"] = "я" .. p[8], ["ҁ"] = "я" .. p[9], } }, } end s["Grek-displaytext"] = { from = {"Þ", "þ", c.turnedcommaabove, "['ʼ" .. c.RSQuo .. c.prime .. c.keraia .. c.coronis .. c.psili .. "]"}, -- Not tonos: used as the numeral sign in entries. to = {"Ϸ", "ϸ", c.revcommaabove, c.RSQuo} } s["Grek-entryname"] = { remove_diacritics = c.caron .. c.diaerbelow .. c.brevebelow, from = s["Grek-displaytext"].from, to = {"Ϸ", "ϸ", c.revcommaabove, "'"} } s["Grek-sortkey"] = { remove_diacritics = "'ʼ;·`¨´῀" .. c.grave .. c.acute .. c.diaer .. c.caron .. c.turnedcommaabove .. c.commaabove .. c.revcommaabove .. c.macron .. c.breve .. c.diaerbelow .. c.brevebelow .. c.perispomeni .. c.ypogegrammeni .. c.RSQuo .. c.prime .. c.keraia .. c.lowerkeraia .. c.tonos .. c.coronis .. c.psili .. c.dasia, from = {"ϝ", "ͷ", "ϛ", "ͱ", "ͺ", "ϳ", "ϻ", "[ϟϙ]", "[ςϲ]", "ͳ"}, to = {"ε" .. p[1], "ε" .. p[2], "ε" .. p[3], "ζ" .. p[1], "ι", "ι" .. p[1], "π" .. p[1], "π" .. p[2], "σ", "ϡ"} } s["itc-Latn-displaytext"] = { from = {c.caron}, to = {c.breve}, } s["itc-Latn-entryname"] = {remove_diacritics = c.macron .. c.breve .. c.diaer .. c.caron .. c.dinvbreve} s["itc-Latn-sortkey"] = { remove_diacritics = c.circ .. c.tilde .. c.macron .. c.breve .. c.diaer .. c.caron .. c.zigzag .. c.dmacron .. c.dtilde .. c.dinvbreve .. c.small_a .. c.small_e .. c.small_i .. c.small_o .. c.small_u, -- Chiefly medieval abbreviations. from = {"ᵃ", "æ", "[đꝱꟈ]", "ᵉ", "ⁱ", "ꝁ", "[ƚꝉꝲ]", "ꝳ", "ꝴ", "[ꝋᵒ]", "œ", "[ꝑꝓꝕ]", "[ꝗꝙ]", "[ꝛꝵꝶꝝ]", "[ꟊˢ]", "[ꝷᵗ]", "ᵘ", "ꝟ", "⁊"}, to = {"a", "ae", "d", "e", "i", "k", "l", "m", "n", "o", "oe", "p", "q", "r", "s", "t", "u", "v", "&"} } s["Jpan-standardchars"] = -- exclude ぢづヂヅ "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちっつてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろん" .. "ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチッツテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロン" local jpx_displaytext = { from = {"~", "="}, to = {"〜", "゠"} } s["jpx-displaytext"] = { Jpan = jpx_displaytext, Hani = jpx_displaytext, Hrkt = jpx_displaytext, Hira = jpx_displaytext, Kana = jpx_displaytext -- not Latn or Brai } s["jpx-entryname"] = s["jpx-displaytext"] s["jpx-sortkey"] = { Jpan = "Jpan-sortkey", Hani = "Hani-sortkey", Hrkt = "Hira-sortkey", -- sort general kana by normalizing to Hira Hira = "Hira-sortkey", Kana = "Kana-sortkey", Latn = {remove_diacritics = c.tilde .. c.macron .. c.diaer} } s["jpx-translit"] = { Hrkt = "Hrkt-translit", Hira = "Hrkt-translit", Kana = "Hrkt-translit" } local HaniChars = m_scripts.getByCode("Hani"):getCharacters() -- `漢字(한자)`→`漢字` -- `가-나-다`→`가나다`, `가--나--다`→`가-나-다` -- `온돌(溫突/溫堗)`→`온돌` ([[ondol]]) s["Kore-entryname"] = { remove_diacritics = u(0x302E) .. u(0x302F), from = {"([" .. HaniChars .. "])%(.-%)", "^%-", "%-$", "%-(%-?)", "\1", "%([" .. HaniChars .. "/]+%)"}, to = {"%1", "\1", "\1", "%1", "-"} } s["Lisu-sortkey"] = { from = {"𑾰"}, to = {"ꓬ" .. p[1]} } s["Mong-displaytext"] = { from = {"([ᠨ-ᡂᡸ])ᠶ([ᠨ-ᡂᡸ])", "([ᠠ-ᡂᡸ])ᠸ([^᠋ᠠ-ᠧ])", "([ᠠ-ᡂᡸ])ᠸ$"}, to = {"%1ᠢ%2", "%1ᠧ%2", "%1ᠧ"} } s["Mong-entryname"] = s["Mong-displaytext"] s["Polyt-displaytext"] = s["Grek-displaytext"] s["Polyt-entryname"] = { remove_diacritics = c.macron .. c.breve .. c.dbrevebelow, from = s["Grek-entryname"].from, to = s["Grek-entryname"].to } s["Polyt-sortkey"] = s["Grek-sortkey"] -- Samr do s["Samr-entryname"] = { remove_diacritics = c.CGJ .. u(0x0816) .. "-" .. u(0x082D), } s["Samr-sortkey"] = s["Samr-entryname"] end s["roa-oil-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'", from = {"æ", "œ", "·"}, to = {"ae", "oe", " "} } s["Tibt-displaytext"] = { from = {"ༀ", "༌", "།།", "༚༚", "༚༝", "༝༚", "༝༝", "ཷ", "ཹ", "ེེ", "ོོ"}, to = {"ཨོཾ", "་", "༎", "༛", "༟", "࿎", "༞", "ྲཱྀ", "ླཱྀ", "ཻ", "ཽ"} } s["Tibt-entryname"] = s["Tibt-displaytext"] s["wen-sortkey"] = { from = {"ch", "[lłßꞩẜ]", "dz[" .. c.caron .. c.acute .. "]", "[bcefmnoprswz][" .. c.caron .. c.acute .. c.dotabove .. "]"}, to = { "h" .. p[1], { ["l"] = "l" .. p[1], ["ł"] = "l", ["ß"] = "s", ["ꞩ"] = "š", ["ẜ"] = "š", }, { ["dz" .. c.caron] = "d" .. p[1], ["dz" .. c.acute] = "d" .. p[2] }, { ["b" .. c.acute] = "b" .. p[1], ["c" .. c.caron] = "c" .. p[1], ["c" .. c.acute] = "c" .. p[2], ["e" .. c.caron] = "e" .. p[1], ["e" .. c.dotabove] = "e" .. p[1], ["f" .. c.acute] = "f" .. p[1], ["m" .. c.acute] = "m" .. p[1], ["n" .. c.acute] = "n" .. p[1], ["o" .. c.acute] = "o" .. p[1], ["p" .. c.acute] = "p" .. p[1], ["r" .. c.caron] = "r" .. p[1], ["r" .. c.acute] = "r" .. p[2], ["s" .. c.caron] = "s" .. p[1], ["s" .. c.acute] = "s" .. p[2], ["w" .. c.acute] = "w" .. p[1], ["z" .. c.caron] = "z" .. p[1], ["z" .. c.acute] = "z" .. p[2], } } } export.shared = s -- Short-term solution to override the standard substitution process, by forcing the module to substitute the entire text in one pass, if "cont" is given. This results in any PUA characters that are used as stand-ins for formatting being handled by the language-specific substitution process, which is usually undesirable. If the value is "none" then the formatting tags do not get turned into PUA characters in the first place. -- This override is provided for languages which use formatting between strings of text which might need to interact with each other (e.g. Korean 값이 transliterates as "gaps-i", but [[값]] has the formatting '''값'''[[-이]]. The normal process would split the text at the second '''.) export.substitution = { ["gmy"] = "none", ["ja"] = "cont", ["jje"] = "cont", ["ko"] = "cont", ["ko-ear"] = "cont", ["ru"] = "cont", ["th-new"] = "cont", ["sa"] = "cont", ["zkt"] = "cont", } -- Code aliases. The left side is the alias and the right side is the canonical code. NOTE: These are gradually -- being deprecated, so should not be added to on a permanent basis. Temporary additions are permitted under reasonable -- circumstances (e.g. to facilitate changing a language's code). When an alias is no longer used, it should be removed. -- Aliases in this table are tracked at [[Wiktionary:Tracking/languages/LANG]]; see e.g. -- [[Special:WhatLinksHere/Wiktionary:Tracking/languages/RL.]] for the `RL.` alias. export.aliases = { ["EL."] = "la-ecc", ["LL."] = "la-lat", ["ML."] = "la-med", ["NL."] = "la-new", ["VL."] = "la-vul", ["nds-DE"] = "nds-de", ["nds-NL"] = "nds-nl", ["roa-oan"] = "roa-ona", ["sa-cls"] = "cls", ["sa-ved"] = "vsn", } -- Codes which are tracked. Note that all aliases listed above are also tracked, so should not be duplicated here. -- Tracking uses the same mechanism described above in the comment above `export.aliases`. export.track = { -- Codes duplicated between full and etymology-only languages. ["lzh-lit"] = true, -- Languages actively being converted to families. ["bh"] = true, -- inc-bih ["nan"] = true, -- zhx-nan } return export an2n8ocjrz3pphhn0cs35eazuj38bnp 26560 23968 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:languages/data]] 23968 Scribunto text/plain local m_scripts = require("Module:scripts") local table = table local insert = table.insert local u = require("Module:string/char") local export = {} -- UTF-8 encoded strings for some commonly-used diacritics. local c = { prime = u(0x02B9), grave = u(0x0300), acute = u(0x0301), circ = u(0x0302), tilde = u(0x0303), macron = u(0x0304), overline = u(0x0305), breve = u(0x0306), dotabove = u(0x0307), diaer = u(0x0308), ringabove = u(0x030A), dacute = u(0x030B), caron = u(0x030C), lineabove = u(0x030D), dgrave = u(0x030F), invbreve = u(0x0311), turnedcommaabove = u(0x0312), commaabove = u(0x0313), revcommaabove = u(0x0314), dotbelow = u(0x0323), diaerbelow = u(0x0324), ringbelow = u(0x0325), cedilla = u(0x0327), ogonek = u(0x0328), brevebelow = u(0x032E), macronbelow = u(0x0331), perispomeni = u(0x0342), ypogegrammeni = u(0x0345), CGJ = u(0x034F), -- combining grapheme joiner zigzag = u(0x035B), dbrevebelow = u(0x035C), dmacron = u(0x035E), dtilde = u(0x0360), dinvbreve = u(0x0361), small_a = u(0x0363), small_e = u(0x0364), small_i = u(0x0365), small_o = u(0x0366), small_u = u(0x0367), keraia = u(0x0374), lowerkeraia = u(0x0375), tonos = u(0x0384), palatalization = u(0x0484), dasiapneumata = u(0x0485), psilipneumata = u(0x0486), kashida = u(0x0640), fathatan = u(0x064B), dammatan = u(0x064C), kasratan = u(0x064D), fatha = u(0x064E), damma = u(0x064F), kasra = u(0x0650), shadda = u(0x0651), sukun = u(0x0652), hamzaabove = u(0x0654), nunghunna = u(0x0658), zwarakay = u(0x0659), smallv = u(0x065A), superalef = u(0x0670), udatta = u(0x0951), anudatta = u(0x0952), dottedgrave = u(0x1DC0), dottedacute = u(0x1DC1), coronis = u(0x1FBD), psili = u(0x1FBF), dasia = u(0x1FEF), ZWNJ = u(0x200C), -- zero width non-joiner ZWJ = u(0x200D), -- zero width joiner RSQuo = u(0x2019), -- right single quote kavyka = u(0xA67C), VS01 = u(0xFE00), -- variation selector 1 -- Punctuation for the standardChars field. -- Note: characters are literal (i.e. no magic characters). punc = " ',-‐‑‒–—…∅", -- Range covering all diacritics. diacritics = u(0x300) .. "-" .. u(0x34E) .. u(0x350) .. "-" .. u(0x36F) .. u(0x1AB0) .. "-" .. u(0x1ACE) .. u(0x1DC0) .. "-" .. u(0x1DFF) .. u(0x20D0) .. "-" .. u(0x20F0) .. u(0xFE20) .. "-" .. u(0xFE2F), } -- Braille characters for the standardChars field. local braille = {} for i = 0x2800, 0x28FF do insert(braille, u(i)) end c.braille = table.concat(braille) export.chars = c -- PUA characters, generally used in sortkeys. -- Note: if the limit needs to be increased, do so in powers of 2 (due to the way memory is allocated for tables). local p = {} for i = 1, 32 do p[i] = u(0xF000+i-1) end export.puaChars = p local s = {} -- These values are placed here to make it possible to synchronise a group of languages without the need for a dedicated function module. -- cau do local cau_remove_diacritics = c.grave .. c.acute .. c.macron local cau_from = {"[IlΙІӀᴴ]"} local cau_to = {{ ["l"] = "ӏ", ["Ι"] = "ӏ", ["І"] = "ӏ", ["Ӏ"] = "ӏ", ["ᴴ"] = "ᵸ", }} s["cau-Cyrl-displaytext"] = { from = cau_from, to = cau_to, } s["cau-Cyrl-entryname"] = { remove_diacritics = cau_remove_diacritics, from = cau_from, to = cau_to, } s["cau-Latn-entryname"] = {remove_diacritics = cau_remove_diacritics} end -- Cyrs do local Cyrs_remove_diacritics = c.grave .. c.acute .. c.dotabove .. c.diaer .. c.invbreve .. c.palatalization .. c.dasiapneumata .. c.psilipneumata .. c.dottedgrave .. c.dottedacute .. c.kavyka s["Cyrs-entryname"] = {remove_diacritics = Cyrs_remove_diacritics} s["Cyrs-sortkey"] = { remove_diacritics = Cyrs_remove_diacritics, from = { "ї", "оу", -- 2 chars "[ґꙣєѕꙃꙅꙁіꙇђꙉѻꙩꙫꙭꙮꚙꚛꙋѡѿꙍѽꙑѣꙗѥꙕѧꙙѩꙝꙛѫѭѯѱѳѵҁ]" }, to = { "и" .. p[1], "у", { ["ґ"] = "г" .. p[1], ["ꙣ"] = "д" .. p[1], ["є"] = "е", ["ѕ"] = "ж" .. p[1], ["ꙃ"] = "ж" .. p[1], ["ꙅ"] = "ж" .. p[1], ["ꙁ"] = "з", ["і"] = "и" .. p[1], ["ꙇ"] = "и" .. p[1], ["ђ"] = "и" .. p[2], ["ꙉ"] = "и" .. p[2], ["ѻ"] = "о", ["ꙩ"] = "о", ["ꙫ"] = "о", ["ꙭ"] = "о", ["ꙮ"] = "о", ["ꚙ"] = "о", ["ꚛ"] = "о", ["ꙋ"] = "у", ["ѡ"] = "х" .. p[1], ["ѿ"] = "х" .. p[1], ["ꙍ"] = "х" .. p[1], ["ѽ"] = "х" .. p[1], ["ꙑ"] = "ы", ["ѣ"] = "ь" .. p[1], ["ꙗ"] = "ь" .. p[2], ["ѥ"] = "ь" .. p[3], ["ꙕ"] = "ю", ["ѧ"] = "я", ["ꙙ"] = "я", ["ѩ"] = "я" .. p[1], ["ꙝ"] = "я" .. p[1], ["ꙛ"] = "я" .. p[2], ["ѫ"] = "я" .. p[3], ["ѭ"] = "я" .. p[4], ["ѯ"] = "я" .. p[5], ["ѱ"] = "я" .. p[6], ["ѳ"] = "я" .. p[7], ["ѵ"] = "я" .. p[8], ["ҁ"] = "я" .. p[9], } }, } end s["Grek-displaytext"] = { from = {"Þ", "þ", c.turnedcommaabove, "['ʼ" .. c.RSQuo .. c.prime .. c.keraia .. c.coronis .. c.psili .. "]"}, -- Not tonos: used as the numeral sign in entries. to = {"Ϸ", "ϸ", c.revcommaabove, c.RSQuo} } s["Grek-entryname"] = { remove_diacritics = c.caron .. c.diaerbelow .. c.brevebelow, from = s["Grek-displaytext"].from, to = {"Ϸ", "ϸ", c.revcommaabove, "'"} } s["Grek-sortkey"] = { remove_diacritics = "'ʼ;·`¨´῀" .. c.grave .. c.acute .. c.diaer .. c.caron .. c.turnedcommaabove .. c.commaabove .. c.revcommaabove .. c.macron .. c.breve .. c.diaerbelow .. c.brevebelow .. c.perispomeni .. c.ypogegrammeni .. c.RSQuo .. c.prime .. c.keraia .. c.lowerkeraia .. c.tonos .. c.coronis .. c.psili .. c.dasia, from = {"ϝ", "ͷ", "ϛ", "ͱ", "ͺ", "ϳ", "ϻ", "[ϟϙ]", "[ςϲ]", "ͳ"}, to = {"ε" .. p[1], "ε" .. p[2], "ε" .. p[3], "ζ" .. p[1], "ι", "ι" .. p[1], "π" .. p[1], "π" .. p[2], "σ", "ϡ"} } s["itc-Latn-displaytext"] = { from = {c.caron}, to = {c.breve}, } s["itc-Latn-entryname"] = {remove_diacritics = c.macron .. c.breve .. c.diaer .. c.caron .. c.dinvbreve} s["itc-Latn-sortkey"] = { remove_diacritics = c.circ .. c.tilde .. c.macron .. c.breve .. c.diaer .. c.caron .. c.zigzag .. c.dmacron .. c.dtilde .. c.dinvbreve .. c.small_a .. c.small_e .. c.small_i .. c.small_o .. c.small_u, -- Chiefly medieval abbreviations. from = {"ᵃ", "æ", "[đꝱꟈ]", "ᵉ", "ⁱ", "ꝁ", "[ƚꝉꝲ]", "ꝳ", "ꝴ", "[ꝋᵒ]", "œ", "[ꝑꝓꝕ]", "[ꝗꝙ]", "[ꝛꝵꝶꝝ]", "[ꟊˢ]", "[ꝷᵗ]", "ᵘ", "ꝟ", "⁊"}, to = {"a", "ae", "d", "e", "i", "k", "l", "m", "n", "o", "oe", "p", "q", "r", "s", "t", "u", "v", "&"} } s["Jpan-standardchars"] = -- exclude ぢづヂヅ "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちっつてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろん" .. "ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチッツテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロン" local jpx_displaytext = { from = {"~", "="}, to = {"〜", "゠"} } s["jpx-displaytext"] = { Jpan = jpx_displaytext, Hani = jpx_displaytext, Hrkt = jpx_displaytext, Hira = jpx_displaytext, Kana = jpx_displaytext -- not Latn or Brai } s["jpx-entryname"] = s["jpx-displaytext"] s["jpx-sortkey"] = { Jpan = "Jpan-sortkey", Hani = "Hani-sortkey", Hrkt = "Hira-sortkey", -- sort general kana by normalizing to Hira Hira = "Hira-sortkey", Kana = "Kana-sortkey", Latn = {remove_diacritics = c.tilde .. c.macron .. c.diaer} } s["jpx-translit"] = { Hrkt = "Hrkt-translit", Hira = "Hrkt-translit", Kana = "Hrkt-translit" } local HaniChars = m_scripts.getByCode("Hani"):getCharacters() -- `漢字(한자)`→`漢字` -- `가-나-다`→`가나다`, `가--나--다`→`가-나-다` -- `온돌(溫突/溫堗)`→`온돌` ([[ondol]]) s["Kore-entryname"] = { remove_diacritics = u(0x302E) .. u(0x302F), from = {"([" .. HaniChars .. "])%(.-%)", "^%-", "%-$", "%-(%-?)", "\1", "%([" .. HaniChars .. "/]+%)"}, to = {"%1", "\1", "\1", "%1", "-"} } s["Lisu-sortkey"] = { from = {"𑾰"}, to = {"ꓬ" .. p[1]} } s["Mong-displaytext"] = { from = {"([ᠨ-ᡂᡸ])ᠶ([ᠨ-ᡂᡸ])", "([ᠠ-ᡂᡸ])ᠸ([^᠋ᠠ-ᠧ])", "([ᠠ-ᡂᡸ])ᠸ$"}, to = {"%1ᠢ%2", "%1ᠧ%2", "%1ᠧ"} } s["Mong-entryname"] = s["Mong-displaytext"] s["Polyt-displaytext"] = s["Grek-displaytext"] s["Polyt-entryname"] = { remove_diacritics = c.macron .. c.breve .. c.dbrevebelow, from = s["Grek-entryname"].from, to = s["Grek-entryname"].to } s["Polyt-sortkey"] = s["Grek-sortkey"] -- Samr do s["Samr-entryname"] = { remove_diacritics = c.CGJ .. u(0x0816) .. "-" .. u(0x082D), } s["Samr-sortkey"] = s["Samr-entryname"] end s["roa-oil-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'", from = {"æ", "œ", "·"}, to = {"ae", "oe", " "} } s["Tibt-displaytext"] = { from = {"ༀ", "༌", "།།", "༚༚", "༚༝", "༝༚", "༝༝", "ཷ", "ཹ", "ེེ", "ོོ"}, to = {"ཨོཾ", "་", "༎", "༛", "༟", "࿎", "༞", "ྲཱྀ", "ླཱྀ", "ཻ", "ཽ"} } s["Tibt-entryname"] = s["Tibt-displaytext"] s["wen-sortkey"] = { from = {"ch", "[lłßꞩẜ]", "dz[" .. c.caron .. c.acute .. "]", "[bcefmnoprswz][" .. c.caron .. c.acute .. c.dotabove .. "]"}, to = { "h" .. p[1], { ["l"] = "l" .. p[1], ["ł"] = "l", ["ß"] = "s", ["ꞩ"] = "š", ["ẜ"] = "š", }, { ["dz" .. c.caron] = "d" .. p[1], ["dz" .. c.acute] = "d" .. p[2] }, { ["b" .. c.acute] = "b" .. p[1], ["c" .. c.caron] = "c" .. p[1], ["c" .. c.acute] = "c" .. p[2], ["e" .. c.caron] = "e" .. p[1], ["e" .. c.dotabove] = "e" .. p[1], ["f" .. c.acute] = "f" .. p[1], ["m" .. c.acute] = "m" .. p[1], ["n" .. c.acute] = "n" .. p[1], ["o" .. c.acute] = "o" .. p[1], ["p" .. c.acute] = "p" .. p[1], ["r" .. c.caron] = "r" .. p[1], ["r" .. c.acute] = "r" .. p[2], ["s" .. c.caron] = "s" .. p[1], ["s" .. c.acute] = "s" .. p[2], ["w" .. c.acute] = "w" .. p[1], ["z" .. c.caron] = "z" .. p[1], ["z" .. c.acute] = "z" .. p[2], } } } export.shared = s -- Short-term solution to override the standard substitution process, by forcing the module to substitute the entire text in one pass, if "cont" is given. This results in any PUA characters that are used as stand-ins for formatting being handled by the language-specific substitution process, which is usually undesirable. If the value is "none" then the formatting tags do not get turned into PUA characters in the first place. -- This override is provided for languages which use formatting between strings of text which might need to interact with each other (e.g. Korean 값이 transliterates as "gaps-i", but [[값]] has the formatting '''값'''[[-이]]. The normal process would split the text at the second '''.) export.substitution = { ["gmy"] = "none", ["ja"] = "cont", ["jje"] = "cont", ["ko"] = "cont", ["ko-ear"] = "cont", ["ru"] = "cont", ["th-new"] = "cont", ["sa"] = "cont", ["zkt"] = "cont", } -- Code aliases. The left side is the alias and the right side is the canonical code. NOTE: These are gradually -- being deprecated, so should not be added to on a permanent basis. Temporary additions are permitted under reasonable -- circumstances (e.g. to facilitate changing a language's code). When an alias is no longer used, it should be removed. -- Aliases in this table are tracked at [[Wiktionary:Tracking/languages/LANG]]; see e.g. -- [[Special:WhatLinksHere/Wiktionary:Tracking/languages/RL.]] for the `RL.` alias. export.aliases = { ["EL."] = "la-ecc", ["LL."] = "la-lat", ["ML."] = "la-med", ["NL."] = "la-new", ["VL."] = "la-vul", ["nds-DE"] = "nds-de", ["nds-NL"] = "nds-nl", ["roa-oan"] = "roa-ona", ["sa-cls"] = "cls", ["sa-ved"] = "vsn", } -- Codes which are tracked. Note that all aliases listed above are also tracked, so should not be duplicated here. -- Tracking uses the same mechanism described above in the comment above `export.aliases`. export.track = { -- Codes duplicated between full and etymology-only languages. ["lzh-lit"] = true, -- Languages actively being converted to families. ["bh"] = true, -- inc-bih ["nan"] = true, -- zhx-nan } return export an2n8ocjrz3pphhn0cs35eazuj38bnp Modul:languages/data/2 828 3699 26557 24228 2026-04-10T19:19:58Z id>Swarabakti 0 26557 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared -- Ideally, we want to move these into [[Module:languages/data]], but because (a) it's necessary to use require on that module, and (b) they're only used in this data module, it's less memory-efficient to do that at the moment. If it becomes possible to use mw.loadData, then these should be moved there. s["de-Latn-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove, from = {"æ", "œ", "ß"}, to = {"ae", "oe", "ss"} } s["de-Latn-standardchars"] = "AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsẞßTtUuÜüVvWwXxYyZz" s["ka-entryname"] = {remove_diacritics = c.circ} s["no-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla, remove_exceptions = {"å"}, from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} } s["no-standardchars"] = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc s["tg-entryname"] = {remove_diacritics = c.grave .. c.acute} s["tk-entryname"] = {remove_diacritics = c.macron} local m = {} m["aa"] = { "Afar", 27811, "cus-eas", "Latn, Ethi", entry_name = { Latn = {remove_diacritics = c.acute}, }, } m["ab"] = { "Abkhaz", 5111, "cau-abz", "Cyrl, Geor, Latn", translit = { Cyrl = "ab-translit", Geor = "Geor-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"] }, entry_name = { Cyrl = { remove_diacritics = c.acute, from = {"^а%-"}, to = {"а"}, }, Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = { "х'ә", -- 3 chars "гь", "гә", "ӷь", "ҕь", "ӷә", "ҕә", "дә", "ё", "жь", "жә", "ҙә", "ӡә", "ӡ'", "кь", "кә", "қь", "қә", "ҟь", "ҟә", "ҫә", "тә", "ҭә", "ф'", "хь", "хә", "х'", "ҳә", "ць", "цә", "ц'", "ҵә", "ҵ'", "шь", "шә", "џь", -- 2 chars "ӷ", "ҕ", "ҙ", "ӡ", "қ", "ҟ", "ԥ", "ҧ", "ҫ", "ҭ", "ҳ", "ҵ", "ҷ", "ҽ", "ҿ", "ҩ", "џ", "ә", -- 1 char "^а", }, to = { "х" .. p[4], "г" .. p[1], "г" .. p[2], "г" .. p[5], "г" .. p[6], "г" .. p[7], "г" .. p[8], "д" .. p[1], "е" .. p[1], "ж" .. p[1], "ж" .. p[2], "з" .. p[2], "з" .. p[4], "з" .. p[5], "к" .. p[1], "к" .. p[2], "к" .. p[4], "к" .. p[5], "к" .. p[7], "к" .. p[8], "с" .. p[2], "т" .. p[1], "т" .. p[3], "ф" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[6], "ц" .. p[1], "ц" .. p[2], "ц" .. p[3], "ц" .. p[5], "ц" .. p[6], "ш" .. p[1], "ш" .. p[2], "ы" .. p[3], "г" .. p[3], "г" .. p[4], "з" .. p[1], "з" .. p[3], "к" .. p[3], "к" .. p[6], "п" .. p[1], "п" .. p[2], "с" .. p[1], "т" .. p[2], "х" .. p[5], "ц" .. p[4], "ч" .. p[1], "ч" .. p[2], "ч" .. p[3], "ы" .. p[1], "ы" .. p[2], "ь" .. p[1], "", } }, }, } m["ae"] = { "Avestan", 29572, "ira-cen", "Avst, Gujr", translit = { Avst = "Avst-translit" }, } m["af"] = { "Afrikaans", 14196, "gmw-frk", "Latn, Arab", ancestors = "nl", sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'", from = {"['ʼ]n"}, to = {"n" .. p[1]} } }, } m["ak"] = { "Akan", 28026, "alv-ctn", "Latn", } m["am"] = { "Amharic", 28244, "sem-eth", "Ethi", translit = "Ethi-translit", } m["an"] = { "Aragonese", 8765, "roa-nar", "Latn", } m["ar"] = { "Arab", 13955, "sem-arb", "Arab, Hebr, Syrc, Brai, Nbat", translit = { Arab = "ar-translit" }, strip_diacritics = { Arab = "ar-stripdiacritics", }, -- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]] } m["as"] = { "Assamese", 29401, "inc-bas", "as-Beng", ancestors = "inc-mas", translit = "as-translit", } m["av"] = { "Avar", 29561, "cau-ava", "Cyrl, Latn, Arab", ancestors = "oav", translit = { Cyrl = "cau-nec-translit", Arab = "ar-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"], }, entry_name = { Cyrl = s["cau-Cyrl-entryname"], Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = {"гъ", "гь", "гӏ", "ё", "кк", "къ", "кь", "кӏ", "лъ", "лӏ", "тӏ", "хх", "хъ", "хь", "хӏ", "цӏ", "чӏ"}, to = {"г" .. p[1], "г" .. p[2], "г" .. p[3], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "к" .. p[4], "л" .. p[1], "л" .. p[2], "т" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[4], "ц" .. p[1], "ч" .. p[1]} }, }, } m["ay"] = { "Aymara", 4627, "sai-aym", "Latn", } m["az"] = { "Azerbaijani", 9292, "trk-ogz", "Latn, Cyrl, fa-Arab", ancestors = "trk-oat", dotted_dotless_i = true, entry_name = { Latn = { from = {"ʼ"}, to = {"'"}, }, ["fa-Arab"] = { module = "ar-entryname", ["from"] = { "ۆ", "ۇ", "وْ", "ڲ", "ؽ", }, ["to"] = { "و", "و", "و", "گ", "ی", }, }, }, display_text = { Latn = { from = {"'"}, to = {"ʼ"} } }, sort_key = { Latn = { from = { "i", -- Ensure "i" comes after "ı". "ç", "ə", "ğ", "x", "ı", "q", "ö", "ş", "ü", "w" }, to = { "i" .. p[1], "c" .. p[1], "e" .. p[1], "g" .. p[1], "h" .. p[1], "i", "k" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1] } }, Cyrl = { from = {"ғ", "ә", "ы", "ј", "ҝ", "ө", "ү", "һ", "ҹ"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "и" .. p[2], "к" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]} }, }, } m["ba"] = { "Bashkir", 13389, "trk-kbu", "Cyrl", translit = "ba-translit", override_translit = true, sort_key = { from = {"ғ", "ҙ", "ё", "ҡ", "ң", "ө", "ҫ", "ү", "һ", "ә"}, to = {"г" .. p[1], "д" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "с" .. p[1], "у" .. p[1], "х" .. p[1], "э" .. p[1]} }, } m["be"] = { "Belarusian", 9091, "zle", "Cyrl, Latn", ancestors = "zle-mbe", translit = { Cyrl = "be-translit", }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute, }, Latn = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"Ć", "ć", "Ń", "ń", "Ś", "ś", "Ź", "ź"}, }, }, sort_key = { Cyrl = { remove_diacritics = c.grave .. c.acute, from = {"ґ", "ё", "і", "ў"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "у" .. p[1]} }, Latn = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"Ć", "ć", "Ń", "ń", "Ś", "ś", "Ź", "ź"}, from = {"ć", "č", "dz", "dź", "dž", "ch", "ł", "ń", "ś", "š", "ŭ", "ź", "ž"}, to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "d" .. p[3], "h" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]} }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзІіЙйКкЛлМмНнОоПпРрСсТтУуЎўФфХхЦцЧчШшЫыЬьЭэЮюЯя", Latn = "AaBbCcĆćČčDdEeFfGgHhIiJjKkLlŁłMmNnŃńOoPpRrSsŚśŠšTtUuŬŭVvYyZzŹźŽž", (c.punc:gsub("'", "")) -- Exclude apostrophe. }, } m["bg"] = { "Bulgarian", 7918, "zls", "Cyrl", ancestors = "cu-bgm", translit = "bg-translit", entry_name = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"}, }, sort_key = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"}, }, standardChars = "АаБбВвГгДдЕеЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЬьЮюЯя" .. c.punc, } m["bh"] = { "Bihari", 135305, "inc-eas", "Deva", } m["bi"] = { "Bislama", 35452, "crp", "Latn", ancestors = "en", } m["bm"] = { "Bambara", 33243, "dmn-emn", "Latn, Nkoo", sort_key = { Latn = { from = {"ɛ", "ɲ", "ŋ", "ɔ"}, to = {"e" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1]} }, }, } m["bn"] = { "Bengali", 9610, "inc-bas", "Beng, Newa", ancestors = "inc-mbn", translit = { Beng = "bn-translit" }, } m["bo"] = { "Tibetan", 34271, "sit-tib", "Tibt", -- sometimes Deva? ancestors = "xct", translit = "Tibt-translit", override_translit = true, display_text = s["Tibt-displaytext"], entry_name = s["Tibt-entryname"], sort_key = "Tibt-sortkey", } m["br"] = { "Breton", 12107, "cel-brs", "Latn", ancestors = "xbm", sort_key = { from = {"ch", "c['ʼ’]h"}, to = {"c" .. p[1], "c" .. p[2]} }, } m["ca"] = { "Catalan", 7026, "roa-ocr", "Latn", ancestors = "roa-oca", sort_key = {remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla .. "·"}, standardChars = "AaÀàBbCcÇçDdEeÉéÈèFfGgHhIiÍíÏïJjLlMmNnOoÓóÒòPpQqRrSsTtUuÚúÜüVvXxYyZz·" .. c.punc, } m["ce"] = { "Chechen", 33350, "cau-vay", "Cyrl, Latn, Arab", translit = { Cyrl = "cau-nec-translit", Arab = "ar-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"] }, entry_name = { Cyrl = s["cau-Cyrl-entryname"], Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = {"аь", "гӏ", "ё", "кх", "къ", "кӏ", "оь", "пӏ", "тӏ", "уь", "хь", "хӏ", "цӏ", "чӏ", "юь", "яь"}, to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "о" .. p[1], "п" .. p[1], "т" .. p[1], "у" .. p[1], "х" .. p[1], "х" .. p[2], "ц" .. p[1], "ч" .. p[1], "ю" .. p[1], "я" .. p[1]} }, }, } m["ch"] = { "Chamorro", 33262, "poz", "Latn", sort_key = { remove_diacritics = "'", from = {"å", "ch", "ñ", "ng"}, to = {"a" .. p[1], "c" .. p[1], "n" .. p[1], "n" .. p[2]} }, } m["co"] = { "Corsican", 33111, "roa-itr", "Latn", sort_key = { from = {"chj", "ghj", "sc", "sg"}, to = {"c" .. p[1], "g" .. p[1], "s" .. p[1], "s" .. p[2]} }, standardChars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìÏïJjLlMmNnOoÒòPpQqRrSsTtUuÙùÜüVvZz" .. c.punc, } m["cr"] = { "Cree", 33390, "alg", "Latn, Cans", translit = { Cans = "cr-translit" }, } m["cs"] = { "Czech", 9056, "zlw", "Latn", ancestors = "cs-ear", sort_key = { from = {"á", "č", "ď", "é", "ě", "ch", "í", "ň", "ó", "ř", "š", "ť", "ú", "ů", "ý", "ž"}, to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "h" .. p[1], "i" .. p[1], "n" .. p[1], "o" .. p[1], "r" .. p[1], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "y" .. p[1], "z" .. p[1]} }, standardChars = "AaÁáBbCcČčDdĎďEeÉéĚěFfGgHhIiÍíJjKkLlMmNnŇňOoÓóPpRrŘřSsŠšTtŤťUuÚúŮůVvYyÝýZzŽž" .. c.punc, } m["cu"] = { "Old Church Slavonic", 35499, "zls", "Cyrs, Glag, Zname", translit = { Cyrs = "Cyrs-translit", Glag = "Glag-translit" }, entry_name = { Cyrs = s["Cyrs-entryname"] }, sort_key = { Cyrs = s["Cyrs-sortkey"] }, } m["cv"] = { "Chuvash", 33348, "trk-ogr", "Cyrl", ancestors = "cv-mid", translit = "cv-translit", override_translit = true, sort_key = { from = {"ӑ", "ё", "ӗ", "ҫ", "ӳ"}, to = {"а" .. p[1], "е" .. p[1], "е" .. p[2], "с" .. p[1], "у" .. p[1]} }, } m["cy"] = { "Welsh", 9309, "cel-brw", "Latn", ancestors = "wlm", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. "'", from = {"ch", "dd", "ff", "ng", "ll", "ph", "rh", "th"}, to = {"c" .. p[1], "d" .. p[1], "f" .. p[1], "g" .. p[1], "l" .. p[1], "p" .. p[1], "r" .. p[1], "t" .. p[1]} }, standardChars = "ÂâAaBbCcDdEeÊêFfGgHhIiÎîLlMmNnOoÔôPpRrSsTtUuÛûWwŴŵYyŶŷ" .. c.punc, } m["da"] = { "Danish", 9035, "gmq-eas", "Latn", ancestors = "gmq-oda", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla, remove_exceptions = {"å"}, from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc, } m["de"] = { "German", 188, "gmw-hgm", "Latn, Latf, Brai", ancestors = "de-ear", sort_key = { Latn = s["de-Latn-sortkey"], Latf = s["de-Latn-sortkey"], }, standardChars = { Latn = s["de-Latn-standardchars"], Latf = s["de-Latn-standardchars"], Brai = c.braille, c.punc } } m["dv"] = { "Dhivehi", 32656, "inc-ins", "Thaa, Diak", translit = { Thaa = "dv-translit", Diak = "Diak-translit", }, override_translit = true, } m["dz"] = { "Dzongkha", 33081, "sit-tib", "Tibt", ancestors = "xct", translit = "Tibt-translit", override_translit = true, display_text = s["Tibt-displaytext"], entry_name = s["Tibt-entryname"], sort_key = "Tibt-sortkey", } m["ee"] = { "Ewe", 30005, "alv-gbe", "Latn", sort_key = { remove_diacritics = c.tilde, from = {"ɖ", "dz", "ɛ", "ƒ", "gb", "ɣ", "kp", "ny", "ŋ", "ɔ", "ts", "ʋ"}, to = {"d" .. p[1], "d" .. p[2], "e" .. p[1], "f" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "t" .. p[1], "v" .. p[1]} }, } m["el"] = { "Greek", 9129, "grk", "Grek, Polyt, Brai", ancestors = "el-kth", translit = "el-translit", override_translit = true, display_text = { Grek = s["Grek-displaytext"], Polyt = s["Polyt-displaytext"], }, entry_name = { Grek = s["Grek-entryname"], Polyt = s["Polyt-entryname"], }, sort_key = { Grek = s["Grek-sortkey"], Polyt = s["Polyt-sortkey"], }, standardChars = { Grek = "΅·ͺ΄ΑαΆάΒβΓγΔδΕεέΈΖζΗηΉήΘθΙιΊίΪϊΐΚκΛλΜμΝνΞξΟοΌόΠπΡρΣσςΤτΥυΎύΫϋΰΦφΧχΨψΩωΏώ", Brai = c.braille, c.punc }, } m["en"] = { "English", 1860, "gmw-ang", "Latn, Brai, Shaw, Dsrt", -- entries in Shaw or Dsrt might require prior discussion wikimedia_codes = "en, simple", ancestors = "en-ear", sort_key = { Latn = { -- Many of these are needed for sorting language names. remove_diacritics = "'\"%-%.,%s·ʻʼ" .. c.diacritics, -- These are found in entry names. from = {"[ɒæ🅱¢©ᴄðđəǝɜɡħʜıɨłŋɲøɔœꝑꝓꝕßʋ]"}, to = {{ ["ɒ"] = "a", ["æ"] = "ae", ["🅱"] = "b", ["¢"] = "c", ["©"] = "c", ["ᴄ"] = "c", ["ð"] = "d", ["đ"] = "d", ["ə"] = "e", ["ǝ"] = "e", ["ɜ"] = "e", ["ɡ"] = "g", ["ħ"] = "h", ["ʜ"] = "h", ["ı"] = "i", ["ɨ"] = "i", ["ł"] = "l", ["ŋ"] = "n", ["ɲ"] = "n", ["ø"] = "o", ["ɔ"] = "o", ["œ"] = "oe", ["ꝑ"] = "p", ["ꝓ"] = "p", ["ꝕ"] = "p", ["ß"] = "ss", ["ʋ"] = "v", }}, }, }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", Brai = c.braille, c.punc }, } m["eo"] = { "Esperanto", 143, "art", "Latn", sort_key = { remove_diacritics = c.grave .. c.acute, from = {"ĉ", "ĝ", "ĥ", "ĵ", "ŝ", "ŭ"}, to = {"c" .. p[1], "g" .. p[1], "h" .. p[1], "j" .. p[1], "s" .. p[1], "u" .. p[1]} }, standardChars = "AaBbCcĈĉDdEeFfGgĜĝHhĤĥIiJjĴĵKkLlMmNnOoPpRrSsŜŝTtUuŬŭVvZz" .. c.punc, } m["es"] = { "Spanish", 1321, "roa-cas", "Latn, Brai", ancestors = "es-ear", sort_key = { Latn = { remove_exceptions = {"ñ"}, remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla, from = {"ª", "æ", "ñ", "º", "œ"}, to = {"a", "ae", "n" .. p[1], "o", "oe"} }, }, standardChars = { Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxYyZz", Brai = c.braille, c.punc }, } m["et"] = { "Estonian", 9072, "urj-fin", "Latn", sort_key = { from = { "š", "ž", "õ", "ä", "ö", "ü", -- 2 chars "z" -- 1 char }, to = { "s" .. p[1], "s" .. p[3], "w" .. p[1], "w" .. p[2], "w" .. p[3], "w" .. p[4], "s" .. p[2] } }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvÕõÄäÖöÜü" .. c.punc, } m["eu"] = { "Basque", 8752, "euq", "Latn", sort_key = { from = {"ç", "ñ"}, to = {"c" .. p[1], "n" .. p[1]} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnÑñOoPpRrSsTtUuXxZz" .. c.punc, } m["fa"] = { "Persian", 9168, "ira-swi", "fa-Arab, Hebr", ancestors = "fa-cls", display_text = { Hebr = "Hebr-common", }, entry_name = { ["fa-Arab"] = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ٱ"}, -- character "ۂ" code U+06C2 to "ه"; hamzatu l-waṣli to a regular alif to = {"ه", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, }, Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["ff"] = { "Fula", 33454, "alv-fwo", "Latn, Adlm", } m["fi"] = { "Finnish", 1412, "urj-fin", "Latn", display_text = { from = {"'"}, to = {"’"} }, entry_name = { -- used to indicate gemination of the next consonant remove_diacritics = "ˣ", from = {"’"}, to = {"'"}, }, sort_key = { -- [[Appendix:Finnish alphabet#Collation]] + "aͤ" and "oͤ" as historical variants of "ä" and "ö". remove_diacritics = "'’:" .. c.diacritics, remove_exceptions = { "a[" .. c.ringabove .. c.diaer .. c.small_e .. "]", -- åäaͤ "o[" .. c.diaer .. c.tilde .. c.dacute .. c.small_e .. "]", -- öõőoͤ "u[" .. c.diaer .. c.dacute .. "]" -- üű }, from = {"æ", "[ðđ]", "ł", "ŋ", "œ", "ß", "þ", "u[" .. c.diaer .. c.dacute .. "]", "å", "aͤ", "o[" .. c.tilde .. c.dacute .. c.small_e .. "]", "ø", "(.)['%-]"}, to = {"ae", "d", "l", "n", "oe", "ss", "th", "y", "z" .. p[1], "ä", "ö", "ö", "%1"} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÄäÖö" .. c.punc, } m["fj"] = { "Fijian", 33295, "poz-pcc", "Latn", } m["fo"] = { "Faroese", 25258, "gmq-ins", "Latn", sort_key = { from = {"á", "ð", "í", "ó", "ú", "ý", "æ", "ø"}, to = {"a" .. p[1], "d" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2]} }, standardChars = "AaÁáBbDdÐðEeFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvYyÝýÆæØø" .. c.punc, } m["fr"] = { "French", 150, "roa-oil", "Latn, Brai", ancestors = "frm", sort_key = { Latn = s["roa-oil-sortkey"] }, standardChars = { Latn = "AaÀàÂâBbCcÇçDdEeÉéÈèÊêËëFfGgHhIiÎîÏïJjLlMmNnOoÔôŒœPpQqRrSsTtUuÙùÛûÜüVvXxYyZz", Brai = c.braille, c.punc }, } m["fy"] = { "West Frisian", 27175, "gmw-fri", "Latn", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer, from = {"y"}, to = {"i"} }, standardChars = "AaâäàÆæBbCcDdEeéêëèFfGgHhIiïìYyỳJjKkLlMmNnOoôöòPpRrSsTtUuúûüùVvWwZz" .. c.punc, } m["ga"] = { "Irish", 9142, "cel-gae", "Latn, Latg", ancestors = "mga", sort_key = { remove_diacritics = c.acute, from = {"ḃ", "ċ", "ḋ", "ḟ", "ġ", "ṁ", "ṗ", "ṡ", "ṫ"}, to = {"bh", "ch", "dh", "fh", "gh", "mh", "ph", "sh", "th"} }, standardChars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíLlMmNnOoÓóPpRrSsTtUuÚúVv" .. c.punc, } m["gd"] = { "Scottish Gaelic", 9314, "cel-gae", "Latn, Latg", ancestors = "mga", sort_key = {remove_diacritics = c.grave .. c.acute}, standardChars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìLlMmNnOoÒòPpRrSsTtUuÙù" .. c.punc, } m["gl"] = { "Galician", 9307, "roa-gap", "Latn", sort_key = { remove_diacritics = c.acute, from = {"ñ"}, to = {"n" .. p[1]} }, standardChars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíÏïLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxZz" .. c.punc, } m["gn"] = { "Guaraní", 35876, "tup-gua", "Latn", } m["gu"] = { "Gujarati", 5137, "inc-wes", "Arab, Gujr", ancestors = "inc-mgu", translit = { Gujr = "gu-translit", }, entry_name = { Arab = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.kasra .. c.shadda .. c.sukun}, Gujr = {remove_diacritics = "઼"}, }, } m["gv"] = { "Manx", 12175, "cel-gae", "Latn", ancestors = "mga", sort_key = {remove_diacritics = c.cedilla .. "-"}, standardChars = "AaBbCcÇçDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwYy" .. c.punc, } m["ha"] = { "Hausa", 56475, "cdc-wst", "Latn, Arab", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron} }, sort_key = { Latn = { from = {"ɓ", "b'", "ɗ", "d'", "ƙ", "k'", "sh", "ƴ", "'y"}, to = {"b" .. p[1], "b" .. p[2], "d" .. p[1], "d" .. p[2], "k" .. p[1], "k" .. p[2], "s" .. p[1], "y" .. p[1], "y" .. p[2]} }, }, } m["he"] = { "Hebrew", 9288, "sem-can", "Hebr, Phnx, Brai, Samr", ancestors = "he-med", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", Samr = s["Samr-entryname"], }, sort_key = { Hebr = "Hebr-common", Samr = s["Samr-sortkey"], }, } m["hi"] = { "Hindi", 1568, "inc-hnd", "Deva, Kthi, Newa", translit = { Deva = "hi-translit" }, standardChars = { Deva = "अआइईउऊएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलवशषसहत्रज्ञक्षक़ख़ग़ज़झ़ड़ढ़फ़काखागाघाङाचाछाजाझाञाटाठाडाढाणाताथादाधानापाफाबाभामायारालावाशाषासाहात्राज्ञाक्षाक़ाख़ाग़ाज़ाझ़ाड़ाढ़ाफ़ाकिखिगिघिङिचिछिजिझिञिटिठिडिढिणितिथिदिधिनिपिफिबिभिमियिरिलिविशिषिसिहित्रिज्ञिक्षिक़िख़िग़िज़िझ़िड़िढ़िफ़िकीखीगीघीङीचीछीजीझीञीटीठीडीढीणीतीथीदीधीनीपीफीबीभीमीयीरीलीवीशीषीसीहीत्रीज्ञीक्षीक़ीख़ीग़ीज़ीझ़ीड़ीढ़ीफ़ीकुखुगुघुङुचुछुजुझुञुटुठुडुढुणुतुथुदुधुनुपुफुबुभुमुयुरुलुवुशुषुसुहुत्रुज्ञुक्षुक़ुख़ुग़ुज़ुझ़ुड़ुढ़ुफ़ुकूखूगूघूङूचूछूजूझूञूटूठूडूढूणूतूथूदूधूनूपूफूबूभूमूयूरूलूवूशूषूसूहूत्रूज्ञूक्षूक़ूख़ूग़ूज़ूझ़ूड़ूढ़ूफ़ूकेखेगेघेङेचेछेजेझेञेटेठेडेढेणेतेथेदेधेनेपेफेबेभेमेयेरेलेवेशेषेसेहेत्रेज्ञेक्षेक़ेख़ेग़ेज़ेझ़ेड़ेढ़ेफ़ेकैखैगैघैङैचैछैजैझैञैटैठैडैढैणैतैथैदैधैनैपैफैबैभैमैयैरैलैवैशैषैसैहैत्रैज्ञैक्षैक़ैख़ैग़ैज़ैझ़ैड़ैढ़ैफ़ैकोखोगोघोङोचोछोजोझोञोटोठोडोढोणोतोथोदोधोनोपोफोबोभोमोयोरोलोवोशोषोसोहोत्रोज्ञोक्षोक़ोख़ोग़ोज़ोझ़ोड़ोढ़ोफ़ोकौखौगौघौङौचौछौजौझौञौटौठौडौढौणौतौथौदौधौनौपौफौबौभौमौयौरौलौवौशौषौसौहौत्रौज्ञौक्षौक़ौख़ौग़ौज़ौझ़ौड़ौढ़ौफ़ौक्ख्ग्घ्ङ्च्छ्ज्झ्ञ्ट्ठ्ड्ढ्ण्त्थ्द्ध्न्प्फ्ब्भ्म्य्र्ल्व्श्ष्स्ह्त्र्ज्ञ्क्ष्क़्ख़्ग़्ज़्झ़्ड़्ढ़्फ़्।॥०१२३४५६७८९॰", c.punc }, } m["ho"] = { "Hiri Motu", 33617, "crp", "Latn", ancestors = "meu", } m["ht"] = { "Haitian Creole", 33491, "crp", "Latn", ancestors = "ht-sdm", sort_key = { from = { "oun", -- 3 chars "an", "ch", "è", "en", "ng", "ò", "on", "ou", "ui" -- 2 chars }, to = { "o" .. p[4], "a" .. p[1], "c" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "u" .. p[1] } }, } m["hu"] = { "Hungarian", 9067, "urj-ugr", "Latn, Hung", ancestors = "ohu", sort_key = { Latn = { from = { "dzs", -- 3 chars "á", "cs", "dz", "é", "gy", "í", "ly", "ny", "ó", "ö", "ő", "sz", "ty", "ú", "ü", "ű", "zs", -- 2 chars }, to = { "d" .. p[2], "a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "u" .. p[3], "z" .. p[1], } }, }, standardChars = { Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóÖöŐőPpQqRrSsTtUuÚúÜüŰűVvWwXxYyZz", c.punc }, } m["hy"] = { "Armenian", 8785, "hyx", "Armn, Brai", ancestors = "axm", translit = { Armn = "Armn-translit" }, override_translit = true, entry_name = { Armn = { remove_diacritics = "՛՜՞՟", from = {"եւ", "<sup>յ</sup>", "<sup>ի</sup>", "<sup>է</sup>", "յ̵", "ՙ", "՚"}, to = {"և", "յ", "ի", "է", "ֈ", "ʻ", "’"} }, }, sort_key = { Armn = { from = { "ու", "եւ", -- 2 chars "և" -- 1 char }, to = { "ւ", "եվ", "եվ" } }, }, } m["hz"] = { "Herero", 33315, "bnt-swb", "Latn", } m["ia"] = { "Interlingua", 35934, "art", "Latn", } m["id"] = { "Indonesian", 9240, "poz-mly", "Latn", ancestors = "ms", standardChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" .. c.punc, } m["ie"] = { "Interlingue", 35850, "art", "Latn", type = "appendix-constructed", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ}, } m["ig"] = { "Igbo", 33578, "alv-igb", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.macron}, sort_key = { from = {"gb", "gh", "gw", "ị", "kp", "kw", "ṅ", "nw", "ny", "ọ", "sh", "ụ"}, to = {"g" .. p[1], "g" .. p[2], "g" .. p[3], "i" .. p[1], "k" .. p[1], "k" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "o" .. p[1], "s" .. p[1], "u" .. p[1]} }, } m["ii"] = { "Nuosu", 34235, "tbq-nlo", "Yiii", translit = "ii-translit", } m["ik"] = { "Inupiaq", 27183, "esx-inu", "Latn", sort_key = { from = { "ch", "ġ", "dj", "ḷ", "ł̣", "ñ", "ng", "r̂", "sr", "zr", -- 2 chars "ł", "ŋ", "ʼ" -- 1 char }, to = { "c" .. p[1], "g" .. p[1], "h" .. p[1], "l" .. p[1], "l" .. p[3], "n" .. p[1], "n" .. p[2], "r" .. p[1], "s" .. p[1], "z" .. p[1], "l" .. p[2], "n" .. p[2], "z" .. p[2] } }, } m["io"] = { "Ido", 35224, "art", "Latn", } m["is"] = { "Icelandic", 294, "gmq-ins", "Latn", sort_key = { from = {"á", "ð", "é", "í", "ó", "ú", "ý", "þ", "æ", "ö"}, to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2], "z" .. p[3]} }, standardChars = "AaÁáBbDdÐðEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvXxYyÝýÞþÆæÖö" .. c.punc, } m["it"] = { "Italian", 652, "roa-itr", "Latn", ancestors = "roa-oit", sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove}, standardChars = "AaÀàBbCcDdEeÈèÉéFfGgHhIiÌìLlMmNnOoÒòPpQqRrSsTtUuÙùVvZz" .. c.punc, } m["iu"] = { "Inuktitut", 29921, "esx-inu", "Cans, Latn", translit = { Cans = "cr-translit" }, override_translit = true, } m["ja"] = { "Japanese", 5287, "jpx", "Jpan, Latn, Brai", ancestors = "ja-ear", translit = s["jpx-translit"], link_tr = true, display_text = s["jpx-displaytext"], entry_name = s["jpx-entryname"], sort_key = s["jpx-sortkey"], } m["jv"] = { "Javanese", 33549, "poz", "Latn, Java, Arab", ancestors = "kaw", translit = { Java = "jv-translit" }, link_tr = true, entry_name = { Latn = {remove_diacritics = c.circ} -- Modern jv don't use ê }, sort_key = { Latn = { from = {"å", "dh", "é", "è", "ng", "ny", "th"}, to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "n" .. p[2], "t" .. p[1]} }, }, } m["ka"] = { "Georgian", 8108, "ccs-gzn", "Geor, Geok, Hebr", -- Hebr is used to write Judeo-Georgian ancestors = "ka-mid", translit = { Geor = "Geor-translit", Geok = "Geok-translit", }, override_translit = true, display_text = { Hebr = "Hebr-common", }, entry_name = { Geor = s["ka-entryname"], Geok = s["ka-entryname"], Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", } } m["kg"] = { "Kongo", 33702, "bnt-kng", "Latn", } m["ki"] = { "Kikuyu", 33587, "bnt-kka", "Latn", } m["kj"] = { "Kwanyama", 1405077, "bnt-ova", "Latn", } m["kk"] = { "Kazakh", 9252, "trk-kno", "Cyrl, Latn, kk-Arab", translit = { Cyrl = { from = { "Ё", "ё", "Й", "й", "Нг", "нг", "Ӯ", "ӯ", -- 2 chars; are "Ӯ" and "ӯ" actually used? "А", "а", "Ә", "ә", "Б", "б", "В", "в", "Г", "г", "Ғ", "ғ", "Д", "д", "Е", "е", "Ж", "ж", "З", "з", "И", "и", "К", "к", "Қ", "қ", "Л", "л", "М", "м", "Н", "н", "Ң", "ң", "О", "о", "Ө", "ө", "П", "п", "Р", "р", "С", "с", "Т", "т", "У", "у", "Ұ", "ұ", "Ү", "ү", "Ф", "ф", "Х", "х", "Һ", "һ", "Ц", "ц", "Ч", "ч", "Ш", "ш", "Щ", "щ", "Ъ", "ъ", "Ы", "ы", "І", "і", "Ь", "ь", "Э", "э", "Ю", "ю", "Я", "я", -- 1 char }, to = { "E", "e", "İ", "i", "Ñ", "ñ", "U", "u", "A", "a", "Ä", "ä", "B", "b", "V", "v", "G", "g", "Ğ", "ğ", "D", "d", "E", "e", "J", "j", "Z", "z", "İ", "i", "K", "k", "Q", "q", "L", "l", "M", "m", "N", "n", "Ñ", "ñ", "O", "o", "Ö", "ö", "P", "p", "R", "r", "S", "s", "T", "t", "U", "u", "Ū", "ū", "Ü", "ü", "F", "f", "X", "x", "H", "h", "S", "s", "Ç", "ç", "Ş", "ş", "Ş", "ş", "", "", "Y", "y", "I", "ı", "", "", "É", "é", "Ü", "ü", "Ä", "ä", } } }, -- override_translit = true, sort_key = { Cyrl = { from = {"ә", "ғ", "ё", "қ", "ң", "ө", "ұ", "ү", "һ", "і"}, to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "у" .. p[2], "х" .. p[1], "ы" .. p[1]} }, }, standardChars = { Cyrl = "АаӘәБбВвГгҒғДдЕеЁёЖжЗзИиЙйКкҚқЛлМмНнҢңОоӨөПпРрСсТтУуҰұҮүФфХхҺһЦцЧчШшЩщЪъЫыІіЬьЭэЮюЯя", c.punc }, } m["kl"] = { "Greenlandic", 25355, "esx-inu", "Latn", sort_key = { from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} } } m["km"] = { "Khmer", 9205, "mkh-kmr", "Khmr", ancestors = "xhm", translit = "km-translit", } m["kn"] = { "Kannada", 33673, "dra-kan", "Knda, Tutg", ancestors = "dra-mkn", translit = { Knda = "kn-translit", }, } m["ko"] = { "Korean", 9176, "qfa-kor", "Kore, Brai", ancestors = "ko-ear", translit = { Kore = "ko-translit", }, entry_name = { Kore = s["Kore-entryname"], }, } m["kr"] = { "Kanuri", 36094, "ssa-sah", "Latn, Arab", -- the sortkey and entry_name are only for standard Kanuri; when dialectal entries get added, someone will have to work out how the dialects should be represented orthographically entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.breve} }, sort_key = { Latn = { from = {"ǝ", "ny", "ɍ", "sh"}, to = {"e" .. p[1], "n" .. p[1], "r" .. p[1], "s" .. p[1]} }, }, } m["ks"] = { "Kashmiri", 33552, "inc-kas", "ks-Arab, Deva, Shrd, Latn", translit = { ["ks-Arab"] = "ks-Arab-translit", Deva = "ks-Deva-translit", Shrd = "Shrd-translit", }, } -- "kv" IS TREATED AS "koi", "kpv", SEE WT:LT m["kw"] = { "Cornish", 25289, "cel-brs", "Latn", ancestors = "cnx", sort_key = { from = {"ch"}, to = {"c" .. p[1]} }, } m["ky"] = { "Kyrgyz", 9255, "trk-kkp", "Cyrl, Latn, Arab", translit = { Cyrl = "ky-translit" }, override_translit = true, sort_key = { Cyrl = { from = {"ё", "ң", "ө", "ү"}, to = {"е" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1]} }, }, } m["la"] = { "Latin", 397, "itc-laf", "Latn, Ital", ancestors = "itc-ola", display_text = { Latn = s["itc-Latn-displaytext"] }, entry_name = { Latn = s["itc-Latn-entryname"] }, sort_key = { Latn = s["itc-Latn-sortkey"] }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiLlMmNnOoPpQqRrSsTtUuVvXx", c.punc }, } m["lb"] = { "Luxembourgish", 9051, "gmw-hgm", "Latn, Brai", ancestors = "gmw-cfr", sort_key = { Latn = { from = {"ä", "ë", "é"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} }, }, } m["lg"] = { "Luganda", 33368, "bnt-nyg", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ}, sort_key = { from = {"ŋ"}, to = {"n" .. p[1]} }, } m["li"] = { "Limburgish", 102172, "gmw-frk", "Latn", ancestors = "dum", } m["ln"] = { "Lingala", 36217, "bnt-bmo", "Latn", sort_key = { remove_diacritics = c.acute .. c.circ .. c.caron, from = {"ɛ", "gb", "mb", "mp", "nd", "ng", "nk", "ns", "nt", "ny", "nz", "ɔ"}, to = {"e" .. p[1], "g" .. p[1], "m" .. p[1], "m" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "n" .. p[4], "n" .. p[5], "n" .. p[6], "n" .. p[7], "o" .. p[1]} }, } m["lo"] = { "Lao", 9211, "tai-swe", "Laoo", translit = "lo-translit", sort_key = "Laoo-sortkey", standardChars = "0-9ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮຯ-ໝ" .. c.punc, } m["lt"] = { "Lithuanian", 9083, "bat-eas", "Latn", ancestors = "olt", display_text = "lt-common", entry_name = "lt-common", sort_key = "lt-common", standardChars = "AaĄąBbCcČčDdEeĘęĖėFfGgHhIiĮįYyJjKkLlMmNnOoPpRrSsŠšTtUuŲųŪūVvZzŽž" .. c.punc, } m["lu"] = { "Luba-Katanga", 36157, "bnt-lub", "Latn", } m["lv"] = { "Latvian", 9078, "bat-eas", "Latn", entry_name = { -- This attempts to convert vowels with tone marks to vowels either with or without macrons. Specifically, there should be no macrons if the vowel is part of a diphthong (including resonant diphthongs such pìrksts -> pirksts not #pīrksts). What we do is first convert the vowel + tone mark to a vowel + tilde in a decomposed fashion, then remove the tilde in diphthongs, then convert the remaining vowel + tilde sequences to macroned vowels, then delete any other tilde. We leave already-macroned vowels alone: Both e.g. ar and ār occur before consonants. FIXME: This still might not be sufficient. from = {"([Ee])" .. c.cedilla, "[" .. c.grave .. c.circ .. c.tilde .."]", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .. "?([^aAeEiIoOuU])", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .."?$", "([iI])" .. c.tilde .. "?([eE])" .. c.tilde .. "?", "([aAeEiIuU])" .. c.tilde, c.tilde}, to = {"%1", c.tilde, "%1%2%3", "%1%2", "%1%2", "%1" .. c.macron} }, sort_key = { from = {"ā", "č", "ē", "ģ", "ī", "ķ", "ļ", "ņ", "š", "ū", "ž"}, to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1]} }, standardChars = "AaĀāBbCcČčDdEeĒēFfGgĢģHhIiĪīJjKkĶķLlĻļMmNnŅņOoPpRrSsŠšTtUuŪūVvZzŽž" .. c.punc, } m["mg"] = { "Malagasy", 7930, "poz-bre", "Latn, Arab", } m["mh"] = { "Marshallese", 36280, "poz-mic", "Latn", sort_key = { from = {"ā", "ļ", "m̧", "ņ", "n̄", "o̧", "ō", "ū"}, to = {"a" .. p[1], "l" .. p[1], "m" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "u" .. p[1]} }, } m["mi"] = { "Maori", 36451, "poz-pep", "Latn", sort_key = { remove_diacritics = c.macron, from = {"ng", "wh"}, to = {"n" .. p[1], "w" .. p[1]} }, } m["mk"] = { "Macedonian", 9296, "zls", "Cyrl, Polyt", ancestors = "cu", translit = { Cyrl = "mk-translit" }, display_text = { Polyt = s["Polyt-displaytext"] }, entry_name = { Cyrl = { remove_diacritics = c.acute, remove_exceptions = {"Ѓ", "ѓ", "Ќ", "ќ"} }, Polyt = s["Polyt-entryname"], }, sort_key = { Cyrl = { remove_diacritics = c.grave, remove_exceptions = {"ѓ", "ќ"}, from = {"ѓ", "ѕ", "ј", "љ", "њ", "ќ", "џ"}, to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "т" .. p[1], "ч" .. p[1]} }, Polyt = s["Polyt-sortkey"], }, standardChars = { Cyrl = "АаБбВвГгДдЃѓЕеЖжЗзЅѕИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЌќУуФфХхЦцЧчЏџШш", c.punc }, } m["ml"] = { "Malayalam", 36236, "dra-mal", "Mlym", translit = "ml-translit", override_translit = true, } m["mn"] = { "Mongolian", 9246, "xgn-cen", "Cyrl, Mong, Latn, Brai", ancestors = "cmg", translit = { Cyrl = "mn-translit", Mong = "Mong-translit", }, override_translit = true, display_text = { Mong = s["Mong-displaytext"] }, entry_name = { Cyrl = {remove_diacritics = c.grave .. c.acute}, Mong = s["Mong-entryname"], }, sort_key = { Cyrl = { remove_diacritics = c.grave, from = {"ё", "ө", "ү"}, to = {"е" .. p[1], "о" .. p[1], "у" .. p[1]} }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйЛлМмНнОоӨөРрСсТтУуҮүХхЦцЧчШшЫыЬьЭэЮюЯя—", Brai = c.braille, c.punc }, } -- "mo" IS TREATED AS "ro", SEE WT:LT m["mr"] = { "Marathi", 1571, "inc-sou", "Deva, Modi", ancestors = "omr", translit = { Deva = "mr-translit", Modi = "mr-Modi-translit", }, entry_name = { Deva = { from = {"च़", "ज़", "झ़"}, to = {"च", "ज", "झ"} }, }, } m["ms"] = { "Malay", 9237, "poz-mly", "Latn, ms-Arab", ancestors = "ms-cla", standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", c.punc }, } m["mt"] = { "Maltese", 9166, "sem-arb", "Latn", display_text = { from = {"'"}, to = {"’"} }, entry_name = { from = {"’"}, to = {"'"}, }, ancestors = "sqr", sort_key = { from = { "ċ", "ġ", "ż", -- Convert into PUA so that decomposed form does not get caught by the next step. "([cgz])", -- Ensure "c" comes after "ċ", "g" comes after "ġ" and "z" comes after "ż". "g" .. p[1] .. "ħ", -- "għ" after initial conversion of "g". p[3], p[4], "ħ", "ie", p[5] -- Convert "ċ", "ġ", "ħ", "ie", "ż" into final output. }, to = { p[3], p[4], p[5], "%1" .. p[1], "g" .. p[2], "c", "g", "h" .. p[1], "i" .. p[1], "z" } }, } m["my"] = { "Burmese", 9228, "tbq-brm", "Mymr", ancestors = "obr", translit = "my-translit", override_translit = true, sort_key = { from = {"ျ", "ြ", "ွ", "ှ", "ဿ"}, to = {"္ယ", "္ရ", "္ဝ", "္ဟ", "သ္သ"} }, } m["na"] = { "Nauruan", 13307, "poz-mic", "Latn", } m["nb"] = { "Norwegian Bokmål", 25167, "gmq", "Latn", wikimedia_codes = "no", ancestors = "gmq-mno, da", -- da as an (but not the) ancestor of nb was agreed on - do not change without discussion sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["nd"] = { "Northern Ndebele", 35613, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["ne"] = { "Nepali", 33823, "inc-pah", "Deva, Newa", translit = { Deva = "ne-translit" }, } m["ng"] = { "Ndonga", 33900, "bnt-ova", "Latn", } m["nl"] = { "Dutch", 7411, "gmw-frk", "Latn, Brai", ancestors = "dum", sort_key = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'"}, }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", Brai = c.braille, c.punc }, } m["nn"] = { "Norwegian Nynorsk", 25164, "gmq-wes", "Latn", ancestors = "gmq-mno", entry_name = { remove_diacritics = c.grave .. c.acute, }, sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["no"] = { "Norwegian", 9043, "gmq-wes", "Latn", ancestors = "gmq-mno", sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["nr"] = { "Southern Ndebele", 36785, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["nv"] = { "Navajo", 13310, "apa", "Latn, Brai", sort_key = { remove_diacritics = c.acute .. c.ogonek, from = { "chʼ", "tłʼ", "tsʼ", -- 3 chars "ch", "dl", "dz", "gh", "hw", "kʼ", "kw", "sh", "tł", "ts", "zh", -- 2 chars "ł", "ʼ" -- 1 char }, to = { "c" .. p[2], "t" .. p[2], "t" .. p[4], "c" .. p[1], "d" .. p[1], "d" .. p[2], "g" .. p[1], "h" .. p[1], "k" .. p[1], "k" .. p[2], "s" .. p[1], "t" .. p[1], "t" .. p[3], "z" .. p[1], "l" .. p[1], "z" .. p[2] } }, } m["ny"] = { "Chichewa", 33273, "bnt-nys", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ}, sort_key = { from = {"ng'"}, to = {"ng"} }, } m["oc"] = { "Occitan", 14185, "roa-ocr", "Latn, Hebr", ancestors = "pro", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla, from = {"([lns])·h"}, to = {"%1h"} }, Hebr = "Hebr-common", }, } m["oj"] = { "Ojibwe", 33875, "alg", "Cans, Latn", sort_key = { Latn = { from = {"aa", "ʼ", "ii", "oo", "sh", "zh"}, to = {"a" .. p[1], "h" .. p[1], "i" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1]} }, }, } m["om"] = { "Oromo", 33864, "cus-eas", "Latn, Ethi", } m["or"] = { "Odia", 33810, "inc-eas", "Orya", ancestors = "inc-mor", translit = "or-translit", } m["os"] = { "Ossetian", 33968, "xsc-sar", "Cyrl, Geor, Latn", ancestors = "oos", translit = { Cyrl = "os-translit", Geor = "Geor-translit", }, override_translit = true, display_text = { Cyrl = { from = {"æ"}, to = {"ӕ"} }, Latn = { from = {"ӕ"}, to = {"æ"} }, }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute, from = {"æ"}, to = {"ӕ"} }, Latn = { from = {"ӕ"}, to = {"æ"} }, }, sort_key = { Cyrl = { from = {"ӕ", "гъ", "дж", "дз", "ё", "къ", "пъ", "тъ", "хъ", "цъ", "чъ"}, to = {"а" .. p[1], "г" .. p[1], "д" .. p[1], "д" .. p[2], "е" .. p[1], "к" .. p[1], "п" .. p[1], "т" .. p[1], "х" .. p[1], "ц" .. p[1], "ч" .. p[1]} }, }, } m["pa"] = { "Punjabi", 58635, "inc-pan", "Guru, pa-Arab", ancestors = "inc-opa", translit = { Guru = "Guru-translit", ["pa-Arab"] = "pa-Arab-translit", }, entry_name = { ["pa-Arab"] = { remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna, from = {"ݨ", "ࣇ"}, to = {"ن", "ل"} }, }, } m["pi"] = { "Pali", 36727, "inc-mid", "Latn, Brah, Deva, Beng, Sinh, Mymr, Thai, Lana, Laoo, Khmr, Cakm", --and also Khom ancestors = "sa", translit = { Brah = "Brah-translit", Deva = "sa-translit", Beng = "pi-translit", Sinh = "si-translit", Mymr = "pi-translit", Thai = "pi-translit", Lana = "pi-translit", Laoo = "pi-translit", Khmr = "pi-translit", Cakm = "Cakm-translit", }, entry_name = { Thai = { from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here. to = {"ิํ", "ฐ", "ญ"} }, remove_diacritics = c.VS01 }, sort_key = { -- FIXME: This needs to be converted into the current standardized format. from = {"ā", "ī", "ū", "ḍ", "ḷ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṭ", "([เโ])([ก-ฮ])", "([ເໂ])([ກ-ຮ])", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", u(0xFE00), u(0x200D)}, to = {"a~", "i~", "u~", "d~", "l~", "m~", "n~", "n~~", "n~~~", "t~", "%2%1", "%2%1", "ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"} }, } m["pl"] = { "Polish", 809, "zlw-lch", "Latn", ancestors = "zlw-mpl", sort_key = { from = {"ą", "ć", "ę", "ł", "ń", "ó", "ś", "ź", "ż"}, to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1], "z" .. p[2]} }, standardChars = "AaĄąBbCcĆćDdEeĘęFfGgHhIiJjKkLlŁłMmNnŃńOoÓóPpRrSsŚśTtUuWwYyZzŹźŻż" .. c.punc, } m["ps"] = { "Pashto", 58680, "ira-pat", "ps-Arab", entry_name = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.zwarakay .. c.superalef}, } m["pt"] = { "Portuguese", 5146, "roa-gap", "Latn, Brai", sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla, from = {"ª", "æ", "º", "œ"}, to = {"a", "ae", "o", "oe"} }, }, standardChars = { Latn = "AaÁáÂâÃãBbCcÇçDdEeÉéÊêFfGgHhIiÍíJjLlMmNnOoÓóÔôÕõPpQqRrSsTtUuÚúVvXxZz", Brai = c.braille, c.punc }, } m["qu"] = { "Quechua", 5218, "qwe", "Latn", } m["rm"] = { "Romansch", 13199, "roa-rhe", "Latn", sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.small_e}, } m["ro"] = { "Romanian", 7913, "roa-eas", "Latn, Cyrl, Cyrs", translit = { Cyrl = "ro-translit" }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute, from = {"ă", "â", "î", "ș", "ț"}, to = {"a" .. p[1], "a" .. p[2], "i" .. p[1], "s" .. p[1], "t" .. p[1]} }, Cyrl = { from = {"ӂ"}, to = {"ж" .. p[1]} }, }, standardChars = { Latn = "AaĂăÂâBbCcDdEeFfGgHhIiÎîJjLlMmNnOoPpRrSsȘșTtȚțUuVvXxZz", Cyrl = "АаБбВвГгДдЕеЖжӁӂЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЫыЬьЭэЮюЯя", c.punc }, } m["ru"] = { "Russian", 7737, "zle", "Cyrl, Brai", ancestors = "zle-mru", translit = { Cyrl = "ru-translit" }, display_text = { Cyrl = { from = {"'"}, to = {"’"} }, }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute .. c.diaer, remove_exceptions = {"Ё", "ё", "Ѣ̈", "ѣ̈", "Я̈", "я̈"}, from = {"’"}, to = {"'"}, }, }, sort_key = { Cyrl = { remove_diacritics = c.grave .. c.acute .. c.diaer, from = { "і", "ѣ", "ѳ", "ѵ" }, to = { "и" .. p[1], "ь" .. p[1], "я" .. p[2], "я" .. p[3] } }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя—", Brai = c.braille, (c.punc:gsub("'", "")) -- Exclude apostrophe. }, } m["rw"] = { "Rwanda-Rundi", 3217514, "bnt-glb", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ .. c.macron .. c.caron}, } m["sa"] = { "Sanskrit", 11059, "inc", "as-Beng, Bali, Beng, Bhks, Brah, Mymr, xwo-Mong, Deva, Gujr, Guru, Gran, Hani, Java, Kthi, Knda, Kawi, Khar, Khmr, Laoo, Mlym, mnc-Mong, Marc, Modi, Mong, Nand, Newa, Orya, Phag, Ranj, Saur, Shrd, Sidd, Sinh, Soyo, Lana, Takr, Taml, Tang, Telu, Thai, Tibt, Tutg, Tirh, Zanb", --and also Khom; script codes sorted by canonical name rather than code for [[MOD:sa-convert]] translit = { Beng = "sa-Beng-translit", ["as-Beng"] = "sa-Beng-translit", Brah = "Brah-translit", Deva = "sa-translit", Gujr = "sa-Gujr-translit", Guru = "sa-Guru-translit", Java = "sa-Java-translit", Kthi = "sa-Kthi-translit", Khmr = "pi-translit", Knda = "sa-Knda-translit", Lana = "pi-translit", Laoo = "pi-translit", Mlym = "sa-Mlym-translit", Modi = "sa-Modi-translit", Mong = "Mong-translit", ["mnc-Mong"] = "mnc-translit", ["xwo-Mong"] = "xal-translit", Mymr = "pi-translit", Orya = "sa-Orya-translit", Shrd = "Shrd-translit", Sidd = "Sidd-translit", Sinh = "si-translit", Taml = "sa-Taml-translit", Telu = "sa-Telu-translit", Thai = "pi-translit", Tibt = "Tibt-translit", }, display_text = { Mong = s["Mong-displaytext"], Tibt = s["Tibt-displaytext"], }, entry_name = { Mong = s["Mong-entryname"], Tibt = s["Tibt-entryname"], Thai = { from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here. to = {"ิํ", "ฐ", "ญ"} }, remove_diacritics = c.VS01 .. c.udatta .. c.anudatta }, sort_key = { Tibt = "Tibt-sortkey", { -- FIXME: This needs to be converted into the current standardized format. from = {"ā", "ī", "ū", "ḍ", "ḷ", "ḹ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṛ", "ṝ", "ś", "ṣ", "ṭ", "([เโไ])([ก-ฮ])", "([ເໂໄ])([ກ-ຮ])", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", u(0xFE00), u(0x200D)}, to = {"a~", "i~", "u~", "d~", "l~", "l~~", "m~", "n~", "n~~", "n~~~", "r~", "r~~", "s~", "s~~", "t~", "%2%1", "%2%1", "ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"}, }, }, } m["sc"] = { "Sardinian", 33976, "roa-sou", "Latn", } m["sd"] = { "Sindhi", 33997, "inc-snd", "sd-Arab, Deva, Sind, Khoj", translit = { Sind = "Sind-translit" }, entry_name = { ["sd-Arab"] = { remove_diacritics = c.kashida .. c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, from = {"ٱ"}, to = {"ا"} }, }, } m["se"] = { "Northern Sami", 33947, "smi", "Latn", display_text = { from = {"'"}, to = {"ˈ"} }, entry_name = {remove_diacritics = c.macron .. c.dotbelow .. "'ˈ"}, sort_key = { from = {"á", "č", "đ", "ŋ", "š", "ŧ", "ž"}, to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "n" .. p[1], "s" .. p[1], "t" .. p[1], "z" .. p[1]} }, standardChars = "AaÁáBbCcČčDdĐđEeFfGgHhIiJjKkLlMmNnŊŋOoPpRrSsŠšTtŦŧUuVvZzŽž" .. c.punc, } m["sg"] = { "Sango", 33954, "crp", "Latn", ancestors = "ngb", } m["sh"] = { "Serbo-Croatian", 9301, "zls", "Latn, Cyrl, Glag, Arab", ietf_subtag = "hbs", -- ISO 639-3 code, since "sh" is deprecated from ISO 639-1 wikimedia_codes = "sh, bs, hr, sr", entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"Ć", "ć", "Ś", "ś", "Ź", "ź"} }, Cyrl = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"З́", "з́", "С́", "с́"} }, }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"ć", "ś", "ź"}, from = {"č", "ć", "dž", "đ", "lj", "nj", "š", "ś", "ž", "ź"}, to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "z" .. p[1], "z" .. p[2]} }, Cyrl = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"з́", "с́"}, from = {"ђ", "з́", "ј", "љ", "њ", "с́", "ћ", "џ"}, to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "с" .. p[1], "т" .. p[1], "ч" .. p[1]} }, }, standardChars = { Latn = "AaBbCcČčĆćDdĐđEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž", Cyrl = "АаБбВвГгДдЂђЕеЖжЗзИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЋћУуФфХхЦцЧчЏџШш", c.punc }, } m["si"] = { "Sinhalese", 13267, "inc-ins", "Sinh", translit = "si-translit", override_translit = true, } m["sk"] = { "Slovak", 9058, "zlw", "Latn", ancestors = "zlw-osk", sort_key = {remove_diacritics = c.acute .. c.circ .. c.diaer .. c.caron}, standardChars = "AaÁáÄäBbCcČčDdĎďEeÉéFfGgHhIiÍíJjKkLlĹ弾MmNnŇňOoÓóÔôPpRrŔŕSsŠšTtŤťUuÚúVvYyÝýZzŽž" .. c.punc, } m["sl"] = { "Slovene", 9063, "zls", "Latn", entry_name = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.dgrave .. c.invbreve .. c.dotbelow, remove_exceptions = {"Ć", "ć", "Ǵ", "ǵ", "Ś", "ś", "Ź", "ź"}, from = {"Ə", "ə", "Ł", "ł"}, to = {"E", "e", "L", "l"}, }, sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dotabove .. c.ringabove .. c.dgrave .. c.invbreve .. c.dotbelow .. c.ringbelow .. c.ogonek, remove_exceptions = {"ć", "ǵ", "ś", "ź"}, from = {"ä", "č", "ć", "đ", "ə", "ë", "ǧ", "ǵ", "ï", "ł", "ö", "š", "ś", "ü", "ž", "ź"}, to = {"a" .. p[1], "c" .. p[1], "c" .. p[2], "d" .. p[1], "e", "e" .. p[1], "g" .. p[1], "g" .. p[2], "i" .. p[1], "l", "o" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]}, }, standardChars = "AaBbCcČčDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž" .. c.punc, } m["sm"] = { "Samoan", 34011, "poz-pnp", "Latn", } m["sn"] = { "Shona", 34004, "bnt-sho", "Latn", entry_name = {remove_diacritics = c.acute}, } m["so"] = { "Somali", 13275, "cus-som", "Latn, Arab, Osma", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ} }, } m["sq"] = { "Albanian", 8748, "sqj", "Latn, Grek, ota-Arab, Elba, Todr, Vith", translit = { Elba = "Elba-translit", }, display_text = { Grek = s["Grek-displaytext"], }, entry_name = { Latn = { remove_diacritics = c.acute .. c.circ, from = {'^[ie] (%w)', '^të (%w)'}, to = {'%1', '%1'}, }, Grek = { -- Diacritic removal from Grek-entryname excluded. from = s["Grek-entryname"].from, to = s["Grek-entryname"].to, }, }, sort_key = { Latn = { remove_diacritics = c.acute .. c.circ .. c.tilde .. c.breve .. c.caron, from = {'^[ie] (%w)', '^të (%w)', 'ç', 'dh', 'ë', 'gj', 'll', 'nj', 'rr', 'sh', 'th', 'xh', 'zh'}, to = {'%1', '%1', 'c'..p[1], 'd'..p[1], 'e'..p[1], 'g'..p[1], 'l'..p[1], 'n'..p[1], 'r'..p[1], 's'..p[1], 't'..p[1], 'x'..p[1], 'z'..p[1]}, } -- TODO: Grek }, standardChars = { Latn = "AaBbCcÇçDdEeËëFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZz", c.punc }, } m["ss"] = { "Swazi", 34014, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["st"] = { "Sotho", 34340, "bnt-sts", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["su"] = { "Sundanese", 34002, "poz-msa", "Latn, Sund, Arab", ancestors = "osn", translit = { Sund = "Sund-translit" }, } m["sv"] = { "Swedish", 9027, "gmq-eas", "Latn", ancestors = "gmq-osw-lat", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla .. "':", remove_exceptions = {"å"}, from = {"ø", "æ", "œ", "ß", "å", "aͤ", "oͤ"}, to = {"o", "ae", "oe", "ss", "z" .. p[1], "ä", "ö"} }, standardChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvXxYyÅåÄäÖö" .. c.punc, } m["sw"] = { "Swahili", 7838, "bnt-swh", "Latn, Arab", sort_key = { Latn = { from = {"ng'"}, to = {"ng" .. p[1]} }, }, } m["ta"] = { "Tamil", 5885, "dra-tam", "Taml", ancestors = "ta-mid", translit = "ta-translit", override_translit = true, } m["te"] = { "Telugu", 8097, "dra-tel", "Telu", translit = "te-translit", override_translit = true, } m["tg"] = { "Tajik", 9260, "ira-swi", "Cyrl, fa-Arab, Latn", ancestors = "fa-cls", translit = { Cyrl = "tg-translit" }, override_translit = true, entry_name = { Cyrl = s["tg-entryname"], Latn = s["tg-entryname"], }, sort_key = { Cyrl = { from = {"ғ", "ё", "ӣ", "қ", "ӯ", "ҳ", "ҷ"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "к" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]} }, }, } m["th"] = { "Thai", 9217, "tai-swe", "Thai, Khomt, Brai", translit = { Thai = "th-translit" }, sort_key = { Thai = "Thai-sortkey" }, } m["ti"] = { "Tigrinya", 34124, "sem-eth", "Ethi", translit = "Ethi-translit", } m["tk"] = { "Turkmen", 9267, "trk-ogz", "Latn, Cyrl, Arab", entry_name = { Latn = s["tk-entryname"], Cyrl = s["tk-entryname"], }, sort_key = { Latn = { from = {"ç", "ä", "ž", "ň", "ö", "ş", "ü", "ý"}, to = {"c" .. p[1], "e" .. p[1], "j" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "y" .. p[1]} }, Cyrl = { from = {"ё", "җ", "ң", "ө", "ү", "ә"}, to = {"е" .. p[1], "ж" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "э" .. p[1]} }, }, ancestors = "trk-eog", } m["tl"] = { "Tagalog", 34057, "phi", "Latn, Tglg", translit = { Tglg = "tl-translit" }, override_translit = true, entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ} }, standardChars = { Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy", c.punc }, sort_key = { Latn = "tl-sortkey", }, } m["tn"] = { "Tswana", 34137, "bnt-sts", "Latn", } m["to"] = { "Tongan", 34094, "poz-ton", "Latn", entry_name = {remove_diacritics = c.acute}, sort_key = {remove_diacritics = c.macron}, } m["tr"] = { "Turkish", 256, "trk-ogz", "Latn", ancestors = "ota", dotted_dotless_i = true, sort_key = { from = { -- Ignore circumflex, but account for capital Î wrongly becoming ı + circ due to dotted dotless I logic. "ı" .. c.circ, c.circ, "i", -- Ensure "i" comes after "ı". "ç", "ğ", "ı", "ö", "ş", "ü" }, to = { "i", "", "i" .. p[1], "c" .. p[1], "g" .. p[1], "i", "o" .. p[1], "s" .. p[1], "u" .. p[1] } }, standardChars = "AaÂâBbCcÇçDdEeFfGgĞğHhIıİiÎîJjKkLlMmNnOoÖöPpRrSsŞşTtUuÛûÜüVvYyZz" .. c.punc, } m["ts"] = { "Tsonga", 34327, "bnt-tsr", "Latn", } m["tt"] = { "Tatar", 25285, "trk-kbu", "Cyrl, Latn, tt-Arab", translit = { Cyrl = "tt-translit" }, override_translit = false, -- until Module code can detect Russian loans such as [[аэропорт]] dotted_dotless_i = true, sort_key = { Cyrl = { from = {"ә", "ў", "ғ", "ё", "җ", "қ", "ң", "ө", "ү", "һ"}, to = {"а" .. p[1], "в" .. p[1], "г" .. p[1], "е" .. p[1], "ж" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1]} }, Latn = { from = { "i", -- Ensure "i" comes after "ı". "ä", "ə", "ç", "ğ", "ı", "ñ", "ŋ", "ö", "ɵ", "ş", "ü" }, to = { "i" .. p[1], "a" .. p[1], "a" .. p[2], "c" .. p[1], "g" .. p[1], "i", "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "s" .. p[1], "u" .. p[1] } }, }, } -- "tw" IS TREATED AS "ak", SEE WT:LT m["ty"] = { "Tahitian", 34128, "poz-pep", "Latn", } m["ug"] = { "Uyghur", 13263, "trk-kar", "ug-Arab, Latn, Cyrl", ancestors = "chg", translit = { ["ug-Arab"] = "ug-translit", Cyrl = "ug-translit", }, override_translit = true, } m["uk"] = { "Ukrainian", 8798, "zle", "Cyrl", ancestors = "zle-muk", translit = "uk-translit", entry_name = {remove_diacritics = c.grave .. c.acute}, sort_key = { remove_diacritics = c.grave .. c.acute, from = { "ї", -- 2 chars "ґ", "є", "і" -- 1 char }, to = { "и" .. p[2], "г" .. p[1], "е" .. p[1], "и" .. p[1] } }, standardChars = "АаБбВвГгДдЕеЄєЖжЗзИиІіЇїЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЬьЮюЯя" .. c.punc:gsub("'", ""), -- Exclude apostrophe. } m["ur"] = { "Urdu", 1617, "inc-hnd", "ur-Arab, Hebr", translit = { ["ur-Arab"] = "ur-translit" }, display_text = { Hebr = "Hebr-common", }, entry_name = { ["ur-Arab"] = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, standardChars = { ["ur-Arab"] = "ایببپتثجچحخدذرزژسشصضطظعغفقکگلࣇڷمنݨوؤہھئٹڈڑآے", c.punc, }, } m["uz"] = { "Uzbek", 9264, "trk-kar", "Latn, Cyrl, fa-Arab", ancestors = "chg", translit = { Cyrl = "uz-translit" }, sort_key = { Latn = { from = {"oʻ", "gʻ", "sh", "ch", "ng"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3], "z" .. p[4], "z" .. p[5]} }, Cyrl = { from = {"ё", "ў", "қ", "ғ", "ҳ"}, to = {"е" .. p[1], "я" .. p[1], "я" .. p[2], "я" .. p[3], "я" .. p[4]} }, }, entry_name = { ["fa-Arab"] = "ar-entryname", }, } m["ve"] = { "Venda", 32704, "bnt-bso", "Latn", } m["vi"] = { "Vietnamese", 9199, "mkh-vie", "Latn, Hani", ancestors = "mkh-mvi", sort_key = { Latn = "vi-sortkey", Hani = "Hani-sortkey", }, } m["vo"] = { "Volapük", 36986, "art", "Latn", } m["wa"] = { "Walloon", 34219, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["wo"] = { "Wolof", 34257, "alv-fwo", "Latn, Arab, Gara", } m["xh"] = { "Xhosa", 13218, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["yi"] = { "Yiddish", 8641, "gmw-hgm", "Hebr, Latn", ancestors = "gmh", translit = { Hebr = "yi-translit", }, display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["yo"] = { "Yoruba", 34311, "alv-yor", "Latn, Arab", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.macron} }, sort_key = { Latn = { from = {"ẹ", "ɛ", "gb", "ị", "kp", "ọ", "ɔ", "ṣ", "sh", "ụ"}, to = {"e" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "o" .. p[1], "o" .. p[1], "s" .. p[1], "s" .. p[1], "u" .. p[1]} }, }, } m["za"] = { "Zhuang", 13216, "tai", "Latn, Hani", sort_key = { Latn = "za-sortkey", Hani = "Hani-sortkey", }, } m["zh"] = { "Chinese", 7850, "zhx", "Hants, Latn, Bopo, Nshu, Brai", ancestors = "ltc", generate_forms = "zh-generateforms", translit = { Hani = "zh-translit", Bopo = "zh-translit", }, sort_key = { Hani = "Hani-sortkey" }, } m["zu"] = { "Zulu", 10179, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } return require("Module:languages").finalizeData(m, "language") i0jc3kit8zdle0lkybvkdlrypii56t1 26558 26557 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:languages/data/2]] 26557 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared -- Ideally, we want to move these into [[Module:languages/data]], but because (a) it's necessary to use require on that module, and (b) they're only used in this data module, it's less memory-efficient to do that at the moment. If it becomes possible to use mw.loadData, then these should be moved there. s["de-Latn-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove, from = {"æ", "œ", "ß"}, to = {"ae", "oe", "ss"} } s["de-Latn-standardchars"] = "AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsẞßTtUuÜüVvWwXxYyZz" s["ka-entryname"] = {remove_diacritics = c.circ} s["no-sortkey"] = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla, remove_exceptions = {"å"}, from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} } s["no-standardchars"] = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc s["tg-entryname"] = {remove_diacritics = c.grave .. c.acute} s["tk-entryname"] = {remove_diacritics = c.macron} local m = {} m["aa"] = { "Afar", 27811, "cus-eas", "Latn, Ethi", entry_name = { Latn = {remove_diacritics = c.acute}, }, } m["ab"] = { "Abkhaz", 5111, "cau-abz", "Cyrl, Geor, Latn", translit = { Cyrl = "ab-translit", Geor = "Geor-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"] }, entry_name = { Cyrl = { remove_diacritics = c.acute, from = {"^а%-"}, to = {"а"}, }, Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = { "х'ә", -- 3 chars "гь", "гә", "ӷь", "ҕь", "ӷә", "ҕә", "дә", "ё", "жь", "жә", "ҙә", "ӡә", "ӡ'", "кь", "кә", "қь", "қә", "ҟь", "ҟә", "ҫә", "тә", "ҭә", "ф'", "хь", "хә", "х'", "ҳә", "ць", "цә", "ц'", "ҵә", "ҵ'", "шь", "шә", "џь", -- 2 chars "ӷ", "ҕ", "ҙ", "ӡ", "қ", "ҟ", "ԥ", "ҧ", "ҫ", "ҭ", "ҳ", "ҵ", "ҷ", "ҽ", "ҿ", "ҩ", "џ", "ә", -- 1 char "^а", }, to = { "х" .. p[4], "г" .. p[1], "г" .. p[2], "г" .. p[5], "г" .. p[6], "г" .. p[7], "г" .. p[8], "д" .. p[1], "е" .. p[1], "ж" .. p[1], "ж" .. p[2], "з" .. p[2], "з" .. p[4], "з" .. p[5], "к" .. p[1], "к" .. p[2], "к" .. p[4], "к" .. p[5], "к" .. p[7], "к" .. p[8], "с" .. p[2], "т" .. p[1], "т" .. p[3], "ф" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[6], "ц" .. p[1], "ц" .. p[2], "ц" .. p[3], "ц" .. p[5], "ц" .. p[6], "ш" .. p[1], "ш" .. p[2], "ы" .. p[3], "г" .. p[3], "г" .. p[4], "з" .. p[1], "з" .. p[3], "к" .. p[3], "к" .. p[6], "п" .. p[1], "п" .. p[2], "с" .. p[1], "т" .. p[2], "х" .. p[5], "ц" .. p[4], "ч" .. p[1], "ч" .. p[2], "ч" .. p[3], "ы" .. p[1], "ы" .. p[2], "ь" .. p[1], "", } }, }, } m["ae"] = { "Avestan", 29572, "ira-cen", "Avst, Gujr", translit = { Avst = "Avst-translit" }, } m["af"] = { "Afrikaans", 14196, "gmw-frk", "Latn, Arab", ancestors = "nl", sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'", from = {"['ʼ]n"}, to = {"n" .. p[1]} } }, } m["ak"] = { "Akan", 28026, "alv-ctn", "Latn", } m["am"] = { "Amharic", 28244, "sem-eth", "Ethi", translit = "Ethi-translit", } m["an"] = { "Aragonese", 8765, "roa-nar", "Latn", } m["ar"] = { "Arab", 13955, "sem-arb", "Arab, Hebr, Syrc, Brai, Nbat", translit = { Arab = "ar-translit" }, strip_diacritics = { Arab = "ar-stripdiacritics", }, -- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]] } m["as"] = { "Assamese", 29401, "inc-bas", "as-Beng", ancestors = "inc-mas", translit = "as-translit", } m["av"] = { "Avar", 29561, "cau-ava", "Cyrl, Latn, Arab", ancestors = "oav", translit = { Cyrl = "cau-nec-translit", Arab = "ar-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"], }, entry_name = { Cyrl = s["cau-Cyrl-entryname"], Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = {"гъ", "гь", "гӏ", "ё", "кк", "къ", "кь", "кӏ", "лъ", "лӏ", "тӏ", "хх", "хъ", "хь", "хӏ", "цӏ", "чӏ"}, to = {"г" .. p[1], "г" .. p[2], "г" .. p[3], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "к" .. p[4], "л" .. p[1], "л" .. p[2], "т" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[4], "ц" .. p[1], "ч" .. p[1]} }, }, } m["ay"] = { "Aymara", 4627, "sai-aym", "Latn", } m["az"] = { "Azerbaijani", 9292, "trk-ogz", "Latn, Cyrl, fa-Arab", ancestors = "trk-oat", dotted_dotless_i = true, entry_name = { Latn = { from = {"ʼ"}, to = {"'"}, }, ["fa-Arab"] = { module = "ar-entryname", ["from"] = { "ۆ", "ۇ", "وْ", "ڲ", "ؽ", }, ["to"] = { "و", "و", "و", "گ", "ی", }, }, }, display_text = { Latn = { from = {"'"}, to = {"ʼ"} } }, sort_key = { Latn = { from = { "i", -- Ensure "i" comes after "ı". "ç", "ə", "ğ", "x", "ı", "q", "ö", "ş", "ü", "w" }, to = { "i" .. p[1], "c" .. p[1], "e" .. p[1], "g" .. p[1], "h" .. p[1], "i", "k" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1] } }, Cyrl = { from = {"ғ", "ә", "ы", "ј", "ҝ", "ө", "ү", "һ", "ҹ"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "и" .. p[2], "к" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]} }, }, } m["ba"] = { "Bashkir", 13389, "trk-kbu", "Cyrl", translit = "ba-translit", override_translit = true, sort_key = { from = {"ғ", "ҙ", "ё", "ҡ", "ң", "ө", "ҫ", "ү", "һ", "ә"}, to = {"г" .. p[1], "д" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "с" .. p[1], "у" .. p[1], "х" .. p[1], "э" .. p[1]} }, } m["be"] = { "Belarusian", 9091, "zle", "Cyrl, Latn", ancestors = "zle-mbe", translit = { Cyrl = "be-translit", }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute, }, Latn = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"Ć", "ć", "Ń", "ń", "Ś", "ś", "Ź", "ź"}, }, }, sort_key = { Cyrl = { remove_diacritics = c.grave .. c.acute, from = {"ґ", "ё", "і", "ў"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "у" .. p[1]} }, Latn = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"Ć", "ć", "Ń", "ń", "Ś", "ś", "Ź", "ź"}, from = {"ć", "č", "dz", "dź", "dž", "ch", "ł", "ń", "ś", "š", "ŭ", "ź", "ž"}, to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "d" .. p[3], "h" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]} }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзІіЙйКкЛлМмНнОоПпРрСсТтУуЎўФфХхЦцЧчШшЫыЬьЭэЮюЯя", Latn = "AaBbCcĆćČčDdEeFfGgHhIiJjKkLlŁłMmNnŃńOoPpRrSsŚśŠšTtUuŬŭVvYyZzŹźŽž", (c.punc:gsub("'", "")) -- Exclude apostrophe. }, } m["bg"] = { "Bulgarian", 7918, "zls", "Cyrl", ancestors = "cu-bgm", translit = "bg-translit", entry_name = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"}, }, sort_key = { remove_diacritics = c.grave .. c.acute, remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"}, }, standardChars = "АаБбВвГгДдЕеЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЬьЮюЯя" .. c.punc, } m["bh"] = { "Bihari", 135305, "inc-eas", "Deva", } m["bi"] = { "Bislama", 35452, "crp", "Latn", ancestors = "en", } m["bm"] = { "Bambara", 33243, "dmn-emn", "Latn, Nkoo", sort_key = { Latn = { from = {"ɛ", "ɲ", "ŋ", "ɔ"}, to = {"e" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1]} }, }, } m["bn"] = { "Bengali", 9610, "inc-bas", "Beng, Newa", ancestors = "inc-mbn", translit = { Beng = "bn-translit" }, } m["bo"] = { "Tibetan", 34271, "sit-tib", "Tibt", -- sometimes Deva? ancestors = "xct", translit = "Tibt-translit", override_translit = true, display_text = s["Tibt-displaytext"], entry_name = s["Tibt-entryname"], sort_key = "Tibt-sortkey", } m["br"] = { "Breton", 12107, "cel-brs", "Latn", ancestors = "xbm", sort_key = { from = {"ch", "c['ʼ’]h"}, to = {"c" .. p[1], "c" .. p[2]} }, } m["ca"] = { "Catalan", 7026, "roa-ocr", "Latn", ancestors = "roa-oca", sort_key = {remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla .. "·"}, standardChars = "AaÀàBbCcÇçDdEeÉéÈèFfGgHhIiÍíÏïJjLlMmNnOoÓóÒòPpQqRrSsTtUuÚúÜüVvXxYyZz·" .. c.punc, } m["ce"] = { "Chechen", 33350, "cau-vay", "Cyrl, Latn, Arab", translit = { Cyrl = "cau-nec-translit", Arab = "ar-translit", }, override_translit = true, display_text = { Cyrl = s["cau-Cyrl-displaytext"] }, entry_name = { Cyrl = s["cau-Cyrl-entryname"], Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = {"аь", "гӏ", "ё", "кх", "къ", "кӏ", "оь", "пӏ", "тӏ", "уь", "хь", "хӏ", "цӏ", "чӏ", "юь", "яь"}, to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "о" .. p[1], "п" .. p[1], "т" .. p[1], "у" .. p[1], "х" .. p[1], "х" .. p[2], "ц" .. p[1], "ч" .. p[1], "ю" .. p[1], "я" .. p[1]} }, }, } m["ch"] = { "Chamorro", 33262, "poz", "Latn", sort_key = { remove_diacritics = "'", from = {"å", "ch", "ñ", "ng"}, to = {"a" .. p[1], "c" .. p[1], "n" .. p[1], "n" .. p[2]} }, } m["co"] = { "Corsican", 33111, "roa-itr", "Latn", sort_key = { from = {"chj", "ghj", "sc", "sg"}, to = {"c" .. p[1], "g" .. p[1], "s" .. p[1], "s" .. p[2]} }, standardChars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìÏïJjLlMmNnOoÒòPpQqRrSsTtUuÙùÜüVvZz" .. c.punc, } m["cr"] = { "Cree", 33390, "alg", "Latn, Cans", translit = { Cans = "cr-translit" }, } m["cs"] = { "Czech", 9056, "zlw", "Latn", ancestors = "cs-ear", sort_key = { from = {"á", "č", "ď", "é", "ě", "ch", "í", "ň", "ó", "ř", "š", "ť", "ú", "ů", "ý", "ž"}, to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "h" .. p[1], "i" .. p[1], "n" .. p[1], "o" .. p[1], "r" .. p[1], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "y" .. p[1], "z" .. p[1]} }, standardChars = "AaÁáBbCcČčDdĎďEeÉéĚěFfGgHhIiÍíJjKkLlMmNnŇňOoÓóPpRrŘřSsŠšTtŤťUuÚúŮůVvYyÝýZzŽž" .. c.punc, } m["cu"] = { "Old Church Slavonic", 35499, "zls", "Cyrs, Glag, Zname", translit = { Cyrs = "Cyrs-translit", Glag = "Glag-translit" }, entry_name = { Cyrs = s["Cyrs-entryname"] }, sort_key = { Cyrs = s["Cyrs-sortkey"] }, } m["cv"] = { "Chuvash", 33348, "trk-ogr", "Cyrl", ancestors = "cv-mid", translit = "cv-translit", override_translit = true, sort_key = { from = {"ӑ", "ё", "ӗ", "ҫ", "ӳ"}, to = {"а" .. p[1], "е" .. p[1], "е" .. p[2], "с" .. p[1], "у" .. p[1]} }, } m["cy"] = { "Welsh", 9309, "cel-brw", "Latn", ancestors = "wlm", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. "'", from = {"ch", "dd", "ff", "ng", "ll", "ph", "rh", "th"}, to = {"c" .. p[1], "d" .. p[1], "f" .. p[1], "g" .. p[1], "l" .. p[1], "p" .. p[1], "r" .. p[1], "t" .. p[1]} }, standardChars = "ÂâAaBbCcDdEeÊêFfGgHhIiÎîLlMmNnOoÔôPpRrSsTtUuÛûWwŴŵYyŶŷ" .. c.punc, } m["da"] = { "Danish", 9035, "gmq-eas", "Latn", ancestors = "gmq-oda", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla, remove_exceptions = {"å"}, from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc, } m["de"] = { "German", 188, "gmw-hgm", "Latn, Latf, Brai", ancestors = "de-ear", sort_key = { Latn = s["de-Latn-sortkey"], Latf = s["de-Latn-sortkey"], }, standardChars = { Latn = s["de-Latn-standardchars"], Latf = s["de-Latn-standardchars"], Brai = c.braille, c.punc } } m["dv"] = { "Dhivehi", 32656, "inc-ins", "Thaa, Diak", translit = { Thaa = "dv-translit", Diak = "Diak-translit", }, override_translit = true, } m["dz"] = { "Dzongkha", 33081, "sit-tib", "Tibt", ancestors = "xct", translit = "Tibt-translit", override_translit = true, display_text = s["Tibt-displaytext"], entry_name = s["Tibt-entryname"], sort_key = "Tibt-sortkey", } m["ee"] = { "Ewe", 30005, "alv-gbe", "Latn", sort_key = { remove_diacritics = c.tilde, from = {"ɖ", "dz", "ɛ", "ƒ", "gb", "ɣ", "kp", "ny", "ŋ", "ɔ", "ts", "ʋ"}, to = {"d" .. p[1], "d" .. p[2], "e" .. p[1], "f" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "t" .. p[1], "v" .. p[1]} }, } m["el"] = { "Greek", 9129, "grk", "Grek, Polyt, Brai", ancestors = "el-kth", translit = "el-translit", override_translit = true, display_text = { Grek = s["Grek-displaytext"], Polyt = s["Polyt-displaytext"], }, entry_name = { Grek = s["Grek-entryname"], Polyt = s["Polyt-entryname"], }, sort_key = { Grek = s["Grek-sortkey"], Polyt = s["Polyt-sortkey"], }, standardChars = { Grek = "΅·ͺ΄ΑαΆάΒβΓγΔδΕεέΈΖζΗηΉήΘθΙιΊίΪϊΐΚκΛλΜμΝνΞξΟοΌόΠπΡρΣσςΤτΥυΎύΫϋΰΦφΧχΨψΩωΏώ", Brai = c.braille, c.punc }, } m["en"] = { "English", 1860, "gmw-ang", "Latn, Brai, Shaw, Dsrt", -- entries in Shaw or Dsrt might require prior discussion wikimedia_codes = "en, simple", ancestors = "en-ear", sort_key = { Latn = { -- Many of these are needed for sorting language names. remove_diacritics = "'\"%-%.,%s·ʻʼ" .. c.diacritics, -- These are found in entry names. from = {"[ɒæ🅱¢©ᴄðđəǝɜɡħʜıɨłŋɲøɔœꝑꝓꝕßʋ]"}, to = {{ ["ɒ"] = "a", ["æ"] = "ae", ["🅱"] = "b", ["¢"] = "c", ["©"] = "c", ["ᴄ"] = "c", ["ð"] = "d", ["đ"] = "d", ["ə"] = "e", ["ǝ"] = "e", ["ɜ"] = "e", ["ɡ"] = "g", ["ħ"] = "h", ["ʜ"] = "h", ["ı"] = "i", ["ɨ"] = "i", ["ł"] = "l", ["ŋ"] = "n", ["ɲ"] = "n", ["ø"] = "o", ["ɔ"] = "o", ["œ"] = "oe", ["ꝑ"] = "p", ["ꝓ"] = "p", ["ꝕ"] = "p", ["ß"] = "ss", ["ʋ"] = "v", }}, }, }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", Brai = c.braille, c.punc }, } m["eo"] = { "Esperanto", 143, "art", "Latn", sort_key = { remove_diacritics = c.grave .. c.acute, from = {"ĉ", "ĝ", "ĥ", "ĵ", "ŝ", "ŭ"}, to = {"c" .. p[1], "g" .. p[1], "h" .. p[1], "j" .. p[1], "s" .. p[1], "u" .. p[1]} }, standardChars = "AaBbCcĈĉDdEeFfGgĜĝHhĤĥIiJjĴĵKkLlMmNnOoPpRrSsŜŝTtUuŬŭVvZz" .. c.punc, } m["es"] = { "Spanish", 1321, "roa-cas", "Latn, Brai", ancestors = "es-ear", sort_key = { Latn = { remove_exceptions = {"ñ"}, remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla, from = {"ª", "æ", "ñ", "º", "œ"}, to = {"a", "ae", "n" .. p[1], "o", "oe"} }, }, standardChars = { Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxYyZz", Brai = c.braille, c.punc }, } m["et"] = { "Estonian", 9072, "urj-fin", "Latn", sort_key = { from = { "š", "ž", "õ", "ä", "ö", "ü", -- 2 chars "z" -- 1 char }, to = { "s" .. p[1], "s" .. p[3], "w" .. p[1], "w" .. p[2], "w" .. p[3], "w" .. p[4], "s" .. p[2] } }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvÕõÄäÖöÜü" .. c.punc, } m["eu"] = { "Basque", 8752, "euq", "Latn", sort_key = { from = {"ç", "ñ"}, to = {"c" .. p[1], "n" .. p[1]} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnÑñOoPpRrSsTtUuXxZz" .. c.punc, } m["fa"] = { "Persian", 9168, "ira-swi", "fa-Arab, Hebr", ancestors = "fa-cls", display_text = { Hebr = "Hebr-common", }, entry_name = { ["fa-Arab"] = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ٱ"}, -- character "ۂ" code U+06C2 to "ه"; hamzatu l-waṣli to a regular alif to = {"ه", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, }, Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["ff"] = { "Fula", 33454, "alv-fwo", "Latn, Adlm", } m["fi"] = { "Finnish", 1412, "urj-fin", "Latn", display_text = { from = {"'"}, to = {"’"} }, entry_name = { -- used to indicate gemination of the next consonant remove_diacritics = "ˣ", from = {"’"}, to = {"'"}, }, sort_key = { -- [[Appendix:Finnish alphabet#Collation]] + "aͤ" and "oͤ" as historical variants of "ä" and "ö". remove_diacritics = "'’:" .. c.diacritics, remove_exceptions = { "a[" .. c.ringabove .. c.diaer .. c.small_e .. "]", -- åäaͤ "o[" .. c.diaer .. c.tilde .. c.dacute .. c.small_e .. "]", -- öõőoͤ "u[" .. c.diaer .. c.dacute .. "]" -- üű }, from = {"æ", "[ðđ]", "ł", "ŋ", "œ", "ß", "þ", "u[" .. c.diaer .. c.dacute .. "]", "å", "aͤ", "o[" .. c.tilde .. c.dacute .. c.small_e .. "]", "ø", "(.)['%-]"}, to = {"ae", "d", "l", "n", "oe", "ss", "th", "y", "z" .. p[1], "ä", "ö", "ö", "%1"} }, standardChars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÄäÖö" .. c.punc, } m["fj"] = { "Fijian", 33295, "poz-pcc", "Latn", } m["fo"] = { "Faroese", 25258, "gmq-ins", "Latn", sort_key = { from = {"á", "ð", "í", "ó", "ú", "ý", "æ", "ø"}, to = {"a" .. p[1], "d" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2]} }, standardChars = "AaÁáBbDdÐðEeFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvYyÝýÆæØø" .. c.punc, } m["fr"] = { "French", 150, "roa-oil", "Latn, Brai", ancestors = "frm", sort_key = { Latn = s["roa-oil-sortkey"] }, standardChars = { Latn = "AaÀàÂâBbCcÇçDdEeÉéÈèÊêËëFfGgHhIiÎîÏïJjLlMmNnOoÔôŒœPpQqRrSsTtUuÙùÛûÜüVvXxYyZz", Brai = c.braille, c.punc }, } m["fy"] = { "West Frisian", 27175, "gmw-fri", "Latn", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer, from = {"y"}, to = {"i"} }, standardChars = "AaâäàÆæBbCcDdEeéêëèFfGgHhIiïìYyỳJjKkLlMmNnOoôöòPpRrSsTtUuúûüùVvWwZz" .. c.punc, } m["ga"] = { "Irish", 9142, "cel-gae", "Latn, Latg", ancestors = "mga", sort_key = { remove_diacritics = c.acute, from = {"ḃ", "ċ", "ḋ", "ḟ", "ġ", "ṁ", "ṗ", "ṡ", "ṫ"}, to = {"bh", "ch", "dh", "fh", "gh", "mh", "ph", "sh", "th"} }, standardChars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíLlMmNnOoÓóPpRrSsTtUuÚúVv" .. c.punc, } m["gd"] = { "Scottish Gaelic", 9314, "cel-gae", "Latn, Latg", ancestors = "mga", sort_key = {remove_diacritics = c.grave .. c.acute}, standardChars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìLlMmNnOoÒòPpRrSsTtUuÙù" .. c.punc, } m["gl"] = { "Galician", 9307, "roa-gap", "Latn", sort_key = { remove_diacritics = c.acute, from = {"ñ"}, to = {"n" .. p[1]} }, standardChars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíÏïLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxZz" .. c.punc, } m["gn"] = { "Guaraní", 35876, "tup-gua", "Latn", } m["gu"] = { "Gujarati", 5137, "inc-wes", "Arab, Gujr", ancestors = "inc-mgu", translit = { Gujr = "gu-translit", }, entry_name = { Arab = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.kasra .. c.shadda .. c.sukun}, Gujr = {remove_diacritics = "઼"}, }, } m["gv"] = { "Manx", 12175, "cel-gae", "Latn", ancestors = "mga", sort_key = {remove_diacritics = c.cedilla .. "-"}, standardChars = "AaBbCcÇçDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwYy" .. c.punc, } m["ha"] = { "Hausa", 56475, "cdc-wst", "Latn, Arab", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron} }, sort_key = { Latn = { from = {"ɓ", "b'", "ɗ", "d'", "ƙ", "k'", "sh", "ƴ", "'y"}, to = {"b" .. p[1], "b" .. p[2], "d" .. p[1], "d" .. p[2], "k" .. p[1], "k" .. p[2], "s" .. p[1], "y" .. p[1], "y" .. p[2]} }, }, } m["he"] = { "Hebrew", 9288, "sem-can", "Hebr, Phnx, Brai, Samr", ancestors = "he-med", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", Samr = s["Samr-entryname"], }, sort_key = { Hebr = "Hebr-common", Samr = s["Samr-sortkey"], }, } m["hi"] = { "Hindi", 1568, "inc-hnd", "Deva, Kthi, Newa", translit = { Deva = "hi-translit" }, standardChars = { Deva = "अआइईउऊएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलवशषसहत्रज्ञक्षक़ख़ग़ज़झ़ड़ढ़फ़काखागाघाङाचाछाजाझाञाटाठाडाढाणाताथादाधानापाफाबाभामायारालावाशाषासाहात्राज्ञाक्षाक़ाख़ाग़ाज़ाझ़ाड़ाढ़ाफ़ाकिखिगिघिङिचिछिजिझिञिटिठिडिढिणितिथिदिधिनिपिफिबिभिमियिरिलिविशिषिसिहित्रिज्ञिक्षिक़िख़िग़िज़िझ़िड़िढ़िफ़िकीखीगीघीङीचीछीजीझीञीटीठीडीढीणीतीथीदीधीनीपीफीबीभीमीयीरीलीवीशीषीसीहीत्रीज्ञीक्षीक़ीख़ीग़ीज़ीझ़ीड़ीढ़ीफ़ीकुखुगुघुङुचुछुजुझुञुटुठुडुढुणुतुथुदुधुनुपुफुबुभुमुयुरुलुवुशुषुसुहुत्रुज्ञुक्षुक़ुख़ुग़ुज़ुझ़ुड़ुढ़ुफ़ुकूखूगूघूङूचूछूजूझूञूटूठूडूढूणूतूथूदूधूनूपूफूबूभूमूयूरूलूवूशूषूसूहूत्रूज्ञूक्षूक़ूख़ूग़ूज़ूझ़ूड़ूढ़ूफ़ूकेखेगेघेङेचेछेजेझेञेटेठेडेढेणेतेथेदेधेनेपेफेबेभेमेयेरेलेवेशेषेसेहेत्रेज्ञेक्षेक़ेख़ेग़ेज़ेझ़ेड़ेढ़ेफ़ेकैखैगैघैङैचैछैजैझैञैटैठैडैढैणैतैथैदैधैनैपैफैबैभैमैयैरैलैवैशैषैसैहैत्रैज्ञैक्षैक़ैख़ैग़ैज़ैझ़ैड़ैढ़ैफ़ैकोखोगोघोङोचोछोजोझोञोटोठोडोढोणोतोथोदोधोनोपोफोबोभोमोयोरोलोवोशोषोसोहोत्रोज्ञोक्षोक़ोख़ोग़ोज़ोझ़ोड़ोढ़ोफ़ोकौखौगौघौङौचौछौजौझौञौटौठौडौढौणौतौथौदौधौनौपौफौबौभौमौयौरौलौवौशौषौसौहौत्रौज्ञौक्षौक़ौख़ौग़ौज़ौझ़ौड़ौढ़ौफ़ौक्ख्ग्घ्ङ्च्छ्ज्झ्ञ्ट्ठ्ड्ढ्ण्त्थ्द्ध्न्प्फ्ब्भ्म्य्र्ल्व्श्ष्स्ह्त्र्ज्ञ्क्ष्क़्ख़्ग़्ज़्झ़्ड़्ढ़्फ़्।॥०१२३४५६७८९॰", c.punc }, } m["ho"] = { "Hiri Motu", 33617, "crp", "Latn", ancestors = "meu", } m["ht"] = { "Haitian Creole", 33491, "crp", "Latn", ancestors = "ht-sdm", sort_key = { from = { "oun", -- 3 chars "an", "ch", "è", "en", "ng", "ò", "on", "ou", "ui" -- 2 chars }, to = { "o" .. p[4], "a" .. p[1], "c" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "u" .. p[1] } }, } m["hu"] = { "Hungarian", 9067, "urj-ugr", "Latn, Hung", ancestors = "ohu", sort_key = { Latn = { from = { "dzs", -- 3 chars "á", "cs", "dz", "é", "gy", "í", "ly", "ny", "ó", "ö", "ő", "sz", "ty", "ú", "ü", "ű", "zs", -- 2 chars }, to = { "d" .. p[2], "a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "u" .. p[3], "z" .. p[1], } }, }, standardChars = { Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóÖöŐőPpQqRrSsTtUuÚúÜüŰűVvWwXxYyZz", c.punc }, } m["hy"] = { "Armenian", 8785, "hyx", "Armn, Brai", ancestors = "axm", translit = { Armn = "Armn-translit" }, override_translit = true, entry_name = { Armn = { remove_diacritics = "՛՜՞՟", from = {"եւ", "<sup>յ</sup>", "<sup>ի</sup>", "<sup>է</sup>", "յ̵", "ՙ", "՚"}, to = {"և", "յ", "ի", "է", "ֈ", "ʻ", "’"} }, }, sort_key = { Armn = { from = { "ու", "եւ", -- 2 chars "և" -- 1 char }, to = { "ւ", "եվ", "եվ" } }, }, } m["hz"] = { "Herero", 33315, "bnt-swb", "Latn", } m["ia"] = { "Interlingua", 35934, "art", "Latn", } m["id"] = { "Indonesian", 9240, "poz-mly", "Latn", ancestors = "ms", standardChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" .. c.punc, } m["ie"] = { "Interlingue", 35850, "art", "Latn", type = "appendix-constructed", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ}, } m["ig"] = { "Igbo", 33578, "alv-igb", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.macron}, sort_key = { from = {"gb", "gh", "gw", "ị", "kp", "kw", "ṅ", "nw", "ny", "ọ", "sh", "ụ"}, to = {"g" .. p[1], "g" .. p[2], "g" .. p[3], "i" .. p[1], "k" .. p[1], "k" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "o" .. p[1], "s" .. p[1], "u" .. p[1]} }, } m["ii"] = { "Nuosu", 34235, "tbq-nlo", "Yiii", translit = "ii-translit", } m["ik"] = { "Inupiaq", 27183, "esx-inu", "Latn", sort_key = { from = { "ch", "ġ", "dj", "ḷ", "ł̣", "ñ", "ng", "r̂", "sr", "zr", -- 2 chars "ł", "ŋ", "ʼ" -- 1 char }, to = { "c" .. p[1], "g" .. p[1], "h" .. p[1], "l" .. p[1], "l" .. p[3], "n" .. p[1], "n" .. p[2], "r" .. p[1], "s" .. p[1], "z" .. p[1], "l" .. p[2], "n" .. p[2], "z" .. p[2] } }, } m["io"] = { "Ido", 35224, "art", "Latn", } m["is"] = { "Icelandic", 294, "gmq-ins", "Latn", sort_key = { from = {"á", "ð", "é", "í", "ó", "ú", "ý", "þ", "æ", "ö"}, to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2], "z" .. p[3]} }, standardChars = "AaÁáBbDdÐðEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvXxYyÝýÞþÆæÖö" .. c.punc, } m["it"] = { "Italian", 652, "roa-itr", "Latn", ancestors = "roa-oit", sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove}, standardChars = "AaÀàBbCcDdEeÈèÉéFfGgHhIiÌìLlMmNnOoÒòPpQqRrSsTtUuÙùVvZz" .. c.punc, } m["iu"] = { "Inuktitut", 29921, "esx-inu", "Cans, Latn", translit = { Cans = "cr-translit" }, override_translit = true, } m["ja"] = { "Japanese", 5287, "jpx", "Jpan, Latn, Brai", ancestors = "ja-ear", translit = s["jpx-translit"], link_tr = true, display_text = s["jpx-displaytext"], entry_name = s["jpx-entryname"], sort_key = s["jpx-sortkey"], } m["jv"] = { "Javanese", 33549, "poz", "Latn, Java, Arab", ancestors = "kaw", translit = { Java = "jv-translit" }, link_tr = true, entry_name = { Latn = {remove_diacritics = c.circ} -- Modern jv don't use ê }, sort_key = { Latn = { from = {"å", "dh", "é", "è", "ng", "ny", "th"}, to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "n" .. p[2], "t" .. p[1]} }, }, } m["ka"] = { "Georgian", 8108, "ccs-gzn", "Geor, Geok, Hebr", -- Hebr is used to write Judeo-Georgian ancestors = "ka-mid", translit = { Geor = "Geor-translit", Geok = "Geok-translit", }, override_translit = true, display_text = { Hebr = "Hebr-common", }, entry_name = { Geor = s["ka-entryname"], Geok = s["ka-entryname"], Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", } } m["kg"] = { "Kongo", 33702, "bnt-kng", "Latn", } m["ki"] = { "Kikuyu", 33587, "bnt-kka", "Latn", } m["kj"] = { "Kwanyama", 1405077, "bnt-ova", "Latn", } m["kk"] = { "Kazakh", 9252, "trk-kno", "Cyrl, Latn, kk-Arab", translit = { Cyrl = { from = { "Ё", "ё", "Й", "й", "Нг", "нг", "Ӯ", "ӯ", -- 2 chars; are "Ӯ" and "ӯ" actually used? "А", "а", "Ә", "ә", "Б", "б", "В", "в", "Г", "г", "Ғ", "ғ", "Д", "д", "Е", "е", "Ж", "ж", "З", "з", "И", "и", "К", "к", "Қ", "қ", "Л", "л", "М", "м", "Н", "н", "Ң", "ң", "О", "о", "Ө", "ө", "П", "п", "Р", "р", "С", "с", "Т", "т", "У", "у", "Ұ", "ұ", "Ү", "ү", "Ф", "ф", "Х", "х", "Һ", "һ", "Ц", "ц", "Ч", "ч", "Ш", "ш", "Щ", "щ", "Ъ", "ъ", "Ы", "ы", "І", "і", "Ь", "ь", "Э", "э", "Ю", "ю", "Я", "я", -- 1 char }, to = { "E", "e", "İ", "i", "Ñ", "ñ", "U", "u", "A", "a", "Ä", "ä", "B", "b", "V", "v", "G", "g", "Ğ", "ğ", "D", "d", "E", "e", "J", "j", "Z", "z", "İ", "i", "K", "k", "Q", "q", "L", "l", "M", "m", "N", "n", "Ñ", "ñ", "O", "o", "Ö", "ö", "P", "p", "R", "r", "S", "s", "T", "t", "U", "u", "Ū", "ū", "Ü", "ü", "F", "f", "X", "x", "H", "h", "S", "s", "Ç", "ç", "Ş", "ş", "Ş", "ş", "", "", "Y", "y", "I", "ı", "", "", "É", "é", "Ü", "ü", "Ä", "ä", } } }, -- override_translit = true, sort_key = { Cyrl = { from = {"ә", "ғ", "ё", "қ", "ң", "ө", "ұ", "ү", "һ", "і"}, to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "у" .. p[2], "х" .. p[1], "ы" .. p[1]} }, }, standardChars = { Cyrl = "АаӘәБбВвГгҒғДдЕеЁёЖжЗзИиЙйКкҚқЛлМмНнҢңОоӨөПпРрСсТтУуҰұҮүФфХхҺһЦцЧчШшЩщЪъЫыІіЬьЭэЮюЯя", c.punc }, } m["kl"] = { "Greenlandic", 25355, "esx-inu", "Latn", sort_key = { from = {"æ", "ø", "å"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} } } m["km"] = { "Khmer", 9205, "mkh-kmr", "Khmr", ancestors = "xhm", translit = "km-translit", } m["kn"] = { "Kannada", 33673, "dra-kan", "Knda, Tutg", ancestors = "dra-mkn", translit = { Knda = "kn-translit", }, } m["ko"] = { "Korean", 9176, "qfa-kor", "Kore, Brai", ancestors = "ko-ear", translit = { Kore = "ko-translit", }, entry_name = { Kore = s["Kore-entryname"], }, } m["kr"] = { "Kanuri", 36094, "ssa-sah", "Latn, Arab", -- the sortkey and entry_name are only for standard Kanuri; when dialectal entries get added, someone will have to work out how the dialects should be represented orthographically entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.breve} }, sort_key = { Latn = { from = {"ǝ", "ny", "ɍ", "sh"}, to = {"e" .. p[1], "n" .. p[1], "r" .. p[1], "s" .. p[1]} }, }, } m["ks"] = { "Kashmiri", 33552, "inc-kas", "ks-Arab, Deva, Shrd, Latn", translit = { ["ks-Arab"] = "ks-Arab-translit", Deva = "ks-Deva-translit", Shrd = "Shrd-translit", }, } -- "kv" IS TREATED AS "koi", "kpv", SEE WT:LT m["kw"] = { "Cornish", 25289, "cel-brs", "Latn", ancestors = "cnx", sort_key = { from = {"ch"}, to = {"c" .. p[1]} }, } m["ky"] = { "Kyrgyz", 9255, "trk-kkp", "Cyrl, Latn, Arab", translit = { Cyrl = "ky-translit" }, override_translit = true, sort_key = { Cyrl = { from = {"ё", "ң", "ө", "ү"}, to = {"е" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1]} }, }, } m["la"] = { "Latin", 397, "itc-laf", "Latn, Ital", ancestors = "itc-ola", display_text = { Latn = s["itc-Latn-displaytext"] }, entry_name = { Latn = s["itc-Latn-entryname"] }, sort_key = { Latn = s["itc-Latn-sortkey"] }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiLlMmNnOoPpQqRrSsTtUuVvXx", c.punc }, } m["lb"] = { "Luxembourgish", 9051, "gmw-hgm", "Latn, Brai", ancestors = "gmw-cfr", sort_key = { Latn = { from = {"ä", "ë", "é"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]} }, }, } m["lg"] = { "Luganda", 33368, "bnt-nyg", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ}, sort_key = { from = {"ŋ"}, to = {"n" .. p[1]} }, } m["li"] = { "Limburgish", 102172, "gmw-frk", "Latn", ancestors = "dum", } m["ln"] = { "Lingala", 36217, "bnt-bmo", "Latn", sort_key = { remove_diacritics = c.acute .. c.circ .. c.caron, from = {"ɛ", "gb", "mb", "mp", "nd", "ng", "nk", "ns", "nt", "ny", "nz", "ɔ"}, to = {"e" .. p[1], "g" .. p[1], "m" .. p[1], "m" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "n" .. p[4], "n" .. p[5], "n" .. p[6], "n" .. p[7], "o" .. p[1]} }, } m["lo"] = { "Lao", 9211, "tai-swe", "Laoo", translit = "lo-translit", sort_key = "Laoo-sortkey", standardChars = "0-9ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮຯ-ໝ" .. c.punc, } m["lt"] = { "Lithuanian", 9083, "bat-eas", "Latn", ancestors = "olt", display_text = "lt-common", entry_name = "lt-common", sort_key = "lt-common", standardChars = "AaĄąBbCcČčDdEeĘęĖėFfGgHhIiĮįYyJjKkLlMmNnOoPpRrSsŠšTtUuŲųŪūVvZzŽž" .. c.punc, } m["lu"] = { "Luba-Katanga", 36157, "bnt-lub", "Latn", } m["lv"] = { "Latvian", 9078, "bat-eas", "Latn", entry_name = { -- This attempts to convert vowels with tone marks to vowels either with or without macrons. Specifically, there should be no macrons if the vowel is part of a diphthong (including resonant diphthongs such pìrksts -> pirksts not #pīrksts). What we do is first convert the vowel + tone mark to a vowel + tilde in a decomposed fashion, then remove the tilde in diphthongs, then convert the remaining vowel + tilde sequences to macroned vowels, then delete any other tilde. We leave already-macroned vowels alone: Both e.g. ar and ār occur before consonants. FIXME: This still might not be sufficient. from = {"([Ee])" .. c.cedilla, "[" .. c.grave .. c.circ .. c.tilde .."]", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .. "?([^aAeEiIoOuU])", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .."?$", "([iI])" .. c.tilde .. "?([eE])" .. c.tilde .. "?", "([aAeEiIuU])" .. c.tilde, c.tilde}, to = {"%1", c.tilde, "%1%2%3", "%1%2", "%1%2", "%1" .. c.macron} }, sort_key = { from = {"ā", "č", "ē", "ģ", "ī", "ķ", "ļ", "ņ", "š", "ū", "ž"}, to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1]} }, standardChars = "AaĀāBbCcČčDdEeĒēFfGgĢģHhIiĪīJjKkĶķLlĻļMmNnŅņOoPpRrSsŠšTtUuŪūVvZzŽž" .. c.punc, } m["mg"] = { "Malagasy", 7930, "poz-bre", "Latn, Arab", } m["mh"] = { "Marshallese", 36280, "poz-mic", "Latn", sort_key = { from = {"ā", "ļ", "m̧", "ņ", "n̄", "o̧", "ō", "ū"}, to = {"a" .. p[1], "l" .. p[1], "m" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "u" .. p[1]} }, } m["mi"] = { "Maori", 36451, "poz-pep", "Latn", sort_key = { remove_diacritics = c.macron, from = {"ng", "wh"}, to = {"n" .. p[1], "w" .. p[1]} }, } m["mk"] = { "Macedonian", 9296, "zls", "Cyrl, Polyt", ancestors = "cu", translit = { Cyrl = "mk-translit" }, display_text = { Polyt = s["Polyt-displaytext"] }, entry_name = { Cyrl = { remove_diacritics = c.acute, remove_exceptions = {"Ѓ", "ѓ", "Ќ", "ќ"} }, Polyt = s["Polyt-entryname"], }, sort_key = { Cyrl = { remove_diacritics = c.grave, remove_exceptions = {"ѓ", "ќ"}, from = {"ѓ", "ѕ", "ј", "љ", "њ", "ќ", "џ"}, to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "т" .. p[1], "ч" .. p[1]} }, Polyt = s["Polyt-sortkey"], }, standardChars = { Cyrl = "АаБбВвГгДдЃѓЕеЖжЗзЅѕИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЌќУуФфХхЦцЧчЏџШш", c.punc }, } m["ml"] = { "Malayalam", 36236, "dra-mal", "Mlym", translit = "ml-translit", override_translit = true, } m["mn"] = { "Mongolian", 9246, "xgn-cen", "Cyrl, Mong, Latn, Brai", ancestors = "cmg", translit = { Cyrl = "mn-translit", Mong = "Mong-translit", }, override_translit = true, display_text = { Mong = s["Mong-displaytext"] }, entry_name = { Cyrl = {remove_diacritics = c.grave .. c.acute}, Mong = s["Mong-entryname"], }, sort_key = { Cyrl = { remove_diacritics = c.grave, from = {"ё", "ө", "ү"}, to = {"е" .. p[1], "о" .. p[1], "у" .. p[1]} }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйЛлМмНнОоӨөРрСсТтУуҮүХхЦцЧчШшЫыЬьЭэЮюЯя—", Brai = c.braille, c.punc }, } -- "mo" IS TREATED AS "ro", SEE WT:LT m["mr"] = { "Marathi", 1571, "inc-sou", "Deva, Modi", ancestors = "omr", translit = { Deva = "mr-translit", Modi = "mr-Modi-translit", }, entry_name = { Deva = { from = {"च़", "ज़", "झ़"}, to = {"च", "ज", "झ"} }, }, } m["ms"] = { "Malay", 9237, "poz-mly", "Latn, ms-Arab", ancestors = "ms-cla", standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", c.punc }, } m["mt"] = { "Maltese", 9166, "sem-arb", "Latn", display_text = { from = {"'"}, to = {"’"} }, entry_name = { from = {"’"}, to = {"'"}, }, ancestors = "sqr", sort_key = { from = { "ċ", "ġ", "ż", -- Convert into PUA so that decomposed form does not get caught by the next step. "([cgz])", -- Ensure "c" comes after "ċ", "g" comes after "ġ" and "z" comes after "ż". "g" .. p[1] .. "ħ", -- "għ" after initial conversion of "g". p[3], p[4], "ħ", "ie", p[5] -- Convert "ċ", "ġ", "ħ", "ie", "ż" into final output. }, to = { p[3], p[4], p[5], "%1" .. p[1], "g" .. p[2], "c", "g", "h" .. p[1], "i" .. p[1], "z" } }, } m["my"] = { "Burmese", 9228, "tbq-brm", "Mymr", ancestors = "obr", translit = "my-translit", override_translit = true, sort_key = { from = {"ျ", "ြ", "ွ", "ှ", "ဿ"}, to = {"္ယ", "္ရ", "္ဝ", "္ဟ", "သ္သ"} }, } m["na"] = { "Nauruan", 13307, "poz-mic", "Latn", } m["nb"] = { "Norwegian Bokmål", 25167, "gmq", "Latn", wikimedia_codes = "no", ancestors = "gmq-mno, da", -- da as an (but not the) ancestor of nb was agreed on - do not change without discussion sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["nd"] = { "Northern Ndebele", 35613, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["ne"] = { "Nepali", 33823, "inc-pah", "Deva, Newa", translit = { Deva = "ne-translit" }, } m["ng"] = { "Ndonga", 33900, "bnt-ova", "Latn", } m["nl"] = { "Dutch", 7411, "gmw-frk", "Latn, Brai", ancestors = "dum", sort_key = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'"}, }, standardChars = { Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", Brai = c.braille, c.punc }, } m["nn"] = { "Norwegian Nynorsk", 25164, "gmq-wes", "Latn", ancestors = "gmq-mno", entry_name = { remove_diacritics = c.grave .. c.acute, }, sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["no"] = { "Norwegian", 9043, "gmq-wes", "Latn", ancestors = "gmq-mno", sort_key = s["no-sortkey"], standardChars = s["no-standardchars"], } m["nr"] = { "Southern Ndebele", 36785, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["nv"] = { "Navajo", 13310, "apa", "Latn, Brai", sort_key = { remove_diacritics = c.acute .. c.ogonek, from = { "chʼ", "tłʼ", "tsʼ", -- 3 chars "ch", "dl", "dz", "gh", "hw", "kʼ", "kw", "sh", "tł", "ts", "zh", -- 2 chars "ł", "ʼ" -- 1 char }, to = { "c" .. p[2], "t" .. p[2], "t" .. p[4], "c" .. p[1], "d" .. p[1], "d" .. p[2], "g" .. p[1], "h" .. p[1], "k" .. p[1], "k" .. p[2], "s" .. p[1], "t" .. p[1], "t" .. p[3], "z" .. p[1], "l" .. p[1], "z" .. p[2] } }, } m["ny"] = { "Chichewa", 33273, "bnt-nys", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ}, sort_key = { from = {"ng'"}, to = {"ng"} }, } m["oc"] = { "Occitan", 14185, "roa-ocr", "Latn, Hebr", ancestors = "pro", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla, from = {"([lns])·h"}, to = {"%1h"} }, Hebr = "Hebr-common", }, } m["oj"] = { "Ojibwe", 33875, "alg", "Cans, Latn", sort_key = { Latn = { from = {"aa", "ʼ", "ii", "oo", "sh", "zh"}, to = {"a" .. p[1], "h" .. p[1], "i" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1]} }, }, } m["om"] = { "Oromo", 33864, "cus-eas", "Latn, Ethi", } m["or"] = { "Odia", 33810, "inc-eas", "Orya", ancestors = "inc-mor", translit = "or-translit", } m["os"] = { "Ossetian", 33968, "xsc-sar", "Cyrl, Geor, Latn", ancestors = "oos", translit = { Cyrl = "os-translit", Geor = "Geor-translit", }, override_translit = true, display_text = { Cyrl = { from = {"æ"}, to = {"ӕ"} }, Latn = { from = {"ӕ"}, to = {"æ"} }, }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute, from = {"æ"}, to = {"ӕ"} }, Latn = { from = {"ӕ"}, to = {"æ"} }, }, sort_key = { Cyrl = { from = {"ӕ", "гъ", "дж", "дз", "ё", "къ", "пъ", "тъ", "хъ", "цъ", "чъ"}, to = {"а" .. p[1], "г" .. p[1], "д" .. p[1], "д" .. p[2], "е" .. p[1], "к" .. p[1], "п" .. p[1], "т" .. p[1], "х" .. p[1], "ц" .. p[1], "ч" .. p[1]} }, }, } m["pa"] = { "Punjabi", 58635, "inc-pan", "Guru, pa-Arab", ancestors = "inc-opa", translit = { Guru = "Guru-translit", ["pa-Arab"] = "pa-Arab-translit", }, entry_name = { ["pa-Arab"] = { remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna, from = {"ݨ", "ࣇ"}, to = {"ن", "ل"} }, }, } m["pi"] = { "Pali", 36727, "inc-mid", "Latn, Brah, Deva, Beng, Sinh, Mymr, Thai, Lana, Laoo, Khmr, Cakm", --and also Khom ancestors = "sa", translit = { Brah = "Brah-translit", Deva = "sa-translit", Beng = "pi-translit", Sinh = "si-translit", Mymr = "pi-translit", Thai = "pi-translit", Lana = "pi-translit", Laoo = "pi-translit", Khmr = "pi-translit", Cakm = "Cakm-translit", }, entry_name = { Thai = { from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here. to = {"ิํ", "ฐ", "ญ"} }, remove_diacritics = c.VS01 }, sort_key = { -- FIXME: This needs to be converted into the current standardized format. from = {"ā", "ī", "ū", "ḍ", "ḷ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṭ", "([เโ])([ก-ฮ])", "([ເໂ])([ກ-ຮ])", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", u(0xFE00), u(0x200D)}, to = {"a~", "i~", "u~", "d~", "l~", "m~", "n~", "n~~", "n~~~", "t~", "%2%1", "%2%1", "ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"} }, } m["pl"] = { "Polish", 809, "zlw-lch", "Latn", ancestors = "zlw-mpl", sort_key = { from = {"ą", "ć", "ę", "ł", "ń", "ó", "ś", "ź", "ż"}, to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1], "z" .. p[2]} }, standardChars = "AaĄąBbCcĆćDdEeĘęFfGgHhIiJjKkLlŁłMmNnŃńOoÓóPpRrSsŚśTtUuWwYyZzŹźŻż" .. c.punc, } m["ps"] = { "Pashto", 58680, "ira-pat", "ps-Arab", entry_name = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.zwarakay .. c.superalef}, } m["pt"] = { "Portuguese", 5146, "roa-gap", "Latn, Brai", sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla, from = {"ª", "æ", "º", "œ"}, to = {"a", "ae", "o", "oe"} }, }, standardChars = { Latn = "AaÁáÂâÃãBbCcÇçDdEeÉéÊêFfGgHhIiÍíJjLlMmNnOoÓóÔôÕõPpQqRrSsTtUuÚúVvXxZz", Brai = c.braille, c.punc }, } m["qu"] = { "Quechua", 5218, "qwe", "Latn", } m["rm"] = { "Romansch", 13199, "roa-rhe", "Latn", sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.small_e}, } m["ro"] = { "Romanian", 7913, "roa-eas", "Latn, Cyrl, Cyrs", translit = { Cyrl = "ro-translit" }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute, from = {"ă", "â", "î", "ș", "ț"}, to = {"a" .. p[1], "a" .. p[2], "i" .. p[1], "s" .. p[1], "t" .. p[1]} }, Cyrl = { from = {"ӂ"}, to = {"ж" .. p[1]} }, }, standardChars = { Latn = "AaĂăÂâBbCcDdEeFfGgHhIiÎîJjLlMmNnOoPpRrSsȘșTtȚțUuVvXxZz", Cyrl = "АаБбВвГгДдЕеЖжӁӂЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЫыЬьЭэЮюЯя", c.punc }, } m["ru"] = { "Russian", 7737, "zle", "Cyrl, Brai", ancestors = "zle-mru", translit = { Cyrl = "ru-translit" }, display_text = { Cyrl = { from = {"'"}, to = {"’"} }, }, entry_name = { Cyrl = { remove_diacritics = c.grave .. c.acute .. c.diaer, remove_exceptions = {"Ё", "ё", "Ѣ̈", "ѣ̈", "Я̈", "я̈"}, from = {"’"}, to = {"'"}, }, }, sort_key = { Cyrl = { remove_diacritics = c.grave .. c.acute .. c.diaer, from = { "і", "ѣ", "ѳ", "ѵ" }, to = { "и" .. p[1], "ь" .. p[1], "я" .. p[2], "я" .. p[3] } }, }, standardChars = { Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя—", Brai = c.braille, (c.punc:gsub("'", "")) -- Exclude apostrophe. }, } m["rw"] = { "Rwanda-Rundi", 3217514, "bnt-glb", "Latn", entry_name = {remove_diacritics = c.acute .. c.circ .. c.macron .. c.caron}, } m["sa"] = { "Sanskrit", 11059, "inc", "as-Beng, Bali, Beng, Bhks, Brah, Mymr, xwo-Mong, Deva, Gujr, Guru, Gran, Hani, Java, Kthi, Knda, Kawi, Khar, Khmr, Laoo, Mlym, mnc-Mong, Marc, Modi, Mong, Nand, Newa, Orya, Phag, Ranj, Saur, Shrd, Sidd, Sinh, Soyo, Lana, Takr, Taml, Tang, Telu, Thai, Tibt, Tutg, Tirh, Zanb", --and also Khom; script codes sorted by canonical name rather than code for [[MOD:sa-convert]] translit = { Beng = "sa-Beng-translit", ["as-Beng"] = "sa-Beng-translit", Brah = "Brah-translit", Deva = "sa-translit", Gujr = "sa-Gujr-translit", Guru = "sa-Guru-translit", Java = "sa-Java-translit", Kthi = "sa-Kthi-translit", Khmr = "pi-translit", Knda = "sa-Knda-translit", Lana = "pi-translit", Laoo = "pi-translit", Mlym = "sa-Mlym-translit", Modi = "sa-Modi-translit", Mong = "Mong-translit", ["mnc-Mong"] = "mnc-translit", ["xwo-Mong"] = "xal-translit", Mymr = "pi-translit", Orya = "sa-Orya-translit", Shrd = "Shrd-translit", Sidd = "Sidd-translit", Sinh = "si-translit", Taml = "sa-Taml-translit", Telu = "sa-Telu-translit", Thai = "pi-translit", Tibt = "Tibt-translit", }, display_text = { Mong = s["Mong-displaytext"], Tibt = s["Tibt-displaytext"], }, entry_name = { Mong = s["Mong-entryname"], Tibt = s["Tibt-entryname"], Thai = { from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here. to = {"ิํ", "ฐ", "ญ"} }, remove_diacritics = c.VS01 .. c.udatta .. c.anudatta }, sort_key = { Tibt = "Tibt-sortkey", { -- FIXME: This needs to be converted into the current standardized format. from = {"ā", "ī", "ū", "ḍ", "ḷ", "ḹ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṛ", "ṝ", "ś", "ṣ", "ṭ", "([เโไ])([ก-ฮ])", "([ເໂໄ])([ກ-ຮ])", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", u(0xFE00), u(0x200D)}, to = {"a~", "i~", "u~", "d~", "l~", "l~~", "m~", "n~", "n~~", "n~~~", "r~", "r~~", "s~", "s~~", "t~", "%2%1", "%2%1", "ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"}, }, }, } m["sc"] = { "Sardinian", 33976, "roa-sou", "Latn", } m["sd"] = { "Sindhi", 33997, "inc-snd", "sd-Arab, Deva, Sind, Khoj", translit = { Sind = "Sind-translit" }, entry_name = { ["sd-Arab"] = { remove_diacritics = c.kashida .. c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, from = {"ٱ"}, to = {"ا"} }, }, } m["se"] = { "Northern Sami", 33947, "smi", "Latn", display_text = { from = {"'"}, to = {"ˈ"} }, entry_name = {remove_diacritics = c.macron .. c.dotbelow .. "'ˈ"}, sort_key = { from = {"á", "č", "đ", "ŋ", "š", "ŧ", "ž"}, to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "n" .. p[1], "s" .. p[1], "t" .. p[1], "z" .. p[1]} }, standardChars = "AaÁáBbCcČčDdĐđEeFfGgHhIiJjKkLlMmNnŊŋOoPpRrSsŠšTtŦŧUuVvZzŽž" .. c.punc, } m["sg"] = { "Sango", 33954, "crp", "Latn", ancestors = "ngb", } m["sh"] = { "Serbo-Croatian", 9301, "zls", "Latn, Cyrl, Glag, Arab", ietf_subtag = "hbs", -- ISO 639-3 code, since "sh" is deprecated from ISO 639-1 wikimedia_codes = "sh, bs, hr, sr", entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"Ć", "ć", "Ś", "ś", "Ź", "ź"} }, Cyrl = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"З́", "з́", "С́", "с́"} }, }, sort_key = { Latn = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"ć", "ś", "ź"}, from = {"č", "ć", "dž", "đ", "lj", "nj", "š", "ś", "ž", "ź"}, to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "z" .. p[1], "z" .. p[2]} }, Cyrl = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {"з́", "с́"}, from = {"ђ", "з́", "ј", "љ", "њ", "с́", "ћ", "џ"}, to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "с" .. p[1], "т" .. p[1], "ч" .. p[1]} }, }, standardChars = { Latn = "AaBbCcČčĆćDdĐđEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž", Cyrl = "АаБбВвГгДдЂђЕеЖжЗзИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЋћУуФфХхЦцЧчЏџШш", c.punc }, } m["si"] = { "Sinhalese", 13267, "inc-ins", "Sinh", translit = "si-translit", override_translit = true, } m["sk"] = { "Slovak", 9058, "zlw", "Latn", ancestors = "zlw-osk", sort_key = {remove_diacritics = c.acute .. c.circ .. c.diaer .. c.caron}, standardChars = "AaÁáÄäBbCcČčDdĎďEeÉéFfGgHhIiÍíJjKkLlĹ弾MmNnŇňOoÓóÔôPpRrŔŕSsŠšTtŤťUuÚúVvYyÝýZzŽž" .. c.punc, } m["sl"] = { "Slovene", 9063, "zls", "Latn", entry_name = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.dgrave .. c.invbreve .. c.dotbelow, remove_exceptions = {"Ć", "ć", "Ǵ", "ǵ", "Ś", "ś", "Ź", "ź"}, from = {"Ə", "ə", "Ł", "ł"}, to = {"E", "e", "L", "l"}, }, sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dotabove .. c.ringabove .. c.dgrave .. c.invbreve .. c.dotbelow .. c.ringbelow .. c.ogonek, remove_exceptions = {"ć", "ǵ", "ś", "ź"}, from = {"ä", "č", "ć", "đ", "ə", "ë", "ǧ", "ǵ", "ï", "ł", "ö", "š", "ś", "ü", "ž", "ź"}, to = {"a" .. p[1], "c" .. p[1], "c" .. p[2], "d" .. p[1], "e", "e" .. p[1], "g" .. p[1], "g" .. p[2], "i" .. p[1], "l", "o" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]}, }, standardChars = "AaBbCcČčDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž" .. c.punc, } m["sm"] = { "Samoan", 34011, "poz-pnp", "Latn", } m["sn"] = { "Shona", 34004, "bnt-sho", "Latn", entry_name = {remove_diacritics = c.acute}, } m["so"] = { "Somali", 13275, "cus-som", "Latn, Arab, Osma", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ} }, } m["sq"] = { "Albanian", 8748, "sqj", "Latn, Grek, ota-Arab, Elba, Todr, Vith", translit = { Elba = "Elba-translit", }, display_text = { Grek = s["Grek-displaytext"], }, entry_name = { Latn = { remove_diacritics = c.acute .. c.circ, from = {'^[ie] (%w)', '^të (%w)'}, to = {'%1', '%1'}, }, Grek = { -- Diacritic removal from Grek-entryname excluded. from = s["Grek-entryname"].from, to = s["Grek-entryname"].to, }, }, sort_key = { Latn = { remove_diacritics = c.acute .. c.circ .. c.tilde .. c.breve .. c.caron, from = {'^[ie] (%w)', '^të (%w)', 'ç', 'dh', 'ë', 'gj', 'll', 'nj', 'rr', 'sh', 'th', 'xh', 'zh'}, to = {'%1', '%1', 'c'..p[1], 'd'..p[1], 'e'..p[1], 'g'..p[1], 'l'..p[1], 'n'..p[1], 'r'..p[1], 's'..p[1], 't'..p[1], 'x'..p[1], 'z'..p[1]}, } -- TODO: Grek }, standardChars = { Latn = "AaBbCcÇçDdEeËëFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZz", c.punc }, } m["ss"] = { "Swazi", 34014, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["st"] = { "Sotho", 34340, "bnt-sts", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["su"] = { "Sundanese", 34002, "poz-msa", "Latn, Sund, Arab", ancestors = "osn", translit = { Sund = "Sund-translit" }, } m["sv"] = { "Swedish", 9027, "gmq-eas", "Latn", ancestors = "gmq-osw-lat", sort_key = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla .. "':", remove_exceptions = {"å"}, from = {"ø", "æ", "œ", "ß", "å", "aͤ", "oͤ"}, to = {"o", "ae", "oe", "ss", "z" .. p[1], "ä", "ö"} }, standardChars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvXxYyÅåÄäÖö" .. c.punc, } m["sw"] = { "Swahili", 7838, "bnt-swh", "Latn, Arab", sort_key = { Latn = { from = {"ng'"}, to = {"ng" .. p[1]} }, }, } m["ta"] = { "Tamil", 5885, "dra-tam", "Taml", ancestors = "ta-mid", translit = "ta-translit", override_translit = true, } m["te"] = { "Telugu", 8097, "dra-tel", "Telu", translit = "te-translit", override_translit = true, } m["tg"] = { "Tajik", 9260, "ira-swi", "Cyrl, fa-Arab, Latn", ancestors = "fa-cls", translit = { Cyrl = "tg-translit" }, override_translit = true, entry_name = { Cyrl = s["tg-entryname"], Latn = s["tg-entryname"], }, sort_key = { Cyrl = { from = {"ғ", "ё", "ӣ", "қ", "ӯ", "ҳ", "ҷ"}, to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "к" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]} }, }, } m["th"] = { "Thai", 9217, "tai-swe", "Thai, Khomt, Brai", translit = { Thai = "th-translit" }, sort_key = { Thai = "Thai-sortkey" }, } m["ti"] = { "Tigrinya", 34124, "sem-eth", "Ethi", translit = "Ethi-translit", } m["tk"] = { "Turkmen", 9267, "trk-ogz", "Latn, Cyrl, Arab", entry_name = { Latn = s["tk-entryname"], Cyrl = s["tk-entryname"], }, sort_key = { Latn = { from = {"ç", "ä", "ž", "ň", "ö", "ş", "ü", "ý"}, to = {"c" .. p[1], "e" .. p[1], "j" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "y" .. p[1]} }, Cyrl = { from = {"ё", "җ", "ң", "ө", "ү", "ә"}, to = {"е" .. p[1], "ж" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "э" .. p[1]} }, }, ancestors = "trk-eog", } m["tl"] = { "Tagalog", 34057, "phi", "Latn, Tglg", translit = { Tglg = "tl-translit" }, override_translit = true, entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.circ} }, standardChars = { Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy", c.punc }, sort_key = { Latn = "tl-sortkey", }, } m["tn"] = { "Tswana", 34137, "bnt-sts", "Latn", } m["to"] = { "Tongan", 34094, "poz-ton", "Latn", entry_name = {remove_diacritics = c.acute}, sort_key = {remove_diacritics = c.macron}, } m["tr"] = { "Turkish", 256, "trk-ogz", "Latn", ancestors = "ota", dotted_dotless_i = true, sort_key = { from = { -- Ignore circumflex, but account for capital Î wrongly becoming ı + circ due to dotted dotless I logic. "ı" .. c.circ, c.circ, "i", -- Ensure "i" comes after "ı". "ç", "ğ", "ı", "ö", "ş", "ü" }, to = { "i", "", "i" .. p[1], "c" .. p[1], "g" .. p[1], "i", "o" .. p[1], "s" .. p[1], "u" .. p[1] } }, standardChars = "AaÂâBbCcÇçDdEeFfGgĞğHhIıİiÎîJjKkLlMmNnOoÖöPpRrSsŞşTtUuÛûÜüVvYyZz" .. c.punc, } m["ts"] = { "Tsonga", 34327, "bnt-tsr", "Latn", } m["tt"] = { "Tatar", 25285, "trk-kbu", "Cyrl, Latn, tt-Arab", translit = { Cyrl = "tt-translit" }, override_translit = false, -- until Module code can detect Russian loans such as [[аэропорт]] dotted_dotless_i = true, sort_key = { Cyrl = { from = {"ә", "ў", "ғ", "ё", "җ", "қ", "ң", "ө", "ү", "һ"}, to = {"а" .. p[1], "в" .. p[1], "г" .. p[1], "е" .. p[1], "ж" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1]} }, Latn = { from = { "i", -- Ensure "i" comes after "ı". "ä", "ə", "ç", "ğ", "ı", "ñ", "ŋ", "ö", "ɵ", "ş", "ü" }, to = { "i" .. p[1], "a" .. p[1], "a" .. p[2], "c" .. p[1], "g" .. p[1], "i", "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "s" .. p[1], "u" .. p[1] } }, }, } -- "tw" IS TREATED AS "ak", SEE WT:LT m["ty"] = { "Tahitian", 34128, "poz-pep", "Latn", } m["ug"] = { "Uyghur", 13263, "trk-kar", "ug-Arab, Latn, Cyrl", ancestors = "chg", translit = { ["ug-Arab"] = "ug-translit", Cyrl = "ug-translit", }, override_translit = true, } m["uk"] = { "Ukrainian", 8798, "zle", "Cyrl", ancestors = "zle-muk", translit = "uk-translit", entry_name = {remove_diacritics = c.grave .. c.acute}, sort_key = { remove_diacritics = c.grave .. c.acute, from = { "ї", -- 2 chars "ґ", "є", "і" -- 1 char }, to = { "и" .. p[2], "г" .. p[1], "е" .. p[1], "и" .. p[1] } }, standardChars = "АаБбВвГгДдЕеЄєЖжЗзИиІіЇїЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЬьЮюЯя" .. c.punc:gsub("'", ""), -- Exclude apostrophe. } m["ur"] = { "Urdu", 1617, "inc-hnd", "ur-Arab, Hebr", translit = { ["ur-Arab"] = "ur-translit" }, display_text = { Hebr = "Hebr-common", }, entry_name = { ["ur-Arab"] = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, standardChars = { ["ur-Arab"] = "ایببپتثجچحخدذرزژسشصضطظعغفقکگلࣇڷمنݨوؤہھئٹڈڑآے", c.punc, }, } m["uz"] = { "Uzbek", 9264, "trk-kar", "Latn, Cyrl, fa-Arab", ancestors = "chg", translit = { Cyrl = "uz-translit" }, sort_key = { Latn = { from = {"oʻ", "gʻ", "sh", "ch", "ng"}, to = {"z" .. p[1], "z" .. p[2], "z" .. p[3], "z" .. p[4], "z" .. p[5]} }, Cyrl = { from = {"ё", "ў", "қ", "ғ", "ҳ"}, to = {"е" .. p[1], "я" .. p[1], "я" .. p[2], "я" .. p[3], "я" .. p[4]} }, }, entry_name = { ["fa-Arab"] = "ar-entryname", }, } m["ve"] = { "Venda", 32704, "bnt-bso", "Latn", } m["vi"] = { "Vietnamese", 9199, "mkh-vie", "Latn, Hani", ancestors = "mkh-mvi", sort_key = { Latn = "vi-sortkey", Hani = "Hani-sortkey", }, } m["vo"] = { "Volapük", 36986, "art", "Latn", } m["wa"] = { "Walloon", 34219, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["wo"] = { "Wolof", 34257, "alv-fwo", "Latn, Arab, Gara", } m["xh"] = { "Xhosa", 13218, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } m["yi"] = { "Yiddish", 8641, "gmw-hgm", "Hebr, Latn", ancestors = "gmh", translit = { Hebr = "yi-translit", }, display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["yo"] = { "Yoruba", 34311, "alv-yor", "Latn, Arab", entry_name = { Latn = {remove_diacritics = c.grave .. c.acute .. c.macron} }, sort_key = { Latn = { from = {"ẹ", "ɛ", "gb", "ị", "kp", "ọ", "ɔ", "ṣ", "sh", "ụ"}, to = {"e" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "o" .. p[1], "o" .. p[1], "s" .. p[1], "s" .. p[1], "u" .. p[1]} }, }, } m["za"] = { "Zhuang", 13216, "tai", "Latn, Hani", sort_key = { Latn = "za-sortkey", Hani = "Hani-sortkey", }, } m["zh"] = { "Chinese", 7850, "zhx", "Hants, Latn, Bopo, Nshu, Brai", ancestors = "ltc", generate_forms = "zh-generateforms", translit = { Hani = "zh-translit", Bopo = "zh-translit", }, sort_key = { Hani = "Hani-sortkey" }, } m["zu"] = { "Zulu", 10179, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, } return require("Module:languages").finalizeData(m, "language") i0jc3kit8zdle0lkybvkdlrypii56t1 Modul:scripts/data 828 3702 26539 8039 2025-11-08T17:21:45Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26539 Scribunto text/plain --[=[ When adding new scripts to this file, please don't forget to add style definitons for the script in [[MediaWiki:Gadget-LanguagesAndScripts.css]]. ]=] local concat = table.concat local insert = table.insert local ipairs = ipairs local next = next local remove = table.remove local select = select local sort = table.sort -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end ------------------------------------------------------------------------------------ -- -- Helper functions -- ------------------------------------------------------------------------------------ -- Note: a[2] > b[2] means opens are sorted before closes if otherwise equal. local function sort_ranges(a, b) return a[1] < b[1] or a[1] == b[1] and a[2] > b[2] end -- Returns the union of two or more range tables. local function union(...) local ranges = {} for i = 1, select("#", ...) do local argt = select(i, ...) for j, v in ipairs(argt) do insert(ranges, {v, j % 2 == 1 and 1 or -1}) end end sort(ranges, sort_ranges) local ret, i = {}, 0 for _, range in ipairs(ranges) do i = i + range[2] if i == 0 and range[2] == -1 then -- close insert(ret, range[1]) elseif i == 1 and range[2] == 1 then -- open if ret[#ret] and range[1] <= ret[#ret] + 1 then remove(ret) -- merge adjacent ranges else insert(ret, range[1]) end end end return ret end -- Adds the `characters` key, which is determined by a script's `ranges` table. local function process_ranges(sc) local ranges, chars = sc.ranges, {} for i = 2, #ranges, 2 do if ranges[i] == ranges[i - 1] then insert(chars, u(ranges[i])) else insert(chars, u(ranges[i - 1])) if ranges[i] > ranges[i - 1] + 1 then insert(chars, "-") end insert(chars, u(ranges[i])) end end sc.characters = concat(chars) ranges.n = #ranges return sc end local function handle_normalization_fixes(fixes) local combiningClasses = fixes.combiningClasses if combiningClasses then local chars, i = {}, 0 for char in next, combiningClasses do i = i + 1 chars[i] = char end fixes.combiningClassCharacters = concat(chars) end return fixes end ------------------------------------------------------------------------------------ -- -- Data -- ------------------------------------------------------------------------------------ local m = {} m["Adlm"] = process_ranges{ "Adlam", 19606346, "alphabet", ranges = { 0x061F, 0x061F, 0x0640, 0x0640, 0x1E900, 0x1E94B, 0x1E950, 0x1E959, 0x1E95E, 0x1E95F, }, capitalized = true, direction = "rtl", } m["Afak"] = { "Afaka", 382019, "syllabary", -- Not in Unicode } m["Aghb"] = process_ranges{ "Caucasian Albanian", 2495716, "alphabet", ranges = { 0x10530, 0x10563, 0x1056F, 0x1056F, }, } m["Ahom"] = process_ranges{ "Ahom", 2839633, "abugida", ranges = { 0x11700, 0x1171A, 0x1171D, 0x1172B, 0x11730, 0x11746, }, } m["Arab"] = process_ranges{ "Arabic", 1828555, "abjad", -- more precisely, impure abjad varieties = {"Jawi", {"Nastaliq", "Nastaleeq"}}, ranges = { 0x0600, 0x06FF, 0x0750, 0x077F, 0x0870, 0x088E, 0x0890, 0x0891, 0x0897, 0x08E1, 0x08E3, 0x08FF, 0xFB50, 0xFBC2, 0xFBD3, 0xFD8F, 0xFD92, 0xFDC7, 0xFDCF, 0xFDCF, 0xFDF0, 0xFDFF, 0xFE70, 0xFE74, 0xFE76, 0xFEFC, 0x102E0, 0x102FB, 0x10E60, 0x10E7E, 0x10EC2, 0x10EC4, 0x10EFC, 0x10EFF, 0x1EE00, 0x1EE03, 0x1EE05, 0x1EE1F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE24, 0x1EE27, 0x1EE27, 0x1EE29, 0x1EE32, 0x1EE34, 0x1EE37, 0x1EE39, 0x1EE39, 0x1EE3B, 0x1EE3B, 0x1EE42, 0x1EE42, 0x1EE47, 0x1EE47, 0x1EE49, 0x1EE49, 0x1EE4B, 0x1EE4B, 0x1EE4D, 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE54, 0x1EE57, 0x1EE57, 0x1EE59, 0x1EE59, 0x1EE5B, 0x1EE5B, 0x1EE5D, 0x1EE5D, 0x1EE5F, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE64, 0x1EE67, 0x1EE6A, 0x1EE6C, 0x1EE72, 0x1EE74, 0x1EE77, 0x1EE79, 0x1EE7C, 0x1EE7E, 0x1EE7E, 0x1EE80, 0x1EE89, 0x1EE8B, 0x1EE9B, 0x1EEA1, 0x1EEA3, 0x1EEA5, 0x1EEA9, 0x1EEAB, 0x1EEBB, 0x1EEF0, 0x1EEF1, }, direction = "rtl", normalizationFixes = handle_normalization_fixes{ from = {"ٳ"}, to = {"اٟ"} }, } m["fa-Arab"] = { "Arabic", 744068, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, otherNames = {"Perso-Arabic"}, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["kk-Arab"] = { "Arabic", 90681452, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["ks-Arab"] = m["fa-Arab"] m["ku-Arab"] = m["fa-Arab"] m["ms-Arab"] = m["kk-Arab"] m["mzn-Arab"] = m["fa-Arab"] m["ota-Arab"] = m["fa-Arab"] m["pa-Arab"] = { "Shahmukhi", 133800, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, otherNames = {"Arabic"}, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["ps-Arab"] = m["fa-Arab"] m["sd-Arab"] = m["fa-Arab"] m["tt-Arab"] = m["fa-Arab"] m["ug-Arab"] = m["fa-Arab"] m["ur-Arab"] = m["fa-Arab"] -- Aran (Nastaliq) is subsumed into Arab m["Armi"] = process_ranges{ "Imperial Aramaic", 26978, "abjad", ranges = { 0x10840, 0x10855, 0x10857, 0x1085F, }, direction = "rtl", } m["Armn"] = process_ranges{ "Armenian", 11932, "alphabet", ranges = { 0x0531, 0x0556, 0x0559, 0x058A, 0x058D, 0x058F, 0xFB13, 0xFB17, }, capitalized = true, } m["Avst"] = process_ranges{ "Avestan", 790681, "alphabet", ranges = { 0x10B00, 0x10B35, 0x10B39, 0x10B3F, }, direction = "rtl", } m["pal-Avst"] = { "Pazend", 4925073, m["Avst"][3], ranges = m["Avst"].ranges, characters = m["Avst"].characters, direction = "rtl", parent = "Avst", } m["Bali"] = process_ranges{ "Balinese", 804984, "abugida", ranges = { 0x1B00, 0x1B4C, 0x1B4E, 0x1B7F, }, } m["Bamu"] = process_ranges{ "Bamum", 806024, "syllabary", ranges = { 0xA6A0, 0xA6F7, 0x16800, 0x16A38, }, } m["Bass"] = process_ranges{ "Bassa", 810458, "alphabet", aliases = {"Bassa Vah", "Vah"}, ranges = { 0x16AD0, 0x16AED, 0x16AF0, 0x16AF5, }, } m["Batk"] = process_ranges{ "Batak", 51592, "abugida", ranges = { 0x1BC0, 0x1BF3, 0x1BFC, 0x1BFF, }, } m["Beng"] = process_ranges{ "Bengali", 756802, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0980, 0x0983, 0x0985, 0x098C, 0x098F, 0x0990, 0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B2, 0x09B2, 0x09B6, 0x09B9, 0x09BC, 0x09C4, 0x09C7, 0x09C8, 0x09CB, 0x09CE, 0x09D7, 0x09D7, 0x09DC, 0x09DD, 0x09DF, 0x09E3, 0x09E6, 0x09EF, 0x09F2, 0x09FE, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD2, 0x1CD5, 0x1CD6, 0x1CD8, 0x1CD8, 0x1CE1, 0x1CE1, 0x1CEA, 0x1CEA, 0x1CED, 0x1CED, 0x1CF2, 0x1CF2, 0x1CF5, 0x1CF7, 0xA8F1, 0xA8F1, }, normalizationFixes = handle_normalization_fixes{ from = {"অা", "ঋৃ", "ঌৢ"}, to = {"আ", "ৠ", "ৡ"} }, } m["as-Beng"] = process_ranges{ "Assamese", 191272, m["Beng"][3], otherNames = {"Eastern Nagari"}, ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0980, 0x0983, 0x0985, 0x098C, 0x098F, 0x0990, 0x0993, 0x09A8, 0x09AA, 0x09AF, 0x09B2, 0x09B2, 0x09B6, 0x09B9, 0x09BC, 0x09C4, 0x09C7, 0x09C8, 0x09CB, 0x09CE, 0x09D7, 0x09D7, 0x09DC, 0x09DD, 0x09DF, 0x09E3, 0x09E6, 0x09FE, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD2, 0x1CD5, 0x1CD6, 0x1CD8, 0x1CD8, 0x1CE1, 0x1CE1, 0x1CEA, 0x1CEA, 0x1CED, 0x1CED, 0x1CF2, 0x1CF2, 0x1CF5, 0x1CF7, 0xA8F1, 0xA8F1, }, normalizationFixes = m["Beng"].normalizationFixes, } m["Bhks"] = process_ranges{ "Bhaiksuki", 17017839, "abugida", ranges = { 0x11C00, 0x11C08, 0x11C0A, 0x11C36, 0x11C38, 0x11C45, 0x11C50, 0x11C6C, }, } m["Blis"] = { "Blissymbolic", 609817, "logography", aliases = {"Blissymbols"}, -- Not in Unicode } m["Bopo"] = process_ranges{ "Zhuyin", 198269, "semisyllabary", aliases = {"Zhuyin Fuhao", "Bopomofo"}, ranges = { 0x02EA, 0x02EB, 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x302A, 0x302D, 0x3030, 0x3030, 0x3037, 0x3037, 0x30FB, 0x30FB, 0x3105, 0x312F, 0x31A0, 0x31BF, 0xFE45, 0xFE46, 0xFF61, 0xFF65, }, } m["Brah"] = process_ranges{ "Brahmi", 185083, "abugida", ranges = { 0x11000, 0x1104D, 0x11052, 0x11075, 0x1107F, 0x1107F, }, normalizationFixes = handle_normalization_fixes{ from = {"𑀅𑀸", "𑀋𑀾", "𑀏𑁂"}, to = {"𑀆", "𑀌", "𑀐"} }, } m["Brai"] = process_ranges{ "Braille", 79894, "alphabet", ranges = { 0x2800, 0x28FF, }, } m["Bugi"] = process_ranges{ "Lontara", 1074947, "abugida", aliases = {"Buginese"}, ranges = { 0x1A00, 0x1A1B, 0x1A1E, 0x1A1F, 0xA9CF, 0xA9CF, }, } m["Buhd"] = process_ranges{ "Buhid", 1002969, "abugida", ranges = { 0x1735, 0x1736, 0x1740, 0x1751, 0x1752, 0x1753, }, } m["Cakm"] = process_ranges{ "Chakma", 1059328, "abugida", ranges = { 0x09E6, 0x09EF, 0x1040, 0x1049, 0x11100, 0x11134, 0x11136, 0x11147, }, } m["Cans"] = process_ranges{ "Canadian syllabic", 2479183, "abugida", ranges = { 0x1400, 0x167F, 0x18B0, 0x18F5, 0x11AB0, 0x11ABF, }, } m["Cari"] = process_ranges{ "Carian", 1094567, "alphabet", ranges = { 0x102A0, 0x102D0, }, } m["Cham"] = process_ranges{ "Cham", 1060381, "abugida", ranges = { 0xAA00, 0xAA36, 0xAA40, 0xAA4D, 0xAA50, 0xAA59, 0xAA5C, 0xAA5F, }, } m["Cher"] = process_ranges{ "Cherokee", 26549, "syllabary", ranges = { 0x13A0, 0x13F5, 0x13F8, 0x13FD, 0xAB70, 0xABBF, }, } m["Chis"] = { "Chisoi", 123173777, "abugida", -- Not in Unicode } m["Chrs"] = process_ranges{ "Khwarezmian", 72386710, "abjad", aliases = {"Chorasmian"}, ranges = { 0x10FB0, 0x10FCB, }, direction = "rtl", } m["Copt"] = process_ranges{ "Coptic", 321083, "alphabet", ranges = { 0x03E2, 0x03EF, 0x2C80, 0x2CF3, 0x2CF9, 0x2CFF, 0x102E0, 0x102FB, }, capitalized = true, } m["Cpmn"] = process_ranges{ "Cypro-Minoan", 1751985, "syllabary", aliases = {"Cypro Minoan"}, ranges = { 0x10100, 0x10101, 0x12F90, 0x12FF2, }, } m["Cprt"] = process_ranges{ "Cypriot", 1757689, "syllabary", ranges = { 0x10100, 0x10102, 0x10107, 0x10133, 0x10137, 0x1013F, 0x10800, 0x10805, 0x10808, 0x10808, 0x1080A, 0x10835, 0x10837, 0x10838, 0x1083C, 0x1083C, 0x1083F, 0x1083F, }, direction = "rtl", } m["Cyrl"] = process_ranges{ "Cyrillic", 8209, "alphabet", ranges = { 0x0400, 0x052F, 0x1C80, 0x1C8A, 0x1D2B, 0x1D2B, 0x1D78, 0x1D78, 0x1DF8, 0x1DF8, 0x2DE0, 0x2DFF, 0x2E43, 0x2E43, 0xA640, 0xA69F, 0xFE2E, 0xFE2F, 0x1E030, 0x1E06D, 0x1E08F, 0x1E08F, }, capitalized = true, } m["Cyrs"] = { "Old Cyrillic", 442244, m["Cyrl"][3], aliases = {"Early Cyrillic"}, ranges = m["Cyrl"].ranges, characters = m["Cyrl"].characters, capitalized = m["Cyrl"].capitalized, wikipedia_article = "Early Cyrillic alphabet", normalizationFixes = handle_normalization_fixes{ from = {"Ѹ", "ѹ"}, to = {"Ꙋ", "ꙋ"} }, } m["Deva"] = process_ranges{ "Devanagari", 38592, "abugida", ranges = { 0x0900, 0x097F, 0x1CD0, 0x1CF6, 0x1CF8, 0x1CF9, 0x20F0, 0x20F0, 0xA830, 0xA839, 0xA8E0, 0xA8FF, 0x11B00, 0x11B09, }, normalizationFixes = handle_normalization_fixes{ from = {"ॆॆ", "ेे", "ाॅ", "ाॆ", "ाꣿ", "ॊॆ", "ाे", "ाै", "ोे", "ाऺ", "ॖॖ", "अॅ", "अॆ", "अा", "एॅ", "एॆ", "एे", "एꣿ", "ऎॆ", "अॉ", "आॅ", "अॊ", "आॆ", "अो", "आे", "अौ", "आै", "ओे", "अऺ", "अऻ", "आऺ", "अाꣿ", "आꣿ", "ऒॆ", "अॖ", "अॗ", "ॶॖ", "्‍?ा"}, to = {"ꣿ", "ै", "ॉ", "ॊ", "ॏ", "ॏ", "ो", "ौ", "ौ", "ऻ", "ॗ", "ॲ", "ऄ", "आ", "ऍ", "ऎ", "ऐ", "ꣾ", "ꣾ", "ऑ", "ऑ", "ऒ", "ऒ", "ओ", "ओ", "औ", "औ", "औ", "ॳ", "ॴ", "ॴ", "ॵ", "ॵ", "ॵ", "ॶ", "ॷ", "ॷ"} }, } m["Diak"] = process_ranges{ "Dhives Akuru", 3307073, "abugida", aliases = {"Dhivehi Akuru", "Dives Akuru", "Divehi Akuru"}, ranges = { 0x11900, 0x11906, 0x11909, 0x11909, 0x1190C, 0x11913, 0x11915, 0x11916, 0x11918, 0x11935, 0x11937, 0x11938, 0x1193B, 0x11946, 0x11950, 0x11959, }, } m["Dogr"] = process_ranges{ "Dogra", 72402987, "abugida", ranges = { 0x0964, 0x096F, 0xA830, 0xA839, 0x11800, 0x1183B, }, } m["Dsrt"] = process_ranges{ "Deseret", 1200582, "alphabet", ranges = { 0x10400, 0x1044F, }, capitalized = true, } m["Dupl"] = process_ranges{ "Duployan", 5316025, "alphabet", ranges = { 0x1BC00, 0x1BC6A, 0x1BC70, 0x1BC7C, 0x1BC80, 0x1BC88, 0x1BC90, 0x1BC99, 0x1BC9C, 0x1BCA3, }, } m["Egyd"] = { "Demotic", 188519, "abjad, logography", -- Not in Unicode } m["Egyh"] = { "Hieratic", 208111, "abjad, logography", -- Unified with Egyptian hieroglyphic in Unicode } m["Egyp"] = process_ranges{ "Egyptian hieroglyphic", 132659, "abjad, logography", ranges = { 0x13000, 0x13455, 0x13460, 0x143FA, }, varieties = {"Hieratic"}, wikipedia_article = "Egyptian hieroglyphs", normalizationFixes = handle_normalization_fixes{ from = {"𓃁", "𓆖"}, to = {"𓃀𓐶𓂝", "𓆓𓐳𓐷𓏏𓐰𓇿𓐸"} }, } m["Elba"] = process_ranges{ "Elbasan", 1036714, "alphabet", ranges = { 0x10500, 0x10527, }, } m["Elym"] = process_ranges{ "Elymaic", 60744423, "abjad", ranges = { 0x10FE0, 0x10FF6, }, direction = "rtl", } m["Ethi"] = process_ranges{ "Ethiopic", 257634, "abugida", aliases = {"Ge'ez", "Geʽez"}, ranges = { 0x1200, 0x1248, 0x124A, 0x124D, 0x1250, 0x1256, 0x1258, 0x1258, 0x125A, 0x125D, 0x1260, 0x1288, 0x128A, 0x128D, 0x1290, 0x12B0, 0x12B2, 0x12B5, 0x12B8, 0x12BE, 0x12C0, 0x12C0, 0x12C2, 0x12C5, 0x12C8, 0x12D6, 0x12D8, 0x1310, 0x1312, 0x1315, 0x1318, 0x135A, 0x135D, 0x137C, 0x1380, 0x1399, 0x2D80, 0x2D96, 0x2DA0, 0x2DA6, 0x2DA8, 0x2DAE, 0x2DB0, 0x2DB6, 0x2DB8, 0x2DBE, 0x2DC0, 0x2DC6, 0x2DC8, 0x2DCE, 0x2DD0, 0x2DD6, 0x2DD8, 0x2DDE, 0xAB01, 0xAB06, 0xAB09, 0xAB0E, 0xAB11, 0xAB16, 0xAB20, 0xAB26, 0xAB28, 0xAB2E, 0x1E7E0, 0x1E7E6, 0x1E7E8, 0x1E7EB, 0x1E7ED, 0x1E7EE, 0x1E7F0, 0x1E7FE, }, } m["Gara"] = process_ranges{ "Garay", 3095302, "alphabet", capitalized = true, direction = "rtl", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x10D40, 0x10D65, 0x10D69, 0x10D85, 0x10D8E, 0x10D8F, }, } m["Geok"] = process_ranges{ "Khutsuri", 1090055, "alphabet", ranges = { -- Ⴀ-Ⴭ is Asomtavruli, ⴀ-ⴭ is Nuskhuri 0x10A0, 0x10C5, 0x10C7, 0x10C7, 0x10CD, 0x10CD, 0x10FB, 0x10FB, 0x2D00, 0x2D25, 0x2D27, 0x2D27, 0x2D2D, 0x2D2D, }, varieties = {"Nuskhuri", "Asomtavruli"}, capitalized = true, } m["Geor"] = process_ranges{ "Georgian", 3317411, "alphabet", ranges = { -- ა-ჿ is lowercase Mkhedruli; Ა-Ჿ is uppercase Mkhedruli (Mtavruli) 0x0589, 0x0589, 0x10D0, 0x10FF, 0x1C90, 0x1CBA, 0x1CBD, 0x1CBF, }, varieties = {"Mkhedruli", "Mtavruli"}, capitalized = true, } m["Glag"] = process_ranges{ "Glagolitic", 145625, "alphabet", ranges = { 0x0484, 0x0484, 0x0487, 0x0487, 0x0589, 0x0589, 0x10FB, 0x10FB, 0x2C00, 0x2C5F, 0x2E43, 0x2E43, 0xA66F, 0xA66F, 0x1E000, 0x1E006, 0x1E008, 0x1E018, 0x1E01B, 0x1E021, 0x1E023, 0x1E024, 0x1E026, 0x1E02A, }, capitalized = true, } m["Gong"] = process_ranges{ "Gunjala Gondi", 18125340, "abugida", ranges = { 0x0964, 0x0965, 0x11D60, 0x11D65, 0x11D67, 0x11D68, 0x11D6A, 0x11D8E, 0x11D90, 0x11D91, 0x11D93, 0x11D98, 0x11DA0, 0x11DA9, }, } m["Gonm"] = process_ranges{ "Masaram Gondi", 16977603, "abugida", ranges = { 0x0964, 0x0965, 0x11D00, 0x11D06, 0x11D08, 0x11D09, 0x11D0B, 0x11D36, 0x11D3A, 0x11D3A, 0x11D3C, 0x11D3D, 0x11D3F, 0x11D47, 0x11D50, 0x11D59, }, } m["Goth"] = process_ranges{ "Gothic", 467784, "alphabet", ranges = { 0x10330, 0x1034A, }, wikipedia_article = "Gothic alphabet", } m["Gran"] = process_ranges{ "Grantha", 1119274, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0BE6, 0x0BF3, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD3, 0x1CF2, 0x1CF4, 0x1CF8, 0x1CF9, 0x20F0, 0x20F0, 0x11300, 0x11303, 0x11305, 0x1130C, 0x1130F, 0x11310, 0x11313, 0x11328, 0x1132A, 0x11330, 0x11332, 0x11333, 0x11335, 0x11339, 0x1133B, 0x11344, 0x11347, 0x11348, 0x1134B, 0x1134D, 0x11350, 0x11350, 0x11357, 0x11357, 0x1135D, 0x11363, 0x11366, 0x1136C, 0x11370, 0x11374, 0x11FD0, 0x11FD1, 0x11FD3, 0x11FD3, }, } m["Grek"] = process_ranges{ "Greek", 8216, "alphabet", ranges = { 0x0341, 0x0341, 0x0374, 0x0375, 0x037E, 0x037E, 0x0384, 0x038A, 0x038C, 0x038C, 0x038E, 0x03A1, 0x03A3, 0x03D7, 0x03DA, 0x03DB, 0x03DE, 0x03E1, 0x03F0, 0x03F1, 0x03F4, 0x03F4, 0x03FC, 0x03FC, 0x1D26, 0x1D2A, 0x1D5D, 0x1D61, 0x1D66, 0x1D6A, 0x1DBF, 0x1DBF, 0x2126, 0x2127, 0x2129, 0x2129, 0x213C, 0x2140, 0xAB65, 0xAB65, 0x10140, 0x1018E, 0x101A0, 0x101A0, 0x1D200, 0x1D245, }, capitalized = true, } m["Polyt"] = process_ranges{ "Greek", 1475332, m["Grek"][3], ranges = union(m["Grek"].ranges, { 0x0340, 0x0340, 0x0342, 0x0345, 0x0370, 0x0373, 0x0376, 0x0377, 0x037A, 0x037D, 0x037F, 0x037F, 0x03D8, 0x03D9, 0x03DC, 0x03DD, 0x03F2, 0x03F3, 0x03F5, 0x03FB, 0x03FD, 0x03FF, 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D, 0x1F50, 0x1F57, 0x1F59, 0x1F59, 0x1F5B, 0x1F5B, 0x1F5D, 0x1F5D, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FC4, 0x1FC6, 0x1FD3, 0x1FD6, 0x1FDB, 0x1FDD, 0x1FEF, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFE, }), ietf_subtag = "Grek", capitalized = m["Grek"].capitalized, parent = "Grek", } m["Gujr"] = process_ranges{ "Gujarati", 733944, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0A81, 0x0A83, 0x0A85, 0x0A8D, 0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3, 0x0AB5, 0x0AB9, 0x0ABC, 0x0AC5, 0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0AD0, 0x0AD0, 0x0AE0, 0x0AE3, 0x0AE6, 0x0AF1, 0x0AF9, 0x0AFF, 0xA830, 0xA839, }, normalizationFixes = handle_normalization_fixes{ from = {"ઓ", "અાૈ", "અા", "અૅ", "અે", "અૈ", "અૉ", "અો", "અૌ", "આૅ", "આૈ", "ૅા"}, to = {"અાૅ", "ઔ", "આ", "ઍ", "એ", "ઐ", "ઑ", "ઓ", "ઔ", "ઓ", "ઔ", "ૉ"} }, } m["Gukh"] = process_ranges{ "Khema", 110064239, "abugida", aliases = {"Gurung Khema", "Khema Phri", "Khema Lipi"}, ranges = { 0x0965, 0x0965, 0x16100, 0x16139, }, } m["Guru"] = process_ranges{ "Gurmukhi", 689894, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0A01, 0x0A03, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10, 0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36, 0x0A38, 0x0A39, 0x0A3C, 0x0A3C, 0x0A3E, 0x0A42, 0x0A47, 0x0A48, 0x0A4B, 0x0A4D, 0x0A51, 0x0A51, 0x0A59, 0x0A5C, 0x0A5E, 0x0A5E, 0x0A66, 0x0A76, 0xA830, 0xA839, }, normalizationFixes = handle_normalization_fixes{ from = {"ਅਾ", "ਅੈ", "ਅੌ", "ੲਿ", "ੲੀ", "ੲੇ", "ੳੁ", "ੳੂ", "ੳੋ"}, to = {"ਆ", "ਐ", "ਔ", "ਇ", "ਈ", "ਏ", "ਉ", "ਊ", "ਓ"} }, } m["Hang"] = process_ranges{ "Hangul", 8222, "syllabary", aliases = {"Hangeul"}, ranges = { 0x1100, 0x11FF, 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x302E, 0x3030, 0x3037, 0x3037, 0x30FB, 0x30FB, 0x3131, 0x318E, 0x3200, 0x321E, 0x3260, 0x327E, 0xA960, 0xA97C, 0xAC00, 0xD7A3, 0xD7B0, 0xD7C6, 0xD7CB, 0xD7FB, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0xFFA0, 0xFFBE, 0xFFC2, 0xFFC7, 0xFFCA, 0xFFCF, 0xFFD2, 0xFFD7, 0xFFDA, 0xFFDC, }, } m["Hani"] = process_ranges{ "Han", 8201, "logography", ranges = { 0x2E80, 0x2E99, 0x2E9B, 0x2EF3, 0x2F00, 0x2FD5, 0x2FF0, 0x2FFF, 0x3001, 0x3003, 0x3005, 0x3011, 0x3013, 0x301F, 0x3021, 0x302D, 0x3030, 0x3030, 0x3037, 0x303F, 0x3190, 0x319F, 0x31C0, 0x31E5, 0x31EF, 0x31EF, 0x3220, 0x3247, 0x3280, 0x32B0, 0x32C0, 0x32CB, 0x30FB, 0x30FB, 0x32FF, 0x32FF, 0x3358, 0x3370, 0x337B, 0x337F, 0x33E0, 0x33FE, 0x3400, 0x4DBF, 0x4E00, 0x9FFF, 0xA700, 0xA707, 0xF900, 0xFA6D, 0xFA70, 0xFAD9, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0x16FE2, 0x16FE3, 0x16FF0, 0x16FF1, 0x1D360, 0x1D371, 0x1F250, 0x1F251, 0x20000, 0x2A6DF, 0x2A700, 0x2B739, 0x2B740, 0x2B81D, 0x2B820, 0x2CEA1, 0x2CEB0, 0x2EBE0, 0x2EBF0, 0x2EE5D, 0x2F800, 0x2FA1D, 0x30000, 0x3134A, 0x31350, 0x323AF, }, varieties = {"Hanzi", "Kanji", "Hanja", "Chu Nom"}, spaces = false, } m["Hans"] = { "Simplified Han", 185614, m["Hani"][3], ranges = m["Hani"].ranges, characters = m["Hani"].characters, spaces = m["Hani"].spaces, parent = "Hani", } m["Hant"] = { "Traditional Han", 178528, m["Hani"][3], ranges = m["Hani"].ranges, characters = m["Hani"].characters, spaces = m["Hani"].spaces, parent = "Hani", } m["Hano"] = process_ranges{ "Hanunoo", 1584045, "abugida", aliases = {"Hanunó'o", "Hanuno'o"}, ranges = { 0x1720, 0x1736, }, } m["Hatr"] = process_ranges{ "Hatran", 20813038, "abjad", ranges = { 0x108E0, 0x108F2, 0x108F4, 0x108F5, 0x108FB, 0x108FF, }, direction = "rtl", } m["Hebr"] = process_ranges{ "Hebrew", 33513, "abjad", -- more precisely, impure abjad ranges = { 0x0591, 0x05C7, 0x05D0, 0x05EA, 0x05EF, 0x05F4, 0x2135, 0x2138, 0xFB1D, 0xFB36, 0xFB38, 0xFB3C, 0xFB3E, 0xFB3E, 0xFB40, 0xFB41, 0xFB43, 0xFB44, 0xFB46, 0xFB4F, }, direction = "rtl", } m["Hira"] = process_ranges{ "Hiragana", 48332, "syllabary", ranges = { 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x3030, 0x3035, 0x3037, 0x3037, 0x303C, 0x303D, 0x3041, 0x3096, 0x3099, 0x30A0, 0x30FB, 0x30FC, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0xFF70, 0xFF70, 0xFF9E, 0xFF9F, 0x1B001, 0x1B11F, 0x1B132, 0x1B132, 0x1B150, 0x1B152, 0x1F200, 0x1F200, }, varieties = {"Hentaigana"}, spaces = false, } m["Hluw"] = process_ranges{ "Anatolian hieroglyphic", 521323, "logography, syllabary", ranges = { 0x14400, 0x14646, }, wikipedia_article = "Anatolian hieroglyphs", } m["Hmng"] = process_ranges{ "Pahawh Hmong", 365954, "semisyllabary", aliases = {"Hmong"}, ranges = { 0x16B00, 0x16B45, 0x16B50, 0x16B59, 0x16B5B, 0x16B61, 0x16B63, 0x16B77, 0x16B7D, 0x16B8F, }, } m["Hmnp"] = process_ranges{ "Nyiakeng Puachue Hmong", 33712499, "alphabet", ranges = { 0x1E100, 0x1E12C, 0x1E130, 0x1E13D, 0x1E140, 0x1E149, 0x1E14E, 0x1E14F, }, } m["Hung"] = process_ranges{ "Old Hungarian", 446224, "alphabet", aliases = {"Hungarian runic"}, ranges = { 0x10C80, 0x10CB2, 0x10CC0, 0x10CF2, 0x10CFA, 0x10CFF, }, capitalized = true, direction = "rtl", } m["Ibrnn"] = { "Northeastern Iberian", 1113155, "semisyllabary", ietf_subtag = "Zzzz", -- Not in Unicode } m["Ibrns"] = { "Southeastern Iberian", 2305351, "semisyllabary", ietf_subtag = "Zzzz", -- Not in Unicode } m["Image"] = { -- To be used to avoid any formatting or link processing "Image-rendered", 478798, -- This should not have any characters listed ietf_subtag = "Zyyy", translit = false, character_category = false, -- none } m["Inds"] = { "Indus", 601388, aliases = {"Harappan", "Indus Valley"}, } m["Ipach"] = { "International Phonetic Alphabet", 21204, aliases = {"IPA"}, ietf_subtag = "Latn", } m["Ital"] = process_ranges{ "Old Italic", 4891256, "alphabet", ranges = { 0x10300, 0x10323, 0x1032D, 0x1032F, }, } m["Java"] = process_ranges{ "Javanese", 879704, "abugida", ranges = { 0xA980, 0xA9CD, 0xA9CF, 0xA9D9, 0xA9DE, 0xA9DF, }, } m["Jurc"] = { "Jurchen", 912240, "logography", spaces = false, } m["Kali"] = process_ranges{ "Kayah Li", 4919239, "abugida", ranges = { 0xA900, 0xA92F, }, } m["Kana"] = process_ranges{ "Katakana", 82946, "syllabary", ranges = { 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x3030, 0x3035, 0x3037, 0x3037, 0x303C, 0x303D, 0x3099, 0x309C, 0x30A0, 0x30FF, 0x31F0, 0x31FF, 0x32D0, 0x32FE, 0x3300, 0x3357, 0xFE45, 0xFE46, 0xFF61, 0xFF9F, 0x1AFF0, 0x1AFF3, 0x1AFF5, 0x1AFFB, 0x1AFFD, 0x1AFFE, 0x1B000, 0x1B000, 0x1B120, 0x1B122, 0x1B155, 0x1B155, 0x1B164, 0x1B167, }, spaces = false, } m["Kawi"] = process_ranges{ "Kawi", 975802, "abugida", ranges = { 0x11F00, 0x11F10, 0x11F12, 0x11F3A, 0x11F3E, 0x11F5A, }, } m["Khar"] = process_ranges{ "Kharoshthi", 1161266, "abugida", ranges = { 0x10A00, 0x10A03, 0x10A05, 0x10A06, 0x10A0C, 0x10A13, 0x10A15, 0x10A17, 0x10A19, 0x10A35, 0x10A38, 0x10A3A, 0x10A3F, 0x10A48, 0x10A50, 0x10A58, }, direction = "rtl", } m["Khmr"] = process_ranges{ "Khmer", 1054190, "abugida", ranges = { 0x1780, 0x17DD, 0x17E0, 0x17E9, 0x17F0, 0x17F9, 0x19E0, 0x19FF, }, spaces = false, normalizationFixes = handle_normalization_fixes{ from = {"ឣ", "ឤ"}, to = {"អ", "អា"} }, } m["Khoj"] = process_ranges{ "Khojki", 1740656, "abugida", ranges = { 0x0AE6, 0x0AEF, 0xA830, 0xA839, 0x11200, 0x11211, 0x11213, 0x11241, }, normalizationFixes = handle_normalization_fixes{ from = {"𑈀𑈬𑈱", "𑈀𑈬", "𑈀𑈱", "𑈀𑈳", "𑈁𑈱", "𑈆𑈬", "𑈬𑈰", "𑈬𑈱", "𑉀𑈮"}, to = {"𑈇", "𑈁", "𑈅", "𑈇", "𑈇", "𑈃", "𑈲", "𑈳", "𑈂"} }, } m["Khomt"] = { "Khom Thai", 13023788, "abugida", -- Not in Unicode } m["Kitl"] = { "Khitan large", 6401797, "logography", spaces = false, } m["Kits"] = process_ranges{ "Khitan small", 6401800, "logography, syllabary", ranges = { 0x16FE4, 0x16FE4, 0x18B00, 0x18CD5, 0x18CFF, 0x18CFF, }, spaces = false, } m["Knda"] = process_ranges{ "Kannada", 839666, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0C80, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBC, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD, 0x0CD5, 0x0CD6, 0x0CDD, 0x0CDE, 0x0CE0, 0x0CE3, 0x0CE6, 0x0CEF, 0x0CF1, 0x0CF3, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD3, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, 0x1CF4, 0x1CF4, 0xA830, 0xA835, }, normalizationFixes = handle_normalization_fixes{ from = {"ಉಾ", "ಋಾ", "ಒೌ"}, to = {"ಊ", "ೠ", "ಔ"} }, } m["Kpel"] = { "Kpelle", 1586299, "syllabary", -- Not in Unicode } m["Krai"] = process_ranges{ "Kirat Rai", 123173834, "abugida", aliases = {"Rai", "Khambu Rai", "Rai Barṇamālā", "Kirat Khambu Rai"}, ranges = { 0x16D40, 0x16D79, }, } m["Kthi"] = process_ranges{ "Kaithi", 1253814, "abugida", ranges = { 0x0966, 0x096F, 0xA830, 0xA839, 0x11080, 0x110C2, 0x110CD, 0x110CD, }, } m["Kulit"] = { "Kulitan", 6443044, "abugida", -- Not in Unicode } m["Lana"] = process_ranges{ "Tai Tham", 1314503, "abugida", aliases = {"Tham", "Tua Mueang", "Lanna"}, ranges = { 0x1A20, 0x1A5E, 0x1A60, 0x1A7C, 0x1A7F, 0x1A89, 0x1A90, 0x1A99, 0x1AA0, 0x1AAD, }, spaces = false, } m["Laoo"] = process_ranges{ "Lao", 1815229, "abugida", ranges = { 0x0E81, 0x0E82, 0x0E84, 0x0E84, 0x0E86, 0x0E8A, 0x0E8C, 0x0EA3, 0x0EA5, 0x0EA5, 0x0EA7, 0x0EBD, 0x0EC0, 0x0EC4, 0x0EC6, 0x0EC6, 0x0EC8, 0x0ECE, 0x0ED0, 0x0ED9, 0x0EDC, 0x0EDF, }, spaces = false, } m["Latn"] = process_ranges{ "Latin", 8229, "alphabet", aliases = {"Roman"}, ranges = { 0x0041, 0x005A, 0x0061, 0x007A, 0x00AA, 0x00AA, 0x00BA, 0x00BA, 0x00C0, 0x00D6, 0x00D8, 0x00F6, 0x00F8, 0x02B8, 0x02C0, 0x02C1, 0x02E0, 0x02E4, 0x0363, 0x036F, 0x0485, 0x0486, 0x0951, 0x0952, 0x10FB, 0x10FB, 0x1D00, 0x1D25, 0x1D2C, 0x1D5C, 0x1D62, 0x1D65, 0x1D6B, 0x1D77, 0x1D79, 0x1DBE, 0x1DF8, 0x1DF8, 0x1E00, 0x1EFF, 0x202F, 0x202F, 0x2071, 0x2071, 0x207F, 0x207F, 0x2090, 0x209C, 0x20F0, 0x20F0, 0x2100, 0x2125, 0x2128, 0x2128, 0x212A, 0x2134, 0x2139, 0x213B, 0x2141, 0x214E, 0x2160, 0x2188, 0x2C60, 0x2C7F, 0xA700, 0xA707, 0xA722, 0xA787, 0xA78B, 0xA7CD, 0xA7D0, 0xA7D1, 0xA7D3, 0xA7D3, 0xA7D5, 0xA7DC, 0xA7F2, 0xA7FF, 0xA92E, 0xA92E, 0xAB30, 0xAB5A, 0xAB5C, 0xAB64, 0xAB66, 0xAB69, 0xFB00, 0xFB06, 0xFF21, 0xFF3A, 0xFF41, 0xFF5A, 0x10780, 0x10785, 0x10787, 0x107B0, 0x107B2, 0x107BA, 0x1DF00, 0x1DF1E, 0x1DF25, 0x1DF2A, }, varieties = {"Rumi", "Romaji", "Rōmaji", "Romaja"}, capitalized = true, translit = false, } m["Latf"] = { "Fraktur", 148443, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, otherNames = {"Blackletter"}, -- Blackletter is actually the parent "script" capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["Latg"] = { "Gaelic", 1432616, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, otherNames = {"Irish"}, capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["pjt-Latn"] = { "Latin", nil, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["Leke"] = { "Leke", 19572613, "abugida", -- Not in Unicode } m["Lepc"] = process_ranges{ "Lepcha", 1481626, "abugida", aliases = {"Róng"}, ranges = { 0x1C00, 0x1C37, 0x1C3B, 0x1C49, 0x1C4D, 0x1C4F, }, } m["Limb"] = process_ranges{ "Limbu", 933796, "abugida", ranges = { 0x0965, 0x0965, 0x1900, 0x191E, 0x1920, 0x192B, 0x1930, 0x193B, 0x1940, 0x1940, 0x1944, 0x194F, }, } m["Lina"] = process_ranges{ "Linear A", 30972, ranges = { 0x10107, 0x10133, 0x10600, 0x10736, 0x10740, 0x10755, 0x10760, 0x10767, }, } m["Linb"] = process_ranges{ "Linear B", 190102, ranges = { 0x10000, 0x1000B, 0x1000D, 0x10026, 0x10028, 0x1003A, 0x1003C, 0x1003D, 0x1003F, 0x1004D, 0x10050, 0x1005D, 0x10080, 0x100FA, 0x10100, 0x10102, 0x10107, 0x10133, 0x10137, 0x1013F, }, } m["Lisu"] = process_ranges{ "Fraser", 1194621, "alphabet", aliases = {"Old Lisu", "Lisu"}, ranges = { 0x300A, 0x300B, 0xA4D0, 0xA4FF, 0x11FB0, 0x11FB0, }, normalizationFixes = handle_normalization_fixes{ from = {"['’]", "[.ꓸ][.ꓸ]", "[.ꓸ][,ꓹ]"}, to = {"ʼ", "ꓺ", "ꓻ"} }, } m["Loma"] = { "Loma", 13023816, "syllabary", -- Not in Unicode } m["Lyci"] = process_ranges{ "Lycian", 913587, "alphabet", ranges = { 0x10280, 0x1029C, }, } m["Lydi"] = process_ranges{ "Lydian", 4261300, "alphabet", ranges = { 0x10920, 0x10939, 0x1093F, 0x1093F, }, direction = "rtl", } m["Mahj"] = process_ranges{ "Mahajani", 6732850, "abugida", ranges = { 0x0964, 0x096F, 0xA830, 0xA839, 0x11150, 0x11176, }, } m["Maka"] = process_ranges{ "Makasar", 72947229, "abugida", aliases = {"Old Makasar"}, ranges = { 0x11EE0, 0x11EF8, }, } m["Mand"] = process_ranges{ "Mandaic", 1812130, aliases = {"Mandaean"}, ranges = { 0x0640, 0x0640, 0x0840, 0x085B, 0x085E, 0x085E, }, direction = "rtl", } m["Mani"] = process_ranges{ "Manichaean", 3544702, "abjad", ranges = { 0x0640, 0x0640, 0x10AC0, 0x10AE6, 0x10AEB, 0x10AF6, }, direction = "rtl", } m["Marc"] = process_ranges{ "Marchen", 72403709, "abugida", ranges = { 0x11C70, 0x11C8F, 0x11C92, 0x11CA7, 0x11CA9, 0x11CB6, }, } m["Maya"] = process_ranges{ "Maya", 211248, aliases = {"Maya hieroglyphic", "Mayan", "Mayan hieroglyphic"}, ranges = { 0x1D2E0, 0x1D2F3, }, } m["Medf"] = process_ranges{ "Medefaidrin", 1519764, aliases = {"Oberi Okaime", "Oberi Ɔkaimɛ"}, ranges = { 0x16E40, 0x16E9A, }, capitalized = true, } m["Mend"] = process_ranges{ "Mende", 951069, aliases = {"Mende Kikakui"}, ranges = { 0x1E800, 0x1E8C4, 0x1E8C7, 0x1E8D6, }, direction = "rtl", } m["Merc"] = process_ranges{ "Meroitic cursive", 73028124, "abugida", ranges = { 0x109A0, 0x109B7, 0x109BC, 0x109CF, 0x109D2, 0x109FF, }, direction = "rtl", } m["Mero"] = process_ranges{ "Meroitic hieroglyphic", 73028623, "abugida", ranges = { 0x10980, 0x1099F, }, direction = "rtl", wikipedia_article = "Meroitic hieroglyphs", } m["Mlym"] = process_ranges{ "Malayalam", 1164129, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0D00, 0x0D0C, 0x0D0E, 0x0D10, 0x0D12, 0x0D44, 0x0D46, 0x0D48, 0x0D4A, 0x0D4F, 0x0D54, 0x0D63, 0x0D66, 0x0D7F, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, 0xA830, 0xA832, }, normalizationFixes = handle_normalization_fixes{ from = {"ഇൗ", "ഉൗ", "എെ", "ഒാ", "ഒൗ", "ക്‍", "ണ്‍", "ന്‍റ", "ന്‍", "മ്‍", "യ്‍", "ര്‍", "ല്‍", "ള്‍", "ഴ്‍", "െെ", "ൻ്റ"}, to = {"ഈ", "ഊ", "ഐ", "ഓ", "ഔ", "ൿ", "ൺ", "ൻറ", "ൻ", "ൔ", "ൕ", "ർ", "ൽ", "ൾ", "ൖ", "ൈ", "ന്റ"} }, } m["Modi"] = process_ranges{ "Modi", 1703713, "abugida", ranges = { 0xA830, 0xA839, 0x11600, 0x11644, 0x11650, 0x11659, }, normalizationFixes = handle_normalization_fixes{ from = {"𑘀𑘹", "𑘀𑘺", "𑘁𑘹", "𑘁𑘺"}, to = {"𑘊", "𑘋", "𑘌", "𑘍"} }, } m["Mong"] = process_ranges{ "Mongolian", 1055705, "alphabet", aliases = {"Mongol bichig", "Hudum Mongol bichig"}, ranges = { 0x1800, 0x1805, 0x180A, 0x1819, 0x1820, 0x1842, 0x1878, 0x1878, 0x1880, 0x1897, 0x18A6, 0x18A6, 0x18A9, 0x18A9, 0x200C, 0x200D, 0x202F, 0x202F, 0x3001, 0x3002, 0x3008, 0x300B, 0x11660, 0x11668, }, direction = "vertical-ltr", } m["mnc-Mong"] = process_ranges{ "Manchu", 122888, m["Mong"][3], ranges = { 0x1801, 0x1801, 0x1804, 0x1804, 0x1808, 0x180F, 0x1820, 0x1820, 0x1823, 0x1823, 0x1828, 0x182A, 0x182E, 0x1830, 0x1834, 0x1838, 0x183A, 0x183A, 0x185D, 0x185D, 0x185F, 0x1861, 0x1864, 0x1869, 0x186C, 0x1871, 0x1873, 0x1877, 0x1880, 0x1888, 0x188F, 0x188F, 0x189A, 0x18A5, 0x18A8, 0x18A8, 0x18AA, 0x18AA, 0x200C, 0x200D, 0x202F, 0x202F, }, direction = "vertical-ltr", parent = "Mong", } m["sjo-Mong"] = process_ranges{ "Xibe", 113624153, m["Mong"][3], aliases = {"Sibe"}, ranges = { 0x1804, 0x1804, 0x1807, 0x1807, 0x180A, 0x180F, 0x1820, 0x1820, 0x1823, 0x1823, 0x1828, 0x1828, 0x182A, 0x182A, 0x182E, 0x1830, 0x1834, 0x1838, 0x183A, 0x183A, 0x185D, 0x1872, 0x200C, 0x200D, 0x202F, 0x202F, }, direction = "vertical-ltr", parent = "mnc-Mong", } m["xwo-Mong"] = process_ranges{ "Clear Script", 529085, m["Mong"][3], aliases = {"Todo", "Todo bichig"}, ranges = { 0x1800, 0x1801, 0x1804, 0x1806, 0x180A, 0x1820, 0x1828, 0x1828, 0x182F, 0x1831, 0x1834, 0x1834, 0x1837, 0x1838, 0x183A, 0x183B, 0x1840, 0x1840, 0x1843, 0x185C, 0x1880, 0x1887, 0x1889, 0x188F, 0x1894, 0x1894, 0x1896, 0x1899, 0x18A7, 0x18A7, 0x200C, 0x200D, 0x202F, 0x202F, 0x11669, 0x1166C, }, direction = "vertical-ltr", parent = "Mong", } m["Moon"] = { "Moon", 918391, "alphabet", aliases = {"Moon System of Embossed Reading", "Moon type", "Moon writing", "Moon alphabet", "Moon code"}, -- Not in Unicode } m["Morse"] = { "Morse code", 79897, ietf_subtag = "Zsym", } m["Mroo"] = process_ranges{ "Mru", 75919253, aliases = {"Mro", "Mrung"}, ranges = { 0x16A40, 0x16A5E, 0x16A60, 0x16A69, 0x16A6E, 0x16A6F, }, } m["Mtei"] = process_ranges{ "Meitei Mayek", 2981413, "abugida", aliases = {"Meetei Mayek", "Manipuri"}, ranges = { 0xAAE0, 0xAAF6, 0xABC0, 0xABED, 0xABF0, 0xABF9, }, } m["Mult"] = process_ranges{ "Multani", 17047906, "abugida", ranges = { 0x0A66, 0x0A6F, 0x11280, 0x11286, 0x11288, 0x11288, 0x1128A, 0x1128D, 0x1128F, 0x1129D, 0x1129F, 0x112A9, }, } m["Music"] = process_ranges{ "musical notation", 233861, "pictography", ranges = { 0x2669, 0x266F, 0x1D100, 0x1D126, 0x1D129, 0x1D1EA, }, ietf_subtag = "Zsym", translit = false, } m["Mymr"] = process_ranges{ "Burmese", 43887939, "abugida", aliases = {"Myanmar"}, ranges = { 0x1000, 0x109F, 0xA92E, 0xA92E, 0xA9E0, 0xA9FE, 0xAA60, 0xAA7F, 0x116D0, 0x116E3, }, spaces = false, } m["Nagm"] = process_ranges{ "Mundari Bani", 106917274, "alphabet", aliases = {"Nag Mundari"}, ranges = { 0x1E4D0, 0x1E4F9, }, } m["Nand"] = process_ranges{ "Nandinagari", 6963324, "abugida", ranges = { 0x0964, 0x0965, 0x0CE6, 0x0CEF, 0x1CE9, 0x1CE9, 0x1CF2, 0x1CF2, 0x1CFA, 0x1CFA, 0xA830, 0xA835, 0x119A0, 0x119A7, 0x119AA, 0x119D7, 0x119DA, 0x119E4, }, } m["Narb"] = process_ranges{ "Ancient North Arabian", 1472213, "abjad", aliases = {"Old North Arabian"}, ranges = { 0x10A80, 0x10A9F, }, direction = "rtl", } m["Nbat"] = process_ranges{ "Nabataean", 855624, "abjad", aliases = {"Nabatean"}, ranges = { 0x10880, 0x1089E, 0x108A7, 0x108AF, }, direction = "rtl", } m["Newa"] = process_ranges{ "Newa", 7237292, "abugida", aliases = {"Newar", "Newari", "Prachalit Nepal"}, ranges = { 0x11400, 0x1145B, 0x1145D, 0x11461, }, } m["Nkdb"] = { "Dongba", 1190953, "pictography", aliases = {"Naxi Dongba", "Nakhi Dongba", "Tomba", "Tompa", "Mo-so"}, spaces = false, -- Not in Unicode } m["Nkgb"] = { "Geba", 731189, "syllabary", aliases = {"Nakhi Geba", "Naxi Geba"}, spaces = false, -- Not in Unicode } m["Nkoo"] = process_ranges{ "N'Ko", 1062587, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x07C0, 0x07FA, 0x07FD, 0x07FF, 0xFD3E, 0xFD3F, }, direction = "rtl", } m["None"] = { "unspecified", nil, -- This should not have any characters listed ietf_subtag = "Zyyy", translit = false, character_category = false, -- none } m["Nshu"] = process_ranges{ "Nüshu", 56436, "syllabary", aliases = {"Nushu"}, ranges = { 0x16FE1, 0x16FE1, 0x1B170, 0x1B2FB, }, spaces = false, } m["Ogam"] = process_ranges{ "Ogham", 184661, ranges = { 0x1680, 0x169C, }, } m["Olck"] = process_ranges{ "Ol Chiki", 201688, aliases = {"Ol Chemetʼ", "Ol", "Santali"}, ranges = { 0x1C50, 0x1C7F, }, } m["Onao"] = process_ranges{ "Ol Onal", 108607084, "alphabet", ranges = { 0x0964, 0x0965, 0x1E5D0, 0x1E5FA, 0x1E5FF, 0x1E5FF, }, } m["Orkh"] = process_ranges{ "Old Turkic", 5058305, aliases = {"Orkhon runic"}, ranges = { 0x10C00, 0x10C48, }, direction = "rtl", } m["Orya"] = process_ranges{ "Odia", 1760127, "abugida", aliases = {"Oriya"}, ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0B01, 0x0B03, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28, 0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B35, 0x0B39, 0x0B3C, 0x0B44, 0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B55, 0x0B57, 0x0B5C, 0x0B5D, 0x0B5F, 0x0B63, 0x0B66, 0x0B77, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, }, normalizationFixes = handle_normalization_fixes{ from = {"ଅା", "ଏୗ", "ଓୗ"}, to = {"ଆ", "ଐ", "ଔ"} }, } m["Osge"] = process_ranges{ "Osage", 7105529, ranges = { 0x104B0, 0x104D3, 0x104D8, 0x104FB, }, capitalized = true, } m["Osma"] = process_ranges{ "Osmanya", 1377866, ranges = { 0x10480, 0x1049D, 0x104A0, 0x104A9, }, } m["Ougr"] = process_ranges{ "Old Uyghur", 1998938, "abjad, alphabet", ranges = { 0x0640, 0x0640, 0x10AF2, 0x10AF2, 0x10F70, 0x10F89, }, -- This should ideally be "vertical-ltr", but getting the CSS right is tricky because it's right-to-left horizontally, but left-to-right vertically. Currently, displaying it vertically causes it to display bottom-to-top. direction = "rtl", } m["Palm"] = process_ranges{ "Palmyrene", 17538100, ranges = { 0x10860, 0x1087F, }, direction = "rtl", } m["Pauc"] = process_ranges{ "Pau Cin Hau", 25339852, ranges = { 0x11AC0, 0x11AF8, }, } m["Pcun"] = { "Proto-Cuneiform", 1650699, "pictography", -- Not in Unicode } m["Pelm"] = { "Proto-Elamite", 56305763, "pictography", -- Not in Unicode } m["Perm"] = process_ranges{ "Old Permic", 147899, ranges = { 0x0483, 0x0483, 0x10350, 0x1037A, }, } m["Phag"] = process_ranges{ "Phags-pa", 822836, "abugida", ranges = { 0x1802, 0x1803, 0x1805, 0x1805, 0x200C, 0x200D, 0x202F, 0x202F, 0x3002, 0x3002, 0xA840, 0xA877, }, direction = "vertical-ltr", } m["Phli"] = process_ranges{ "Inscriptional Pahlavi", 24089793, "abjad", ranges = { 0x10B60, 0x10B72, 0x10B78, 0x10B7F, }, direction = "rtl", } m["Phlp"] = process_ranges{ "Psalter Pahlavi", 7253954, "abjad", ranges = { 0x0640, 0x0640, 0x10B80, 0x10B91, 0x10B99, 0x10B9C, 0x10BA9, 0x10BAF, }, direction = "rtl", } m["Phlv"] = { "Book Pahlavi", 72403118, "abjad", direction = "rtl", wikipedia_article = "Pahlavi scripts#Book Pahlavi", -- Not in Unicode } m["Phnx"] = process_ranges{ "Phoenician", 26752, "abjad", ranges = { 0x10900, 0x1091B, 0x1091F, 0x1091F, }, direction = "rtl", } m["Plrd"] = process_ranges{ "Pollard", 601734, "abugida", aliases = {"Miao"}, ranges = { 0x16F00, 0x16F4A, 0x16F4F, 0x16F87, 0x16F8F, 0x16F9F, }, } m["Prti"] = process_ranges{ "Inscriptional Parthian", 13023804, ranges = { 0x10B40, 0x10B55, 0x10B58, 0x10B5F, }, direction = "rtl", } m["Psin"] = { "Proto-Sinaitic", 1065250, "abjad", direction = "rtl", -- Not in Unicode } m["Ranj"] = { "Ranjana", 2385276, "abugida", -- Not in Unicode } m["Rjng"] = process_ranges{ "Rejang", 2007960, "abugida", ranges = { 0xA930, 0xA953, 0xA95F, 0xA95F, }, } m["Rohg"] = process_ranges{ "Hanifi Rohingya", 21028705, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x0640, 0x0640, 0x06D4, 0x06D4, 0x10D00, 0x10D27, 0x10D30, 0x10D39, }, direction = "rtl", } m["Roro"] = { "Rongorongo", 209764, -- Not in Unicode } m["Rumin"] = process_ranges{ "Rumi numerals", nil, ranges = { 0x10E60, 0x10E7E, }, ietf_subtag = "Arab", } m["Runr"] = process_ranges{ "Runic", 82996, "alphabet", ranges = { 0x16A0, 0x16EA, 0x16EE, 0x16F8, }, } m["Samr"] = process_ranges{ "Samaritan", 1550930, "abjad", ranges = { 0x0800, 0x082D, 0x0830, 0x083E, }, direction = "rtl", } m["Sarb"] = process_ranges{ "Ancient South Arabian", 446074, "abjad", aliases = {"Old South Arabian"}, ranges = { 0x10A60, 0x10A7F, }, direction = "rtl", } m["Saur"] = process_ranges{ "Saurashtra", 3535165, "abugida", ranges = { 0xA880, 0xA8C5, 0xA8CE, 0xA8D9, }, } m["Semap"] = { "flag semaphore", 250796, "pictography", ietf_subtag = "Zsym", } m["Sgnw"] = process_ranges{ "SignWriting", 1497335, "pictography", aliases = {"Sutton SignWriting"}, ranges = { 0x1D800, 0x1DA8B, 0x1DA9B, 0x1DA9F, 0x1DAA1, 0x1DAAF, }, translit = false, } m["Shaw"] = process_ranges{ "Shavian", 1970098, aliases = {"Shaw"}, ranges = { 0x10450, 0x1047F, }, } m["Shrd"] = process_ranges{ "Sharada", 2047117, "abugida", ranges = { 0x0951, 0x0951, 0x1CD7, 0x1CD7, 0x1CD9, 0x1CD9, 0x1CDC, 0x1CDD, 0x1CE0, 0x1CE0, 0xA830, 0xA835, 0xA838, 0xA838, 0x11180, 0x111DF, }, } m["Shui"] = { "Sui", 752854, "logography", spaces = false, -- Not in Unicode } m["Sidd"] = process_ranges{ "Siddham", 250379, "abugida", ranges = { 0x11580, 0x115B5, 0x115B8, 0x115DD, }, } m["Sidt"] = { "Sidetic", 36659, "alphabet", direction = "rtl", -- Not in Unicode } m["Sind"] = process_ranges{ "Khudabadi", 6402810, "abugida", aliases = {"Khudawadi"}, ranges = { 0x0964, 0x0965, 0xA830, 0xA839, 0x112B0, 0x112EA, 0x112F0, 0x112F9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑊰𑋠", "𑊰𑋥", "𑊰𑋦", "𑊰𑋧", "𑊰𑋨"}, to = {"𑊱", "𑊶", "𑊷", "𑊸", "𑊹"} }, } m["Sinh"] = process_ranges{ "Sinhalese", 1574992, "abugida", aliases = {"Sinhala"}, ranges = { 0x0964, 0x0965, 0x0D81, 0x0D83, 0x0D85, 0x0D96, 0x0D9A, 0x0DB1, 0x0DB3, 0x0DBB, 0x0DBD, 0x0DBD, 0x0DC0, 0x0DC6, 0x0DCA, 0x0DCA, 0x0DCF, 0x0DD4, 0x0DD6, 0x0DD6, 0x0DD8, 0x0DDF, 0x0DE6, 0x0DEF, 0x0DF2, 0x0DF4, 0x1CF2, 0x1CF2, 0x111E1, 0x111F4, }, normalizationFixes = handle_normalization_fixes{ from = {"අා", "අැ", "අෑ", "උෟ", "ඍෘ", "ඏෟ", "එ්", "එෙ", "ඔෟ", "ෘෘ"}, to = {"ආ", "ඇ", "ඈ", "ඌ", "ඎ", "ඐ", "ඒ", "ඓ", "ඖ", "ෲ"} }, } m["Sogd"] = process_ranges{ "Sogdian", 578359, "abjad", ranges = { 0x0640, 0x0640, 0x10F30, 0x10F59, }, direction = "rtl", } m["Sogo"] = process_ranges{ "Old Sogdian", 72403254, "abjad", ranges = { 0x10F00, 0x10F27, }, direction = "rtl", } m["Sora"] = process_ranges{ "Sorang Sompeng", 7563292, aliases = {"Sora Sompeng"}, ranges = { 0x110D0, 0x110E8, 0x110F0, 0x110F9, }, } m["Soyo"] = process_ranges{ "Soyombo", 8009382, "abugida", ranges = { 0x11A50, 0x11AA2, }, } m["Sund"] = process_ranges{ "Sundanese", 51589, "abugida", ranges = { 0x1B80, 0x1BBF, 0x1CC0, 0x1CC7, }, } m["Sunu"] = process_ranges{ "Sunuwar", 109984965, "alphabet", ranges = { 0x11BC0, 0x11BE1, 0x11BF0, 0x11BF9, }, } m["Sylo"] = process_ranges{ "Sylheti Nagri", 144128, "abugida", aliases = {"Sylheti Nāgarī", "Syloti Nagri"}, ranges = { 0x0964, 0x0965, 0x09E6, 0x09EF, 0xA800, 0xA82C, }, } m["Syrc"] = process_ranges{ "Syriac", 26567, "abjad", -- more precisely, impure abjad ranges = { 0x060C, 0x060C, 0x061B, 0x061C, 0x061F, 0x061F, 0x0640, 0x0640, 0x064B, 0x0655, 0x0670, 0x0670, 0x0700, 0x070D, 0x070F, 0x074A, 0x074D, 0x074F, 0x0860, 0x086A, 0x1DF8, 0x1DF8, 0x1DFA, 0x1DFA, }, direction = "rtl", } -- Syre, Syrj, Syrn are apparently subsumed into Syrc; discuss if this causes issues m["Tagb"] = process_ranges{ "Tagbanwa", 977444, "abugida", ranges = { 0x1735, 0x1736, 0x1760, 0x176C, 0x176E, 0x1770, 0x1772, 0x1773, }, } m["Takr"] = process_ranges{ "Takri", 759202, "abugida", ranges = { 0x0964, 0x0965, 0xA830, 0xA839, 0x11680, 0x116B9, 0x116C0, 0x116C9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑚀𑚭", "𑚀𑚴", "𑚀𑚵", "𑚆𑚲"}, to = {"𑚁", "𑚈", "𑚉", "𑚇"} }, } m["Tale"] = process_ranges{ "Tai Nüa", 2566326, "abugida", aliases = {"Tai Nuea", "New Tai Nüa", "New Tai Nuea", "Dehong Dai", "Tai Dehong", "Tai Le"}, ranges = { 0x1040, 0x1049, 0x1950, 0x196D, 0x1970, 0x1974, }, spaces = false, } m["Talu"] = process_ranges{ "New Tai Lue", 3498863, "abugida", ranges = { 0x1980, 0x19AB, 0x19B0, 0x19C9, 0x19D0, 0x19DA, 0x19DE, 0x19DF, }, spaces = false, } m["Taml"] = process_ranges{ "Tamil", 26803, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0B82, 0x0B83, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95, 0x0B99, 0x0B9A, 0x0B9C, 0x0B9C, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA, 0x0BAE, 0x0BB9, 0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0BD0, 0x0BD0, 0x0BD7, 0x0BD7, 0x0BE6, 0x0BFA, 0x1CDA, 0x1CDA, 0xA8F3, 0xA8F3, 0x11301, 0x11301, 0x11303, 0x11303, 0x1133B, 0x1133C, 0x11FC0, 0x11FF1, 0x11FFF, 0x11FFF, }, normalizationFixes = handle_normalization_fixes{ from = {"அூ", "ஸ்ரீ"}, to = {"ஆ", "ஶ்ரீ"} }, } m["Tang"] = process_ranges{ "Tangut", 1373610, "logography, syllabary", ranges = { 0x31EF, 0x31EF, 0x16FE0, 0x16FE0, 0x17000, 0x187F7, 0x18800, 0x18AFF, 0x18D00, 0x18D08, }, spaces = false, } m["Tavt"] = process_ranges{ "Tai Viet", 11818517, "abugida", ranges = { 0xAA80, 0xAAC2, 0xAADB, 0xAADF, }, spaces = false, } m["Tayo"] = { "Lai Tay", 16306701, "abugida", aliases = {"Tai Yo"}, direction = "vertical-rtl", -- Not in Unicode } m["Telu"] = process_ranges{ "Telugu", 570450, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0C00, 0x0C0C, 0x0C0E, 0x0C10, 0x0C12, 0x0C28, 0x0C2A, 0x0C39, 0x0C3C, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56, 0x0C58, 0x0C5A, 0x0C5D, 0x0C5D, 0x0C60, 0x0C63, 0x0C66, 0x0C6F, 0x0C77, 0x0C7F, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, }, normalizationFixes = handle_normalization_fixes{ from = {"ఒౌ", "ఒౕ", "ిౕ", "ెౕ", "ొౕ"}, to = {"ఔ", "ఓ", "ీ", "ే", "ో"} }, } m["Teng"] = { "Tengwar", 473725, } m["Tfng"] = process_ranges{ "Tifinagh", 208503, "abjad, alphabet", ranges = { 0x2D30, 0x2D67, 0x2D6F, 0x2D70, 0x2D7F, 0x2D7F, }, otherNames = {"Libyco-Berber", "Berber"}, -- per Wikipedia, Libyco-Berber is the parent } m["Tglg"] = process_ranges{ "Baybayin", 812124, "abugida", aliases = {"Tagalog"}, varieties = {"Kur-itan"}, ranges = { 0x1700, 0x1715, 0x171F, 0x171F, 0x1735, 0x1736, }, } m["Thaa"] = process_ranges{ "Thaana", 877906, "abugida", ranges = { 0x060C, 0x060C, 0x061B, 0x061C, 0x061F, 0x061F, 0x0660, 0x0669, 0x0780, 0x07B1, 0xFDF2, 0xFDF2, 0xFDFD, 0xFDFD, }, direction = "rtl", } m["Thai"] = process_ranges{ "Thai", 236376, "abugida", ranges = { 0x0E01, 0x0E3A, 0x0E40, 0x0E5B, }, spaces = false, } m["Tibt"] = process_ranges{ "Tibetan", 46861, "abugida", ranges = { 0x0F00, 0x0F47, 0x0F49, 0x0F6C, 0x0F71, 0x0F97, 0x0F99, 0x0FBC, 0x0FBE, 0x0FCC, 0x0FCE, 0x0FD4, 0x0FD9, 0x0FDA, 0x3008, 0x300B, }, normalizationFixes = handle_normalization_fixes{ combiningClasses = {["༹"] = 1}, from = {"ཷ", "ཹ"}, to = {"ྲཱྀ", "ླཱྀ"} }, } m["sit-tam-Tibt"] = { "Tamyig", 109875213, m["Tibt"][3], ranges = m["Tibt"].ranges, characters = m["Tibt"].characters, parent = "Tibt", normalizationFixes = m["Tibt"].normalizationFixes, } m["Tirh"] = process_ranges{ "Tirhuta", 1765752, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x1CF2, 0x1CF2, 0xA830, 0xA839, 0x11480, 0x114C7, 0x114D0, 0x114D9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑒁𑒰", "𑒋𑒺", "𑒍𑒺", "𑒪𑒵", "𑒪𑒶"}, to = {"𑒂", "𑒌", "𑒎", "𑒉", "𑒊"} }, } m["Tnsa"] = process_ranges{ "Tangsa", 105576311, "alphabet", ranges = { 0x16A70, 0x16ABE, 0x16AC0, 0x16AC9, }, } m["Todr"] = process_ranges{ "Todhri", 10274731, "alphabet", direction = "rtl", ranges = { 0x105C0, 0x105F3, }, } m["Tols"] = { "Tolong Siki", 4459822, "alphabet", -- Not in Unicode } m["Toto"] = process_ranges{ "Toto", 104837516, "abugida", ranges = { 0x1E290, 0x1E2AE, }, } m["Tutg"] = process_ranges{ "Tigalari", 2604990, "abugida", aliases = {"Tulu"}, ranges = { 0x1CF2, 0x1CF2, 0x1CF4, 0x1CF4, 0xA8F1, 0xA8F1, 0x11380, 0x11389, 0x1138B, 0x1138B, 0x1138E, 0x1138E, 0x11390, 0x113B5, 0x113B7, 0x113C0, 0x113C2, 0x113C2, 0x113C5, 0x113C5, 0x113C7, 0x113CA, 0x113CC, 0x113D5, 0x113D7, 0x113D8, 0x113E1, 0x113E2, }, } m["Ugar"] = process_ranges{ "Ugaritic", 332652, "abjad", ranges = { 0x10380, 0x1039D, 0x1039F, 0x1039F, }, } m["Vaii"] = process_ranges{ "Vai", 523078, "syllabary", ranges = { 0xA500, 0xA62B, }, } m["Visp"] = { "Visible Speech", 1303365, "alphabet", -- Not in Unicode } m["Vith"] = process_ranges{ "Vithkuqi", 3301993, "alphabet", ranges = { 0x10570, 0x1057A, 0x1057C, 0x1058A, 0x1058C, 0x10592, 0x10594, 0x10595, 0x10597, 0x105A1, 0x105A3, 0x105B1, 0x105B3, 0x105B9, 0x105BB, 0x105BC, }, capitalized = true, } m["Wara"] = process_ranges{ "Varang Kshiti", 79199, aliases = {"Warang Citi"}, ranges = { 0x118A0, 0x118F2, 0x118FF, 0x118FF, }, capitalized = true, } m["Wcho"] = process_ranges{ "Wancho", 33713728, "alphabet", ranges = { 0x1E2C0, 0x1E2F9, 0x1E2FF, 0x1E2FF, }, } m["Wole"] = { "Woleai", 6643710, "syllabary", -- Not in Unicode } m["Xpeo"] = process_ranges{ "Old Persian", 1471822, ranges = { 0x103A0, 0x103C3, 0x103C8, 0x103D5, }, } m["Xsux"] = process_ranges{ "Cuneiform", 401, aliases = {"Sumero-Akkadian Cuneiform"}, ranges = { 0x12000, 0x12399, 0x12400, 0x1246E, 0x12470, 0x12474, 0x12480, 0x12543, }, } m["Yezi"] = process_ranges{ "Yezidi", 13175481, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x0660, 0x0669, 0x10E80, 0x10EA9, 0x10EAB, 0x10EAD, 0x10EB0, 0x10EB1, }, direction = "rtl", } m["Yiii"] = process_ranges{ "Yi", 1197646, "syllabary", ranges = { 0x3001, 0x3002, 0x3008, 0x3011, 0x3014, 0x301B, 0x30FB, 0x30FB, 0xA000, 0xA48C, 0xA490, 0xA4C6, 0xFF61, 0xFF65, }, } m["Zanb"] = process_ranges{ "Zanabazar Square", 50809208, "abugida", ranges = { 0x11A00, 0x11A47, }, } m["Zmth"] = process_ranges{ "mathematical notation", 1140046, ranges = { 0x00AC, 0x00AC, 0x00B1, 0x00B1, 0x00D7, 0x00D7, 0x00F7, 0x00F7, 0x03D0, 0x03D2, 0x03D5, 0x03D5, 0x03F0, 0x03F1, 0x03F4, 0x03F6, 0x0606, 0x0608, 0x2016, 0x2016, 0x2032, 0x2034, 0x2040, 0x2040, 0x2044, 0x2044, 0x2052, 0x2052, 0x205F, 0x205F, 0x2061, 0x2064, 0x207A, 0x207E, 0x208A, 0x208E, 0x20D0, 0x20DC, 0x20E1, 0x20E1, 0x20E5, 0x20E6, 0x20EB, 0x20EF, 0x2102, 0x2102, 0x2107, 0x2107, 0x210A, 0x2113, 0x2115, 0x2115, 0x2118, 0x211D, 0x2124, 0x2124, 0x2128, 0x2129, 0x212C, 0x212D, 0x212F, 0x2131, 0x2133, 0x2138, 0x213C, 0x2149, 0x214B, 0x214B, 0x2190, 0x21A7, 0x21A9, 0x21AE, 0x21B0, 0x21B1, 0x21B6, 0x21B7, 0x21BC, 0x21DB, 0x21DD, 0x21DD, 0x21E4, 0x21E5, 0x21F4, 0x22FF, 0x2308, 0x230B, 0x2320, 0x2321, 0x237C, 0x237C, 0x239B, 0x23B5, 0x23B7, 0x23B7, 0x23D0, 0x23D0, 0x23DC, 0x23E2, 0x25A0, 0x25A1, 0x25AE, 0x25B7, 0x25BC, 0x25C1, 0x25C6, 0x25C7, 0x25CA, 0x25CB, 0x25CF, 0x25D3, 0x25E2, 0x25E2, 0x25E4, 0x25E4, 0x25E7, 0x25EC, 0x25F8, 0x25FF, 0x2605, 0x2606, 0x2640, 0x2640, 0x2642, 0x2642, 0x2660, 0x2663, 0x266D, 0x266F, 0x27C0, 0x27FF, 0x2900, 0x2AFF, 0x2B30, 0x2B44, 0x2B47, 0x2B4C, 0xFB29, 0xFB29, 0xFE61, 0xFE66, 0xFE68, 0xFE68, 0xFF0B, 0xFF0B, 0xFF1C, 0xFF1E, 0xFF3C, 0xFF3C, 0xFF3E, 0xFF3E, 0xFF5C, 0xFF5C, 0xFF5E, 0xFF5E, 0xFFE2, 0xFFE2, 0xFFE9, 0xFFEC, 0x1D400, 0x1D454, 0x1D456, 0x1D49C, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D4A9, 0x1D4AC, 0x1D4AE, 0x1D4B9, 0x1D4BB, 0x1D4BB, 0x1D4BD, 0x1D4C3, 0x1D4C5, 0x1D505, 0x1D507, 0x1D50A, 0x1D50D, 0x1D514, 0x1D516, 0x1D51C, 0x1D51E, 0x1D539, 0x1D53B, 0x1D53E, 0x1D540, 0x1D544, 0x1D546, 0x1D546, 0x1D54A, 0x1D550, 0x1D552, 0x1D6A5, 0x1D6A8, 0x1D7CB, 0x1D7CE, 0x1D7FF, 0x1EE00, 0x1EE03, 0x1EE05, 0x1EE1F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE24, 0x1EE27, 0x1EE27, 0x1EE29, 0x1EE32, 0x1EE34, 0x1EE37, 0x1EE39, 0x1EE39, 0x1EE3B, 0x1EE3B, 0x1EE42, 0x1EE42, 0x1EE47, 0x1EE47, 0x1EE49, 0x1EE49, 0x1EE4B, 0x1EE4B, 0x1EE4D, 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE54, 0x1EE57, 0x1EE57, 0x1EE59, 0x1EE59, 0x1EE5B, 0x1EE5B, 0x1EE5D, 0x1EE5D, 0x1EE5F, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE64, 0x1EE67, 0x1EE6A, 0x1EE6C, 0x1EE72, 0x1EE74, 0x1EE77, 0x1EE79, 0x1EE7C, 0x1EE7E, 0x1EE7E, 0x1EE80, 0x1EE89, 0x1EE8B, 0x1EE9B, 0x1EEA1, 0x1EEA3, 0x1EEA5, 0x1EEA9, 0x1EEAB, 0x1EEBB, 0x1EEF0, 0x1EEF1, }, translit = false, } m["Zname"] = process_ranges{ "Znamenny musical notation", 965834, "pictography", ranges = { 0x1CF00, 0x1CF2D, 0x1CF30, 0x1CF46, 0x1CF50, 0x1CFC3, }, ietf_subtag = "Zsym", translit = false, } m["Zsym"] = process_ranges{ "symbolic", 80071, "pictography", ranges = { 0x20DD, 0x20E0, 0x20E2, 0x20E4, 0x20E7, 0x20EA, 0x20F0, 0x20F0, 0x2100, 0x2101, 0x2103, 0x2106, 0x2108, 0x2109, 0x2114, 0x2114, 0x2116, 0x2117, 0x211E, 0x2123, 0x2125, 0x2127, 0x212A, 0x212B, 0x212E, 0x212E, 0x2132, 0x2132, 0x2139, 0x213B, 0x214A, 0x214A, 0x214C, 0x214F, 0x21A8, 0x21A8, 0x21AF, 0x21AF, 0x21B2, 0x21B5, 0x21B8, 0x21BB, 0x21DC, 0x21DC, 0x21DE, 0x21E3, 0x21E6, 0x21F3, 0x2300, 0x2307, 0x230C, 0x231F, 0x2322, 0x237B, 0x237D, 0x239A, 0x23B6, 0x23B6, 0x23B8, 0x23CF, 0x23D1, 0x23DB, 0x23E3, 0x23FF, 0x2500, 0x259F, 0x25A2, 0x25AD, 0x25B8, 0x25BB, 0x25C2, 0x25C5, 0x25C8, 0x25C9, 0x25CC, 0x25CE, 0x25D4, 0x25E1, 0x25E3, 0x25E3, 0x25E5, 0x25E6, 0x25ED, 0x25F7, 0x2600, 0x2604, 0x2607, 0x263F, 0x2641, 0x2641, 0x2643, 0x265F, 0x2664, 0x266C, 0x2670, 0x27BF, 0x2B00, 0x2B2F, 0x2B45, 0x2B46, 0x2B4D, 0x2B73, 0x2B76, 0x2B95, 0x2B97, 0x2BFF, 0x4DC0, 0x4DFF, 0x1F000, 0x1F02B, 0x1F030, 0x1F093, 0x1F0A0, 0x1F0AE, 0x1F0B1, 0x1F0BF, 0x1F0C1, 0x1F0CF, 0x1F0D1, 0x1F0F5, 0x1F300, 0x1F6D7, 0x1F6DC, 0x1F6EC, 0x1F6F0, 0x1F6FC, 0x1F700, 0x1F776, 0x1F77B, 0x1F7D9, 0x1F7E0, 0x1F7EB, 0x1F7F0, 0x1F7F0, 0x1F800, 0x1F80B, 0x1F810, 0x1F847, 0x1F850, 0x1F859, 0x1F860, 0x1F887, 0x1F890, 0x1F8AD, 0x1F8B0, 0x1F8B1, 0x1F900, 0x1FA53, 0x1FA60, 0x1FA6D, 0x1FA70, 0x1FA7C, 0x1FA80, 0x1FA88, 0x1FA90, 0x1FABD, 0x1FABF, 0x1FAC5, 0x1FACE, 0x1FADB, 0x1FAE0, 0x1FAE8, 0x1FAF0, 0x1FAF8, 0x1FB00, 0x1FB92, 0x1FB94, 0x1FBCA, 0x1FBF0, 0x1FBF9, }, translit = false, character_category = false, -- none } m["Zyyy"] = { "undetermined", 104839687, -- This should not have any characters listed, probably translit = false, character_category = false, -- none } m["Zzzz"] = { "uncoded", 104839675, -- This should not have any characters listed translit = false, character_category = false, -- none } -- These should be defined after the scripts they are composed of. m["Hrkt"] = process_ranges{ "Kana", 187659, "syllabary", aliases = {"Japanese syllabaries"}, ranges = union( m["Hira"].ranges, m["Kana"].ranges ), spaces = false, } m["Jpan"] = process_ranges{ "Japanese", 190502, "logography, syllabary", ranges = union( m["Hrkt"].ranges, m["Hani"].ranges, m["Latn"].ranges ), spaces = false, sort_by_scraping = true, } m["Kore"] = process_ranges{ "Korean", 711797, "logography, syllabary", ranges = union( m["Hang"].ranges, m["Hani"].ranges, m["Latn"].ranges ), } return require("Module:languages").finalizeData(m, "script") 4clll4yp3tq8cpp8igask4it8as3jlt 26540 26539 2026-07-07T21:53:35Z Sibiru45 115 1 ralatan matan [[:id:Modul:scripts/data]] 26539 Scribunto text/plain --[=[ When adding new scripts to this file, please don't forget to add style definitons for the script in [[MediaWiki:Gadget-LanguagesAndScripts.css]]. ]=] local concat = table.concat local insert = table.insert local ipairs = ipairs local next = next local remove = table.remove local select = select local sort = table.sort -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end ------------------------------------------------------------------------------------ -- -- Helper functions -- ------------------------------------------------------------------------------------ -- Note: a[2] > b[2] means opens are sorted before closes if otherwise equal. local function sort_ranges(a, b) return a[1] < b[1] or a[1] == b[1] and a[2] > b[2] end -- Returns the union of two or more range tables. local function union(...) local ranges = {} for i = 1, select("#", ...) do local argt = select(i, ...) for j, v in ipairs(argt) do insert(ranges, {v, j % 2 == 1 and 1 or -1}) end end sort(ranges, sort_ranges) local ret, i = {}, 0 for _, range in ipairs(ranges) do i = i + range[2] if i == 0 and range[2] == -1 then -- close insert(ret, range[1]) elseif i == 1 and range[2] == 1 then -- open if ret[#ret] and range[1] <= ret[#ret] + 1 then remove(ret) -- merge adjacent ranges else insert(ret, range[1]) end end end return ret end -- Adds the `characters` key, which is determined by a script's `ranges` table. local function process_ranges(sc) local ranges, chars = sc.ranges, {} for i = 2, #ranges, 2 do if ranges[i] == ranges[i - 1] then insert(chars, u(ranges[i])) else insert(chars, u(ranges[i - 1])) if ranges[i] > ranges[i - 1] + 1 then insert(chars, "-") end insert(chars, u(ranges[i])) end end sc.characters = concat(chars) ranges.n = #ranges return sc end local function handle_normalization_fixes(fixes) local combiningClasses = fixes.combiningClasses if combiningClasses then local chars, i = {}, 0 for char in next, combiningClasses do i = i + 1 chars[i] = char end fixes.combiningClassCharacters = concat(chars) end return fixes end ------------------------------------------------------------------------------------ -- -- Data -- ------------------------------------------------------------------------------------ local m = {} m["Adlm"] = process_ranges{ "Adlam", 19606346, "alphabet", ranges = { 0x061F, 0x061F, 0x0640, 0x0640, 0x1E900, 0x1E94B, 0x1E950, 0x1E959, 0x1E95E, 0x1E95F, }, capitalized = true, direction = "rtl", } m["Afak"] = { "Afaka", 382019, "syllabary", -- Not in Unicode } m["Aghb"] = process_ranges{ "Caucasian Albanian", 2495716, "alphabet", ranges = { 0x10530, 0x10563, 0x1056F, 0x1056F, }, } m["Ahom"] = process_ranges{ "Ahom", 2839633, "abugida", ranges = { 0x11700, 0x1171A, 0x1171D, 0x1172B, 0x11730, 0x11746, }, } m["Arab"] = process_ranges{ "Arabic", 1828555, "abjad", -- more precisely, impure abjad varieties = {"Jawi", {"Nastaliq", "Nastaleeq"}}, ranges = { 0x0600, 0x06FF, 0x0750, 0x077F, 0x0870, 0x088E, 0x0890, 0x0891, 0x0897, 0x08E1, 0x08E3, 0x08FF, 0xFB50, 0xFBC2, 0xFBD3, 0xFD8F, 0xFD92, 0xFDC7, 0xFDCF, 0xFDCF, 0xFDF0, 0xFDFF, 0xFE70, 0xFE74, 0xFE76, 0xFEFC, 0x102E0, 0x102FB, 0x10E60, 0x10E7E, 0x10EC2, 0x10EC4, 0x10EFC, 0x10EFF, 0x1EE00, 0x1EE03, 0x1EE05, 0x1EE1F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE24, 0x1EE27, 0x1EE27, 0x1EE29, 0x1EE32, 0x1EE34, 0x1EE37, 0x1EE39, 0x1EE39, 0x1EE3B, 0x1EE3B, 0x1EE42, 0x1EE42, 0x1EE47, 0x1EE47, 0x1EE49, 0x1EE49, 0x1EE4B, 0x1EE4B, 0x1EE4D, 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE54, 0x1EE57, 0x1EE57, 0x1EE59, 0x1EE59, 0x1EE5B, 0x1EE5B, 0x1EE5D, 0x1EE5D, 0x1EE5F, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE64, 0x1EE67, 0x1EE6A, 0x1EE6C, 0x1EE72, 0x1EE74, 0x1EE77, 0x1EE79, 0x1EE7C, 0x1EE7E, 0x1EE7E, 0x1EE80, 0x1EE89, 0x1EE8B, 0x1EE9B, 0x1EEA1, 0x1EEA3, 0x1EEA5, 0x1EEA9, 0x1EEAB, 0x1EEBB, 0x1EEF0, 0x1EEF1, }, direction = "rtl", normalizationFixes = handle_normalization_fixes{ from = {"ٳ"}, to = {"اٟ"} }, } m["fa-Arab"] = { "Arabic", 744068, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, otherNames = {"Perso-Arabic"}, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["kk-Arab"] = { "Arabic", 90681452, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["ks-Arab"] = m["fa-Arab"] m["ku-Arab"] = m["fa-Arab"] m["ms-Arab"] = m["kk-Arab"] m["mzn-Arab"] = m["fa-Arab"] m["ota-Arab"] = m["fa-Arab"] m["pa-Arab"] = { "Shahmukhi", 133800, m["Arab"][3], ranges = m["Arab"].ranges, characters = m["Arab"].characters, otherNames = {"Arabic"}, direction = "rtl", parent = "Arab", normalizationFixes = m["Arab"].normalizationFixes, } m["ps-Arab"] = m["fa-Arab"] m["sd-Arab"] = m["fa-Arab"] m["tt-Arab"] = m["fa-Arab"] m["ug-Arab"] = m["fa-Arab"] m["ur-Arab"] = m["fa-Arab"] -- Aran (Nastaliq) is subsumed into Arab m["Armi"] = process_ranges{ "Imperial Aramaic", 26978, "abjad", ranges = { 0x10840, 0x10855, 0x10857, 0x1085F, }, direction = "rtl", } m["Armn"] = process_ranges{ "Armenian", 11932, "alphabet", ranges = { 0x0531, 0x0556, 0x0559, 0x058A, 0x058D, 0x058F, 0xFB13, 0xFB17, }, capitalized = true, } m["Avst"] = process_ranges{ "Avestan", 790681, "alphabet", ranges = { 0x10B00, 0x10B35, 0x10B39, 0x10B3F, }, direction = "rtl", } m["pal-Avst"] = { "Pazend", 4925073, m["Avst"][3], ranges = m["Avst"].ranges, characters = m["Avst"].characters, direction = "rtl", parent = "Avst", } m["Bali"] = process_ranges{ "Balinese", 804984, "abugida", ranges = { 0x1B00, 0x1B4C, 0x1B4E, 0x1B7F, }, } m["Bamu"] = process_ranges{ "Bamum", 806024, "syllabary", ranges = { 0xA6A0, 0xA6F7, 0x16800, 0x16A38, }, } m["Bass"] = process_ranges{ "Bassa", 810458, "alphabet", aliases = {"Bassa Vah", "Vah"}, ranges = { 0x16AD0, 0x16AED, 0x16AF0, 0x16AF5, }, } m["Batk"] = process_ranges{ "Batak", 51592, "abugida", ranges = { 0x1BC0, 0x1BF3, 0x1BFC, 0x1BFF, }, } m["Beng"] = process_ranges{ "Bengali", 756802, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0980, 0x0983, 0x0985, 0x098C, 0x098F, 0x0990, 0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B2, 0x09B2, 0x09B6, 0x09B9, 0x09BC, 0x09C4, 0x09C7, 0x09C8, 0x09CB, 0x09CE, 0x09D7, 0x09D7, 0x09DC, 0x09DD, 0x09DF, 0x09E3, 0x09E6, 0x09EF, 0x09F2, 0x09FE, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD2, 0x1CD5, 0x1CD6, 0x1CD8, 0x1CD8, 0x1CE1, 0x1CE1, 0x1CEA, 0x1CEA, 0x1CED, 0x1CED, 0x1CF2, 0x1CF2, 0x1CF5, 0x1CF7, 0xA8F1, 0xA8F1, }, normalizationFixes = handle_normalization_fixes{ from = {"অা", "ঋৃ", "ঌৢ"}, to = {"আ", "ৠ", "ৡ"} }, } m["as-Beng"] = process_ranges{ "Assamese", 191272, m["Beng"][3], otherNames = {"Eastern Nagari"}, ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0980, 0x0983, 0x0985, 0x098C, 0x098F, 0x0990, 0x0993, 0x09A8, 0x09AA, 0x09AF, 0x09B2, 0x09B2, 0x09B6, 0x09B9, 0x09BC, 0x09C4, 0x09C7, 0x09C8, 0x09CB, 0x09CE, 0x09D7, 0x09D7, 0x09DC, 0x09DD, 0x09DF, 0x09E3, 0x09E6, 0x09FE, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD2, 0x1CD5, 0x1CD6, 0x1CD8, 0x1CD8, 0x1CE1, 0x1CE1, 0x1CEA, 0x1CEA, 0x1CED, 0x1CED, 0x1CF2, 0x1CF2, 0x1CF5, 0x1CF7, 0xA8F1, 0xA8F1, }, normalizationFixes = m["Beng"].normalizationFixes, } m["Bhks"] = process_ranges{ "Bhaiksuki", 17017839, "abugida", ranges = { 0x11C00, 0x11C08, 0x11C0A, 0x11C36, 0x11C38, 0x11C45, 0x11C50, 0x11C6C, }, } m["Blis"] = { "Blissymbolic", 609817, "logography", aliases = {"Blissymbols"}, -- Not in Unicode } m["Bopo"] = process_ranges{ "Zhuyin", 198269, "semisyllabary", aliases = {"Zhuyin Fuhao", "Bopomofo"}, ranges = { 0x02EA, 0x02EB, 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x302A, 0x302D, 0x3030, 0x3030, 0x3037, 0x3037, 0x30FB, 0x30FB, 0x3105, 0x312F, 0x31A0, 0x31BF, 0xFE45, 0xFE46, 0xFF61, 0xFF65, }, } m["Brah"] = process_ranges{ "Brahmi", 185083, "abugida", ranges = { 0x11000, 0x1104D, 0x11052, 0x11075, 0x1107F, 0x1107F, }, normalizationFixes = handle_normalization_fixes{ from = {"𑀅𑀸", "𑀋𑀾", "𑀏𑁂"}, to = {"𑀆", "𑀌", "𑀐"} }, } m["Brai"] = process_ranges{ "Braille", 79894, "alphabet", ranges = { 0x2800, 0x28FF, }, } m["Bugi"] = process_ranges{ "Lontara", 1074947, "abugida", aliases = {"Buginese"}, ranges = { 0x1A00, 0x1A1B, 0x1A1E, 0x1A1F, 0xA9CF, 0xA9CF, }, } m["Buhd"] = process_ranges{ "Buhid", 1002969, "abugida", ranges = { 0x1735, 0x1736, 0x1740, 0x1751, 0x1752, 0x1753, }, } m["Cakm"] = process_ranges{ "Chakma", 1059328, "abugida", ranges = { 0x09E6, 0x09EF, 0x1040, 0x1049, 0x11100, 0x11134, 0x11136, 0x11147, }, } m["Cans"] = process_ranges{ "Canadian syllabic", 2479183, "abugida", ranges = { 0x1400, 0x167F, 0x18B0, 0x18F5, 0x11AB0, 0x11ABF, }, } m["Cari"] = process_ranges{ "Carian", 1094567, "alphabet", ranges = { 0x102A0, 0x102D0, }, } m["Cham"] = process_ranges{ "Cham", 1060381, "abugida", ranges = { 0xAA00, 0xAA36, 0xAA40, 0xAA4D, 0xAA50, 0xAA59, 0xAA5C, 0xAA5F, }, } m["Cher"] = process_ranges{ "Cherokee", 26549, "syllabary", ranges = { 0x13A0, 0x13F5, 0x13F8, 0x13FD, 0xAB70, 0xABBF, }, } m["Chis"] = { "Chisoi", 123173777, "abugida", -- Not in Unicode } m["Chrs"] = process_ranges{ "Khwarezmian", 72386710, "abjad", aliases = {"Chorasmian"}, ranges = { 0x10FB0, 0x10FCB, }, direction = "rtl", } m["Copt"] = process_ranges{ "Coptic", 321083, "alphabet", ranges = { 0x03E2, 0x03EF, 0x2C80, 0x2CF3, 0x2CF9, 0x2CFF, 0x102E0, 0x102FB, }, capitalized = true, } m["Cpmn"] = process_ranges{ "Cypro-Minoan", 1751985, "syllabary", aliases = {"Cypro Minoan"}, ranges = { 0x10100, 0x10101, 0x12F90, 0x12FF2, }, } m["Cprt"] = process_ranges{ "Cypriot", 1757689, "syllabary", ranges = { 0x10100, 0x10102, 0x10107, 0x10133, 0x10137, 0x1013F, 0x10800, 0x10805, 0x10808, 0x10808, 0x1080A, 0x10835, 0x10837, 0x10838, 0x1083C, 0x1083C, 0x1083F, 0x1083F, }, direction = "rtl", } m["Cyrl"] = process_ranges{ "Cyrillic", 8209, "alphabet", ranges = { 0x0400, 0x052F, 0x1C80, 0x1C8A, 0x1D2B, 0x1D2B, 0x1D78, 0x1D78, 0x1DF8, 0x1DF8, 0x2DE0, 0x2DFF, 0x2E43, 0x2E43, 0xA640, 0xA69F, 0xFE2E, 0xFE2F, 0x1E030, 0x1E06D, 0x1E08F, 0x1E08F, }, capitalized = true, } m["Cyrs"] = { "Old Cyrillic", 442244, m["Cyrl"][3], aliases = {"Early Cyrillic"}, ranges = m["Cyrl"].ranges, characters = m["Cyrl"].characters, capitalized = m["Cyrl"].capitalized, wikipedia_article = "Early Cyrillic alphabet", normalizationFixes = handle_normalization_fixes{ from = {"Ѹ", "ѹ"}, to = {"Ꙋ", "ꙋ"} }, } m["Deva"] = process_ranges{ "Devanagari", 38592, "abugida", ranges = { 0x0900, 0x097F, 0x1CD0, 0x1CF6, 0x1CF8, 0x1CF9, 0x20F0, 0x20F0, 0xA830, 0xA839, 0xA8E0, 0xA8FF, 0x11B00, 0x11B09, }, normalizationFixes = handle_normalization_fixes{ from = {"ॆॆ", "ेे", "ाॅ", "ाॆ", "ाꣿ", "ॊॆ", "ाे", "ाै", "ोे", "ाऺ", "ॖॖ", "अॅ", "अॆ", "अा", "एॅ", "एॆ", "एे", "एꣿ", "ऎॆ", "अॉ", "आॅ", "अॊ", "आॆ", "अो", "आे", "अौ", "आै", "ओे", "अऺ", "अऻ", "आऺ", "अाꣿ", "आꣿ", "ऒॆ", "अॖ", "अॗ", "ॶॖ", "्‍?ा"}, to = {"ꣿ", "ै", "ॉ", "ॊ", "ॏ", "ॏ", "ो", "ौ", "ौ", "ऻ", "ॗ", "ॲ", "ऄ", "आ", "ऍ", "ऎ", "ऐ", "ꣾ", "ꣾ", "ऑ", "ऑ", "ऒ", "ऒ", "ओ", "ओ", "औ", "औ", "औ", "ॳ", "ॴ", "ॴ", "ॵ", "ॵ", "ॵ", "ॶ", "ॷ", "ॷ"} }, } m["Diak"] = process_ranges{ "Dhives Akuru", 3307073, "abugida", aliases = {"Dhivehi Akuru", "Dives Akuru", "Divehi Akuru"}, ranges = { 0x11900, 0x11906, 0x11909, 0x11909, 0x1190C, 0x11913, 0x11915, 0x11916, 0x11918, 0x11935, 0x11937, 0x11938, 0x1193B, 0x11946, 0x11950, 0x11959, }, } m["Dogr"] = process_ranges{ "Dogra", 72402987, "abugida", ranges = { 0x0964, 0x096F, 0xA830, 0xA839, 0x11800, 0x1183B, }, } m["Dsrt"] = process_ranges{ "Deseret", 1200582, "alphabet", ranges = { 0x10400, 0x1044F, }, capitalized = true, } m["Dupl"] = process_ranges{ "Duployan", 5316025, "alphabet", ranges = { 0x1BC00, 0x1BC6A, 0x1BC70, 0x1BC7C, 0x1BC80, 0x1BC88, 0x1BC90, 0x1BC99, 0x1BC9C, 0x1BCA3, }, } m["Egyd"] = { "Demotic", 188519, "abjad, logography", -- Not in Unicode } m["Egyh"] = { "Hieratic", 208111, "abjad, logography", -- Unified with Egyptian hieroglyphic in Unicode } m["Egyp"] = process_ranges{ "Egyptian hieroglyphic", 132659, "abjad, logography", ranges = { 0x13000, 0x13455, 0x13460, 0x143FA, }, varieties = {"Hieratic"}, wikipedia_article = "Egyptian hieroglyphs", normalizationFixes = handle_normalization_fixes{ from = {"𓃁", "𓆖"}, to = {"𓃀𓐶𓂝", "𓆓𓐳𓐷𓏏𓐰𓇿𓐸"} }, } m["Elba"] = process_ranges{ "Elbasan", 1036714, "alphabet", ranges = { 0x10500, 0x10527, }, } m["Elym"] = process_ranges{ "Elymaic", 60744423, "abjad", ranges = { 0x10FE0, 0x10FF6, }, direction = "rtl", } m["Ethi"] = process_ranges{ "Ethiopic", 257634, "abugida", aliases = {"Ge'ez", "Geʽez"}, ranges = { 0x1200, 0x1248, 0x124A, 0x124D, 0x1250, 0x1256, 0x1258, 0x1258, 0x125A, 0x125D, 0x1260, 0x1288, 0x128A, 0x128D, 0x1290, 0x12B0, 0x12B2, 0x12B5, 0x12B8, 0x12BE, 0x12C0, 0x12C0, 0x12C2, 0x12C5, 0x12C8, 0x12D6, 0x12D8, 0x1310, 0x1312, 0x1315, 0x1318, 0x135A, 0x135D, 0x137C, 0x1380, 0x1399, 0x2D80, 0x2D96, 0x2DA0, 0x2DA6, 0x2DA8, 0x2DAE, 0x2DB0, 0x2DB6, 0x2DB8, 0x2DBE, 0x2DC0, 0x2DC6, 0x2DC8, 0x2DCE, 0x2DD0, 0x2DD6, 0x2DD8, 0x2DDE, 0xAB01, 0xAB06, 0xAB09, 0xAB0E, 0xAB11, 0xAB16, 0xAB20, 0xAB26, 0xAB28, 0xAB2E, 0x1E7E0, 0x1E7E6, 0x1E7E8, 0x1E7EB, 0x1E7ED, 0x1E7EE, 0x1E7F0, 0x1E7FE, }, } m["Gara"] = process_ranges{ "Garay", 3095302, "alphabet", capitalized = true, direction = "rtl", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x10D40, 0x10D65, 0x10D69, 0x10D85, 0x10D8E, 0x10D8F, }, } m["Geok"] = process_ranges{ "Khutsuri", 1090055, "alphabet", ranges = { -- Ⴀ-Ⴭ is Asomtavruli, ⴀ-ⴭ is Nuskhuri 0x10A0, 0x10C5, 0x10C7, 0x10C7, 0x10CD, 0x10CD, 0x10FB, 0x10FB, 0x2D00, 0x2D25, 0x2D27, 0x2D27, 0x2D2D, 0x2D2D, }, varieties = {"Nuskhuri", "Asomtavruli"}, capitalized = true, } m["Geor"] = process_ranges{ "Georgian", 3317411, "alphabet", ranges = { -- ა-ჿ is lowercase Mkhedruli; Ა-Ჿ is uppercase Mkhedruli (Mtavruli) 0x0589, 0x0589, 0x10D0, 0x10FF, 0x1C90, 0x1CBA, 0x1CBD, 0x1CBF, }, varieties = {"Mkhedruli", "Mtavruli"}, capitalized = true, } m["Glag"] = process_ranges{ "Glagolitic", 145625, "alphabet", ranges = { 0x0484, 0x0484, 0x0487, 0x0487, 0x0589, 0x0589, 0x10FB, 0x10FB, 0x2C00, 0x2C5F, 0x2E43, 0x2E43, 0xA66F, 0xA66F, 0x1E000, 0x1E006, 0x1E008, 0x1E018, 0x1E01B, 0x1E021, 0x1E023, 0x1E024, 0x1E026, 0x1E02A, }, capitalized = true, } m["Gong"] = process_ranges{ "Gunjala Gondi", 18125340, "abugida", ranges = { 0x0964, 0x0965, 0x11D60, 0x11D65, 0x11D67, 0x11D68, 0x11D6A, 0x11D8E, 0x11D90, 0x11D91, 0x11D93, 0x11D98, 0x11DA0, 0x11DA9, }, } m["Gonm"] = process_ranges{ "Masaram Gondi", 16977603, "abugida", ranges = { 0x0964, 0x0965, 0x11D00, 0x11D06, 0x11D08, 0x11D09, 0x11D0B, 0x11D36, 0x11D3A, 0x11D3A, 0x11D3C, 0x11D3D, 0x11D3F, 0x11D47, 0x11D50, 0x11D59, }, } m["Goth"] = process_ranges{ "Gothic", 467784, "alphabet", ranges = { 0x10330, 0x1034A, }, wikipedia_article = "Gothic alphabet", } m["Gran"] = process_ranges{ "Grantha", 1119274, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0BE6, 0x0BF3, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD3, 0x1CF2, 0x1CF4, 0x1CF8, 0x1CF9, 0x20F0, 0x20F0, 0x11300, 0x11303, 0x11305, 0x1130C, 0x1130F, 0x11310, 0x11313, 0x11328, 0x1132A, 0x11330, 0x11332, 0x11333, 0x11335, 0x11339, 0x1133B, 0x11344, 0x11347, 0x11348, 0x1134B, 0x1134D, 0x11350, 0x11350, 0x11357, 0x11357, 0x1135D, 0x11363, 0x11366, 0x1136C, 0x11370, 0x11374, 0x11FD0, 0x11FD1, 0x11FD3, 0x11FD3, }, } m["Grek"] = process_ranges{ "Greek", 8216, "alphabet", ranges = { 0x0341, 0x0341, 0x0374, 0x0375, 0x037E, 0x037E, 0x0384, 0x038A, 0x038C, 0x038C, 0x038E, 0x03A1, 0x03A3, 0x03D7, 0x03DA, 0x03DB, 0x03DE, 0x03E1, 0x03F0, 0x03F1, 0x03F4, 0x03F4, 0x03FC, 0x03FC, 0x1D26, 0x1D2A, 0x1D5D, 0x1D61, 0x1D66, 0x1D6A, 0x1DBF, 0x1DBF, 0x2126, 0x2127, 0x2129, 0x2129, 0x213C, 0x2140, 0xAB65, 0xAB65, 0x10140, 0x1018E, 0x101A0, 0x101A0, 0x1D200, 0x1D245, }, capitalized = true, } m["Polyt"] = process_ranges{ "Greek", 1475332, m["Grek"][3], ranges = union(m["Grek"].ranges, { 0x0340, 0x0340, 0x0342, 0x0345, 0x0370, 0x0373, 0x0376, 0x0377, 0x037A, 0x037D, 0x037F, 0x037F, 0x03D8, 0x03D9, 0x03DC, 0x03DD, 0x03F2, 0x03F3, 0x03F5, 0x03FB, 0x03FD, 0x03FF, 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D, 0x1F50, 0x1F57, 0x1F59, 0x1F59, 0x1F5B, 0x1F5B, 0x1F5D, 0x1F5D, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FC4, 0x1FC6, 0x1FD3, 0x1FD6, 0x1FDB, 0x1FDD, 0x1FEF, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFE, }), ietf_subtag = "Grek", capitalized = m["Grek"].capitalized, parent = "Grek", } m["Gujr"] = process_ranges{ "Gujarati", 733944, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0A81, 0x0A83, 0x0A85, 0x0A8D, 0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3, 0x0AB5, 0x0AB9, 0x0ABC, 0x0AC5, 0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0AD0, 0x0AD0, 0x0AE0, 0x0AE3, 0x0AE6, 0x0AF1, 0x0AF9, 0x0AFF, 0xA830, 0xA839, }, normalizationFixes = handle_normalization_fixes{ from = {"ઓ", "અાૈ", "અા", "અૅ", "અે", "અૈ", "અૉ", "અો", "અૌ", "આૅ", "આૈ", "ૅા"}, to = {"અાૅ", "ઔ", "આ", "ઍ", "એ", "ઐ", "ઑ", "ઓ", "ઔ", "ઓ", "ઔ", "ૉ"} }, } m["Gukh"] = process_ranges{ "Khema", 110064239, "abugida", aliases = {"Gurung Khema", "Khema Phri", "Khema Lipi"}, ranges = { 0x0965, 0x0965, 0x16100, 0x16139, }, } m["Guru"] = process_ranges{ "Gurmukhi", 689894, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0A01, 0x0A03, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10, 0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36, 0x0A38, 0x0A39, 0x0A3C, 0x0A3C, 0x0A3E, 0x0A42, 0x0A47, 0x0A48, 0x0A4B, 0x0A4D, 0x0A51, 0x0A51, 0x0A59, 0x0A5C, 0x0A5E, 0x0A5E, 0x0A66, 0x0A76, 0xA830, 0xA839, }, normalizationFixes = handle_normalization_fixes{ from = {"ਅਾ", "ਅੈ", "ਅੌ", "ੲਿ", "ੲੀ", "ੲੇ", "ੳੁ", "ੳੂ", "ੳੋ"}, to = {"ਆ", "ਐ", "ਔ", "ਇ", "ਈ", "ਏ", "ਉ", "ਊ", "ਓ"} }, } m["Hang"] = process_ranges{ "Hangul", 8222, "syllabary", aliases = {"Hangeul"}, ranges = { 0x1100, 0x11FF, 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x302E, 0x3030, 0x3037, 0x3037, 0x30FB, 0x30FB, 0x3131, 0x318E, 0x3200, 0x321E, 0x3260, 0x327E, 0xA960, 0xA97C, 0xAC00, 0xD7A3, 0xD7B0, 0xD7C6, 0xD7CB, 0xD7FB, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0xFFA0, 0xFFBE, 0xFFC2, 0xFFC7, 0xFFCA, 0xFFCF, 0xFFD2, 0xFFD7, 0xFFDA, 0xFFDC, }, } m["Hani"] = process_ranges{ "Han", 8201, "logography", ranges = { 0x2E80, 0x2E99, 0x2E9B, 0x2EF3, 0x2F00, 0x2FD5, 0x2FF0, 0x2FFF, 0x3001, 0x3003, 0x3005, 0x3011, 0x3013, 0x301F, 0x3021, 0x302D, 0x3030, 0x3030, 0x3037, 0x303F, 0x3190, 0x319F, 0x31C0, 0x31E5, 0x31EF, 0x31EF, 0x3220, 0x3247, 0x3280, 0x32B0, 0x32C0, 0x32CB, 0x30FB, 0x30FB, 0x32FF, 0x32FF, 0x3358, 0x3370, 0x337B, 0x337F, 0x33E0, 0x33FE, 0x3400, 0x4DBF, 0x4E00, 0x9FFF, 0xA700, 0xA707, 0xF900, 0xFA6D, 0xFA70, 0xFAD9, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0x16FE2, 0x16FE3, 0x16FF0, 0x16FF1, 0x1D360, 0x1D371, 0x1F250, 0x1F251, 0x20000, 0x2A6DF, 0x2A700, 0x2B739, 0x2B740, 0x2B81D, 0x2B820, 0x2CEA1, 0x2CEB0, 0x2EBE0, 0x2EBF0, 0x2EE5D, 0x2F800, 0x2FA1D, 0x30000, 0x3134A, 0x31350, 0x323AF, }, varieties = {"Hanzi", "Kanji", "Hanja", "Chu Nom"}, spaces = false, } m["Hans"] = { "Simplified Han", 185614, m["Hani"][3], ranges = m["Hani"].ranges, characters = m["Hani"].characters, spaces = m["Hani"].spaces, parent = "Hani", } m["Hant"] = { "Traditional Han", 178528, m["Hani"][3], ranges = m["Hani"].ranges, characters = m["Hani"].characters, spaces = m["Hani"].spaces, parent = "Hani", } m["Hano"] = process_ranges{ "Hanunoo", 1584045, "abugida", aliases = {"Hanunó'o", "Hanuno'o"}, ranges = { 0x1720, 0x1736, }, } m["Hatr"] = process_ranges{ "Hatran", 20813038, "abjad", ranges = { 0x108E0, 0x108F2, 0x108F4, 0x108F5, 0x108FB, 0x108FF, }, direction = "rtl", } m["Hebr"] = process_ranges{ "Hebrew", 33513, "abjad", -- more precisely, impure abjad ranges = { 0x0591, 0x05C7, 0x05D0, 0x05EA, 0x05EF, 0x05F4, 0x2135, 0x2138, 0xFB1D, 0xFB36, 0xFB38, 0xFB3C, 0xFB3E, 0xFB3E, 0xFB40, 0xFB41, 0xFB43, 0xFB44, 0xFB46, 0xFB4F, }, direction = "rtl", } m["Hira"] = process_ranges{ "Hiragana", 48332, "syllabary", ranges = { 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x3030, 0x3035, 0x3037, 0x3037, 0x303C, 0x303D, 0x3041, 0x3096, 0x3099, 0x30A0, 0x30FB, 0x30FC, 0xFE45, 0xFE46, 0xFF61, 0xFF65, 0xFF70, 0xFF70, 0xFF9E, 0xFF9F, 0x1B001, 0x1B11F, 0x1B132, 0x1B132, 0x1B150, 0x1B152, 0x1F200, 0x1F200, }, varieties = {"Hentaigana"}, spaces = false, } m["Hluw"] = process_ranges{ "Anatolian hieroglyphic", 521323, "logography, syllabary", ranges = { 0x14400, 0x14646, }, wikipedia_article = "Anatolian hieroglyphs", } m["Hmng"] = process_ranges{ "Pahawh Hmong", 365954, "semisyllabary", aliases = {"Hmong"}, ranges = { 0x16B00, 0x16B45, 0x16B50, 0x16B59, 0x16B5B, 0x16B61, 0x16B63, 0x16B77, 0x16B7D, 0x16B8F, }, } m["Hmnp"] = process_ranges{ "Nyiakeng Puachue Hmong", 33712499, "alphabet", ranges = { 0x1E100, 0x1E12C, 0x1E130, 0x1E13D, 0x1E140, 0x1E149, 0x1E14E, 0x1E14F, }, } m["Hung"] = process_ranges{ "Old Hungarian", 446224, "alphabet", aliases = {"Hungarian runic"}, ranges = { 0x10C80, 0x10CB2, 0x10CC0, 0x10CF2, 0x10CFA, 0x10CFF, }, capitalized = true, direction = "rtl", } m["Ibrnn"] = { "Northeastern Iberian", 1113155, "semisyllabary", ietf_subtag = "Zzzz", -- Not in Unicode } m["Ibrns"] = { "Southeastern Iberian", 2305351, "semisyllabary", ietf_subtag = "Zzzz", -- Not in Unicode } m["Image"] = { -- To be used to avoid any formatting or link processing "Image-rendered", 478798, -- This should not have any characters listed ietf_subtag = "Zyyy", translit = false, character_category = false, -- none } m["Inds"] = { "Indus", 601388, aliases = {"Harappan", "Indus Valley"}, } m["Ipach"] = { "International Phonetic Alphabet", 21204, aliases = {"IPA"}, ietf_subtag = "Latn", } m["Ital"] = process_ranges{ "Old Italic", 4891256, "alphabet", ranges = { 0x10300, 0x10323, 0x1032D, 0x1032F, }, } m["Java"] = process_ranges{ "Javanese", 879704, "abugida", ranges = { 0xA980, 0xA9CD, 0xA9CF, 0xA9D9, 0xA9DE, 0xA9DF, }, } m["Jurc"] = { "Jurchen", 912240, "logography", spaces = false, } m["Kali"] = process_ranges{ "Kayah Li", 4919239, "abugida", ranges = { 0xA900, 0xA92F, }, } m["Kana"] = process_ranges{ "Katakana", 82946, "syllabary", ranges = { 0x3001, 0x3003, 0x3008, 0x3011, 0x3013, 0x301F, 0x3030, 0x3035, 0x3037, 0x3037, 0x303C, 0x303D, 0x3099, 0x309C, 0x30A0, 0x30FF, 0x31F0, 0x31FF, 0x32D0, 0x32FE, 0x3300, 0x3357, 0xFE45, 0xFE46, 0xFF61, 0xFF9F, 0x1AFF0, 0x1AFF3, 0x1AFF5, 0x1AFFB, 0x1AFFD, 0x1AFFE, 0x1B000, 0x1B000, 0x1B120, 0x1B122, 0x1B155, 0x1B155, 0x1B164, 0x1B167, }, spaces = false, } m["Kawi"] = process_ranges{ "Kawi", 975802, "abugida", ranges = { 0x11F00, 0x11F10, 0x11F12, 0x11F3A, 0x11F3E, 0x11F5A, }, } m["Khar"] = process_ranges{ "Kharoshthi", 1161266, "abugida", ranges = { 0x10A00, 0x10A03, 0x10A05, 0x10A06, 0x10A0C, 0x10A13, 0x10A15, 0x10A17, 0x10A19, 0x10A35, 0x10A38, 0x10A3A, 0x10A3F, 0x10A48, 0x10A50, 0x10A58, }, direction = "rtl", } m["Khmr"] = process_ranges{ "Khmer", 1054190, "abugida", ranges = { 0x1780, 0x17DD, 0x17E0, 0x17E9, 0x17F0, 0x17F9, 0x19E0, 0x19FF, }, spaces = false, normalizationFixes = handle_normalization_fixes{ from = {"ឣ", "ឤ"}, to = {"អ", "អា"} }, } m["Khoj"] = process_ranges{ "Khojki", 1740656, "abugida", ranges = { 0x0AE6, 0x0AEF, 0xA830, 0xA839, 0x11200, 0x11211, 0x11213, 0x11241, }, normalizationFixes = handle_normalization_fixes{ from = {"𑈀𑈬𑈱", "𑈀𑈬", "𑈀𑈱", "𑈀𑈳", "𑈁𑈱", "𑈆𑈬", "𑈬𑈰", "𑈬𑈱", "𑉀𑈮"}, to = {"𑈇", "𑈁", "𑈅", "𑈇", "𑈇", "𑈃", "𑈲", "𑈳", "𑈂"} }, } m["Khomt"] = { "Khom Thai", 13023788, "abugida", -- Not in Unicode } m["Kitl"] = { "Khitan large", 6401797, "logography", spaces = false, } m["Kits"] = process_ranges{ "Khitan small", 6401800, "logography, syllabary", ranges = { 0x16FE4, 0x16FE4, 0x18B00, 0x18CD5, 0x18CFF, 0x18CFF, }, spaces = false, } m["Knda"] = process_ranges{ "Kannada", 839666, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0C80, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3, 0x0CB5, 0x0CB9, 0x0CBC, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD, 0x0CD5, 0x0CD6, 0x0CDD, 0x0CDE, 0x0CE0, 0x0CE3, 0x0CE6, 0x0CEF, 0x0CF1, 0x0CF3, 0x1CD0, 0x1CD0, 0x1CD2, 0x1CD3, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, 0x1CF4, 0x1CF4, 0xA830, 0xA835, }, normalizationFixes = handle_normalization_fixes{ from = {"ಉಾ", "ಋಾ", "ಒೌ"}, to = {"ಊ", "ೠ", "ಔ"} }, } m["Kpel"] = { "Kpelle", 1586299, "syllabary", -- Not in Unicode } m["Krai"] = process_ranges{ "Kirat Rai", 123173834, "abugida", aliases = {"Rai", "Khambu Rai", "Rai Barṇamālā", "Kirat Khambu Rai"}, ranges = { 0x16D40, 0x16D79, }, } m["Kthi"] = process_ranges{ "Kaithi", 1253814, "abugida", ranges = { 0x0966, 0x096F, 0xA830, 0xA839, 0x11080, 0x110C2, 0x110CD, 0x110CD, }, } m["Kulit"] = { "Kulitan", 6443044, "abugida", -- Not in Unicode } m["Lana"] = process_ranges{ "Tai Tham", 1314503, "abugida", aliases = {"Tham", "Tua Mueang", "Lanna"}, ranges = { 0x1A20, 0x1A5E, 0x1A60, 0x1A7C, 0x1A7F, 0x1A89, 0x1A90, 0x1A99, 0x1AA0, 0x1AAD, }, spaces = false, } m["Laoo"] = process_ranges{ "Lao", 1815229, "abugida", ranges = { 0x0E81, 0x0E82, 0x0E84, 0x0E84, 0x0E86, 0x0E8A, 0x0E8C, 0x0EA3, 0x0EA5, 0x0EA5, 0x0EA7, 0x0EBD, 0x0EC0, 0x0EC4, 0x0EC6, 0x0EC6, 0x0EC8, 0x0ECE, 0x0ED0, 0x0ED9, 0x0EDC, 0x0EDF, }, spaces = false, } m["Latn"] = process_ranges{ "Latin", 8229, "alphabet", aliases = {"Roman"}, ranges = { 0x0041, 0x005A, 0x0061, 0x007A, 0x00AA, 0x00AA, 0x00BA, 0x00BA, 0x00C0, 0x00D6, 0x00D8, 0x00F6, 0x00F8, 0x02B8, 0x02C0, 0x02C1, 0x02E0, 0x02E4, 0x0363, 0x036F, 0x0485, 0x0486, 0x0951, 0x0952, 0x10FB, 0x10FB, 0x1D00, 0x1D25, 0x1D2C, 0x1D5C, 0x1D62, 0x1D65, 0x1D6B, 0x1D77, 0x1D79, 0x1DBE, 0x1DF8, 0x1DF8, 0x1E00, 0x1EFF, 0x202F, 0x202F, 0x2071, 0x2071, 0x207F, 0x207F, 0x2090, 0x209C, 0x20F0, 0x20F0, 0x2100, 0x2125, 0x2128, 0x2128, 0x212A, 0x2134, 0x2139, 0x213B, 0x2141, 0x214E, 0x2160, 0x2188, 0x2C60, 0x2C7F, 0xA700, 0xA707, 0xA722, 0xA787, 0xA78B, 0xA7CD, 0xA7D0, 0xA7D1, 0xA7D3, 0xA7D3, 0xA7D5, 0xA7DC, 0xA7F2, 0xA7FF, 0xA92E, 0xA92E, 0xAB30, 0xAB5A, 0xAB5C, 0xAB64, 0xAB66, 0xAB69, 0xFB00, 0xFB06, 0xFF21, 0xFF3A, 0xFF41, 0xFF5A, 0x10780, 0x10785, 0x10787, 0x107B0, 0x107B2, 0x107BA, 0x1DF00, 0x1DF1E, 0x1DF25, 0x1DF2A, }, varieties = {"Rumi", "Romaji", "Rōmaji", "Romaja"}, capitalized = true, translit = false, } m["Latf"] = { "Fraktur", 148443, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, otherNames = {"Blackletter"}, -- Blackletter is actually the parent "script" capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["Latg"] = { "Gaelic", 1432616, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, otherNames = {"Irish"}, capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["pjt-Latn"] = { "Latin", nil, m["Latn"][3], ranges = m["Latn"].ranges, characters = m["Latn"].characters, capitalized = m["Latn"].capitalized, translit = m["Latn"].translit, parent = "Latn", } m["Leke"] = { "Leke", 19572613, "abugida", -- Not in Unicode } m["Lepc"] = process_ranges{ "Lepcha", 1481626, "abugida", aliases = {"Róng"}, ranges = { 0x1C00, 0x1C37, 0x1C3B, 0x1C49, 0x1C4D, 0x1C4F, }, } m["Limb"] = process_ranges{ "Limbu", 933796, "abugida", ranges = { 0x0965, 0x0965, 0x1900, 0x191E, 0x1920, 0x192B, 0x1930, 0x193B, 0x1940, 0x1940, 0x1944, 0x194F, }, } m["Lina"] = process_ranges{ "Linear A", 30972, ranges = { 0x10107, 0x10133, 0x10600, 0x10736, 0x10740, 0x10755, 0x10760, 0x10767, }, } m["Linb"] = process_ranges{ "Linear B", 190102, ranges = { 0x10000, 0x1000B, 0x1000D, 0x10026, 0x10028, 0x1003A, 0x1003C, 0x1003D, 0x1003F, 0x1004D, 0x10050, 0x1005D, 0x10080, 0x100FA, 0x10100, 0x10102, 0x10107, 0x10133, 0x10137, 0x1013F, }, } m["Lisu"] = process_ranges{ "Fraser", 1194621, "alphabet", aliases = {"Old Lisu", "Lisu"}, ranges = { 0x300A, 0x300B, 0xA4D0, 0xA4FF, 0x11FB0, 0x11FB0, }, normalizationFixes = handle_normalization_fixes{ from = {"['’]", "[.ꓸ][.ꓸ]", "[.ꓸ][,ꓹ]"}, to = {"ʼ", "ꓺ", "ꓻ"} }, } m["Loma"] = { "Loma", 13023816, "syllabary", -- Not in Unicode } m["Lyci"] = process_ranges{ "Lycian", 913587, "alphabet", ranges = { 0x10280, 0x1029C, }, } m["Lydi"] = process_ranges{ "Lydian", 4261300, "alphabet", ranges = { 0x10920, 0x10939, 0x1093F, 0x1093F, }, direction = "rtl", } m["Mahj"] = process_ranges{ "Mahajani", 6732850, "abugida", ranges = { 0x0964, 0x096F, 0xA830, 0xA839, 0x11150, 0x11176, }, } m["Maka"] = process_ranges{ "Makasar", 72947229, "abugida", aliases = {"Old Makasar"}, ranges = { 0x11EE0, 0x11EF8, }, } m["Mand"] = process_ranges{ "Mandaic", 1812130, aliases = {"Mandaean"}, ranges = { 0x0640, 0x0640, 0x0840, 0x085B, 0x085E, 0x085E, }, direction = "rtl", } m["Mani"] = process_ranges{ "Manichaean", 3544702, "abjad", ranges = { 0x0640, 0x0640, 0x10AC0, 0x10AE6, 0x10AEB, 0x10AF6, }, direction = "rtl", } m["Marc"] = process_ranges{ "Marchen", 72403709, "abugida", ranges = { 0x11C70, 0x11C8F, 0x11C92, 0x11CA7, 0x11CA9, 0x11CB6, }, } m["Maya"] = process_ranges{ "Maya", 211248, aliases = {"Maya hieroglyphic", "Mayan", "Mayan hieroglyphic"}, ranges = { 0x1D2E0, 0x1D2F3, }, } m["Medf"] = process_ranges{ "Medefaidrin", 1519764, aliases = {"Oberi Okaime", "Oberi Ɔkaimɛ"}, ranges = { 0x16E40, 0x16E9A, }, capitalized = true, } m["Mend"] = process_ranges{ "Mende", 951069, aliases = {"Mende Kikakui"}, ranges = { 0x1E800, 0x1E8C4, 0x1E8C7, 0x1E8D6, }, direction = "rtl", } m["Merc"] = process_ranges{ "Meroitic cursive", 73028124, "abugida", ranges = { 0x109A0, 0x109B7, 0x109BC, 0x109CF, 0x109D2, 0x109FF, }, direction = "rtl", } m["Mero"] = process_ranges{ "Meroitic hieroglyphic", 73028623, "abugida", ranges = { 0x10980, 0x1099F, }, direction = "rtl", wikipedia_article = "Meroitic hieroglyphs", } m["Mlym"] = process_ranges{ "Malayalam", 1164129, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0D00, 0x0D0C, 0x0D0E, 0x0D10, 0x0D12, 0x0D44, 0x0D46, 0x0D48, 0x0D4A, 0x0D4F, 0x0D54, 0x0D63, 0x0D66, 0x0D7F, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, 0xA830, 0xA832, }, normalizationFixes = handle_normalization_fixes{ from = {"ഇൗ", "ഉൗ", "എെ", "ഒാ", "ഒൗ", "ക്‍", "ണ്‍", "ന്‍റ", "ന്‍", "മ്‍", "യ്‍", "ര്‍", "ല്‍", "ള്‍", "ഴ്‍", "െെ", "ൻ്റ"}, to = {"ഈ", "ഊ", "ഐ", "ഓ", "ഔ", "ൿ", "ൺ", "ൻറ", "ൻ", "ൔ", "ൕ", "ർ", "ൽ", "ൾ", "ൖ", "ൈ", "ന്റ"} }, } m["Modi"] = process_ranges{ "Modi", 1703713, "abugida", ranges = { 0xA830, 0xA839, 0x11600, 0x11644, 0x11650, 0x11659, }, normalizationFixes = handle_normalization_fixes{ from = {"𑘀𑘹", "𑘀𑘺", "𑘁𑘹", "𑘁𑘺"}, to = {"𑘊", "𑘋", "𑘌", "𑘍"} }, } m["Mong"] = process_ranges{ "Mongolian", 1055705, "alphabet", aliases = {"Mongol bichig", "Hudum Mongol bichig"}, ranges = { 0x1800, 0x1805, 0x180A, 0x1819, 0x1820, 0x1842, 0x1878, 0x1878, 0x1880, 0x1897, 0x18A6, 0x18A6, 0x18A9, 0x18A9, 0x200C, 0x200D, 0x202F, 0x202F, 0x3001, 0x3002, 0x3008, 0x300B, 0x11660, 0x11668, }, direction = "vertical-ltr", } m["mnc-Mong"] = process_ranges{ "Manchu", 122888, m["Mong"][3], ranges = { 0x1801, 0x1801, 0x1804, 0x1804, 0x1808, 0x180F, 0x1820, 0x1820, 0x1823, 0x1823, 0x1828, 0x182A, 0x182E, 0x1830, 0x1834, 0x1838, 0x183A, 0x183A, 0x185D, 0x185D, 0x185F, 0x1861, 0x1864, 0x1869, 0x186C, 0x1871, 0x1873, 0x1877, 0x1880, 0x1888, 0x188F, 0x188F, 0x189A, 0x18A5, 0x18A8, 0x18A8, 0x18AA, 0x18AA, 0x200C, 0x200D, 0x202F, 0x202F, }, direction = "vertical-ltr", parent = "Mong", } m["sjo-Mong"] = process_ranges{ "Xibe", 113624153, m["Mong"][3], aliases = {"Sibe"}, ranges = { 0x1804, 0x1804, 0x1807, 0x1807, 0x180A, 0x180F, 0x1820, 0x1820, 0x1823, 0x1823, 0x1828, 0x1828, 0x182A, 0x182A, 0x182E, 0x1830, 0x1834, 0x1838, 0x183A, 0x183A, 0x185D, 0x1872, 0x200C, 0x200D, 0x202F, 0x202F, }, direction = "vertical-ltr", parent = "mnc-Mong", } m["xwo-Mong"] = process_ranges{ "Clear Script", 529085, m["Mong"][3], aliases = {"Todo", "Todo bichig"}, ranges = { 0x1800, 0x1801, 0x1804, 0x1806, 0x180A, 0x1820, 0x1828, 0x1828, 0x182F, 0x1831, 0x1834, 0x1834, 0x1837, 0x1838, 0x183A, 0x183B, 0x1840, 0x1840, 0x1843, 0x185C, 0x1880, 0x1887, 0x1889, 0x188F, 0x1894, 0x1894, 0x1896, 0x1899, 0x18A7, 0x18A7, 0x200C, 0x200D, 0x202F, 0x202F, 0x11669, 0x1166C, }, direction = "vertical-ltr", parent = "Mong", } m["Moon"] = { "Moon", 918391, "alphabet", aliases = {"Moon System of Embossed Reading", "Moon type", "Moon writing", "Moon alphabet", "Moon code"}, -- Not in Unicode } m["Morse"] = { "Morse code", 79897, ietf_subtag = "Zsym", } m["Mroo"] = process_ranges{ "Mru", 75919253, aliases = {"Mro", "Mrung"}, ranges = { 0x16A40, 0x16A5E, 0x16A60, 0x16A69, 0x16A6E, 0x16A6F, }, } m["Mtei"] = process_ranges{ "Meitei Mayek", 2981413, "abugida", aliases = {"Meetei Mayek", "Manipuri"}, ranges = { 0xAAE0, 0xAAF6, 0xABC0, 0xABED, 0xABF0, 0xABF9, }, } m["Mult"] = process_ranges{ "Multani", 17047906, "abugida", ranges = { 0x0A66, 0x0A6F, 0x11280, 0x11286, 0x11288, 0x11288, 0x1128A, 0x1128D, 0x1128F, 0x1129D, 0x1129F, 0x112A9, }, } m["Music"] = process_ranges{ "musical notation", 233861, "pictography", ranges = { 0x2669, 0x266F, 0x1D100, 0x1D126, 0x1D129, 0x1D1EA, }, ietf_subtag = "Zsym", translit = false, } m["Mymr"] = process_ranges{ "Burmese", 43887939, "abugida", aliases = {"Myanmar"}, ranges = { 0x1000, 0x109F, 0xA92E, 0xA92E, 0xA9E0, 0xA9FE, 0xAA60, 0xAA7F, 0x116D0, 0x116E3, }, spaces = false, } m["Nagm"] = process_ranges{ "Mundari Bani", 106917274, "alphabet", aliases = {"Nag Mundari"}, ranges = { 0x1E4D0, 0x1E4F9, }, } m["Nand"] = process_ranges{ "Nandinagari", 6963324, "abugida", ranges = { 0x0964, 0x0965, 0x0CE6, 0x0CEF, 0x1CE9, 0x1CE9, 0x1CF2, 0x1CF2, 0x1CFA, 0x1CFA, 0xA830, 0xA835, 0x119A0, 0x119A7, 0x119AA, 0x119D7, 0x119DA, 0x119E4, }, } m["Narb"] = process_ranges{ "Ancient North Arabian", 1472213, "abjad", aliases = {"Old North Arabian"}, ranges = { 0x10A80, 0x10A9F, }, direction = "rtl", } m["Nbat"] = process_ranges{ "Nabataean", 855624, "abjad", aliases = {"Nabatean"}, ranges = { 0x10880, 0x1089E, 0x108A7, 0x108AF, }, direction = "rtl", } m["Newa"] = process_ranges{ "Newa", 7237292, "abugida", aliases = {"Newar", "Newari", "Prachalit Nepal"}, ranges = { 0x11400, 0x1145B, 0x1145D, 0x11461, }, } m["Nkdb"] = { "Dongba", 1190953, "pictography", aliases = {"Naxi Dongba", "Nakhi Dongba", "Tomba", "Tompa", "Mo-so"}, spaces = false, -- Not in Unicode } m["Nkgb"] = { "Geba", 731189, "syllabary", aliases = {"Nakhi Geba", "Naxi Geba"}, spaces = false, -- Not in Unicode } m["Nkoo"] = process_ranges{ "N'Ko", 1062587, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x07C0, 0x07FA, 0x07FD, 0x07FF, 0xFD3E, 0xFD3F, }, direction = "rtl", } m["None"] = { "unspecified", nil, -- This should not have any characters listed ietf_subtag = "Zyyy", translit = false, character_category = false, -- none } m["Nshu"] = process_ranges{ "Nüshu", 56436, "syllabary", aliases = {"Nushu"}, ranges = { 0x16FE1, 0x16FE1, 0x1B170, 0x1B2FB, }, spaces = false, } m["Ogam"] = process_ranges{ "Ogham", 184661, ranges = { 0x1680, 0x169C, }, } m["Olck"] = process_ranges{ "Ol Chiki", 201688, aliases = {"Ol Chemetʼ", "Ol", "Santali"}, ranges = { 0x1C50, 0x1C7F, }, } m["Onao"] = process_ranges{ "Ol Onal", 108607084, "alphabet", ranges = { 0x0964, 0x0965, 0x1E5D0, 0x1E5FA, 0x1E5FF, 0x1E5FF, }, } m["Orkh"] = process_ranges{ "Old Turkic", 5058305, aliases = {"Orkhon runic"}, ranges = { 0x10C00, 0x10C48, }, direction = "rtl", } m["Orya"] = process_ranges{ "Odia", 1760127, "abugida", aliases = {"Oriya"}, ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0B01, 0x0B03, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28, 0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B35, 0x0B39, 0x0B3C, 0x0B44, 0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B55, 0x0B57, 0x0B5C, 0x0B5D, 0x0B5F, 0x0B63, 0x0B66, 0x0B77, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, }, normalizationFixes = handle_normalization_fixes{ from = {"ଅା", "ଏୗ", "ଓୗ"}, to = {"ଆ", "ଐ", "ଔ"} }, } m["Osge"] = process_ranges{ "Osage", 7105529, ranges = { 0x104B0, 0x104D3, 0x104D8, 0x104FB, }, capitalized = true, } m["Osma"] = process_ranges{ "Osmanya", 1377866, ranges = { 0x10480, 0x1049D, 0x104A0, 0x104A9, }, } m["Ougr"] = process_ranges{ "Old Uyghur", 1998938, "abjad, alphabet", ranges = { 0x0640, 0x0640, 0x10AF2, 0x10AF2, 0x10F70, 0x10F89, }, -- This should ideally be "vertical-ltr", but getting the CSS right is tricky because it's right-to-left horizontally, but left-to-right vertically. Currently, displaying it vertically causes it to display bottom-to-top. direction = "rtl", } m["Palm"] = process_ranges{ "Palmyrene", 17538100, ranges = { 0x10860, 0x1087F, }, direction = "rtl", } m["Pauc"] = process_ranges{ "Pau Cin Hau", 25339852, ranges = { 0x11AC0, 0x11AF8, }, } m["Pcun"] = { "Proto-Cuneiform", 1650699, "pictography", -- Not in Unicode } m["Pelm"] = { "Proto-Elamite", 56305763, "pictography", -- Not in Unicode } m["Perm"] = process_ranges{ "Old Permic", 147899, ranges = { 0x0483, 0x0483, 0x10350, 0x1037A, }, } m["Phag"] = process_ranges{ "Phags-pa", 822836, "abugida", ranges = { 0x1802, 0x1803, 0x1805, 0x1805, 0x200C, 0x200D, 0x202F, 0x202F, 0x3002, 0x3002, 0xA840, 0xA877, }, direction = "vertical-ltr", } m["Phli"] = process_ranges{ "Inscriptional Pahlavi", 24089793, "abjad", ranges = { 0x10B60, 0x10B72, 0x10B78, 0x10B7F, }, direction = "rtl", } m["Phlp"] = process_ranges{ "Psalter Pahlavi", 7253954, "abjad", ranges = { 0x0640, 0x0640, 0x10B80, 0x10B91, 0x10B99, 0x10B9C, 0x10BA9, 0x10BAF, }, direction = "rtl", } m["Phlv"] = { "Book Pahlavi", 72403118, "abjad", direction = "rtl", wikipedia_article = "Pahlavi scripts#Book Pahlavi", -- Not in Unicode } m["Phnx"] = process_ranges{ "Phoenician", 26752, "abjad", ranges = { 0x10900, 0x1091B, 0x1091F, 0x1091F, }, direction = "rtl", } m["Plrd"] = process_ranges{ "Pollard", 601734, "abugida", aliases = {"Miao"}, ranges = { 0x16F00, 0x16F4A, 0x16F4F, 0x16F87, 0x16F8F, 0x16F9F, }, } m["Prti"] = process_ranges{ "Inscriptional Parthian", 13023804, ranges = { 0x10B40, 0x10B55, 0x10B58, 0x10B5F, }, direction = "rtl", } m["Psin"] = { "Proto-Sinaitic", 1065250, "abjad", direction = "rtl", -- Not in Unicode } m["Ranj"] = { "Ranjana", 2385276, "abugida", -- Not in Unicode } m["Rjng"] = process_ranges{ "Rejang", 2007960, "abugida", ranges = { 0xA930, 0xA953, 0xA95F, 0xA95F, }, } m["Rohg"] = process_ranges{ "Hanifi Rohingya", 21028705, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x0640, 0x0640, 0x06D4, 0x06D4, 0x10D00, 0x10D27, 0x10D30, 0x10D39, }, direction = "rtl", } m["Roro"] = { "Rongorongo", 209764, -- Not in Unicode } m["Rumin"] = process_ranges{ "Rumi numerals", nil, ranges = { 0x10E60, 0x10E7E, }, ietf_subtag = "Arab", } m["Runr"] = process_ranges{ "Runic", 82996, "alphabet", ranges = { 0x16A0, 0x16EA, 0x16EE, 0x16F8, }, } m["Samr"] = process_ranges{ "Samaritan", 1550930, "abjad", ranges = { 0x0800, 0x082D, 0x0830, 0x083E, }, direction = "rtl", } m["Sarb"] = process_ranges{ "Ancient South Arabian", 446074, "abjad", aliases = {"Old South Arabian"}, ranges = { 0x10A60, 0x10A7F, }, direction = "rtl", } m["Saur"] = process_ranges{ "Saurashtra", 3535165, "abugida", ranges = { 0xA880, 0xA8C5, 0xA8CE, 0xA8D9, }, } m["Semap"] = { "flag semaphore", 250796, "pictography", ietf_subtag = "Zsym", } m["Sgnw"] = process_ranges{ "SignWriting", 1497335, "pictography", aliases = {"Sutton SignWriting"}, ranges = { 0x1D800, 0x1DA8B, 0x1DA9B, 0x1DA9F, 0x1DAA1, 0x1DAAF, }, translit = false, } m["Shaw"] = process_ranges{ "Shavian", 1970098, aliases = {"Shaw"}, ranges = { 0x10450, 0x1047F, }, } m["Shrd"] = process_ranges{ "Sharada", 2047117, "abugida", ranges = { 0x0951, 0x0951, 0x1CD7, 0x1CD7, 0x1CD9, 0x1CD9, 0x1CDC, 0x1CDD, 0x1CE0, 0x1CE0, 0xA830, 0xA835, 0xA838, 0xA838, 0x11180, 0x111DF, }, } m["Shui"] = { "Sui", 752854, "logography", spaces = false, -- Not in Unicode } m["Sidd"] = process_ranges{ "Siddham", 250379, "abugida", ranges = { 0x11580, 0x115B5, 0x115B8, 0x115DD, }, } m["Sidt"] = { "Sidetic", 36659, "alphabet", direction = "rtl", -- Not in Unicode } m["Sind"] = process_ranges{ "Khudabadi", 6402810, "abugida", aliases = {"Khudawadi"}, ranges = { 0x0964, 0x0965, 0xA830, 0xA839, 0x112B0, 0x112EA, 0x112F0, 0x112F9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑊰𑋠", "𑊰𑋥", "𑊰𑋦", "𑊰𑋧", "𑊰𑋨"}, to = {"𑊱", "𑊶", "𑊷", "𑊸", "𑊹"} }, } m["Sinh"] = process_ranges{ "Sinhalese", 1574992, "abugida", aliases = {"Sinhala"}, ranges = { 0x0964, 0x0965, 0x0D81, 0x0D83, 0x0D85, 0x0D96, 0x0D9A, 0x0DB1, 0x0DB3, 0x0DBB, 0x0DBD, 0x0DBD, 0x0DC0, 0x0DC6, 0x0DCA, 0x0DCA, 0x0DCF, 0x0DD4, 0x0DD6, 0x0DD6, 0x0DD8, 0x0DDF, 0x0DE6, 0x0DEF, 0x0DF2, 0x0DF4, 0x1CF2, 0x1CF2, 0x111E1, 0x111F4, }, normalizationFixes = handle_normalization_fixes{ from = {"අා", "අැ", "අෑ", "උෟ", "ඍෘ", "ඏෟ", "එ්", "එෙ", "ඔෟ", "ෘෘ"}, to = {"ආ", "ඇ", "ඈ", "ඌ", "ඎ", "ඐ", "ඒ", "ඓ", "ඖ", "ෲ"} }, } m["Sogd"] = process_ranges{ "Sogdian", 578359, "abjad", ranges = { 0x0640, 0x0640, 0x10F30, 0x10F59, }, direction = "rtl", } m["Sogo"] = process_ranges{ "Old Sogdian", 72403254, "abjad", ranges = { 0x10F00, 0x10F27, }, direction = "rtl", } m["Sora"] = process_ranges{ "Sorang Sompeng", 7563292, aliases = {"Sora Sompeng"}, ranges = { 0x110D0, 0x110E8, 0x110F0, 0x110F9, }, } m["Soyo"] = process_ranges{ "Soyombo", 8009382, "abugida", ranges = { 0x11A50, 0x11AA2, }, } m["Sund"] = process_ranges{ "Sundanese", 51589, "abugida", ranges = { 0x1B80, 0x1BBF, 0x1CC0, 0x1CC7, }, } m["Sunu"] = process_ranges{ "Sunuwar", 109984965, "alphabet", ranges = { 0x11BC0, 0x11BE1, 0x11BF0, 0x11BF9, }, } m["Sylo"] = process_ranges{ "Sylheti Nagri", 144128, "abugida", aliases = {"Sylheti Nāgarī", "Syloti Nagri"}, ranges = { 0x0964, 0x0965, 0x09E6, 0x09EF, 0xA800, 0xA82C, }, } m["Syrc"] = process_ranges{ "Syriac", 26567, "abjad", -- more precisely, impure abjad ranges = { 0x060C, 0x060C, 0x061B, 0x061C, 0x061F, 0x061F, 0x0640, 0x0640, 0x064B, 0x0655, 0x0670, 0x0670, 0x0700, 0x070D, 0x070F, 0x074A, 0x074D, 0x074F, 0x0860, 0x086A, 0x1DF8, 0x1DF8, 0x1DFA, 0x1DFA, }, direction = "rtl", } -- Syre, Syrj, Syrn are apparently subsumed into Syrc; discuss if this causes issues m["Tagb"] = process_ranges{ "Tagbanwa", 977444, "abugida", ranges = { 0x1735, 0x1736, 0x1760, 0x176C, 0x176E, 0x1770, 0x1772, 0x1773, }, } m["Takr"] = process_ranges{ "Takri", 759202, "abugida", ranges = { 0x0964, 0x0965, 0xA830, 0xA839, 0x11680, 0x116B9, 0x116C0, 0x116C9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑚀𑚭", "𑚀𑚴", "𑚀𑚵", "𑚆𑚲"}, to = {"𑚁", "𑚈", "𑚉", "𑚇"} }, } m["Tale"] = process_ranges{ "Tai Nüa", 2566326, "abugida", aliases = {"Tai Nuea", "New Tai Nüa", "New Tai Nuea", "Dehong Dai", "Tai Dehong", "Tai Le"}, ranges = { 0x1040, 0x1049, 0x1950, 0x196D, 0x1970, 0x1974, }, spaces = false, } m["Talu"] = process_ranges{ "New Tai Lue", 3498863, "abugida", ranges = { 0x1980, 0x19AB, 0x19B0, 0x19C9, 0x19D0, 0x19DA, 0x19DE, 0x19DF, }, spaces = false, } m["Taml"] = process_ranges{ "Tamil", 26803, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0B82, 0x0B83, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95, 0x0B99, 0x0B9A, 0x0B9C, 0x0B9C, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA, 0x0BAE, 0x0BB9, 0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0BD0, 0x0BD0, 0x0BD7, 0x0BD7, 0x0BE6, 0x0BFA, 0x1CDA, 0x1CDA, 0xA8F3, 0xA8F3, 0x11301, 0x11301, 0x11303, 0x11303, 0x1133B, 0x1133C, 0x11FC0, 0x11FF1, 0x11FFF, 0x11FFF, }, normalizationFixes = handle_normalization_fixes{ from = {"அூ", "ஸ்ரீ"}, to = {"ஆ", "ஶ்ரீ"} }, } m["Tang"] = process_ranges{ "Tangut", 1373610, "logography, syllabary", ranges = { 0x31EF, 0x31EF, 0x16FE0, 0x16FE0, 0x17000, 0x187F7, 0x18800, 0x18AFF, 0x18D00, 0x18D08, }, spaces = false, } m["Tavt"] = process_ranges{ "Tai Viet", 11818517, "abugida", ranges = { 0xAA80, 0xAAC2, 0xAADB, 0xAADF, }, spaces = false, } m["Tayo"] = { "Lai Tay", 16306701, "abugida", aliases = {"Tai Yo"}, direction = "vertical-rtl", -- Not in Unicode } m["Telu"] = process_ranges{ "Telugu", 570450, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x0C00, 0x0C0C, 0x0C0E, 0x0C10, 0x0C12, 0x0C28, 0x0C2A, 0x0C39, 0x0C3C, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56, 0x0C58, 0x0C5A, 0x0C5D, 0x0C5D, 0x0C60, 0x0C63, 0x0C66, 0x0C6F, 0x0C77, 0x0C7F, 0x1CDA, 0x1CDA, 0x1CF2, 0x1CF2, }, normalizationFixes = handle_normalization_fixes{ from = {"ఒౌ", "ఒౕ", "ిౕ", "ెౕ", "ొౕ"}, to = {"ఔ", "ఓ", "ీ", "ే", "ో"} }, } m["Teng"] = { "Tengwar", 473725, } m["Tfng"] = process_ranges{ "Tifinagh", 208503, "abjad, alphabet", ranges = { 0x2D30, 0x2D67, 0x2D6F, 0x2D70, 0x2D7F, 0x2D7F, }, otherNames = {"Libyco-Berber", "Berber"}, -- per Wikipedia, Libyco-Berber is the parent } m["Tglg"] = process_ranges{ "Baybayin", 812124, "abugida", aliases = {"Tagalog"}, varieties = {"Kur-itan"}, ranges = { 0x1700, 0x1715, 0x171F, 0x171F, 0x1735, 0x1736, }, } m["Thaa"] = process_ranges{ "Thaana", 877906, "abugida", ranges = { 0x060C, 0x060C, 0x061B, 0x061C, 0x061F, 0x061F, 0x0660, 0x0669, 0x0780, 0x07B1, 0xFDF2, 0xFDF2, 0xFDFD, 0xFDFD, }, direction = "rtl", } m["Thai"] = process_ranges{ "Thai", 236376, "abugida", ranges = { 0x0E01, 0x0E3A, 0x0E40, 0x0E5B, }, spaces = false, } m["Tibt"] = process_ranges{ "Tibetan", 46861, "abugida", ranges = { 0x0F00, 0x0F47, 0x0F49, 0x0F6C, 0x0F71, 0x0F97, 0x0F99, 0x0FBC, 0x0FBE, 0x0FCC, 0x0FCE, 0x0FD4, 0x0FD9, 0x0FDA, 0x3008, 0x300B, }, normalizationFixes = handle_normalization_fixes{ combiningClasses = {["༹"] = 1}, from = {"ཷ", "ཹ"}, to = {"ྲཱྀ", "ླཱྀ"} }, } m["sit-tam-Tibt"] = { "Tamyig", 109875213, m["Tibt"][3], ranges = m["Tibt"].ranges, characters = m["Tibt"].characters, parent = "Tibt", normalizationFixes = m["Tibt"].normalizationFixes, } m["Tirh"] = process_ranges{ "Tirhuta", 1765752, "abugida", ranges = { 0x0951, 0x0952, 0x0964, 0x0965, 0x1CF2, 0x1CF2, 0xA830, 0xA839, 0x11480, 0x114C7, 0x114D0, 0x114D9, }, normalizationFixes = handle_normalization_fixes{ from = {"𑒁𑒰", "𑒋𑒺", "𑒍𑒺", "𑒪𑒵", "𑒪𑒶"}, to = {"𑒂", "𑒌", "𑒎", "𑒉", "𑒊"} }, } m["Tnsa"] = process_ranges{ "Tangsa", 105576311, "alphabet", ranges = { 0x16A70, 0x16ABE, 0x16AC0, 0x16AC9, }, } m["Todr"] = process_ranges{ "Todhri", 10274731, "alphabet", direction = "rtl", ranges = { 0x105C0, 0x105F3, }, } m["Tols"] = { "Tolong Siki", 4459822, "alphabet", -- Not in Unicode } m["Toto"] = process_ranges{ "Toto", 104837516, "abugida", ranges = { 0x1E290, 0x1E2AE, }, } m["Tutg"] = process_ranges{ "Tigalari", 2604990, "abugida", aliases = {"Tulu"}, ranges = { 0x1CF2, 0x1CF2, 0x1CF4, 0x1CF4, 0xA8F1, 0xA8F1, 0x11380, 0x11389, 0x1138B, 0x1138B, 0x1138E, 0x1138E, 0x11390, 0x113B5, 0x113B7, 0x113C0, 0x113C2, 0x113C2, 0x113C5, 0x113C5, 0x113C7, 0x113CA, 0x113CC, 0x113D5, 0x113D7, 0x113D8, 0x113E1, 0x113E2, }, } m["Ugar"] = process_ranges{ "Ugaritic", 332652, "abjad", ranges = { 0x10380, 0x1039D, 0x1039F, 0x1039F, }, } m["Vaii"] = process_ranges{ "Vai", 523078, "syllabary", ranges = { 0xA500, 0xA62B, }, } m["Visp"] = { "Visible Speech", 1303365, "alphabet", -- Not in Unicode } m["Vith"] = process_ranges{ "Vithkuqi", 3301993, "alphabet", ranges = { 0x10570, 0x1057A, 0x1057C, 0x1058A, 0x1058C, 0x10592, 0x10594, 0x10595, 0x10597, 0x105A1, 0x105A3, 0x105B1, 0x105B3, 0x105B9, 0x105BB, 0x105BC, }, capitalized = true, } m["Wara"] = process_ranges{ "Varang Kshiti", 79199, aliases = {"Warang Citi"}, ranges = { 0x118A0, 0x118F2, 0x118FF, 0x118FF, }, capitalized = true, } m["Wcho"] = process_ranges{ "Wancho", 33713728, "alphabet", ranges = { 0x1E2C0, 0x1E2F9, 0x1E2FF, 0x1E2FF, }, } m["Wole"] = { "Woleai", 6643710, "syllabary", -- Not in Unicode } m["Xpeo"] = process_ranges{ "Old Persian", 1471822, ranges = { 0x103A0, 0x103C3, 0x103C8, 0x103D5, }, } m["Xsux"] = process_ranges{ "Cuneiform", 401, aliases = {"Sumero-Akkadian Cuneiform"}, ranges = { 0x12000, 0x12399, 0x12400, 0x1246E, 0x12470, 0x12474, 0x12480, 0x12543, }, } m["Yezi"] = process_ranges{ "Yezidi", 13175481, "alphabet", ranges = { 0x060C, 0x060C, 0x061B, 0x061B, 0x061F, 0x061F, 0x0660, 0x0669, 0x10E80, 0x10EA9, 0x10EAB, 0x10EAD, 0x10EB0, 0x10EB1, }, direction = "rtl", } m["Yiii"] = process_ranges{ "Yi", 1197646, "syllabary", ranges = { 0x3001, 0x3002, 0x3008, 0x3011, 0x3014, 0x301B, 0x30FB, 0x30FB, 0xA000, 0xA48C, 0xA490, 0xA4C6, 0xFF61, 0xFF65, }, } m["Zanb"] = process_ranges{ "Zanabazar Square", 50809208, "abugida", ranges = { 0x11A00, 0x11A47, }, } m["Zmth"] = process_ranges{ "mathematical notation", 1140046, ranges = { 0x00AC, 0x00AC, 0x00B1, 0x00B1, 0x00D7, 0x00D7, 0x00F7, 0x00F7, 0x03D0, 0x03D2, 0x03D5, 0x03D5, 0x03F0, 0x03F1, 0x03F4, 0x03F6, 0x0606, 0x0608, 0x2016, 0x2016, 0x2032, 0x2034, 0x2040, 0x2040, 0x2044, 0x2044, 0x2052, 0x2052, 0x205F, 0x205F, 0x2061, 0x2064, 0x207A, 0x207E, 0x208A, 0x208E, 0x20D0, 0x20DC, 0x20E1, 0x20E1, 0x20E5, 0x20E6, 0x20EB, 0x20EF, 0x2102, 0x2102, 0x2107, 0x2107, 0x210A, 0x2113, 0x2115, 0x2115, 0x2118, 0x211D, 0x2124, 0x2124, 0x2128, 0x2129, 0x212C, 0x212D, 0x212F, 0x2131, 0x2133, 0x2138, 0x213C, 0x2149, 0x214B, 0x214B, 0x2190, 0x21A7, 0x21A9, 0x21AE, 0x21B0, 0x21B1, 0x21B6, 0x21B7, 0x21BC, 0x21DB, 0x21DD, 0x21DD, 0x21E4, 0x21E5, 0x21F4, 0x22FF, 0x2308, 0x230B, 0x2320, 0x2321, 0x237C, 0x237C, 0x239B, 0x23B5, 0x23B7, 0x23B7, 0x23D0, 0x23D0, 0x23DC, 0x23E2, 0x25A0, 0x25A1, 0x25AE, 0x25B7, 0x25BC, 0x25C1, 0x25C6, 0x25C7, 0x25CA, 0x25CB, 0x25CF, 0x25D3, 0x25E2, 0x25E2, 0x25E4, 0x25E4, 0x25E7, 0x25EC, 0x25F8, 0x25FF, 0x2605, 0x2606, 0x2640, 0x2640, 0x2642, 0x2642, 0x2660, 0x2663, 0x266D, 0x266F, 0x27C0, 0x27FF, 0x2900, 0x2AFF, 0x2B30, 0x2B44, 0x2B47, 0x2B4C, 0xFB29, 0xFB29, 0xFE61, 0xFE66, 0xFE68, 0xFE68, 0xFF0B, 0xFF0B, 0xFF1C, 0xFF1E, 0xFF3C, 0xFF3C, 0xFF3E, 0xFF3E, 0xFF5C, 0xFF5C, 0xFF5E, 0xFF5E, 0xFFE2, 0xFFE2, 0xFFE9, 0xFFEC, 0x1D400, 0x1D454, 0x1D456, 0x1D49C, 0x1D49E, 0x1D49F, 0x1D4A2, 0x1D4A2, 0x1D4A5, 0x1D4A6, 0x1D4A9, 0x1D4AC, 0x1D4AE, 0x1D4B9, 0x1D4BB, 0x1D4BB, 0x1D4BD, 0x1D4C3, 0x1D4C5, 0x1D505, 0x1D507, 0x1D50A, 0x1D50D, 0x1D514, 0x1D516, 0x1D51C, 0x1D51E, 0x1D539, 0x1D53B, 0x1D53E, 0x1D540, 0x1D544, 0x1D546, 0x1D546, 0x1D54A, 0x1D550, 0x1D552, 0x1D6A5, 0x1D6A8, 0x1D7CB, 0x1D7CE, 0x1D7FF, 0x1EE00, 0x1EE03, 0x1EE05, 0x1EE1F, 0x1EE21, 0x1EE22, 0x1EE24, 0x1EE24, 0x1EE27, 0x1EE27, 0x1EE29, 0x1EE32, 0x1EE34, 0x1EE37, 0x1EE39, 0x1EE39, 0x1EE3B, 0x1EE3B, 0x1EE42, 0x1EE42, 0x1EE47, 0x1EE47, 0x1EE49, 0x1EE49, 0x1EE4B, 0x1EE4B, 0x1EE4D, 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE54, 0x1EE57, 0x1EE57, 0x1EE59, 0x1EE59, 0x1EE5B, 0x1EE5B, 0x1EE5D, 0x1EE5D, 0x1EE5F, 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE64, 0x1EE67, 0x1EE6A, 0x1EE6C, 0x1EE72, 0x1EE74, 0x1EE77, 0x1EE79, 0x1EE7C, 0x1EE7E, 0x1EE7E, 0x1EE80, 0x1EE89, 0x1EE8B, 0x1EE9B, 0x1EEA1, 0x1EEA3, 0x1EEA5, 0x1EEA9, 0x1EEAB, 0x1EEBB, 0x1EEF0, 0x1EEF1, }, translit = false, } m["Zname"] = process_ranges{ "Znamenny musical notation", 965834, "pictography", ranges = { 0x1CF00, 0x1CF2D, 0x1CF30, 0x1CF46, 0x1CF50, 0x1CFC3, }, ietf_subtag = "Zsym", translit = false, } m["Zsym"] = process_ranges{ "symbolic", 80071, "pictography", ranges = { 0x20DD, 0x20E0, 0x20E2, 0x20E4, 0x20E7, 0x20EA, 0x20F0, 0x20F0, 0x2100, 0x2101, 0x2103, 0x2106, 0x2108, 0x2109, 0x2114, 0x2114, 0x2116, 0x2117, 0x211E, 0x2123, 0x2125, 0x2127, 0x212A, 0x212B, 0x212E, 0x212E, 0x2132, 0x2132, 0x2139, 0x213B, 0x214A, 0x214A, 0x214C, 0x214F, 0x21A8, 0x21A8, 0x21AF, 0x21AF, 0x21B2, 0x21B5, 0x21B8, 0x21BB, 0x21DC, 0x21DC, 0x21DE, 0x21E3, 0x21E6, 0x21F3, 0x2300, 0x2307, 0x230C, 0x231F, 0x2322, 0x237B, 0x237D, 0x239A, 0x23B6, 0x23B6, 0x23B8, 0x23CF, 0x23D1, 0x23DB, 0x23E3, 0x23FF, 0x2500, 0x259F, 0x25A2, 0x25AD, 0x25B8, 0x25BB, 0x25C2, 0x25C5, 0x25C8, 0x25C9, 0x25CC, 0x25CE, 0x25D4, 0x25E1, 0x25E3, 0x25E3, 0x25E5, 0x25E6, 0x25ED, 0x25F7, 0x2600, 0x2604, 0x2607, 0x263F, 0x2641, 0x2641, 0x2643, 0x265F, 0x2664, 0x266C, 0x2670, 0x27BF, 0x2B00, 0x2B2F, 0x2B45, 0x2B46, 0x2B4D, 0x2B73, 0x2B76, 0x2B95, 0x2B97, 0x2BFF, 0x4DC0, 0x4DFF, 0x1F000, 0x1F02B, 0x1F030, 0x1F093, 0x1F0A0, 0x1F0AE, 0x1F0B1, 0x1F0BF, 0x1F0C1, 0x1F0CF, 0x1F0D1, 0x1F0F5, 0x1F300, 0x1F6D7, 0x1F6DC, 0x1F6EC, 0x1F6F0, 0x1F6FC, 0x1F700, 0x1F776, 0x1F77B, 0x1F7D9, 0x1F7E0, 0x1F7EB, 0x1F7F0, 0x1F7F0, 0x1F800, 0x1F80B, 0x1F810, 0x1F847, 0x1F850, 0x1F859, 0x1F860, 0x1F887, 0x1F890, 0x1F8AD, 0x1F8B0, 0x1F8B1, 0x1F900, 0x1FA53, 0x1FA60, 0x1FA6D, 0x1FA70, 0x1FA7C, 0x1FA80, 0x1FA88, 0x1FA90, 0x1FABD, 0x1FABF, 0x1FAC5, 0x1FACE, 0x1FADB, 0x1FAE0, 0x1FAE8, 0x1FAF0, 0x1FAF8, 0x1FB00, 0x1FB92, 0x1FB94, 0x1FBCA, 0x1FBF0, 0x1FBF9, }, translit = false, character_category = false, -- none } m["Zyyy"] = { "undetermined", 104839687, -- This should not have any characters listed, probably translit = false, character_category = false, -- none } m["Zzzz"] = { "uncoded", 104839675, -- This should not have any characters listed translit = false, character_category = false, -- none } -- These should be defined after the scripts they are composed of. m["Hrkt"] = process_ranges{ "Kana", 187659, "syllabary", aliases = {"Japanese syllabaries"}, ranges = union( m["Hira"].ranges, m["Kana"].ranges ), spaces = false, } m["Jpan"] = process_ranges{ "Japanese", 190502, "logography, syllabary", ranges = union( m["Hrkt"].ranges, m["Hani"].ranges, m["Latn"].ranges ), spaces = false, sort_by_scraping = true, } m["Kore"] = process_ranges{ "Korean", 711797, "logography, syllabary", ranges = union( m["Hang"].ranges, m["Hani"].ranges, m["Latn"].ranges ), } return require("Module:languages").finalizeData(m, "script") 4clll4yp3tq8cpp8igask4it8as3jlt Modul:languages/data/patterns 828 3706 26561 8043 2023-08-01T13:14:54Z id>Bennylin 0 dari en.wikt 26561 Scribunto text/plain -- Capture patterns used by [[Module:languages]] to prevent formatting from being disrupted while text is being processed. -- Certain character sequences are substituted beforehand to make pattern matching more straightforward: -- "\1" = "[[" -- "\2" = "]]" return { "((</?link>))\0", -- Special link formatting added by [[Module:links]] "((<[^<>\1\2]+>))", -- HTML tag "((\1[Ff][Ii][Ll][Ee]:[^\1\2]+\2))\0", -- File "((\1[Ii][Mm][Aa][Gg][Ee]:[^\1\2]+\2))\0", -- Image "((\1[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]:[^\1\2]+\2))\0", -- Category "((\1[Cc][Aa][Tt]:[^\1\2]+\2))\0", -- Category "((\1)[^\1\2|]+(\2))\0", -- Bare internal link "((\1)[^\1\2|]-(|)[^\1\2]-(\2))\0", -- Piped internal link "((%[https?://[^[%] ]+)[^[%]]*(%]))\0", -- External link "((\127'\"`UNIQ%-%-%l+%-%x+%-+QINU`\"'\127))", -- Strip marker "('*(''').-'*('''))", -- Bold "('*('').-'*(''))" -- Italics } 0asj561c1s2otij1k07cuhwmbvhewr9 26562 26561 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:languages/data/patterns]] 26561 Scribunto text/plain -- Capture patterns used by [[Module:languages]] to prevent formatting from being disrupted while text is being processed. -- Certain character sequences are substituted beforehand to make pattern matching more straightforward: -- "\1" = "[[" -- "\2" = "]]" return { "((</?link>))\0", -- Special link formatting added by [[Module:links]] "((<[^<>\1\2]+>))", -- HTML tag "((\1[Ff][Ii][Ll][Ee]:[^\1\2]+\2))\0", -- File "((\1[Ii][Mm][Aa][Gg][Ee]:[^\1\2]+\2))\0", -- Image "((\1[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]:[^\1\2]+\2))\0", -- Category "((\1[Cc][Aa][Tt]:[^\1\2]+\2))\0", -- Category "((\1)[^\1\2|]+(\2))\0", -- Bare internal link "((\1)[^\1\2|]-(|)[^\1\2]-(\2))\0", -- Piped internal link "((%[https?://[^[%] ]+)[^[%]]*(%]))\0", -- External link "((\127'\"`UNIQ%-%-%l+%-%x+%-+QINU`\"'\127))", -- Strip marker "('*(''').-'*('''))", -- Bold "('*('').-'*(''))" -- Italics } 0asj561c1s2otij1k07cuhwmbvhewr9 Modul:string utilities 828 3708 26555 10373 2025-11-12T12:24:58Z id>Bennylin 0 26555 Scribunto text/plain local export = {} local function_module = "Module:fun" local load_module = "Module:load" local memoize_module = "Module:memoize" local string_char_module = "Module:string/char" local string_charset_escape_module = "Module:string/charsetEscape" local mw = mw local string = string local table = table local ustring = mw.ustring local byte = string.byte local char = string.char local concat = table.concat local find = string.find local format = string.format local gmatch = string.gmatch local gsub = string.gsub local insert = table.insert local len = string.len local lower = string.lower local match = string.match local next = next local require = require local reverse = string.reverse local select = select local sort = table.sort local sub = string.sub local tonumber = tonumber local tostring = tostring local type = type local ucodepoint = ustring.codepoint local ufind = ustring.find local ugcodepoint = ustring.gcodepoint local ugmatch = ustring.gmatch local ugsub = ustring.gsub local ulower = ustring.lower local umatch = ustring.match local unpack = unpack or table.unpack -- Lua 5.2 compatibility local upper = string.upper local usub = ustring.sub local uupper = ustring.upper local memoize = require(memoize_module) -- Defined below. local codepoint local explode_utf8 local format_fun local get_charset local gsplit local pattern_escape local pattern_simplifier local replacement_escape local title_case local trim local ucfirst local ulen --[==[ 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 charset_escape(...) charset_escape = require(string_charset_escape_module) return charset_escape(...) end local function is_callable(...) is_callable = require(function_module).is_callable return is_callable(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function u(...) u = require(string_char_module) return u(...) end local function prepare_iter(str, pattern, str_lib, plain) local callable = is_callable(pattern) if str_lib or plain then return pattern, #str, string, callable elseif not callable then local simple = pattern_simplifier(pattern) if simple then return simple, #str, string, false end end return pattern, ulen(str), ustring, callable end --[==[ Returns {nil} if the input value is the empty string, or otherwise the same value. If the input is a string and `do_trim` is set, the input value will be trimmed before returning; if the trimmed value is the empty string, returns {nil}. If `quote_delimiters` is set, then any outer pair of quotation marks ({' '} or {" "}) surrounding the rest of the input string will be stripped, if present. The string will not be trimmed again, converted to {nil}, or have further quotation marks stripped, as it exists as a way to embed spaces or the empty string in an input. Genuine quotation marks may also be embedded this way (e.g. {"''foo''"} returns {"'foo'"}). ]==] function export.is_not_empty(str, do_trim, quote_delimiters) if str == "" then return nil elseif not (str and type(str) == "string") then return str elseif do_trim then str = trim(str) if str == "" then return nil end end return quote_delimiters and gsub(str, "^(['\"])(.*)%1$", "%2") or str end --[==[ Explodes a string into an array of UTF-8 characters. '''Warning''': this function assumes that the input is valid UTF-8 in order to optimize speed and memory use. Passing in an input containing non-UTF-8 byte sequences could result in unexpected behaviour. ]==] function export.explode_utf8(str) local text, i = {}, 0 for ch in gmatch(str, ".[\128-\191]*") do i = i + 1 text[i] = ch end return text end explode_utf8 = export.explode_utf8 --[==[ Returns {true} if `str` is a valid UTF-8 string. This is true if, for each character, all of the following are true: * It has the expected number of bytes, which is determined by value of the leading byte: 1-byte characters are `0x00` to `0x7F`, 2-byte characters start with `0xC2` to `0xDF`, 3-byte characters start with `0xE0` to `0xEF`, and 4-byte characters start with `0xF0` to `0xF4`. * The leading byte must not fall outside of the above ranges. * The trailing byte(s) (if any), must be between `0x80` to `0xBF`. * The character's codepoint must be between U+0000 (`0x00`) and U+10FFFF (`0xF4 0x8F 0xBF 0xBF`). * The character cannot have an overlong encoding: for each byte length, the lowest theoretical encoding is equivalent to U+0000 (e.g. `0xE0 0x80 0x80`, the lowest theoretical 3-byte encoding, is exactly equivalent to U+0000). Encodings that use more than the minimum number of bytes are not considered valid, meaning that the first valid 3-byte character is `0xE0 0xA0 0x80` (U+0800), and the first valid 4-byte character is `0xF0 0x90 0x80 0x80` (U+10000). Formally, 2-byte characters have leading bytes ranging from `0xC0` to `0xDF` (rather than `0xC2` to `0xDF`), but `0xC0 0x80` to `0xC1 0xBF` are overlong encodings, so it is simpler to say that the 2-byte range begins at `0xC2`. If `allow_surrogates` is set, surrogates (U+D800 to U+DFFF) will be treated as valid UTF-8. Surrogates are used in UTF-16, which encodes codepoints U+0000 to U+FFFF with 2 bytes, and codepoints from U+10000 upwards using a pair of surrogates, which are taken together as a 4-byte unit. Since surrogates have no use in UTF-8, as it encodes higher codepoints in a different way, they are not considered valid in UTF-8 text. However, there are limited circumstances where they may be necessary: for instance, JSON escapes characters using the format `\u0000`, which must contain exactly 4 hexadecimal digits; under the scheme, codepoints above U+FFFF must be escaped as the equivalent pair of surrogates, even though the text itself must be encoded in UTF-8 (e.g. U+10000 becomes `\uD800\uDC00`). ]==] function export.isutf8(str, allow_surrogates) for ch in gmatch(str, "[\128-\255][\128-\191]*") do if #ch > 4 then return false end local b1, b2, b3, b4 = byte(ch, 1, 4) if not (b2 and b2 >= 0x80 and b2 <= 0xBF) then return false -- 1-byte is always invalid, as gmatch excludes 0x00 to 0x7F elseif not b3 then -- 2-byte if not (b1 >= 0xC2 and b1 <= 0xDF) then -- b1 == 0xC0 or b1 == 0xC1 is overlong return false end elseif not (b3 >= 0x80 and b3 <= 0xBF) then -- trailing byte return false elseif not b4 then -- 3-byte if b1 > 0xEF then return false elseif b2 < 0xA0 then if b1 < 0xE1 then -- b1 == 0xE0 and b2 < 0xA0 is overlong return false end elseif b1 < 0xE0 or (b1 == 0xED and not allow_surrogates) then -- b1 == 0xED and b2 >= 0xA0 is a surrogate return false end elseif not (b4 >= 0x80 and b4 <= 0xBF) then -- 4-byte return false elseif b2 < 0x90 then if not (b1 >= 0xF1 and b1 <= 0xF4) then -- b1 == 0xF0 and b2 < 0x90 is overlong return false end elseif not (b1 >= 0xF0 and b1 <= 0xF3) then -- b1 == 0xF4 and b2 >= 0x90 is too high return false end end return true end do local charset_chars = { ["\0"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^" } charset_chars.__index = charset_chars local chars = setmetatable({ ["$"] = "%$", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+", ["."] = "%.", ["?"] = "%?", ["["] = "%[" }, charset_chars) --[==[ Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]] (Lua's version of regular expressions): {$%()*+-.?[]^}, and converts the null character to {%z}. For example, {"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving arbitrary text (e.g. from user input). ]==] function export.pattern_escape(str) return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars)) end pattern_escape = export.pattern_escape --[==[ Escapes only {%}, which is the only magic character used in replacement [[mw:Extension:Scribunto/Lua reference manual#Patterns|patterns]] with string.gsub and mw.ustring.gsub. ]==] function export.replacement_escape(str) return (gsub(str, "%%", "%%%%")) end replacement_escape = export.replacement_escape local function case_insensitive_char(ch) local upper_ch = uupper(ch) if upper_ch == ch then ch = ulower(ch) if ch == upper_ch then return chars[ch] or ch end end return "[" .. (charset_chars[upper_ch] or upper_ch) .. (charset_chars[ch] or ch) .. "]" end local function iterate(str, str_len, text, n, start, _gsub, _sub, loc1, loc2) if not (loc1 and start <= str_len) then -- Add final chunk and return. n = n + 1 text[n] = _gsub(_sub(str, start), ".", chars) return elseif loc2 < loc1 then if _sub == sub then local b = byte(str, loc1) if b and b >= 128 then loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3) end end n = n + 1 text[n] = _gsub(_sub(str, start, loc1), ".", chars) start = loc1 + 1 if start > str_len then return end else -- Add chunk up to the current match. n = n + 1 text[n] = _gsub(_sub(str, start, loc1 - 1), ".", chars) -- Add current match. n = n + 1 text[n] = _gsub(_sub(str, loc1, loc2), ".", case_insensitive_char) start = loc2 + 1 end return n, start end --[==[ Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]], and makes all characters case-insensitive. An optional pattern or find function (see {split}) may be supplied as the second argument, the third argument (`str_lib`) forces use of the string library, while the fourth argument (`plain`) turns any pattern matching facilities off in the optional pattern supplied. ]==] function export.case_insensitive_pattern(str, pattern_or_func, str_lib, plain) if pattern_or_func == nil then return (gsub(str, str_lib and "[^\128-\255]" or ".[\128-\191]*", case_insensitive_char)) end local text, n, start, str_len, _string, callable = {}, 0, 1 pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain) local _find, _gsub, _sub = _string.find, _string.gsub, _string.sub if callable then repeat n, start = iterate(str, str_len, text, n, start, _gsub, _sub, pattern_or_func(str, start)) until not start -- Special case if the pattern is anchored to the start: "^" always -- anchors to the start position, not the start of the string, so get -- around this by only attempting one match with the pattern, then match -- the end of the string. elseif byte(pattern_or_func) == 0x5E then -- ^ n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain)) if start ~= nil then iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, "$", start, plain)) end else repeat n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain)) until not start end return concat(text) end end do local character_classes local function get_character_classes() character_classes, get_character_classes = { [0x41] = true, [0x61] = true, -- Aa [0x43] = true, [0x63] = true, -- Cc [0x44] = true, [0x64] = true, -- Dd [0x4C] = true, [0x6C] = true, -- Ll [0x50] = true, [0x70] = true, -- Pp [0x53] = true, [0x73] = true, -- Ss [0x55] = true, [0x75] = true, -- Uu [0x57] = true, [0x77] = true, -- Ww [0x58] = true, [0x78] = true, -- Xx [0x5A] = true, -- z dealt with separately. }, nil return character_classes end local function check_sets_equal(set1, set2) local k2 for k1, v1 in next, set1 do local v2 = set2[k1] if v1 ~= v2 and (v2 == nil or not check_sets_equal(v1, v2)) then return false end k2 = next(set2, k2) end return next(set2, k2) == nil end local function check_sets(bytes) local key, set1, set = next(bytes) if set1 == true then return true elseif not check_sets(set1) then return false end while true do key, set = next(bytes, key) if not key then return true elseif not check_sets_equal(set, set1) then return false end end end local function make_charset(range) if #range == 1 then return char(range[1]) end sort(range) local compressed, n, start = {}, 0, range[1] for i = 1, #range do local this, nxt = range[i], range[i + 1] if nxt ~= this + 1 then n = n + 1 compressed[n] = this == start and char(this) or char(start) .. "-" .. char(this) start = nxt end end return "[" .. concat(compressed) .. "]" end local function parse_1_byte_charset(pattern, pos) local ch while true do pos, ch = match(pattern, "()([%%%]\192-\255])", pos) if ch == "%" then local nxt = byte(pattern, pos + 1) if not nxt or nxt >= 128 or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWXZ, but not z return false end pos = pos + 2 elseif ch == "]" then pos = pos + 1 return pos else return false end end end --[==[ Parses `pattern`, a ustring library pattern, and attempts to convert it into a string library pattern. If conversion isn't possible, returns false. ]==] function pattern_simplifier(pattern) if type(pattern) == "number" then return tostring(pattern) end local pos, capture_groups, start, n, output, ch, nxt_pos = 1, 0, 1, 0 while true do -- FIXME: use "()([%%(.[\128-\255])[\128-\191]?[\128-\191]?[\128-\191]?()" and ensure non-UTF8 always fails. pos, ch, nxt_pos = match(pattern, "()([%%(.[\192-\255])[\128-\191]*()", pos) if not ch then break end local nxt = byte(pattern, nxt_pos) if ch == "%" then if nxt == 0x62 then -- b local nxt2, nxt3 = byte(pattern, pos + 2, pos + 3) if not (nxt2 and nxt2 < 128 and nxt3 and nxt3 < 128) then return false end pos = pos + 4 elseif nxt == 0x66 then -- f nxt_pos = nxt_pos + 2 local nxt2, nxt3 = byte(pattern, nxt_pos - 1, nxt_pos) -- Only possible to convert a positive %f charset which is -- all ASCII, so use parse_1_byte_charset. if not (nxt2 == 0x5B and nxt3 and nxt3 ~= 0x5E and nxt3 < 128) then -- [^ return false elseif nxt3 == 0x5D then -- Initial ] is non-magic. nxt_pos = nxt_pos + 1 end pos = parse_1_byte_charset(pattern, nxt_pos) if not pos then return false end elseif nxt == 0x5A then -- Z nxt = byte(pattern, nxt_pos + 1) if nxt == 0x2A or nxt == 0x2D then -- *- pos = pos + 3 else if output == nil then output = {} end local ins = sub(pattern, start, pos - 1) .. "[\1-\127\192-\255]" n = n + 1 if nxt == 0x2B then -- + output[n] = ins .. "%Z*" pos = pos + 3 elseif nxt == 0x3F then -- ? output[n] = ins .. "?[\128-\191]*" pos = pos + 3 else output[n] = ins .. "[\128-\191]*" pos = pos + 2 end start = pos end elseif not nxt or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWX, but not Zz return false -- Skip the next character if it's ASCII. Otherwise, we will -- still need to do length checks. else pos = pos + (nxt < 128 and 2 or 1) end elseif ch == "(" then if nxt == 0x29 or capture_groups == 32 then -- ) return false end capture_groups = capture_groups + 1 pos = pos + 1 elseif ch == "." then if nxt == 0x2A or nxt == 0x2D then -- *- pos = pos + 2 else if output == nil then output = {} end local ins = sub(pattern, start, pos - 1) .. "[^\128-\191]" n = n + 1 if nxt == 0x2B then -- + output[n] = ins .. ".*" pos = pos + 2 elseif nxt == 0x3F then -- ? output[n] = ins .. "?[\128-\191]*" pos = pos + 2 else output[n] = ins .. "[\128-\191]*" pos = pos + 1 end start = pos end elseif ch == "[" then -- Fail negative charsets. TODO: 1-byte charsets should be safe. if nxt == 0x5E then -- ^ return false -- If the first character is "%", ch_len is determined by the -- next one instead. elseif nxt == 0x25 then -- % nxt = byte(pattern, nxt_pos + 1) elseif nxt == 0x5D then -- Initial ] is non-magic. nxt_pos = nxt_pos + 1 end if not nxt then return false end local ch_len = nxt < 128 and 1 or nxt < 224 and 2 or nxt < 240 and 3 or 4 if ch_len == 1 then -- Single-byte charset. pos = parse_1_byte_charset(pattern, nxt_pos) if not pos then return false end else -- Multibyte charset. -- TODO: 1-byte chars should be safe to mix with multibyte chars. CONFIRM THIS FIRST. local charset_pos, bytes = pos pos = pos + 1 while true do -- TODO: non-ASCII charset ranges. pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", pos) -- If escaped, get the next character. No need to -- distinguish magic characters or character classes, -- as they'll all fail for having the wrong length -- anyway. if ch == "%" then pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", nxt_pos) elseif ch == "]" then pos = nxt_pos break end if not (ch and nxt_pos - pos == ch_len) then return false elseif bytes == nil then bytes = {} end local bytes, last = bytes, nxt_pos - 1 for i = pos, last - 1 do local b = byte(pattern, i) local bytes_b = bytes[b] if bytes_b == nil then bytes_b = {} bytes[b] = bytes_b end bytes[b], bytes = bytes_b, bytes_b end bytes[byte(pattern, last)] = true pos = nxt_pos end if not pos then return false end nxt = byte(pattern, pos) if ( (nxt == 0x2A or nxt == 0x2D or nxt == 0x3F) or -- *-? (nxt == 0x2B and ch_len > 2) or -- + not check_sets(bytes) ) then return false end local ranges, b, key, next_byte = {}, 0 repeat key, next_byte = next(bytes) local range, n = {key}, 1 -- Loop starts on the second iteration. for key in next, bytes, key do n = n + 1 range[n] = key end b = b + 1 ranges[b] = range bytes = next_byte until next_byte == true if nxt == 0x2B then -- + local range1, range2 = ranges[1], ranges[2] ranges[1], ranges[3] = make_charset(range1), make_charset(range2) local n = #range2 for i = 1, #range1 do n = n + 1 range2[n] = range1[i] end ranges[2] = make_charset(range2) .. "*" pos = pos + 1 else for i = 1, #ranges do ranges[i] = make_charset(ranges[i]) end end if output == nil then output = {} end nxt = byte(pattern, pos) n = n + 1 output[n] = sub(pattern, start, charset_pos - 1) .. concat(ranges) .. ((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped start = pos end elseif not nxt then break elseif nxt == 0x2B then -- + if nxt_pos - pos ~= 2 then return false elseif output == nil then output = {} end pos, nxt_pos = pos + 1, nxt_pos + 1 nxt = byte(pattern, nxt_pos) local ch2 = sub(pattern, pos, pos) n = n + 1 output[n] = sub(pattern, start, pos - 1) .. "[" .. ch .. ch2 .. "]*" .. ch2 .. ((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped pos, start = nxt_pos, nxt_pos elseif nxt == 0x2A or nxt == 0x2D or nxt == 0x3F then -- *-? return false else pos = nxt_pos end end if start == 1 then return pattern end return concat(output) .. sub(pattern, start) end pattern_simplifier = memoize(pattern_simplifier, true) export.pattern_simplifier = pattern_simplifier end --[==[ Parses `charset`, the interior of a string or ustring library character set, and normalizes it into a string or ustring library pattern (e.g. {"abcd-g"} becomes {"[abcd-g]"}, and {"[]"} becomes {"[[%]]"}). The negative (`^`), range (`-`) and literal (`%`) magic characters work as normal, and character classes may be used (e.g. `%d` and `%w`), but opening and closing square brackets are sanitized so that they behave like ordinary characters. ]==] function get_charset(charset) if type(charset) == "number" then return tostring(charset) end local pos, start, n, output = 1, 1, 0 if byte(charset) == 0x5E then -- ^ pos = pos + 1 end -- FIXME: "]" is non-magic if it's the first character in a charset. local nxt_pos, nxt while true do local new_pos, ch = match(charset, "()([%%%-%]])", pos) if not ch then break -- Skip percent escapes. Ranges can't start with them, either. elseif ch == "%" then pos = new_pos + 2 else -- If `ch` is a hyphen, get the character before iff it's at or ahead of `pos`. if ch == "-" and new_pos > pos then pos, nxt_pos, nxt = new_pos - 1, new_pos, ch ch = sub(charset, pos, pos) else pos, nxt_pos = new_pos, new_pos + 1 nxt = sub(charset, nxt_pos, nxt_pos) end -- Range. if nxt == "-" then if output == nil then output = {} end n = n + 1 output[n] = sub(charset, start, pos - 1) nxt_pos = nxt_pos + 1 nxt = sub(charset, nxt_pos, nxt_pos) -- Ranges fail if they end with a percent escape, so escape the hyphen to avoid undefined behaviour. if nxt == "" or nxt == "%" then n = n + 1 output[n] = (ch == "]" and "%]" or ch) .. "%-" start = nxt_pos nxt_pos = nxt_pos + 2 -- Since ranges can't contain "%]", since it's escaped, range inputs like "]-z" or "a-]" must be -- adjusted to the character before or after, plus "%]" (e.g. "%]^-z" or "a-\\%]"). The escaped "%]" is -- omitted if the range would be empty (i.e. if the first byte is greater than the second). else n = n + 1 output[n] = (ch == "]" and (byte(nxt) >= 0x5D and "%]^" or "^") or ch) .. "-" .. (nxt == "]" and (byte(ch) <= 0x5D and "\\%]" or "\\") or nxt) nxt_pos = nxt_pos + 1 start = nxt_pos end elseif ch == "-" or ch == "]" then if output == nil then output = {} end n = n + 1 output[n] = sub(charset, start, pos - 1) .. "%" .. ch start = nxt_pos end pos = nxt_pos end end if start == 1 then return "[" .. charset .. "]" end return "[" .. concat(output) .. sub(charset, start) .. "]" end get_charset = memoize(get_charset, true) export.get_charset = get_charset function export.len(str) return type(str) == "number" and len(str) or #str - #gsub(str, "[^\128-\191]+", "") end ulen = export.len function export.sub(str, i, j) str, i = type(str) == "number" and tostring(str) or str, i or 1 if i < 0 or j and j < 0 then return usub(str, i, j) elseif j and i > j or i > #str then return "" end local n, new_i = 0 for loc1, loc2 in gmatch(str, "()[^\128-\191]+()[\128-\191]*") do n = n + loc2 - loc1 if not new_i and n >= i then new_i = loc2 - (n - i) - 1 if not j then return sub(str, new_i) end end if j and n > j then return sub(str, new_i, loc2 - (n - j) - 1) end end return new_i and sub(str, new_i) or "" end do local function _find(str, loc1, loc2, ...) if loc1 and not match(str, "^()[^\128-\255]*$") then -- Use raw values of loc1 and loc2 to get loc1 and the length of the match. loc1, loc2 = ulen(sub(str, 1, loc1)), ulen(sub(str, loc1, loc2)) -- Offset length with loc1 to get loc2. loc2 = loc1 + loc2 - 1 end return loc1, loc2, ... end --[==[A version of find which uses string.find when possible, but otherwise uses mw.ustring.find.]==] function export.find(str, pattern, init, plain) init = init or 1 if init ~= 1 and not match(str, "^()[^\128-\255]*$") then return ufind(str, pattern, init, plain) elseif plain then return _find(str, find(str, pattern, init, true)) end local simple = pattern_simplifier(pattern) if simple then return _find(str, find(str, simple, init)) end return ufind(str, pattern, init) end end --[==[A version of match which uses string.match when possible, but otherwise uses mw.ustring.match.]==] function export.match(str, pattern, init) init = init or 1 if init ~= 1 and not match(str, "^()[^\128-\255]*$") then return umatch(str, pattern, init) end local simple = pattern_simplifier(pattern) if simple then return match(str, simple, init) end return umatch(str, pattern, init) end --[==[A version of gmatch which uses string.gmatch when possible, but otherwise uses mw.ustring.gmatch.]==] function export.gmatch(str, pattern) local simple = pattern_simplifier(pattern) if simple then return gmatch(str, simple) end return ugmatch(str, pattern) end --[==[A version of gsub which uses string.gsub when possible, but otherwise uses mw.ustring.gsub.]==] function export.gsub(str, pattern, repl, n) local simple = pattern_simplifier(pattern) if simple then return gsub(str, simple, repl, n) end return ugsub(str, pattern, repl, n) end --[==[ Like gsub, but pattern-matching facilities are turned off, so `pattern` and `repl` (if a string) are treated as literal. ]==] function export.plain_gsub(str, pattern, repl, n) return gsub(str, pattern_escape(pattern), type(repl) == "string" and replacement_escape(repl) or repl, n) end --[==[ Reverses a UTF-8 string; equivalent to string.reverse. ]==] function export.reverse(str) return reverse((gsub(str, "[\192-\255][\128-\191]*", reverse))) end function export.char(...) -- To be moved to [[Module:string/char]]. return u(...) end do local function utf8_err(func_name) error(format("bad argument #1 to '%s' (string is not UTF-8)", func_name), 4) end local function get_codepoint(func_name, b1, b2, b3, b4) if b1 <= 0x7F then return b1, 1 elseif not (b2 and b2 >= 0x80 and b2 <= 0xBF) then utf8_err(func_name) elseif b1 <= 0xDF then local cp = 0x40 * b1 + b2 - 0x3080 return cp >= 0x80 and cp or utf8_err(func_name), 2 elseif not (b3 and b3 >= 0x80 and b3 <= 0xBF) then utf8_err(func_name) elseif b1 <= 0xEF then local cp = 0x1000 * b1 + 0x40 * b2 + b3 - 0xE2080 return cp >= 0x800 and cp or utf8_err(func_name), 3 elseif not (b4 and b4 >= 0x80 and b4 <= 0xBF) then utf8_err(func_name) end local cp = 0x40000 * b1 + 0x1000 * b2 + 0x40 * b3 + b4 - 0x3C82080 return cp >= 0x10000 and cp <= 0x10FFFF and cp or utf8_err(func_name), 4 end function export.codepoint(str, i, j) if str == "" then return -- return nothing elseif type(str) == "number" then return byte(str, i, j) end i, j = i or 1, j == -1 and #str or i or 1 if i == 1 and j == 1 then return (get_codepoint("codepoint", byte(str, 1, 4))) elseif i < 0 or j < 0 then return ucodepoint(str, i, j) -- FIXME end local n, nb, ret, nr = 0, 1, {}, 0 while n < j do n = n + 1 if n < i then local b = byte(str, nb) nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4) else local b1, b2, b3, b4 = byte(str, nb, nb + 3) if not b1 then break end nr = nr + 1 local add ret[nr], add = get_codepoint("codepoint", b1, b2, b3, b4) nb = nb + add end end return unpack(ret) end codepoint = export.codepoint function export.gcodepoint(str, i, j) i, j = i or 1, j ~= -1 and j or nil if i < 0 or j and j < 0 then return ugcodepoint(str, i, j) -- FIXME end local n, nb = 1, 1 while n < i do local b = byte(str, nb) if not b then break end nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4) n = n + 1 end return function() if j and n > j then return nil end n = n + 1 local b1, b2, b3, b4 = byte(str, nb, nb + 3) if not b1 then return nil end local ret, add = get_codepoint("gcodepoint", b1, b2, b3, b4) nb = nb + add return ret end end end do local _ulower = ulower --[==[A version of lower which uses string.lower when possible, but otherwise uses mw.ustring.lower.]==] function export.lower(str) return (match(str, "^()[^\128-\255]*$") and lower or _ulower)(str) end end do local _uupper = uupper --[==[A version of upper which uses string.upper when possible, but otherwise uses mw.ustring.upper.]==] function export.upper(str) return (match(str, "^()[^\128-\255]*$") and upper or _uupper)(str) end end do local function add_captures(t, n, ...) if ... == nil then return end -- Insert any captures from the splitting pattern. local offset, capture = n - 1, ... while capture do n = n + 1 t[n] = capture capture = select(n - offset, ...) end return n end --[==[ Reimplementation of mw.text.split() that includes any capturing groups in the splitting pattern. This works like Python's re.split() function, except that it has Lua's behavior when the split pattern is empty (i.e. advancing by one character at a time; Python returns the whole remainder of the string). When possible, it will use the string library, but otherwise uses the ustring library. There are two optional parameters: `str_lib` forces use of the string library, while `plain` turns any pattern matching facilities off, treating `pattern` as literal. In addition, `pattern` may be a custom find function (or callable table), which takes the input string and start index as its two arguments, and must return the start and end index of the match, plus any optional captures, or nil if there are no further matches. By default, the start index will be calculated using the ustring library, unless `str_lib` or `plain` is set. ]==] function export.split(str, pattern_or_func, str_lib, plain) local iter, t, n = gsplit(str, pattern_or_func, str_lib, plain), {}, 0 repeat n = add_captures(t, n, iter()) until n == nil return t end export.capturing_split = export.split -- To be removed. end --[==[ Returns an iterator function, which iterates over the substrings returned by {split}. The first value returned is the string up the splitting pattern, with any capture groups being returned as additional values on that iteration. ]==] function export.gsplit(str, pattern_or_func, str_lib, plain) local start, final, str_len, _string, callable = 1 pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain) local _find, _sub = _string.find, _string.sub local function iter(loc1, loc2, ...) -- If no match, or there is but we're past the end of the string -- (which happens when the match is the empty string), then return -- the final chunk. if not loc1 then final = true return _sub(str, start) end -- Special case: If we match the empty string, then eat the -- next character; this avoids an infinite loop, and makes -- splitting by the empty string work the way mw.text.gsplit() does -- (including non-adjacent empty string matches with %f). If we -- reach the end of the string this way, set `final` to true, so we -- don't get stuck matching the empty string at the end. local chunk if loc2 < loc1 then -- If using the string library, we need to make sure we advance -- by one UTF-8 character. if _sub == sub then local b = byte(str, loc1) if b and b >= 128 then loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3) end end chunk = _sub(str, start, loc1) if loc1 >= str_len then final = true else start = loc1 + 1 end -- Eat chunk up to the current match. else chunk = _sub(str, start, loc1 - 1) start = loc2 + 1 end return chunk, ... end if callable then return function() if not final then return iter(pattern_or_func(str, start)) end end -- Special case if the pattern is anchored to the start: "^" always -- anchors to the start position, not the start of the string, so get -- around this by only attempting one match with the pattern, then match -- the end of the string. elseif byte(pattern_or_func) == 0x5E then -- ^ local returned return function() if not returned then returned = true return iter(_find(str, pattern_or_func, start, plain)) elseif not final then return iter(_find(str, "$", start, plain)) end end end return function() if not final then return iter(_find(str, pattern_or_func, start, plain)) end end end gsplit = export.gsplit function export.count(str, pattern, plain) if plain then return select(2, gsub(str, pattern_escape(pattern), "")) end local simple = pattern_simplifier(pattern) if simple then return select(2, gsub(str, pattern, "")) end return select(2, ugsub(str, pattern, "")) end function export.trim(str, charset, str_lib, plain) if charset == nil then -- "^.*%S" is the fastest trim algorithm except when strings only consist of characters to be trimmed, which are -- very slow due to catastrophic backtracking. gsub with "^%s*" gets around this by trimming such strings to "" -- first. return match(gsub(str, "^%s*", ""), "^.*%S") or "" elseif charset == "" then return str end charset = plain and ("[" .. charset_escape(charset) .. "]") or get_charset(charset) -- The pattern uses a non-greedy quantifier instead of the algorithm used for %s, because negative character sets -- are non-trivial to compute (e.g. "[^^-z]" becomes "[%^_-z]"). Plus, if the ustring library has to be used, there -- would be two callbacks into PHP, which is slower. local pattern = "^" .. charset .. "*(.-)" .. charset .. "*$" if not str_lib then local simple = pattern_simplifier(pattern) if not simple then return umatch(str, pattern) end pattern = simple end return match(str, pattern) end trim = export.trim do local entities local function get_entities() entities, get_entities = load_data("Module:data/entities"), nil return entities end local function decode_entity(hash, x, code) if hash == "" then return (entities or get_entities())[x .. code] end local cp if x == "" then cp = match(code, "^()%d+$") and tonumber(code) else cp = match(code, "^()%x+$") and tonumber(code, 16) end return cp and (cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF) and u(cp) or nil end -- Non-ASCII characters aren't valid in proper HTML named entities, but MediaWiki uses them in some custom aliases -- which have also been included in [[Module:data/entities]]. function export.decode_entities(str) local amp = find(str, "&", nil, true) return amp and find(str, ";", amp, true) and gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str end end do local entities local function get_entities() -- Memoized HTML entities (taken from mw.text.lua). entities, get_entities = { ["\""] = "&quot;", ["&"] = "&amp;", ["'"] = "&#039;", ["<"] = "&lt;", [">"] = "&gt;", ["\194\160"] = "&nbsp;", }, nil return entities end local function encode_entity(ch) local entity = (entities or get_entities())[ch] if entity == nil then local cp = codepoint(ch) -- U+D800 to U+DFFF are surrogates, so can't be encoded as entities. entity = cp and (cp <= 0xD7FF or cp >= 0xE000) and format("&#%d;", cp) or false entities[ch] = entity end return entity or nil end function export.encode_entities(str, charset, str_lib, plain) if charset == nil then return (gsub(str, "[\"&'<>\194]\160?", entities or get_entities())) elseif charset == "" then return str end local pattern = plain and ("[" .. charset_escape(charset) .. "]") or charset == "." and charset or get_charset(charset) if not str_lib then local simple = pattern_simplifier(pattern) if not simple then return (ugsub(str, pattern, encode_entity)) end pattern = simple end return (gsub(str, pattern, encode_entity)) end end do local function decode_path(code) return char(tonumber(code, 16)) end local function decode(lead, trail) if lead == "+" or lead == "_" then return " " .. trail elseif #trail == 2 then return decode_path(trail) end return lead .. trail end function export.decode_uri(str, enctype) enctype = enctype and upper(enctype) or "QUERY" if enctype == "PATH" then return find(str, "%", nil, true) and gsub(str, "%%(%x%x)", decode_path) or str elseif enctype == "QUERY" then return (find(str, "%", nil, true) or find(str, "+", nil, true)) and gsub(str, "([%%%+])(%x?%x?)", decode) or str elseif enctype == "WIKI" then return (find(str, "%", nil, true) or find(str, "_", nil, true)) and gsub(str, "([%%_])(%x?%x?)", decode) or str end error("bad argument #2 to 'decode_uri' (expected QUERY, PATH, or WIKI)", 2) end end do local function _remove_comments(str, pre) local head = find(str, "<!--", nil, true) if not head then return str end local ret, n = {sub(str, 1, head - 1)}, 1 while true do local loc = find(str, "-->", head + 4, true) if not loc then return pre and concat(ret) or concat(ret) .. sub(str, head) end head = loc + 3 loc = find(str, "<!--", head, true) if not loc then return concat(ret) .. sub(str, head) end n = n + 1 ret[n] = sub(str, head, loc - 1) head = loc end end --[==[ Removes any HTML comments from the input text. `stage` can be one of three options: * {"PRE"} (default) applies the method used by MediaWiki's preprocessor: all {{code|html|<nowiki><!-- ... --></nowiki>}} pairs are removed, as well as any text after an unclosed {{code|html|<nowiki><!--</nowiki>}}. This is generally suitable when parsing raw template or [[mw:Parser extension tags|parser extension tag]] code. (Note, however, that the actual method used by the preprocessor is considerably more complex and differs under certain conditions (e.g. comments inside nowiki tags); if full accuracy is absolutely necessary, use [[Module:template parser]] instead). * {"POST"} applies the method used to generate the final page output once all templates have been expanded: it loops over the text, removing any {{code|html|<nowiki><!-- ... --></nowiki>}} pairs until no more are found (e.g. {{code|html|<nowiki><!-<!-- ... -->- ... --></nowiki>}} would be fully removed), but any unclosed {{code|html|<nowiki><!--</nowiki>}} is ignored. This is suitable for handling links embedded in template inputs, where the {"PRE"} method will have already been applied by the native parser. * {"BOTH"} applies {"PRE"} then {"POST"}. ]==] function export.remove_comments(str, stage) if not stage or stage == "PRE" then return _remove_comments(str, true) end local processed = stage == "POST" and _remove_comments(str) or stage == "BOTH" and _remove_comments(str, true) or error("bad argument #2 to 'remove_comments' (expected PRE, POST, or BOTH)", 2) while processed ~= str do str = processed processed = _remove_comments(str) end return str end end do local byte_escapes local function get_byte_escapes() byte_escapes, get_byte_escapes = load_data("Module:string utilities/data").byte_escapes, nil return byte_escapes end local function escape_byte(b) return (byte_escapes or get_byte_escapes())[b] or format("\\%03d", byte(b)) end function export.escape_bytes(str) return (gsub(str, ".", escape_byte)) end end function export.format_fun(str, fun) return (gsub(str, "{(\\?)((\\?)[^{}]*)}", function(p1, name, p2) if #p1 + #p2 == 1 then return name == "op" and "{" or name == "cl" and "}" or error(mw.getCurrentFrame():getTitle() .. " format: unrecognized escape sequence '{\\" .. name .. "}'") elseif fun(name) and type(fun(name)) ~= "string" then error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" is a " .. type(fun(name)) .. ", not a string") end return fun(name) or error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" not found in table") end)) end format_fun = export.format_fun --[==[ This function, unlike {string.format} and {mw.ustring.format}, takes just two parameters, a format string and a table, and replaces all instances of { {param_name} } in the format string with the table's entry for {param_name}. The opening and closing brace characters can be escaped with { {\op} } and { {\cl} }, respectively. A table entry beginning with a slash can be escaped by doubling the initial slash. ====Examples==== * {string_utilities.format("{foo} fish, {bar} fish, {baz} fish, {quux} fish", {["foo"]="one", ["bar"]="two", ["baz"]="red", ["quux"]="blue"}) } *: produces: {"one fish, two fish, red fish, blue fish"} * {string_utilities.format("The set {\\op}1, 2, 3{\\cl} contains {\\\\hello} elements.", {["\\hello"]="three"})} *: produces: {"The set {1, 2, 3} contains three elements."} *:* Note that the single and double backslashes should be entered as double and quadruple backslashes when quoted in a literal string. ]==] function export.format(str, tbl) return format_fun(str, function(key) return tbl[key] end) end do local function do_uclcfirst(str, case_func) -- Re-case the first letter. local first, remainder = match(str, "^(.[\128-\191]*)(.*)") return first and (case_func(first) .. remainder) or "" end local function uclcfirst(str, case_func) -- Strip off any HTML tags at the beginning. This currently does not handle comments or <ref>...</ref> -- correctly; it's intended for text wrapped in <span> or the like, as happens when passing text through -- [[Module:links]]. local html_at_beginning = nil if str:match("^<") then while true do local html_tag, rest = str:match("^(<.->)(.*)$") if not html_tag then break end if not html_at_beginning then html_at_beginning = {} end insert(html_at_beginning, html_tag) str = rest end end -- If there's a link at the beginning, re-case the first letter of the -- link text. This pattern matches both piped and unpiped links. -- If the link is not piped, the second capture (linktext) will be empty. local link, linktext, remainder = match(str, "^%[%[([^|%]]+)%|?(.-)%]%](.*)$") local retval if link then retval = "[[" .. link .. "|" .. do_uclcfirst(linktext ~= "" and linktext or link, case_func) .. "]]" .. remainder else retval = do_uclcfirst(str, case_func) end if html_at_beginning then retval = concat(html_at_beginning) .. retval end return retval end --[==[ Uppercase the first character of the input string, correctly handling one-part and two-part links, optionally surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly uppercase the first character of text that may include links that have been passed through `full_link()` in [[Module:links]] or a similar function. ]==] function export.ucfirst(str) return uclcfirst(str, uupper) end ucfirst = export.ucfirst --[==[ Lowercase the first character of the input string, correctly handling one-part and two-part links, optionally surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly lowercase the first character of text that may include links that have been passed through `full_link()` in [[Module:links]] or a similar function. ]==] function export.lcfirst(str) return uclcfirst(str, ulower) end --[==[Capitalizes each word of the input string. WARNING: May be broken in the presence of multiword links.]==] function export.capitalize(str) -- Capitalize multi-word that is separated by spaces -- by uppercasing the first letter of each part. return (ugsub(str, "%w+", ucfirst)) end local function do_title_case(first, remainder) first = uupper(first) return remainder == "" and first or (first .. ulower(remainder)) end --[==[ Capitalizes each word of the input string, with any further letters in each word being converted to lowercase. ]==] function export.title_case(str) return str == "" and "" or ugsub(str, "(%w)(%w*)", do_title_case) end title_case = export.title_case --[==[ Converts the input string to {{w|Camel case|CamelCase}}. Any non-word characters are treated as breaks between words. If `lower_first` is set, then the first character of the string will be lowercase (e.g. camelCase). ]==] function export.camel_case(str, lower_first) str = ugsub(str, "%W*(%w*)", title_case) return lower_first and do_uclcfirst(str, ulower) or str end end do local function do_snake_case(nonword, word) return nonword == "" and word or "_" .. word end --[==[ Converts the input string to {{w|Snake case|snake_case}}. Any non-word characters are treated as breaks between words. ]==] function export.snake_case(str) return (ugsub(str, "(%W*)(%w*)", do_snake_case)) end end return export ndjfpg4lokleft04xzto19wigx7fczh 26556 23980 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Modul:string_utilities]] 23980 Scribunto text/plain local export = {} local function_module = "Module:fun" local load_module = "Module:load" local memoize_module = "Module:memoize" local string_char_module = "Module:string/char" local string_charset_escape_module = "Module:string/charsetEscape" local mw = mw local string = string local table = table local ustring = mw.ustring local byte = string.byte local char = string.char local concat = table.concat local find = string.find local format = string.format local gmatch = string.gmatch local gsub = string.gsub local insert = table.insert local len = string.len local lower = string.lower local match = string.match local next = next local require = require local reverse = string.reverse local select = select local sort = table.sort local sub = string.sub local tonumber = tonumber local tostring = tostring local type = type local ucodepoint = ustring.codepoint local ufind = ustring.find local ugcodepoint = ustring.gcodepoint local ugmatch = ustring.gmatch local ugsub = ustring.gsub local ulower = ustring.lower local umatch = ustring.match local unpack = unpack or table.unpack -- Lua 5.2 compatibility local upper = string.upper local usub = ustring.sub local uupper = ustring.upper local memoize = require(memoize_module) -- Defined below. local codepoint local explode_utf8 local format_fun local get_charset local gsplit local pattern_escape local pattern_simplifier local replacement_escape local title_case local trim local ucfirst local ulen --[==[ 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 charset_escape(...) charset_escape = require(string_charset_escape_module) return charset_escape(...) end local function is_callable(...) is_callable = require(function_module).is_callable return is_callable(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function u(...) u = require(string_char_module) return u(...) end local function prepare_iter(str, pattern, str_lib, plain) local callable = is_callable(pattern) if str_lib or plain then return pattern, #str, string, callable elseif not callable then local simple = pattern_simplifier(pattern) if simple then return simple, #str, string, false end end return pattern, ulen(str), ustring, callable end --[==[ Returns {nil} if the input value is the empty string, or otherwise the same value. If the input is a string and `do_trim` is set, the input value will be trimmed before returning; if the trimmed value is the empty string, returns {nil}. If `quote_delimiters` is set, then any outer pair of quotation marks ({' '} or {" "}) surrounding the rest of the input string will be stripped, if present. The string will not be trimmed again, converted to {nil}, or have further quotation marks stripped, as it exists as a way to embed spaces or the empty string in an input. Genuine quotation marks may also be embedded this way (e.g. {"''foo''"} returns {"'foo'"}). ]==] function export.is_not_empty(str, do_trim, quote_delimiters) if str == "" then return nil elseif not (str and type(str) == "string") then return str elseif do_trim then str = trim(str) if str == "" then return nil end end return quote_delimiters and gsub(str, "^(['\"])(.*)%1$", "%2") or str end --[==[ Explodes a string into an array of UTF-8 characters. '''Warning''': this function assumes that the input is valid UTF-8 in order to optimize speed and memory use. Passing in an input containing non-UTF-8 byte sequences could result in unexpected behaviour. ]==] function export.explode_utf8(str) local text, i = {}, 0 for ch in gmatch(str, ".[\128-\191]*") do i = i + 1 text[i] = ch end return text end explode_utf8 = export.explode_utf8 --[==[ Returns {true} if `str` is a valid UTF-8 string. This is true if, for each character, all of the following are true: * It has the expected number of bytes, which is determined by value of the leading byte: 1-byte characters are `0x00` to `0x7F`, 2-byte characters start with `0xC2` to `0xDF`, 3-byte characters start with `0xE0` to `0xEF`, and 4-byte characters start with `0xF0` to `0xF4`. * The leading byte must not fall outside of the above ranges. * The trailing byte(s) (if any), must be between `0x80` to `0xBF`. * The character's codepoint must be between U+0000 (`0x00`) and U+10FFFF (`0xF4 0x8F 0xBF 0xBF`). * The character cannot have an overlong encoding: for each byte length, the lowest theoretical encoding is equivalent to U+0000 (e.g. `0xE0 0x80 0x80`, the lowest theoretical 3-byte encoding, is exactly equivalent to U+0000). Encodings that use more than the minimum number of bytes are not considered valid, meaning that the first valid 3-byte character is `0xE0 0xA0 0x80` (U+0800), and the first valid 4-byte character is `0xF0 0x90 0x80 0x80` (U+10000). Formally, 2-byte characters have leading bytes ranging from `0xC0` to `0xDF` (rather than `0xC2` to `0xDF`), but `0xC0 0x80` to `0xC1 0xBF` are overlong encodings, so it is simpler to say that the 2-byte range begins at `0xC2`. If `allow_surrogates` is set, surrogates (U+D800 to U+DFFF) will be treated as valid UTF-8. Surrogates are used in UTF-16, which encodes codepoints U+0000 to U+FFFF with 2 bytes, and codepoints from U+10000 upwards using a pair of surrogates, which are taken together as a 4-byte unit. Since surrogates have no use in UTF-8, as it encodes higher codepoints in a different way, they are not considered valid in UTF-8 text. However, there are limited circumstances where they may be necessary: for instance, JSON escapes characters using the format `\u0000`, which must contain exactly 4 hexadecimal digits; under the scheme, codepoints above U+FFFF must be escaped as the equivalent pair of surrogates, even though the text itself must be encoded in UTF-8 (e.g. U+10000 becomes `\uD800\uDC00`). ]==] function export.isutf8(str, allow_surrogates) for ch in gmatch(str, "[\128-\255][\128-\191]*") do if #ch > 4 then return false end local b1, b2, b3, b4 = byte(ch, 1, 4) if not (b2 and b2 >= 0x80 and b2 <= 0xBF) then return false -- 1-byte is always invalid, as gmatch excludes 0x00 to 0x7F elseif not b3 then -- 2-byte if not (b1 >= 0xC2 and b1 <= 0xDF) then -- b1 == 0xC0 or b1 == 0xC1 is overlong return false end elseif not (b3 >= 0x80 and b3 <= 0xBF) then -- trailing byte return false elseif not b4 then -- 3-byte if b1 > 0xEF then return false elseif b2 < 0xA0 then if b1 < 0xE1 then -- b1 == 0xE0 and b2 < 0xA0 is overlong return false end elseif b1 < 0xE0 or (b1 == 0xED and not allow_surrogates) then -- b1 == 0xED and b2 >= 0xA0 is a surrogate return false end elseif not (b4 >= 0x80 and b4 <= 0xBF) then -- 4-byte return false elseif b2 < 0x90 then if not (b1 >= 0xF1 and b1 <= 0xF4) then -- b1 == 0xF0 and b2 < 0x90 is overlong return false end elseif not (b1 >= 0xF0 and b1 <= 0xF3) then -- b1 == 0xF4 and b2 >= 0x90 is too high return false end end return true end do local charset_chars = { ["\0"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^" } charset_chars.__index = charset_chars local chars = setmetatable({ ["$"] = "%$", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+", ["."] = "%.", ["?"] = "%?", ["["] = "%[" }, charset_chars) --[==[ Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]] (Lua's version of regular expressions): {$%()*+-.?[]^}, and converts the null character to {%z}. For example, {"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving arbitrary text (e.g. from user input). ]==] function export.pattern_escape(str) return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars)) end pattern_escape = export.pattern_escape --[==[ Escapes only {%}, which is the only magic character used in replacement [[mw:Extension:Scribunto/Lua reference manual#Patterns|patterns]] with string.gsub and mw.ustring.gsub. ]==] function export.replacement_escape(str) return (gsub(str, "%%", "%%%%")) end replacement_escape = export.replacement_escape local function case_insensitive_char(ch) local upper_ch = uupper(ch) if upper_ch == ch then ch = ulower(ch) if ch == upper_ch then return chars[ch] or ch end end return "[" .. (charset_chars[upper_ch] or upper_ch) .. (charset_chars[ch] or ch) .. "]" end local function iterate(str, str_len, text, n, start, _gsub, _sub, loc1, loc2) if not (loc1 and start <= str_len) then -- Add final chunk and return. n = n + 1 text[n] = _gsub(_sub(str, start), ".", chars) return elseif loc2 < loc1 then if _sub == sub then local b = byte(str, loc1) if b and b >= 128 then loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3) end end n = n + 1 text[n] = _gsub(_sub(str, start, loc1), ".", chars) start = loc1 + 1 if start > str_len then return end else -- Add chunk up to the current match. n = n + 1 text[n] = _gsub(_sub(str, start, loc1 - 1), ".", chars) -- Add current match. n = n + 1 text[n] = _gsub(_sub(str, loc1, loc2), ".", case_insensitive_char) start = loc2 + 1 end return n, start end --[==[ Escapes the magic characters used in a [[mw:Extension:Scribunto/Lua reference manual#Patterns|pattern]], and makes all characters case-insensitive. An optional pattern or find function (see {split}) may be supplied as the second argument, the third argument (`str_lib`) forces use of the string library, while the fourth argument (`plain`) turns any pattern matching facilities off in the optional pattern supplied. ]==] function export.case_insensitive_pattern(str, pattern_or_func, str_lib, plain) if pattern_or_func == nil then return (gsub(str, str_lib and "[^\128-\255]" or ".[\128-\191]*", case_insensitive_char)) end local text, n, start, str_len, _string, callable = {}, 0, 1 pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain) local _find, _gsub, _sub = _string.find, _string.gsub, _string.sub if callable then repeat n, start = iterate(str, str_len, text, n, start, _gsub, _sub, pattern_or_func(str, start)) until not start -- Special case if the pattern is anchored to the start: "^" always -- anchors to the start position, not the start of the string, so get -- around this by only attempting one match with the pattern, then match -- the end of the string. elseif byte(pattern_or_func) == 0x5E then -- ^ n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain)) if start ~= nil then iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, "$", start, plain)) end else repeat n, start = iterate(str, str_len, text, n, start, _gsub, _sub, _find(str, pattern_or_func, start, plain)) until not start end return concat(text) end end do local character_classes local function get_character_classes() character_classes, get_character_classes = { [0x41] = true, [0x61] = true, -- Aa [0x43] = true, [0x63] = true, -- Cc [0x44] = true, [0x64] = true, -- Dd [0x4C] = true, [0x6C] = true, -- Ll [0x50] = true, [0x70] = true, -- Pp [0x53] = true, [0x73] = true, -- Ss [0x55] = true, [0x75] = true, -- Uu [0x57] = true, [0x77] = true, -- Ww [0x58] = true, [0x78] = true, -- Xx [0x5A] = true, -- z dealt with separately. }, nil return character_classes end local function check_sets_equal(set1, set2) local k2 for k1, v1 in next, set1 do local v2 = set2[k1] if v1 ~= v2 and (v2 == nil or not check_sets_equal(v1, v2)) then return false end k2 = next(set2, k2) end return next(set2, k2) == nil end local function check_sets(bytes) local key, set1, set = next(bytes) if set1 == true then return true elseif not check_sets(set1) then return false end while true do key, set = next(bytes, key) if not key then return true elseif not check_sets_equal(set, set1) then return false end end end local function make_charset(range) if #range == 1 then return char(range[1]) end sort(range) local compressed, n, start = {}, 0, range[1] for i = 1, #range do local this, nxt = range[i], range[i + 1] if nxt ~= this + 1 then n = n + 1 compressed[n] = this == start and char(this) or char(start) .. "-" .. char(this) start = nxt end end return "[" .. concat(compressed) .. "]" end local function parse_1_byte_charset(pattern, pos) local ch while true do pos, ch = match(pattern, "()([%%%]\192-\255])", pos) if ch == "%" then local nxt = byte(pattern, pos + 1) if not nxt or nxt >= 128 or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWXZ, but not z return false end pos = pos + 2 elseif ch == "]" then pos = pos + 1 return pos else return false end end end --[==[ Parses `pattern`, a ustring library pattern, and attempts to convert it into a string library pattern. If conversion isn't possible, returns false. ]==] function pattern_simplifier(pattern) if type(pattern) == "number" then return tostring(pattern) end local pos, capture_groups, start, n, output, ch, nxt_pos = 1, 0, 1, 0 while true do -- FIXME: use "()([%%(.[\128-\255])[\128-\191]?[\128-\191]?[\128-\191]?()" and ensure non-UTF8 always fails. pos, ch, nxt_pos = match(pattern, "()([%%(.[\192-\255])[\128-\191]*()", pos) if not ch then break end local nxt = byte(pattern, nxt_pos) if ch == "%" then if nxt == 0x62 then -- b local nxt2, nxt3 = byte(pattern, pos + 2, pos + 3) if not (nxt2 and nxt2 < 128 and nxt3 and nxt3 < 128) then return false end pos = pos + 4 elseif nxt == 0x66 then -- f nxt_pos = nxt_pos + 2 local nxt2, nxt3 = byte(pattern, nxt_pos - 1, nxt_pos) -- Only possible to convert a positive %f charset which is -- all ASCII, so use parse_1_byte_charset. if not (nxt2 == 0x5B and nxt3 and nxt3 ~= 0x5E and nxt3 < 128) then -- [^ return false elseif nxt3 == 0x5D then -- Initial ] is non-magic. nxt_pos = nxt_pos + 1 end pos = parse_1_byte_charset(pattern, nxt_pos) if not pos then return false end elseif nxt == 0x5A then -- Z nxt = byte(pattern, nxt_pos + 1) if nxt == 0x2A or nxt == 0x2D then -- *- pos = pos + 3 else if output == nil then output = {} end local ins = sub(pattern, start, pos - 1) .. "[\1-\127\192-\255]" n = n + 1 if nxt == 0x2B then -- + output[n] = ins .. "%Z*" pos = pos + 3 elseif nxt == 0x3F then -- ? output[n] = ins .. "?[\128-\191]*" pos = pos + 3 else output[n] = ins .. "[\128-\191]*" pos = pos + 2 end start = pos end elseif not nxt or (character_classes or get_character_classes())[nxt] then -- acdlpsuwxACDLPSUWX, but not Zz return false -- Skip the next character if it's ASCII. Otherwise, we will -- still need to do length checks. else pos = pos + (nxt < 128 and 2 or 1) end elseif ch == "(" then if nxt == 0x29 or capture_groups == 32 then -- ) return false end capture_groups = capture_groups + 1 pos = pos + 1 elseif ch == "." then if nxt == 0x2A or nxt == 0x2D then -- *- pos = pos + 2 else if output == nil then output = {} end local ins = sub(pattern, start, pos - 1) .. "[^\128-\191]" n = n + 1 if nxt == 0x2B then -- + output[n] = ins .. ".*" pos = pos + 2 elseif nxt == 0x3F then -- ? output[n] = ins .. "?[\128-\191]*" pos = pos + 2 else output[n] = ins .. "[\128-\191]*" pos = pos + 1 end start = pos end elseif ch == "[" then -- Fail negative charsets. TODO: 1-byte charsets should be safe. if nxt == 0x5E then -- ^ return false -- If the first character is "%", ch_len is determined by the -- next one instead. elseif nxt == 0x25 then -- % nxt = byte(pattern, nxt_pos + 1) elseif nxt == 0x5D then -- Initial ] is non-magic. nxt_pos = nxt_pos + 1 end if not nxt then return false end local ch_len = nxt < 128 and 1 or nxt < 224 and 2 or nxt < 240 and 3 or 4 if ch_len == 1 then -- Single-byte charset. pos = parse_1_byte_charset(pattern, nxt_pos) if not pos then return false end else -- Multibyte charset. -- TODO: 1-byte chars should be safe to mix with multibyte chars. CONFIRM THIS FIRST. local charset_pos, bytes = pos pos = pos + 1 while true do -- TODO: non-ASCII charset ranges. pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", pos) -- If escaped, get the next character. No need to -- distinguish magic characters or character classes, -- as they'll all fail for having the wrong length -- anyway. if ch == "%" then pos, ch, nxt_pos = match(pattern, "^()([^\128-\191])[\128-\191]*()", nxt_pos) elseif ch == "]" then pos = nxt_pos break end if not (ch and nxt_pos - pos == ch_len) then return false elseif bytes == nil then bytes = {} end local bytes, last = bytes, nxt_pos - 1 for i = pos, last - 1 do local b = byte(pattern, i) local bytes_b = bytes[b] if bytes_b == nil then bytes_b = {} bytes[b] = bytes_b end bytes[b], bytes = bytes_b, bytes_b end bytes[byte(pattern, last)] = true pos = nxt_pos end if not pos then return false end nxt = byte(pattern, pos) if ( (nxt == 0x2A or nxt == 0x2D or nxt == 0x3F) or -- *-? (nxt == 0x2B and ch_len > 2) or -- + not check_sets(bytes) ) then return false end local ranges, b, key, next_byte = {}, 0 repeat key, next_byte = next(bytes) local range, n = {key}, 1 -- Loop starts on the second iteration. for key in next, bytes, key do n = n + 1 range[n] = key end b = b + 1 ranges[b] = range bytes = next_byte until next_byte == true if nxt == 0x2B then -- + local range1, range2 = ranges[1], ranges[2] ranges[1], ranges[3] = make_charset(range1), make_charset(range2) local n = #range2 for i = 1, #range1 do n = n + 1 range2[n] = range1[i] end ranges[2] = make_charset(range2) .. "*" pos = pos + 1 else for i = 1, #ranges do ranges[i] = make_charset(ranges[i]) end end if output == nil then output = {} end nxt = byte(pattern, pos) n = n + 1 output[n] = sub(pattern, start, charset_pos - 1) .. concat(ranges) .. ((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped start = pos end elseif not nxt then break elseif nxt == 0x2B then -- + if nxt_pos - pos ~= 2 then return false elseif output == nil then output = {} end pos, nxt_pos = pos + 1, nxt_pos + 1 nxt = byte(pattern, nxt_pos) local ch2 = sub(pattern, pos, pos) n = n + 1 output[n] = sub(pattern, start, pos - 1) .. "[" .. ch .. ch2 .. "]*" .. ch2 .. ((nxt == 0x2A or nxt == 0x2B or nxt == 0x2D or nxt == 0x3F) and "%" or "") -- following *+-? now have to be escaped pos, start = nxt_pos, nxt_pos elseif nxt == 0x2A or nxt == 0x2D or nxt == 0x3F then -- *-? return false else pos = nxt_pos end end if start == 1 then return pattern end return concat(output) .. sub(pattern, start) end pattern_simplifier = memoize(pattern_simplifier, true) export.pattern_simplifier = pattern_simplifier end --[==[ Parses `charset`, the interior of a string or ustring library character set, and normalizes it into a string or ustring library pattern (e.g. {"abcd-g"} becomes {"[abcd-g]"}, and {"[]"} becomes {"[[%]]"}). The negative (`^`), range (`-`) and literal (`%`) magic characters work as normal, and character classes may be used (e.g. `%d` and `%w`), but opening and closing square brackets are sanitized so that they behave like ordinary characters. ]==] function get_charset(charset) if type(charset) == "number" then return tostring(charset) end local pos, start, n, output = 1, 1, 0 if byte(charset) == 0x5E then -- ^ pos = pos + 1 end -- FIXME: "]" is non-magic if it's the first character in a charset. local nxt_pos, nxt while true do local new_pos, ch = match(charset, "()([%%%-%]])", pos) if not ch then break -- Skip percent escapes. Ranges can't start with them, either. elseif ch == "%" then pos = new_pos + 2 else -- If `ch` is a hyphen, get the character before iff it's at or ahead of `pos`. if ch == "-" and new_pos > pos then pos, nxt_pos, nxt = new_pos - 1, new_pos, ch ch = sub(charset, pos, pos) else pos, nxt_pos = new_pos, new_pos + 1 nxt = sub(charset, nxt_pos, nxt_pos) end -- Range. if nxt == "-" then if output == nil then output = {} end n = n + 1 output[n] = sub(charset, start, pos - 1) nxt_pos = nxt_pos + 1 nxt = sub(charset, nxt_pos, nxt_pos) -- Ranges fail if they end with a percent escape, so escape the hyphen to avoid undefined behaviour. if nxt == "" or nxt == "%" then n = n + 1 output[n] = (ch == "]" and "%]" or ch) .. "%-" start = nxt_pos nxt_pos = nxt_pos + 2 -- Since ranges can't contain "%]", since it's escaped, range inputs like "]-z" or "a-]" must be -- adjusted to the character before or after, plus "%]" (e.g. "%]^-z" or "a-\\%]"). The escaped "%]" is -- omitted if the range would be empty (i.e. if the first byte is greater than the second). else n = n + 1 output[n] = (ch == "]" and (byte(nxt) >= 0x5D and "%]^" or "^") or ch) .. "-" .. (nxt == "]" and (byte(ch) <= 0x5D and "\\%]" or "\\") or nxt) nxt_pos = nxt_pos + 1 start = nxt_pos end elseif ch == "-" or ch == "]" then if output == nil then output = {} end n = n + 1 output[n] = sub(charset, start, pos - 1) .. "%" .. ch start = nxt_pos end pos = nxt_pos end end if start == 1 then return "[" .. charset .. "]" end return "[" .. concat(output) .. sub(charset, start) .. "]" end get_charset = memoize(get_charset, true) export.get_charset = get_charset function export.len(str) return type(str) == "number" and len(str) or #str - #gsub(str, "[^\128-\191]+", "") end ulen = export.len function export.sub(str, i, j) str, i = type(str) == "number" and tostring(str) or str, i or 1 if i < 0 or j and j < 0 then return usub(str, i, j) elseif j and i > j or i > #str then return "" end local n, new_i = 0 for loc1, loc2 in gmatch(str, "()[^\128-\191]+()[\128-\191]*") do n = n + loc2 - loc1 if not new_i and n >= i then new_i = loc2 - (n - i) - 1 if not j then return sub(str, new_i) end end if j and n > j then return sub(str, new_i, loc2 - (n - j) - 1) end end return new_i and sub(str, new_i) or "" end do local function _find(str, loc1, loc2, ...) if loc1 and not match(str, "^()[^\128-\255]*$") then -- Use raw values of loc1 and loc2 to get loc1 and the length of the match. loc1, loc2 = ulen(sub(str, 1, loc1)), ulen(sub(str, loc1, loc2)) -- Offset length with loc1 to get loc2. loc2 = loc1 + loc2 - 1 end return loc1, loc2, ... end --[==[A version of find which uses string.find when possible, but otherwise uses mw.ustring.find.]==] function export.find(str, pattern, init, plain) init = init or 1 if init ~= 1 and not match(str, "^()[^\128-\255]*$") then return ufind(str, pattern, init, plain) elseif plain then return _find(str, find(str, pattern, init, true)) end local simple = pattern_simplifier(pattern) if simple then return _find(str, find(str, simple, init)) end return ufind(str, pattern, init) end end --[==[A version of match which uses string.match when possible, but otherwise uses mw.ustring.match.]==] function export.match(str, pattern, init) init = init or 1 if init ~= 1 and not match(str, "^()[^\128-\255]*$") then return umatch(str, pattern, init) end local simple = pattern_simplifier(pattern) if simple then return match(str, simple, init) end return umatch(str, pattern, init) end --[==[A version of gmatch which uses string.gmatch when possible, but otherwise uses mw.ustring.gmatch.]==] function export.gmatch(str, pattern) local simple = pattern_simplifier(pattern) if simple then return gmatch(str, simple) end return ugmatch(str, pattern) end --[==[A version of gsub which uses string.gsub when possible, but otherwise uses mw.ustring.gsub.]==] function export.gsub(str, pattern, repl, n) local simple = pattern_simplifier(pattern) if simple then return gsub(str, simple, repl, n) end return ugsub(str, pattern, repl, n) end --[==[ Like gsub, but pattern-matching facilities are turned off, so `pattern` and `repl` (if a string) are treated as literal. ]==] function export.plain_gsub(str, pattern, repl, n) return gsub(str, pattern_escape(pattern), type(repl) == "string" and replacement_escape(repl) or repl, n) end --[==[ Reverses a UTF-8 string; equivalent to string.reverse. ]==] function export.reverse(str) return reverse((gsub(str, "[\192-\255][\128-\191]*", reverse))) end function export.char(...) -- To be moved to [[Module:string/char]]. return u(...) end do local function utf8_err(func_name) error(format("bad argument #1 to '%s' (string is not UTF-8)", func_name), 4) end local function get_codepoint(func_name, b1, b2, b3, b4) if b1 <= 0x7F then return b1, 1 elseif not (b2 and b2 >= 0x80 and b2 <= 0xBF) then utf8_err(func_name) elseif b1 <= 0xDF then local cp = 0x40 * b1 + b2 - 0x3080 return cp >= 0x80 and cp or utf8_err(func_name), 2 elseif not (b3 and b3 >= 0x80 and b3 <= 0xBF) then utf8_err(func_name) elseif b1 <= 0xEF then local cp = 0x1000 * b1 + 0x40 * b2 + b3 - 0xE2080 return cp >= 0x800 and cp or utf8_err(func_name), 3 elseif not (b4 and b4 >= 0x80 and b4 <= 0xBF) then utf8_err(func_name) end local cp = 0x40000 * b1 + 0x1000 * b2 + 0x40 * b3 + b4 - 0x3C82080 return cp >= 0x10000 and cp <= 0x10FFFF and cp or utf8_err(func_name), 4 end function export.codepoint(str, i, j) if str == "" then return -- return nothing elseif type(str) == "number" then return byte(str, i, j) end i, j = i or 1, j == -1 and #str or i or 1 if i == 1 and j == 1 then return (get_codepoint("codepoint", byte(str, 1, 4))) elseif i < 0 or j < 0 then return ucodepoint(str, i, j) -- FIXME end local n, nb, ret, nr = 0, 1, {}, 0 while n < j do n = n + 1 if n < i then local b = byte(str, nb) nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4) else local b1, b2, b3, b4 = byte(str, nb, nb + 3) if not b1 then break end nr = nr + 1 local add ret[nr], add = get_codepoint("codepoint", b1, b2, b3, b4) nb = nb + add end end return unpack(ret) end codepoint = export.codepoint function export.gcodepoint(str, i, j) i, j = i or 1, j ~= -1 and j or nil if i < 0 or j and j < 0 then return ugcodepoint(str, i, j) -- FIXME end local n, nb = 1, 1 while n < i do local b = byte(str, nb) if not b then break end nb = nb + (b < 128 and 1 or b < 224 and 2 or b < 240 and 3 or 4) n = n + 1 end return function() if j and n > j then return nil end n = n + 1 local b1, b2, b3, b4 = byte(str, nb, nb + 3) if not b1 then return nil end local ret, add = get_codepoint("gcodepoint", b1, b2, b3, b4) nb = nb + add return ret end end end do local _ulower = ulower --[==[A version of lower which uses string.lower when possible, but otherwise uses mw.ustring.lower.]==] function export.lower(str) return (match(str, "^()[^\128-\255]*$") and lower or _ulower)(str) end end do local _uupper = uupper --[==[A version of upper which uses string.upper when possible, but otherwise uses mw.ustring.upper.]==] function export.upper(str) return (match(str, "^()[^\128-\255]*$") and upper or _uupper)(str) end end do local function add_captures(t, n, ...) if ... == nil then return end -- Insert any captures from the splitting pattern. local offset, capture = n - 1, ... while capture do n = n + 1 t[n] = capture capture = select(n - offset, ...) end return n end --[==[ Reimplementation of mw.text.split() that includes any capturing groups in the splitting pattern. This works like Python's re.split() function, except that it has Lua's behavior when the split pattern is empty (i.e. advancing by one character at a time; Python returns the whole remainder of the string). When possible, it will use the string library, but otherwise uses the ustring library. There are two optional parameters: `str_lib` forces use of the string library, while `plain` turns any pattern matching facilities off, treating `pattern` as literal. In addition, `pattern` may be a custom find function (or callable table), which takes the input string and start index as its two arguments, and must return the start and end index of the match, plus any optional captures, or nil if there are no further matches. By default, the start index will be calculated using the ustring library, unless `str_lib` or `plain` is set. ]==] function export.split(str, pattern_or_func, str_lib, plain) local iter, t, n = gsplit(str, pattern_or_func, str_lib, plain), {}, 0 repeat n = add_captures(t, n, iter()) until n == nil return t end export.capturing_split = export.split -- To be removed. end --[==[ Returns an iterator function, which iterates over the substrings returned by {split}. The first value returned is the string up the splitting pattern, with any capture groups being returned as additional values on that iteration. ]==] function export.gsplit(str, pattern_or_func, str_lib, plain) local start, final, str_len, _string, callable = 1 pattern_or_func, str_len, _string, callable = prepare_iter(str, pattern_or_func, str_lib, plain) local _find, _sub = _string.find, _string.sub local function iter(loc1, loc2, ...) -- If no match, or there is but we're past the end of the string -- (which happens when the match is the empty string), then return -- the final chunk. if not loc1 then final = true return _sub(str, start) end -- Special case: If we match the empty string, then eat the -- next character; this avoids an infinite loop, and makes -- splitting by the empty string work the way mw.text.gsplit() does -- (including non-adjacent empty string matches with %f). If we -- reach the end of the string this way, set `final` to true, so we -- don't get stuck matching the empty string at the end. local chunk if loc2 < loc1 then -- If using the string library, we need to make sure we advance -- by one UTF-8 character. if _sub == sub then local b = byte(str, loc1) if b and b >= 128 then loc1 = loc1 + (b < 224 and 1 or b < 240 and 2 or 3) end end chunk = _sub(str, start, loc1) if loc1 >= str_len then final = true else start = loc1 + 1 end -- Eat chunk up to the current match. else chunk = _sub(str, start, loc1 - 1) start = loc2 + 1 end return chunk, ... end if callable then return function() if not final then return iter(pattern_or_func(str, start)) end end -- Special case if the pattern is anchored to the start: "^" always -- anchors to the start position, not the start of the string, so get -- around this by only attempting one match with the pattern, then match -- the end of the string. elseif byte(pattern_or_func) == 0x5E then -- ^ local returned return function() if not returned then returned = true return iter(_find(str, pattern_or_func, start, plain)) elseif not final then return iter(_find(str, "$", start, plain)) end end end return function() if not final then return iter(_find(str, pattern_or_func, start, plain)) end end end gsplit = export.gsplit function export.count(str, pattern, plain) if plain then return select(2, gsub(str, pattern_escape(pattern), "")) end local simple = pattern_simplifier(pattern) if simple then return select(2, gsub(str, pattern, "")) end return select(2, ugsub(str, pattern, "")) end function export.trim(str, charset, str_lib, plain) if charset == nil then -- "^.*%S" is the fastest trim algorithm except when strings only consist of characters to be trimmed, which are -- very slow due to catastrophic backtracking. gsub with "^%s*" gets around this by trimming such strings to "" -- first. return match(gsub(str, "^%s*", ""), "^.*%S") or "" elseif charset == "" then return str end charset = plain and ("[" .. charset_escape(charset) .. "]") or get_charset(charset) -- The pattern uses a non-greedy quantifier instead of the algorithm used for %s, because negative character sets -- are non-trivial to compute (e.g. "[^^-z]" becomes "[%^_-z]"). Plus, if the ustring library has to be used, there -- would be two callbacks into PHP, which is slower. local pattern = "^" .. charset .. "*(.-)" .. charset .. "*$" if not str_lib then local simple = pattern_simplifier(pattern) if not simple then return umatch(str, pattern) end pattern = simple end return match(str, pattern) end trim = export.trim do local entities local function get_entities() entities, get_entities = load_data("Module:data/entities"), nil return entities end local function decode_entity(hash, x, code) if hash == "" then return (entities or get_entities())[x .. code] end local cp if x == "" then cp = match(code, "^()%d+$") and tonumber(code) else cp = match(code, "^()%x+$") and tonumber(code, 16) end return cp and (cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF) and u(cp) or nil end -- Non-ASCII characters aren't valid in proper HTML named entities, but MediaWiki uses them in some custom aliases -- which have also been included in [[Module:data/entities]]. function export.decode_entities(str) local amp = find(str, "&", nil, true) return amp and find(str, ";", amp, true) and gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str end end do local entities local function get_entities() -- Memoized HTML entities (taken from mw.text.lua). entities, get_entities = { ["\""] = "&quot;", ["&"] = "&amp;", ["'"] = "&#039;", ["<"] = "&lt;", [">"] = "&gt;", ["\194\160"] = "&nbsp;", }, nil return entities end local function encode_entity(ch) local entity = (entities or get_entities())[ch] if entity == nil then local cp = codepoint(ch) -- U+D800 to U+DFFF are surrogates, so can't be encoded as entities. entity = cp and (cp <= 0xD7FF or cp >= 0xE000) and format("&#%d;", cp) or false entities[ch] = entity end return entity or nil end function export.encode_entities(str, charset, str_lib, plain) if charset == nil then return (gsub(str, "[\"&'<>\194]\160?", entities or get_entities())) elseif charset == "" then return str end local pattern = plain and ("[" .. charset_escape(charset) .. "]") or charset == "." and charset or get_charset(charset) if not str_lib then local simple = pattern_simplifier(pattern) if not simple then return (ugsub(str, pattern, encode_entity)) end pattern = simple end return (gsub(str, pattern, encode_entity)) end end do local function decode_path(code) return char(tonumber(code, 16)) end local function decode(lead, trail) if lead == "+" or lead == "_" then return " " .. trail elseif #trail == 2 then return decode_path(trail) end return lead .. trail end function export.decode_uri(str, enctype) enctype = enctype and upper(enctype) or "QUERY" if enctype == "PATH" then return find(str, "%", nil, true) and gsub(str, "%%(%x%x)", decode_path) or str elseif enctype == "QUERY" then return (find(str, "%", nil, true) or find(str, "+", nil, true)) and gsub(str, "([%%%+])(%x?%x?)", decode) or str elseif enctype == "WIKI" then return (find(str, "%", nil, true) or find(str, "_", nil, true)) and gsub(str, "([%%_])(%x?%x?)", decode) or str end error("bad argument #2 to 'decode_uri' (expected QUERY, PATH, or WIKI)", 2) end end do local function _remove_comments(str, pre) local head = find(str, "<!--", nil, true) if not head then return str end local ret, n = {sub(str, 1, head - 1)}, 1 while true do local loc = find(str, "-->", head + 4, true) if not loc then return pre and concat(ret) or concat(ret) .. sub(str, head) end head = loc + 3 loc = find(str, "<!--", head, true) if not loc then return concat(ret) .. sub(str, head) end n = n + 1 ret[n] = sub(str, head, loc - 1) head = loc end end --[==[ Removes any HTML comments from the input text. `stage` can be one of three options: * {"PRE"} (default) applies the method used by MediaWiki's preprocessor: all {{code|html|<nowiki><!-- ... --></nowiki>}} pairs are removed, as well as any text after an unclosed {{code|html|<nowiki><!--</nowiki>}}. This is generally suitable when parsing raw template or [[mw:Parser extension tags|parser extension tag]] code. (Note, however, that the actual method used by the preprocessor is considerably more complex and differs under certain conditions (e.g. comments inside nowiki tags); if full accuracy is absolutely necessary, use [[Module:template parser]] instead). * {"POST"} applies the method used to generate the final page output once all templates have been expanded: it loops over the text, removing any {{code|html|<nowiki><!-- ... --></nowiki>}} pairs until no more are found (e.g. {{code|html|<nowiki><!-<!-- ... -->- ... --></nowiki>}} would be fully removed), but any unclosed {{code|html|<nowiki><!--</nowiki>}} is ignored. This is suitable for handling links embedded in template inputs, where the {"PRE"} method will have already been applied by the native parser. * {"BOTH"} applies {"PRE"} then {"POST"}. ]==] function export.remove_comments(str, stage) if not stage or stage == "PRE" then return _remove_comments(str, true) end local processed = stage == "POST" and _remove_comments(str) or stage == "BOTH" and _remove_comments(str, true) or error("bad argument #2 to 'remove_comments' (expected PRE, POST, or BOTH)", 2) while processed ~= str do str = processed processed = _remove_comments(str) end return str end end do local byte_escapes local function get_byte_escapes() byte_escapes, get_byte_escapes = load_data("Module:string utilities/data").byte_escapes, nil return byte_escapes end local function escape_byte(b) return (byte_escapes or get_byte_escapes())[b] or format("\\%03d", byte(b)) end function export.escape_bytes(str) return (gsub(str, ".", escape_byte)) end end function export.format_fun(str, fun) return (gsub(str, "{(\\?)((\\?)[^{}]*)}", function(p1, name, p2) if #p1 + #p2 == 1 then return name == "op" and "{" or name == "cl" and "}" or error(mw.getCurrentFrame():getTitle() .. " format: unrecognized escape sequence '{\\" .. name .. "}'") elseif fun(name) and type(fun(name)) ~= "string" then error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" is a " .. type(fun(name)) .. ", not a string") end return fun(name) or error(mw.getCurrentFrame():getTitle() .. " format: \"" .. name .. "\" not found in table") end)) end format_fun = export.format_fun --[==[ This function, unlike {string.format} and {mw.ustring.format}, takes just two parameters, a format string and a table, and replaces all instances of { {param_name} } in the format string with the table's entry for {param_name}. The opening and closing brace characters can be escaped with { {\op} } and { {\cl} }, respectively. A table entry beginning with a slash can be escaped by doubling the initial slash. ====Examples==== * {string_utilities.format("{foo} fish, {bar} fish, {baz} fish, {quux} fish", {["foo"]="one", ["bar"]="two", ["baz"]="red", ["quux"]="blue"}) } *: produces: {"one fish, two fish, red fish, blue fish"} * {string_utilities.format("The set {\\op}1, 2, 3{\\cl} contains {\\\\hello} elements.", {["\\hello"]="three"})} *: produces: {"The set {1, 2, 3} contains three elements."} *:* Note that the single and double backslashes should be entered as double and quadruple backslashes when quoted in a literal string. ]==] function export.format(str, tbl) return format_fun(str, function(key) return tbl[key] end) end do local function do_uclcfirst(str, case_func) -- Re-case the first letter. local first, remainder = match(str, "^(.[\128-\191]*)(.*)") return first and (case_func(first) .. remainder) or "" end local function uclcfirst(str, case_func) -- Strip off any HTML tags at the beginning. This currently does not handle comments or <ref>...</ref> -- correctly; it's intended for text wrapped in <span> or the like, as happens when passing text through -- [[Module:links]]. local html_at_beginning = nil if str:match("^<") then while true do local html_tag, rest = str:match("^(<.->)(.*)$") if not html_tag then break end if not html_at_beginning then html_at_beginning = {} end insert(html_at_beginning, html_tag) str = rest end end -- If there's a link at the beginning, re-case the first letter of the -- link text. This pattern matches both piped and unpiped links. -- If the link is not piped, the second capture (linktext) will be empty. local link, linktext, remainder = match(str, "^%[%[([^|%]]+)%|?(.-)%]%](.*)$") local retval if link then retval = "[[" .. link .. "|" .. do_uclcfirst(linktext ~= "" and linktext or link, case_func) .. "]]" .. remainder else retval = do_uclcfirst(str, case_func) end if html_at_beginning then retval = concat(html_at_beginning) .. retval end return retval end --[==[ Uppercase the first character of the input string, correctly handling one-part and two-part links, optionally surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly uppercase the first character of text that may include links that have been passed through `full_link()` in [[Module:links]] or a similar function. ]==] function export.ucfirst(str) return uclcfirst(str, uupper) end ucfirst = export.ucfirst --[==[ Lowercase the first character of the input string, correctly handling one-part and two-part links, optionally surrounded by HTML tags such as `<nowiki><span>...</span></nowiki>`, possibly nested. Intended to correctly lowercase the first character of text that may include links that have been passed through `full_link()` in [[Module:links]] or a similar function. ]==] function export.lcfirst(str) return uclcfirst(str, ulower) end --[==[Capitalizes each word of the input string. WARNING: May be broken in the presence of multiword links.]==] function export.capitalize(str) -- Capitalize multi-word that is separated by spaces -- by uppercasing the first letter of each part. return (ugsub(str, "%w+", ucfirst)) end local function do_title_case(first, remainder) first = uupper(first) return remainder == "" and first or (first .. ulower(remainder)) end --[==[ Capitalizes each word of the input string, with any further letters in each word being converted to lowercase. ]==] function export.title_case(str) return str == "" and "" or ugsub(str, "(%w)(%w*)", do_title_case) end title_case = export.title_case --[==[ Converts the input string to {{w|Camel case|CamelCase}}. Any non-word characters are treated as breaks between words. If `lower_first` is set, then the first character of the string will be lowercase (e.g. camelCase). ]==] function export.camel_case(str, lower_first) str = ugsub(str, "%W*(%w*)", title_case) return lower_first and do_uclcfirst(str, ulower) or str end end do local function do_snake_case(nonword, word) return nonword == "" and word or "_" .. word end --[==[ Converts the input string to {{w|Snake case|snake_case}}. Any non-word characters are treated as breaks between words. ]==] function export.snake_case(str) return (ugsub(str, "(%W*)(%w*)", do_snake_case)) end end return export ndjfpg4lokleft04xzto19wigx7fczh Modul:labels/data 828 3714 26662 23970 2026-07-08T05:13:55Z Sibiru45 115 26662 Scribunto text/plain local labels = {} -- Grammatical labels labels["singkatan"] = { glossary = true, pos_categories = "Singkatan", } labels["nomina abstrak"] = { display = "abstrak", glossary = true, pos_categories = "Nomina abstrak", } labels["verba abstrak"] = { display = "abstrak", glossary = true, pos_categories = "Verba abstrak", } labels["akronim"] = { glossary = true, pos_categories = "Akronim", } labels["diatesis aktif"] = { aliases = {"aktif"}, glossary = true, } labels["ambitransitif"] = { glossary = true, pos_categories = {"Verba transitif", "Verba intransitif"}, } labels["laras murka"] = { aliases = {"murka", "digunakan saat murka"}, glossary = true, pos_categories = "Istilah laras murka", } labels["bernyawa"] = { glossary = true, } labels["indikatif"] = { aliases = {"modus indikatif"}, glossary = "modus indikatif", } labels["subjungtif"] = { aliases = {"modus subjungtif"}, glossary = "modus subjungtif", } labels["imperatif"] = { aliases = {"modus imperatif"}, glossary = "modus imperatif", } labels["yusif"] = { aliases = {"modus yusif"}, glossary = "modus yusif", } labels["atelis"] = { glossary = true, } labels["atenuatif"] = { pos_categories = "Verba atenuatif", } labels["atributif"] = { glossary = true, } labels["bantu"] = { glossary = true, pos_categories = "Verba bantu", } labels["pokok"] = { aliases = {"bilangan pokok", "numeralia pokok"}, display = "[[bilangan pokok]]", pos_categories = "Numeralia pokok", } labels["katenatif"] = { glossary = "Verba katenatif", } labels["kausatif"] = { glossary = true, } labels["verba kausatif"] = { display = "kausatif", glossary = true, pos_categories = "Verba kausatif", } labels["kolektif"] = { glossary = true, display = "kolektif", pos_categories = "Nomina kolektif", } labels["bilangan kolektif"] = { aliases = {"numeralia kolektifl"}, display = "[[bilangan kolektif]]", pos_categories = "Numeralia kolektif", } labels["lazim"] = { glossary = true, } labels["terbandingkan"] = { glossary = true, } labels["kompletif"] = { pos_categories = "Verba kompletif", } labels["verba konkret"] = { display = "konkret", Wiktionary = true, pos_categories = "Verba konkret", } labels["kontraksi"] = { glossary = true, pos_categories = "Kontraksi", } labels["verba kontrol"] = { aliases = {"kontrol"}, Wikipedia = true, pos_categories = "Verba kontrol", } labels["kopulatif"] = { aliases = {"kopula"}, glossary = true, pos_categories = "Verba kopulatif", } labels["terbilang"] = { glossary = true, pos_categories = "Nomina terbilang", } labels["kumulatif"] = { pos_categories = "Verba kumulatif", } labels["adjektiva defektif"] = { aliases = {"adj defektif"}, display = "defektif", glossary = true, pos_categories = "Adjektiva defektif", } labels["nomina defektif"] = { aliases = {"n defektif"}, display = "defektif", glossary = true, pos_categories = "Nomina defektif", } labels["verba defektif"] = { aliases = {"v defektif"}, display = "defektif", glossary = true, pos_categories = "Verba defektif", } labels["salah ija disangaja"] = { display = "[[salah ija]] disangaja", } labels["delimitatif"] = { pos_categories = "Verba delimitatif", } labels["deponen"] = { glossary = true, pos_categories = "Verba deponen", } labels["distributif"] = { pos_categories = "Verba distributif", } labels["bilangan distributif"] = { aliases = {"numeralia distributif"}, Wiktionary = true, pos_categories = "Numeralia distributif", } labels["ditransitif"] = { glossary = true, pos_categories = "Verba ditransitif", } labels["dysphemistic"] = { aliases = {"dysphemism"}, glossary = "dysphemism", pos_categories = "dysphemisms", } labels["via elipsis"] = { aliases = {"elipsis"}, glossary = "elipsis", pos_categories = "Elipsis", } labels["penegas"] = { glossary = true, } labels["ergatif"] = { glossary = true, pos_categories = "Verba ergatif", } labels["ekspresif"] = { glossary = true, pos_categories = "Istilah ekspresif", } labels["perluasan makna"] = { aliases = {"perluasan"}, } labels["feminin"] = { glossary = true, } labels["fokus"] = { glossary = true, pos_categories = "Adverbia fokus", } labels["pacahan"] = { aliases = {"bilangan pecahan", "numeralia pecahan"}, display = "[[bilangan pecahan]]", pos_categories = "Numeralia pecahan", } labels["frekuentatif"] = { glossary = true, pos_categories = "Verba frekuentatif", } labels["hedge"] = { aliases = {"hedges"}, glossary = true, pos_categories = "hedges", } labels["ideofonis"] = { aliases = {"ideofon"}, glossary = true, } labels["idiomatis"] = { aliases = {"idiom"}, glossary = true, pos_categories = "Idiom", } labels["imperfektum"] = { glossary = true, } labels["imperfektif"] = { glossary = true, pos_categories = "Verba imperfektif", } labels["impersonal"] = { glossary = true, pos_categories = "Verba impersonal", } labels["dalam bentuk tunggal"] = { aliases = {"secara tunggal"}, display = "dalam bentuk [[tunggal]]", } labels["dalam bentuk ganda"] = { aliases = {"secara ganda"}, display = "dalam bentuk [[ganda]]", } labels["dalam bentuk jamak"] = { aliases = {"secara jamak"}, display = "dalam bentuk [[jamak]]", } labels["tak bernyawa"] = { aliases = {"takbernyawa"}, glossary = true, } labels["inkoatif"] = { glossary = true, pos_categories = "Verba inkoatif", } labels["tak takrif"] = { aliases = {"taktakrif"}, glossary = true, } labels["inisial"] = { glossary = true, pos_categories = "Inisial", } labels["verba intensif"] = { display = "intensif", pos_categories = "Verba intensif", } labels["tak transitif"] = { aliases = {"intransitif", "taktransitif"}, glossary = true, pos_categories = "Verba tak transitif", } labels["AFI"] = { aliases = {"IPA", "Alfabet Fonetis Internasional"}, Wikipedia = "Alfabet Fonetis Internasional", plain_categories = "Simbol AFI", } labels["iteratif"] = { glossary = true, pos_categories = "Verba iteratif", } labels["litotes"] = { aliases = {"litote", "litotic", "litotical"}, glossary = true, pos_categories = true, } labels["maskulin"] = { glossary = true, } labels["diatesis mediopasif"] = { aliases = {"mediopasif"}, glossary = true, } labels["meiosis"] = { aliases = {"meioses", "meiotic"}, glossary = true, pos_categories = "meioses", } labels["middle voice"] = { aliases = {"middle", "in middle", "in the middle", "in middle voice", "in the middle voice"}, glossary = true, } labels["salah ija"] = { Wiktionary = true, } labels["jembatan keledai"] = { Wiktionary = true, pos_categories = "Jembatan keledai", } labels["modal"] = { glossary = true, } labels["adverbia modal"] = { display = "modal", glossary = true, pos_categories = "Adverbia modal", } labels["verba modal"] = { display = "modal", glossary = true, pos_categories = "modal verbs", } labels["selalu dalam bentuk ingkar"] = { aliases = {"selalu ingkar"}, glossary = "bentuk polaritas ingkar", pos_categories = "Bentuk polaritas ingkar", } labels["utamanya dalam bentuk ingkar"] = { aliases = {"polaritas ingkar", "biasanya ingkar"}, glossary = "bentuk polaritas ingkar", pos_categories = "Bentuk polaritas ingkar", } labels["utamanya dalam bentuk ingkar jamak"] = { aliases = {"polaritas ingkar jamak"}, display = "biasanya dalam bentuk {{glossary|bentuk polaritas ingkar|ingkar}} [[jamak]]", pos_categories = "Bentuk polaritas ingkar", } labels["neuter"] = { glossary = true, } labels["nominal"] = { glossary = true, pos_categories = "Adjektiva nominal", } labels["tak terbandingkan"] = { aliases = {"takterbandingkan", "takbanding"}, glossary = true, } labels["onomatope"] = { glossary = true, pos_categories = "Onomatope", } labels["tingkat"] = { aliases = {"bilangan tingkat", "numeralia tingkat"}, display = "[[bilangan tingkat]]", pos_categories = "Numeralia tingkat", } labels["verba partitif"] = { display = "{{glossary|transitif}}, biasanya {{glossary|atelis}}", pos_categories = "Verba transitif", -- = "partitive verbs", } labels["partisip"] = { glossary = true, } labels["diatesis pasif"] = { aliases = {"pasif"}, glossary = true, } labels["perfektum"] = { glossary = true, } labels["perfektif"] = { glossary = true, pos_categories = "Verba perfektif", } labels["hanya jamak"] = { aliases = {"pluralia tantum", "plurale tantum"}, pos_categories = "Pluralia tantum", } labels["adjektiva posesif"] = { aliases = {"posesif", "adjektiva posesif"}, display = "posesif", glossary = true, pos_categories = "Adjektiva posesif", } labels["pronomina posesif"] = { aliases = {"penentu posesif"}, display = "posesif", glossary = "penentu posesif", pos_categories = "Pronomina posesif", } labels["postpositif"] = { glossary = true, } labels["predikatif"] = { glossary = true, } labels["preskriptif"] = { aliases = {"normatif"}, glossary = true, } labels["privatif"] = { pos_categories = "Verba privatif", } labels["procedure word"] = { display = "[[procedure word]]", } labels["produktif"] = { glossary = true, } -- TODO: This label is probably inappropriate for many languages labels["pronominal"] = { glossary = "pronominal verb", } labels["ejaan lafal"] = { glossary = true, } labels["pro-verba"] = { Wikipedia = true, } labels["resiprokal"] = { glossary = true, pos_categories = "Verba resiprokal", } labels["refleksif"] = { glossary = true, pos_categories = "Verba refleksif", } labels["pronomina refleksif"] = { glossary = "refleksif", display = "refleksif", pos_categories = "Pronomina refleksif", } labels["relasional"] = { glossary = true, pos_categories = "Adjektiva relasional", } labels["repetitif"] = { pos_categories = "Verba repetitif", } labels["eja ulang"] = { glossary = true, } labels["reversative"] = { pos_categories = "reversative verbs", } labels["rhetorical question"] = { glossary = true, pos_categories = "rhetorical questions", } labels["rhotis"] = { glossary = true, } labels["saturatif"] = { aliases = {"satif"}, pos_categories = "Verba saturatif", } labels["semelfaktif"] = { glossary = true, pos_categories = "Verba semelfaktif", } labels["sentence adverb"] = { glossary = true, pos_categories = "sentence adverbs", } labels["set phrase"] = { display = "[[set phrase]]", } labels["simile"] = { glossary = true, pos_categories = "similes", } labels["hanya tunggal"] = { aliases = {"singularia tantum", "singulare tantum", "tanpa jamak"}, pos_categories = "Singularia tantum", } labels["snowclone"] = { glossary = true, pos_categories = "snowclones", } labels["statif"] = { aliases = {"verba statif"}, glossary = true, pos_categories = "Verba statif", } labels["strictly"] = { aliases = {"strict", "narrowly", "narrow"}, glossary = true, } labels["substantif"] = { glossary = true, track = true, } labels["terminative"] = { pos_categories = "terminative verbs", } labels["transitif"] = { glossary = true, pos_categories = "Verba transitif", } labels["unaccusative"] = { aliases = {"not accusative"}, Wikipedia = "Unaccusative verb", } labels["tak terbilang"] = { aliases = {"takterbilang"}, glossary = true, pos_categories = "Nomina tak terbilang", } labels["unergative"] = { aliases = {"not ergative"}, Wikipedia = "Unergative verb", } labels["UPA"] = { aliases = {"Uralic Phonetic Alphabet"}, Wikipedia = "Uralic Phonetic Alphabet", plain_categories = "UPA symbols", } labels["biasanya dalam bentuk jamak"] = { aliases = {"biasanya secara jamak", "biasanya jamak"}, display = "biasanya dalam bentuk {{glossary|jamak}}", deprecated = true, } -- Usage labels labels["4chan"] = { aliases = {"4chan slang"}, display = "[[w:4chan|4chan]] {{glossary|slang}}", pos_categories = "4chan slang", } labels["4chan lgbt"] = { aliases = {"tttt"}, display = "[[w:4chan|4chan]] /lgbt/ {{glossary|slang}}", pos_categories = "4chan /lgbt/ slang", } labels["ACG"] = { display = "[[ACG]]", -- see also "fandom slang" pos_categories = "fandom slang", } labels["sayang-sayangan"] = { aliases = {"sayang"}, sense_categories = true, } labels["bentuk sayang"] = { display = "sayang-sayangan", pos_categories = "Bentuk sayang-sayangan", } labels["pre-classical"] = { aliases = {"Pre-classical", "pre-Classical", "Pre-Classical", "Preclassical", "preclassical", "ante-classical", "Ante-classical", "ante-Classical", "Ante-Classical", "Anteclassical", "anteclassical"}, display = "pre-Classical", regional_categories = true, } labels["hinaan anti-LGBTQ"] = { -- don't add aliases "homophobia" or "transphobia" because these could be topical categories aliases = {"homofobik", "transfobik"}, display = "{{glossary|hinaan}} anti-[[LGBTQ]]", pos_categories = "Hinaan anti-LGBTQ", } labels["arkais"] = { aliases = {"kuno"}, glossary = true, sense_categories = true, } labels["bentuk arkais"] = { glossary = "arkais", display = "arkais", pos_categories = "Bentuk arkais", } labels["avoidance"] = { glossary = true, } labels["slang balik"] = { aliases = {"balik"}, glossary = true, pos_categories = "Slang balik", } labels["Bargoens"] = { Wikipedia = true, plain_categories = true, } labels["Braille"] = { Wikipedia = true, } labels["British slang"] = { aliases = {"UK slang"}, display = "[[British]] {{glossary|slang}}", plain_categories = true, } labels["Cambridge University slang"] = { aliases = {"University of Cambridge slang", "Cantab slang"}, display = "[[w:University of Cambridge|Cambridge University]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = true, } labels["cant"] = { aliases = {"argot", "cryptolect"}, display = "[[cant]]", pos_categories = true, } labels["capitalized"] = { aliases = {"capitalised"}, display = "[[capitalisation|capitalized]]", } labels["Castilianism"] = { aliases = {"Hispanicism"}, display = "[[Castilianism]]", } labels["childish"] = { aliases = {"baby talk", "child language", "infantile", "puerile"}, display = "[[childish]]", -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "childish terms", } labels["chu Nom"] = { display = "[[Vietnamese]] [[chữ Nôm]]", plain_categories = "Vietnamese Han tu", } labels["Cockney rhyming slang"] = { display = "[[Cockney rhyming slang]]", plain_categories = true, } labels["sambatan"] = { aliases = {"gaul"}, glossary = true, sense_categories = true, } labels["corporate jargon"] = { aliases = {"business jargon", "corporatese", "businessese", "corporate speak", "business speak"}, display = "[[corporate]] [[jargon]]", pos_categories = true, } labels["costermongers"] = { aliases = {"coster", "costers", "costermonger", "costermongers back slang", "costermongers' back slang"}, display = "[[Appendix:Costermongers' back slang|costermongers]]", plain_categories = "Costermongers' back slang", } labels["criminal slang"] = { aliases = {"thieves' cant", "Thieves' Cant", "thieves cant", "thieves'", "thieves", "thieves' cant"}, -- Thieves' Cant is English-only, so defined in the English submodule; if other languages try to use it, it's just criminal slang display = "[[criminal]] {{glossary|slang}}", topical_categories = "Crime", pos_categories = true, } labels["dated"] = { aliases = {"old-fashioned"}, glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp pos_categories = "dated terms", } labels["dated form"] = { aliases = {"old-fashioned form"}, glossary = "dated", display = "dated", pos_categories = "dated forms", } -- combine with previous? labels["dated sense"] = { glossary = "dated", sense_categories = "dated", } labels["hinaan"] = { glossary = true, sense_categories = true, } labels["bentuk hinaan"] = { display = "{{glossary|hinaan}}", pos_categories = "Bentuk hinaan", } labels["dialek"] = {-- separated from "dialectal" so e.g. "obsolete|outside|the|_|dialect|of..." displays right glossary = "dialektal", sense_categories = "dialektal", } labels["dialektal"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp sense_categories = true, } labels["dialectal form"] = { glossary = "dialectal", display = "dialectal", pos_categories = "dialectal forms", } labels["dialects"] = {-- separated from "dialectal" so e.g. "obsolete|outside|dialects" displays right glossary = "dialectal", pos_categories = "dialectal terms", } labels["dis legomenon"] = { display = "[[dis legomenon]]", pos_categories = "dis legomena", } labels["dismissal"] = { display = "[[dismissal]]", pos_categories = "dismissals", } labels["drag slang"] = { aliases = {"Drag Race slang"}, display = "[[drag]] {{glossary|slang}}", pos_categories = "drag slang", } labels["ecclesiastical"] = { display = "[[ecclesiastical#Adjective|ecclesiastical]]", pos_categories = "ecclesiastical terms", } labels["ethnic slur"] = { aliases = {"racial slur"}, display = "[[ethnic]] [[slur]]", pos_categories = "ethnic slurs", } labels["euphemistic"] = { aliases = {"euphemism"}, glossary = "euphemism", pos_categories = "euphemisms", } labels["eye dialect"] = { display = "[[eye dialect]]", pos_categories = true, } labels["familiar"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "familiar terms", } labels["fandom slang"] = { aliases = {"fandom"}, display = "[[fandom]] {{glossary|slang}}", pos_categories = true, } labels["kiasan"] = { aliases = {"metaforis", "metafora", "metafor"}, glossary = true, sense_categories = true, } labels["folk songs"] = { aliases = {"folksongs", "used in folk songs", "used in folksongs"}, pos_categories = "folk poetic terms", display = "used in [[folk song]]s", } labels["folk tales"] = { aliases = {"folktales", "used in folk tales", "used in folktales"}, pos_categories = "folk poetic terms", display = "used in [[folk tale]]s", } labels["folk poetic"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp pos_categories = "folk poetic terms", } labels["formal"] = { glossary = true, sense_categories = true, } labels["bentuk formal"] = { glossary = "formal", display = "formal", pos_categories = "Bentuk formal", } labels["slang gay"] = { display = "{{glossary|slang}} [[gay]]", pos_categories = "Slang gay", } labels["gender-neutral"] = { glossary = "gender-neutral", pos_categories = "gender-neutral terms", } labels["graffiti slang"] = { display = "[[graffiti#Noun|graffiti]] {{glossary|slang}}", pos_categories = true, } labels["genericized trademark"] = { aliases = {"generic trademark", "proprietary eponym"}, display = "[[genericized trademark]]", pos_categories = "genericized trademarks", } labels["ghost word"] = { aliases = {"ghost"}, display = "ghost word", glossary = true, pos_categories = "ghost words", } labels["hapax legomenon"] = { aliases = {"hapax"}, display = "hapax legomenon", glossary = true, pos_categories = "hapax legomena", } labels["tutur tinggi"] = { glossary = "tingkat tutur tinggi", sense_categories = "tutur tinggi", } labels["historis"] = { glossary = true, sense_categories = true, } labels["non-native speakers"] = {-- language-agnostic version aliases = {"NNS"}, display = "[[non-native speaker]]s", -- so preceded by "used by", "error by children and", etc? or reword? regional_categories = {"Non-native speakers'"}, } labels["non-native speakers' English"] = { aliases = {"NNES", "NNSE"}, display = "[[non-native speaker]]s' English", regional_categories = "Non-native speakers'", } -- used exclusively by languages that use the "Jpan" script code labels["historical hiragana"] = { pos_categories = true, } -- used exclusively by languages that use the "Jpan" script code labels["historical katakana"] = { pos_categories = true, } -- applies to Japanese and Korean, etc., please do not confuse with "polite" labels["hormat"] = { glossary = "bentuk hormat", sense_categories = true, } -- for Ancient Greek labels["Homeric epithet"] = { display = "[[Homeric Greek|Homeric]] [[w:Epithets in Homer|epithet]]", omit_postComma = true, plain_categories = "Epic Greek", } -- applies to Japanese and Korean, etc. labels["merendah"] = { glossary = "bentuk merendah", sense_categories = true, } -- for Akkadian labels["in hendiadys"] = { aliases = {"hendiadys"}, display = "in {{w|hendiadys}}", pos_categories = "terms used in hendiadys", } labels["jenaka"] = { aliases = {"candaan", "gurauan"}, glossary = true, sense_categories = true, } labels["hiperbola"] = { glossary = true, pos_categories = "Hiperbola", } labels["lewah ralat"] = { glossary = true, pos_categories = "Bentuk lewah ralat", } labels["lewah asing"] = { glossary = true, sense_categories = true, } labels["imperial"] = { aliases = {"emperor", "empress"}, pos_categories = "royal terms", } labels["incel slang"] = { display = "[[incel]] {{glossary|slang}}", pos_categories = true, } labels["tak formal"] = { aliases = {"informal", "takformal"}, glossary = true, sense_categories = true, } labels["bentuk informal"] = { glossary = "informal", display = "informal", pos_categories = "Bentuk informal", } labels["slang internet"] = { display = "{{glossary|slang}} [[internet]]", pos_categories = "Slang internet", } labels["ironis"] = { display = "[[ironi|ironis]]", } -- Not the same as "journalism", which maps to a topical category (e.g. [[:Category:en:Journalism]], instead of [[:Category:English journalistic terms]]). labels["journalistic"] = { aliases = {"journalese"}, display = "[[journalistic]]", pos_categories = "journalistic terms", } labels["leet"] = { aliases = {"leetspeak"}, display = "[[leetspeak]]", pos_categories = "leetspeak", } labels["slang LGBTQ"] = { aliases = {"slang LGBT"}, display = "{{glossary|slang}} [[LGBTQ]]", pos_categories = "Slang LGBTQ", } labels["harfiah"] = { glossary = true, } labels["sastrawi"] = { aliases = {"sastra"}, glossary = true, sense_categories = true, } labels["bentuk sastrawi"] = { aliases = {"bentuk sastra"}, glossary = "sastrawi", display = "sastrawi", pos_categories = "Bentuk sastrawi", } --see also "short scale" labels["long scale"] = { display = "[[w:Long and short scales|long scale]]" } labels["loosely"] = { aliases = {"loose", "broadly", "broad"}, glossary = true, } labels["medical slang"] = { display = "[[medical]] {{glossary|slang}}", pos_categories = true, } -- for Awetí, Karajá, etc., where men and women use different words labels["men's speech"] = { aliases = {"male speech"}, glossary = "men's speech", pos_categories = "men's speech terms", } labels["metonimia"] = { glossary = true, pos_categories = "metonyms", } labels["military slang"] = { display = "[[military]] {{glossary|slang}}", pos_categories = true, } labels["minced oath"] = { display = "[[minced oath]]", pos_categories = "minced oaths", } labels["multiplicative"] = { aliases = {"multiplicative number", "multiplicative numeral"}, display = "[[multiplicative number]]", pos_categories = "multiplicative numbers", } labels["multiplicity slang"] = { display = "{{l|en|multiplicity|id=multiple personalities}} {{glossary|slang}}", pos_categories = true, } labels["nativising coinage"] = { display = "[[w:Linguistic purism in Korean|nativising coinage]]", pos_categories = "nativising coinages", } labels["naval slang"] = { aliases = {"navy slang"}, display = "[[naval]] {{glossary|slang}}", pos_categories = true, } labels["neologisme"] = { glossary = true, pos_categories = "Neologisme", } labels["neopronoun"] = { display = "[[neopronoun]]", -- pos_categories = {"neopronouns"}, } labels["tak lagi produktif"] = { aliases = {"tak produktif", "takproduktif"}, display = "tak lagi {{glossary|produktif}}", } labels["nonce word"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp? aliases = {"nonce"}, glossary = true, pos_categories = "nonce terms", } labels["tak baku"] = { aliases = {"nonbaku", "takbaku", "tidak baku"}, glossary = true, sense_categories = true, } labels["bentuk tak baku"] = { aliases = {"bentuk nonbaku", "bentuk tidak baku"}, glossary = "tak baku", display = "tak baku", pos_categories = "Bentuk tak baku", } labels["numismatic slang"] = { display = "[[numismatic]] {{glossary|slang}}", pos_categories = true, } labels["usang"] = { glossary = true, sense_categories = true, } labels["bentuk usang"] = { glossary = "usang", display = "usang", pos_categories = "Bentuk usang", } labels["umpatan"] = { glossary = true, sense_categories = true, } labels["officialese"] = { aliases = {"bureaucratic"}, display = "[[officialese]]", pos_categories = "officialese terms", } labels["Oxbridge slang"] = { display = "[[w:Oxbridge|Oxbridge]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = {"Cambridge University slang", "Oxford University slang"}, } labels["Oxford University slang"] = { aliases = {"University of Oxford slang", "Oxon slang"}, display = "[[w:University of Oxford|Oxford University]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = true, } labels["puitis"] = { glossary = true, sense_categories = true, } labels["bentuk puitis"] = { glossary = "puitis", display = "puitis", pos_categories = "Bentuk puitis", } labels["sopan"] = { glossary = true, sense_categories = true, } labels["post-classical"] = { aliases = {"Post-classical", "post-Classical", "Post-Classical", "Postclassical", "postclassical"}, display = "post-Classical", regional_categories = true, } labels["prison slang"] = { display = "[[prison]] {{glossary|slang}}", pos_categories = true, } labels["proscribed"] = { glossary = true, pos_categories = "proscribed terms", } labels["puristic"] = { aliases = {"purism"}, Wikipedia = "Linguistic purism", pos_categories = "puristic terms", } labels["radio slang"] = { display = "[[radio]] {{glossary|slang}}", pos_categories = true, } labels["Reddit slang"] = { display = "[[Reddit]] {{glossary|slang}}", pos_categories = true, } labels["rare"] = { aliases = {"rare sense"}, glossary = true, sense_categories = true, } labels["rare form"] = { glossary = "rare", display = "rare", pos_categories = "rare forms", } labels["rare term"] = { display = "rare", -- see comments about "obsolete" pos_categories = "rare terms", } -- cf Cockney rhyming slang labels["rhyming slang"] = { display = "[[rhyming slang]]", pos_categories = true, } labels["religious slur"] = { aliases = {"sectarian slur"}, display = "[[religious]] [[slur]]", pos_categories = "religious slurs", } labels["retronym"] = { glossary = true, pos_categories = "retronyms", } labels["reverential"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp? display = "[[reverential]]", pos_categories = "reverential terms", } labels["royal"] = { aliases = {"regal"}, pos_categories = "royal terms", } labels["rustic"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp? aliases = {"rural"}, pos_categories = "rustic terms", } labels["sarcastic"] = { display = "[[sarcastic]]", pos_categories = "sarcastic terms", } labels["school slang"] = { aliases = {"public school slang"}, display = "[[school]] {{glossary|slang}}", pos_categories = true, } labels["self-deprecatory"] = { aliases = {"self-deprecating"}, display = "[[self-deprecatory]]", -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "self-deprecatory terms", } -- Swahili Sheng cant / argot -- should this be in a language-specific module? labels["Sheng"] = { Wikipedia = "Sheng slang", plain_categories = true, } labels["siglum"] = { aliases = {"sigla"}, glossary = true, pos_categories = "sigla", } --see also "long scale" labels["short scale"] = { display = "[[w:Long and short scales|short scale]]" } labels["slang"] = { glossary = true, pos_categories = true, } labels["solemn"] = { glossary = true, pos_categories = "solemn terms", } labels["Stenoscript"] = { aliases = {"stenoscript"}, display = "[[Stenoscript]]", pos_categories = "Stenoscript abbreviations", } labels["superseded"] = { glossary = true } labels["swear word"] = { aliases = {"profanity", "expletive"}, pos_categories = "swear words", } labels["syncopated"] = { aliases = {"syncope", "syncopic", "syncopation"}, glossary = true, pos_categories = "syncopic forms", } labels["synecdochically"] = { aliases = {"synecdochic", "synecdochical", "synecdoche"}, glossary = true, pos_categories = "synecdoches", } labels["technical"] = { display = "[[technical]]", pos_categories = "technical terms", } labels["telic"] = { glossary = true, } labels["text messaging"] = { aliases = {"texting"}, display = "[[text messaging]]", pos_categories = "text messaging slang", } labels["tone indicator"] = { display = "[[tone indicator]]", pos_categories = "tone indicators", } labels["trademark"] = { display = "[[trademark]]", pos_categories = "trademarks", } labels["transferred sense"] = { glossary = true, pos_categories = "terms with transferred senses", } labels["transferred senses"] = { display = "[[transferred sense#English|transferred senses]]", pos_categories = "terms with transferred senses", } labels["slang transgender"] = { aliases = {"slang trans"}, display = "{{glossary|slang}} [[transgender]]", pos_categories = "Slang transgender", } labels["Twitch-speak"] = { display = "[[Twitch-speak]]", pos_categories = true, } labels["uds."] = { display = "[[Appendix:Spanish pronouns#Ustedes and vosotros|used formally in Spain]]", } labels["uncommon"] = { glossary = true, sense_categories = true, } labels["uncommon form"] = { glossary = "uncommon", display = "uncommon", pos_categories = "uncommon forms", } labels["slang kampus"] = { aliases = {"slang mahasiswa", "slang universitas"}, display = "[[university]] {{glossary|slang}}", topical_categories = "perguruan tinggi", pos_categories = "Slang kampus", } labels["verlan"] = { glossary = true, plain_categories = true, } labels["very rare"] = { display = "very [[Appendix:Glossary#rare|rare]]", sense_categories = "rare", } labels["kasar"] = { aliases = {"vulgar"}, glossary = true, sense_categories = true, } labels["vesre"] = { Wikipedia = true, plain_categories = true, } labels["slang anak muda"] = { display = "{{glossary|slang}} [[anak muda]]", pos_categories = "Slang", } labels["2channel slang"] = { aliases = {"2channel", "2ch slang"}, display ="[[w:2channel|2channel]] {{glossary|slang}}", pos_categories = {"internet slang" , "2channel slang"}, } -- for Awetí, Karajá, etc., where men & women use different words labels["women's speech"] = { aliases = {"female speech"}, glossary = "women's speech", pos_categories = "women's speech terms", } return require("Module:labels").finalize_data(labels) i89cb0o88p120clqydb873fvlhd6qts 26665 26662 2026-07-08T05:17:53Z Sibiru45 115 26665 Scribunto text/plain local labels = {} -- Grammatical labels labels["singkatan"] = { glossary = true, pos_categories = "Singkatan", } labels["nomina abstrak"] = { display = "abstrak", glossary = true, pos_categories = "Nomina abstrak", } labels["verba abstrak"] = { display = "abstrak", glossary = true, pos_categories = "Verba abstrak", } labels["singkatan"] = { glossary = true, pos_categories = "Akronim", } labels["diatesis aktif"] = { aliases = {"aktif"}, glossary = true, } labels["ambitransitif"] = { glossary = true, pos_categories = {"Verba transitif", "Verba intransitif"}, } labels["laras murka"] = { aliases = {"murka", "digunakan saat murka"}, glossary = true, pos_categories = "Istilah laras murka", } labels["bernyawa"] = { glossary = true, } labels["indikatif"] = { aliases = {"modus indikatif"}, glossary = "modus indikatif", } labels["subjungtif"] = { aliases = {"modus subjungtif"}, glossary = "modus subjungtif", } labels["imperatif"] = { aliases = {"modus imperatif"}, glossary = "modus imperatif", } labels["yusif"] = { aliases = {"modus yusif"}, glossary = "modus yusif", } labels["atelis"] = { glossary = true, } labels["atenuatif"] = { pos_categories = "Verba atenuatif", } labels["atributif"] = { glossary = true, } labels["bantu"] = { glossary = true, pos_categories = "Verba bantu", } labels["pokok"] = { aliases = {"bilangan pokok", "numeralia pokok"}, display = "[[bilangan pokok]]", pos_categories = "Numeralia pokok", } labels["katenatif"] = { glossary = "Verba katenatif", } labels["kausatif"] = { glossary = true, } labels["verba kausatif"] = { display = "kausatif", glossary = true, pos_categories = "Verba kausatif", } labels["kolektif"] = { glossary = true, display = "kolektif", pos_categories = "Nomina kolektif", } labels["bilangan kolektif"] = { aliases = {"numeralia kolektifl"}, display = "[[bilangan kolektif]]", pos_categories = "Numeralia kolektif", } labels["lazim"] = { glossary = true, } labels["terbandingkan"] = { glossary = true, } labels["kompletif"] = { pos_categories = "Verba kompletif", } labels["verba konkret"] = { display = "konkret", Wiktionary = true, pos_categories = "Verba konkret", } labels["kontraksi"] = { glossary = true, pos_categories = "Kontraksi", } labels["verba kontrol"] = { aliases = {"kontrol"}, Wikipedia = true, pos_categories = "Verba kontrol", } labels["kopulatif"] = { aliases = {"kopula"}, glossary = true, pos_categories = "Verba kopulatif", } labels["terbilang"] = { glossary = true, pos_categories = "Nomina terbilang", } labels["kumulatif"] = { pos_categories = "Verba kumulatif", } labels["adjektiva defektif"] = { aliases = {"adj defektif"}, display = "defektif", glossary = true, pos_categories = "Adjektiva defektif", } labels["nomina defektif"] = { aliases = {"n defektif"}, display = "defektif", glossary = true, pos_categories = "Nomina defektif", } labels["verba defektif"] = { aliases = {"v defektif"}, display = "defektif", glossary = true, pos_categories = "Verba defektif", } labels["salah ija disangaja"] = { display = "[[salah ija]] disangaja", } labels["delimitatif"] = { pos_categories = "Verba delimitatif", } labels["deponen"] = { glossary = true, pos_categories = "Verba deponen", } labels["distributif"] = { pos_categories = "Verba distributif", } labels["bilangan distributif"] = { aliases = {"numeralia distributif"}, Wiktionary = true, pos_categories = "Numeralia distributif", } labels["ditransitif"] = { glossary = true, pos_categories = "Verba ditransitif", } labels["dysphemistic"] = { aliases = {"dysphemism"}, glossary = "dysphemism", pos_categories = "dysphemisms", } labels["via elipsis"] = { aliases = {"elipsis"}, glossary = "elipsis", pos_categories = "Elipsis", } labels["penegas"] = { glossary = true, } labels["ergatif"] = { glossary = true, pos_categories = "Verba ergatif", } labels["ekspresif"] = { glossary = true, pos_categories = "Istilah ekspresif", } labels["perluasan makna"] = { aliases = {"perluasan"}, } labels["feminin"] = { glossary = true, } labels["fokus"] = { glossary = true, pos_categories = "Adverbia fokus", } labels["pacahan"] = { aliases = {"bilangan pecahan", "numeralia pecahan"}, display = "[[bilangan pecahan]]", pos_categories = "Numeralia pecahan", } labels["frekuentatif"] = { glossary = true, pos_categories = "Verba frekuentatif", } labels["hedge"] = { aliases = {"hedges"}, glossary = true, pos_categories = "hedges", } labels["ideofonis"] = { aliases = {"ideofon"}, glossary = true, } labels["idiomatis"] = { aliases = {"idiom"}, glossary = true, pos_categories = "Idiom", } labels["imperfektum"] = { glossary = true, } labels["imperfektif"] = { glossary = true, pos_categories = "Verba imperfektif", } labels["impersonal"] = { glossary = true, pos_categories = "Verba impersonal", } labels["dalam bentuk tunggal"] = { aliases = {"secara tunggal"}, display = "dalam bentuk [[tunggal]]", } labels["dalam bentuk ganda"] = { aliases = {"secara ganda"}, display = "dalam bentuk [[ganda]]", } labels["dalam bentuk jamak"] = { aliases = {"secara jamak"}, display = "dalam bentuk [[jamak]]", } labels["tak bernyawa"] = { aliases = {"takbernyawa"}, glossary = true, } labels["inkoatif"] = { glossary = true, pos_categories = "Verba inkoatif", } labels["tak takrif"] = { aliases = {"taktakrif"}, glossary = true, } labels["inisial"] = { glossary = true, pos_categories = "Inisial", } labels["verba intensif"] = { display = "intensif", pos_categories = "Verba intensif", } labels["tak transitif"] = { aliases = {"intransitif", "taktransitif"}, glossary = true, pos_categories = "Verba tak transitif", } labels["AFI"] = { aliases = {"IPA", "Alfabet Fonetis Internasional"}, Wikipedia = "Alfabet Fonetis Internasional", plain_categories = "Simbol AFI", } labels["iteratif"] = { glossary = true, pos_categories = "Verba iteratif", } labels["litotes"] = { aliases = {"litote", "litotic", "litotical"}, glossary = true, pos_categories = true, } labels["maskulin"] = { glossary = true, } labels["diatesis mediopasif"] = { aliases = {"mediopasif"}, glossary = true, } labels["meiosis"] = { aliases = {"meioses", "meiotic"}, glossary = true, pos_categories = "meioses", } labels["middle voice"] = { aliases = {"middle", "in middle", "in the middle", "in middle voice", "in the middle voice"}, glossary = true, } labels["salah ija"] = { Wiktionary = true, } labels["jembatan keledai"] = { Wiktionary = true, pos_categories = "Jembatan keledai", } labels["modal"] = { glossary = true, } labels["adverbia modal"] = { display = "modal", glossary = true, pos_categories = "Adverbia modal", } labels["verba modal"] = { display = "modal", glossary = true, pos_categories = "modal verbs", } labels["selalu dalam bentuk ingkar"] = { aliases = {"selalu ingkar"}, glossary = "bentuk polaritas ingkar", pos_categories = "Bentuk polaritas ingkar", } labels["utamanya dalam bentuk ingkar"] = { aliases = {"polaritas ingkar", "biasanya ingkar"}, glossary = "bentuk polaritas ingkar", pos_categories = "Bentuk polaritas ingkar", } labels["utamanya dalam bentuk ingkar jamak"] = { aliases = {"polaritas ingkar jamak"}, display = "biasanya dalam bentuk {{glossary|bentuk polaritas ingkar|ingkar}} [[jamak]]", pos_categories = "Bentuk polaritas ingkar", } labels["neuter"] = { glossary = true, } labels["nominal"] = { glossary = true, pos_categories = "Adjektiva nominal", } labels["tak terbandingkan"] = { aliases = {"takterbandingkan", "takbanding"}, glossary = true, } labels["onomatope"] = { glossary = true, pos_categories = "Onomatope", } labels["tingkat"] = { aliases = {"bilangan tingkat", "numeralia tingkat"}, display = "[[bilangan tingkat]]", pos_categories = "Numeralia tingkat", } labels["verba partitif"] = { display = "{{glossary|transitif}}, biasanya {{glossary|atelis}}", pos_categories = "Verba transitif", -- = "partitive verbs", } labels["partisip"] = { glossary = true, } labels["diatesis pasif"] = { aliases = {"pasif"}, glossary = true, } labels["perfektum"] = { glossary = true, } labels["perfektif"] = { glossary = true, pos_categories = "Verba perfektif", } labels["hanya jamak"] = { aliases = {"pluralia tantum", "plurale tantum"}, pos_categories = "Pluralia tantum", } labels["adjektiva posesif"] = { aliases = {"posesif", "adjektiva posesif"}, display = "posesif", glossary = true, pos_categories = "Adjektiva posesif", } labels["pronomina posesif"] = { aliases = {"penentu posesif"}, display = "posesif", glossary = "penentu posesif", pos_categories = "Pronomina posesif", } labels["postpositif"] = { glossary = true, } labels["predikatif"] = { glossary = true, } labels["preskriptif"] = { aliases = {"normatif"}, glossary = true, } labels["privatif"] = { pos_categories = "Verba privatif", } labels["procedure word"] = { display = "[[procedure word]]", } labels["produktif"] = { glossary = true, } -- TODO: This label is probably inappropriate for many languages labels["pronominal"] = { glossary = "pronominal verb", } labels["ejaan lafal"] = { glossary = true, } labels["pro-verba"] = { Wikipedia = true, } labels["resiprokal"] = { glossary = true, pos_categories = "Verba resiprokal", } labels["refleksif"] = { glossary = true, pos_categories = "Verba refleksif", } labels["pronomina refleksif"] = { glossary = "refleksif", display = "refleksif", pos_categories = "Pronomina refleksif", } labels["relasional"] = { glossary = true, pos_categories = "Adjektiva relasional", } labels["repetitif"] = { pos_categories = "Verba repetitif", } labels["eja ulang"] = { glossary = true, } labels["reversative"] = { pos_categories = "reversative verbs", } labels["rhetorical question"] = { glossary = true, pos_categories = "rhetorical questions", } labels["rhotis"] = { glossary = true, } labels["saturatif"] = { aliases = {"satif"}, pos_categories = "Verba saturatif", } labels["semelfaktif"] = { glossary = true, pos_categories = "Verba semelfaktif", } labels["sentence adverb"] = { glossary = true, pos_categories = "sentence adverbs", } labels["set phrase"] = { display = "[[set phrase]]", } labels["simile"] = { glossary = true, pos_categories = "similes", } labels["hanya tunggal"] = { aliases = {"singularia tantum", "singulare tantum", "tanpa jamak"}, pos_categories = "Singularia tantum", } labels["snowclone"] = { glossary = true, pos_categories = "snowclones", } labels["statif"] = { aliases = {"verba statif"}, glossary = true, pos_categories = "Verba statif", } labels["strictly"] = { aliases = {"strict", "narrowly", "narrow"}, glossary = true, } labels["substantif"] = { glossary = true, track = true, } labels["terminative"] = { pos_categories = "terminative verbs", } labels["transitif"] = { glossary = true, pos_categories = "Verba transitif", } labels["unaccusative"] = { aliases = {"not accusative"}, Wikipedia = "Unaccusative verb", } labels["tak terbilang"] = { aliases = {"takterbilang"}, glossary = true, pos_categories = "Nomina tak terbilang", } labels["unergative"] = { aliases = {"not ergative"}, Wikipedia = "Unergative verb", } labels["UPA"] = { aliases = {"Uralic Phonetic Alphabet"}, Wikipedia = "Uralic Phonetic Alphabet", plain_categories = "UPA symbols", } labels["biasanya dalam bentuk jamak"] = { aliases = {"biasanya secara jamak", "biasanya jamak"}, display = "biasanya dalam bentuk {{glossary|jamak}}", deprecated = true, } -- Usage labels labels["4chan"] = { aliases = {"4chan slang"}, display = "[[w:4chan|4chan]] {{glossary|slang}}", pos_categories = "4chan slang", } labels["4chan lgbt"] = { aliases = {"tttt"}, display = "[[w:4chan|4chan]] /lgbt/ {{glossary|slang}}", pos_categories = "4chan /lgbt/ slang", } labels["ACG"] = { display = "[[ACG]]", -- see also "fandom slang" pos_categories = "fandom slang", } labels["sayang-sayangan"] = { aliases = {"sayang"}, sense_categories = true, } labels["bentuk sayang"] = { display = "sayang-sayangan", pos_categories = "Bentuk sayang-sayangan", } labels["pre-classical"] = { aliases = {"Pre-classical", "pre-Classical", "Pre-Classical", "Preclassical", "preclassical", "ante-classical", "Ante-classical", "ante-Classical", "Ante-Classical", "Anteclassical", "anteclassical"}, display = "pre-Classical", regional_categories = true, } labels["hinaan anti-LGBTQ"] = { -- don't add aliases "homophobia" or "transphobia" because these could be topical categories aliases = {"homofobik", "transfobik"}, display = "{{glossary|hinaan}} anti-[[LGBTQ]]", pos_categories = "Hinaan anti-LGBTQ", } labels["arkais"] = { aliases = {"kuno"}, glossary = true, sense_categories = true, } labels["bentuk arkais"] = { glossary = "arkais", display = "arkais", pos_categories = "Bentuk arkais", } labels["avoidance"] = { glossary = true, } labels["slang balik"] = { aliases = {"balik"}, glossary = true, pos_categories = "Slang balik", } labels["Bargoens"] = { Wikipedia = true, plain_categories = true, } labels["Braille"] = { Wikipedia = true, } labels["British slang"] = { aliases = {"UK slang"}, display = "[[British]] {{glossary|slang}}", plain_categories = true, } labels["Cambridge University slang"] = { aliases = {"University of Cambridge slang", "Cantab slang"}, display = "[[w:University of Cambridge|Cambridge University]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = true, } labels["cant"] = { aliases = {"argot", "cryptolect"}, display = "[[cant]]", pos_categories = true, } labels["capitalized"] = { aliases = {"capitalised"}, display = "[[capitalisation|capitalized]]", } labels["Castilianism"] = { aliases = {"Hispanicism"}, display = "[[Castilianism]]", } labels["childish"] = { aliases = {"baby talk", "child language", "infantile", "puerile"}, display = "[[childish]]", -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "childish terms", } labels["chu Nom"] = { display = "[[Vietnamese]] [[chữ Nôm]]", plain_categories = "Vietnamese Han tu", } labels["Cockney rhyming slang"] = { display = "[[Cockney rhyming slang]]", plain_categories = true, } labels["sambatan"] = { aliases = {"gaul"}, glossary = true, sense_categories = true, } labels["corporate jargon"] = { aliases = {"business jargon", "corporatese", "businessese", "corporate speak", "business speak"}, display = "[[corporate]] [[jargon]]", pos_categories = true, } labels["costermongers"] = { aliases = {"coster", "costers", "costermonger", "costermongers back slang", "costermongers' back slang"}, display = "[[Appendix:Costermongers' back slang|costermongers]]", plain_categories = "Costermongers' back slang", } labels["criminal slang"] = { aliases = {"thieves' cant", "Thieves' Cant", "thieves cant", "thieves'", "thieves", "thieves' cant"}, -- Thieves' Cant is English-only, so defined in the English submodule; if other languages try to use it, it's just criminal slang display = "[[criminal]] {{glossary|slang}}", topical_categories = "Crime", pos_categories = true, } labels["dated"] = { aliases = {"old-fashioned"}, glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp pos_categories = "dated terms", } labels["dated form"] = { aliases = {"old-fashioned form"}, glossary = "dated", display = "dated", pos_categories = "dated forms", } -- combine with previous? labels["dated sense"] = { glossary = "dated", sense_categories = "dated", } labels["hinaan"] = { glossary = true, sense_categories = true, } labels["bentuk hinaan"] = { display = "{{glossary|hinaan}}", pos_categories = "Bentuk hinaan", } labels["dialek"] = {-- separated from "dialectal" so e.g. "obsolete|outside|the|_|dialect|of..." displays right glossary = "dialektal", sense_categories = "dialektal", } labels["dialektal"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp sense_categories = true, } labels["dialectal form"] = { glossary = "dialectal", display = "dialectal", pos_categories = "dialectal forms", } labels["dialects"] = {-- separated from "dialectal" so e.g. "obsolete|outside|dialects" displays right glossary = "dialectal", pos_categories = "dialectal terms", } labels["dis legomenon"] = { display = "[[dis legomenon]]", pos_categories = "dis legomena", } labels["dismissal"] = { display = "[[dismissal]]", pos_categories = "dismissals", } labels["drag slang"] = { aliases = {"Drag Race slang"}, display = "[[drag]] {{glossary|slang}}", pos_categories = "drag slang", } labels["ecclesiastical"] = { display = "[[ecclesiastical#Adjective|ecclesiastical]]", pos_categories = "ecclesiastical terms", } labels["ethnic slur"] = { aliases = {"racial slur"}, display = "[[ethnic]] [[slur]]", pos_categories = "ethnic slurs", } labels["euphemistic"] = { aliases = {"euphemism"}, glossary = "euphemism", pos_categories = "euphemisms", } labels["eye dialect"] = { display = "[[eye dialect]]", pos_categories = true, } labels["familiar"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "familiar terms", } labels["fandom slang"] = { aliases = {"fandom"}, display = "[[fandom]] {{glossary|slang}}", pos_categories = true, } labels["kiasan"] = { aliases = {"metaforis", "metafora", "metafor"}, glossary = true, sense_categories = true, } labels["folk songs"] = { aliases = {"folksongs", "used in folk songs", "used in folksongs"}, pos_categories = "folk poetic terms", display = "used in [[folk song]]s", } labels["folk tales"] = { aliases = {"folktales", "used in folk tales", "used in folktales"}, pos_categories = "folk poetic terms", display = "used in [[folk tale]]s", } labels["folk poetic"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp pos_categories = "folk poetic terms", } labels["formal"] = { glossary = true, sense_categories = true, } labels["bentuk formal"] = { glossary = "formal", display = "formal", pos_categories = "Bentuk formal", } labels["slang gay"] = { display = "{{glossary|slang}} [[gay]]", pos_categories = "Slang gay", } labels["gender-neutral"] = { glossary = "gender-neutral", pos_categories = "gender-neutral terms", } labels["graffiti slang"] = { display = "[[graffiti#Noun|graffiti]] {{glossary|slang}}", pos_categories = true, } labels["genericized trademark"] = { aliases = {"generic trademark", "proprietary eponym"}, display = "[[genericized trademark]]", pos_categories = "genericized trademarks", } labels["ghost word"] = { aliases = {"ghost"}, display = "ghost word", glossary = true, pos_categories = "ghost words", } labels["hapax legomenon"] = { aliases = {"hapax"}, display = "hapax legomenon", glossary = true, pos_categories = "hapax legomena", } labels["tutur tinggi"] = { glossary = "tingkat tutur tinggi", sense_categories = "tutur tinggi", } labels["historis"] = { glossary = true, sense_categories = true, } labels["non-native speakers"] = {-- language-agnostic version aliases = {"NNS"}, display = "[[non-native speaker]]s", -- so preceded by "used by", "error by children and", etc? or reword? regional_categories = {"Non-native speakers'"}, } labels["non-native speakers' English"] = { aliases = {"NNES", "NNSE"}, display = "[[non-native speaker]]s' English", regional_categories = "Non-native speakers'", } -- used exclusively by languages that use the "Jpan" script code labels["historical hiragana"] = { pos_categories = true, } -- used exclusively by languages that use the "Jpan" script code labels["historical katakana"] = { pos_categories = true, } -- applies to Japanese and Korean, etc., please do not confuse with "polite" labels["hormat"] = { glossary = "bentuk hormat", sense_categories = true, } -- for Ancient Greek labels["Homeric epithet"] = { display = "[[Homeric Greek|Homeric]] [[w:Epithets in Homer|epithet]]", omit_postComma = true, plain_categories = "Epic Greek", } -- applies to Japanese and Korean, etc. labels["merendah"] = { glossary = "bentuk merendah", sense_categories = true, } -- for Akkadian labels["in hendiadys"] = { aliases = {"hendiadys"}, display = "in {{w|hendiadys}}", pos_categories = "terms used in hendiadys", } labels["jenaka"] = { aliases = {"candaan", "gurauan"}, glossary = true, sense_categories = true, } labels["hiperbola"] = { glossary = true, pos_categories = "Hiperbola", } labels["lewah ralat"] = { glossary = true, pos_categories = "Bentuk lewah ralat", } labels["lewah asing"] = { glossary = true, sense_categories = true, } labels["imperial"] = { aliases = {"emperor", "empress"}, pos_categories = "royal terms", } labels["incel slang"] = { display = "[[incel]] {{glossary|slang}}", pos_categories = true, } labels["tak formal"] = { aliases = {"informal", "takformal"}, glossary = true, sense_categories = true, } labels["bentuk informal"] = { glossary = "informal", display = "informal", pos_categories = "Bentuk informal", } labels["slang internet"] = { display = "{{glossary|slang}} [[internet]]", pos_categories = "Slang internet", } labels["ironis"] = { display = "[[ironi|ironis]]", } -- Not the same as "journalism", which maps to a topical category (e.g. [[:Category:en:Journalism]], instead of [[:Category:English journalistic terms]]). labels["journalistic"] = { aliases = {"journalese"}, display = "[[journalistic]]", pos_categories = "journalistic terms", } labels["leet"] = { aliases = {"leetspeak"}, display = "[[leetspeak]]", pos_categories = "leetspeak", } labels["slang LGBTQ"] = { aliases = {"slang LGBT"}, display = "{{glossary|slang}} [[LGBTQ]]", pos_categories = "Slang LGBTQ", } labels["harfiah"] = { glossary = true, } labels["sastrawi"] = { aliases = {"sastra"}, glossary = true, sense_categories = true, } labels["bentuk sastrawi"] = { aliases = {"bentuk sastra"}, glossary = "sastrawi", display = "sastrawi", pos_categories = "Bentuk sastrawi", } --see also "short scale" labels["long scale"] = { display = "[[w:Long and short scales|long scale]]" } labels["loosely"] = { aliases = {"loose", "broadly", "broad"}, glossary = true, } labels["medical slang"] = { display = "[[medical]] {{glossary|slang}}", pos_categories = true, } -- for Awetí, Karajá, etc., where men and women use different words labels["men's speech"] = { aliases = {"male speech"}, glossary = "men's speech", pos_categories = "men's speech terms", } labels["metonimia"] = { glossary = true, pos_categories = "metonyms", } labels["military slang"] = { display = "[[military]] {{glossary|slang}}", pos_categories = true, } labels["minced oath"] = { display = "[[minced oath]]", pos_categories = "minced oaths", } labels["multiplicative"] = { aliases = {"multiplicative number", "multiplicative numeral"}, display = "[[multiplicative number]]", pos_categories = "multiplicative numbers", } labels["multiplicity slang"] = { display = "{{l|en|multiplicity|id=multiple personalities}} {{glossary|slang}}", pos_categories = true, } labels["nativising coinage"] = { display = "[[w:Linguistic purism in Korean|nativising coinage]]", pos_categories = "nativising coinages", } labels["naval slang"] = { aliases = {"navy slang"}, display = "[[naval]] {{glossary|slang}}", pos_categories = true, } labels["neologisme"] = { glossary = true, pos_categories = "Neologisme", } labels["neopronoun"] = { display = "[[neopronoun]]", -- pos_categories = {"neopronouns"}, } labels["tak lagi produktif"] = { aliases = {"tak produktif", "takproduktif"}, display = "tak lagi {{glossary|produktif}}", } labels["nonce word"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp? aliases = {"nonce"}, glossary = true, pos_categories = "nonce terms", } labels["tak baku"] = { aliases = {"nonbaku", "takbaku", "tidak baku"}, glossary = true, sense_categories = true, } labels["bentuk tak baku"] = { aliases = {"bentuk nonbaku", "bentuk tidak baku"}, glossary = "tak baku", display = "tak baku", pos_categories = "Bentuk tak baku", } labels["numismatic slang"] = { display = "[[numismatic]] {{glossary|slang}}", pos_categories = true, } labels["usang"] = { glossary = true, sense_categories = true, } labels["bentuk usang"] = { glossary = "usang", display = "usang", pos_categories = "Bentuk usang", } labels["umpatan"] = { glossary = true, sense_categories = true, } labels["officialese"] = { aliases = {"bureaucratic"}, display = "[[officialese]]", pos_categories = "officialese terms", } labels["Oxbridge slang"] = { display = "[[w:Oxbridge|Oxbridge]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = {"Cambridge University slang", "Oxford University slang"}, } labels["Oxford University slang"] = { aliases = {"University of Oxford slang", "Oxon slang"}, display = "[[w:University of Oxford|Oxford University]] {{glossary|slang}}", topical_categories = "Universities", plain_categories = true, } labels["puitis"] = { glossary = true, sense_categories = true, } labels["bentuk puitis"] = { glossary = "puitis", display = "puitis", pos_categories = "Bentuk puitis", } labels["sopan"] = { glossary = true, sense_categories = true, } labels["post-classical"] = { aliases = {"Post-classical", "post-Classical", "Post-Classical", "Postclassical", "postclassical"}, display = "post-Classical", regional_categories = true, } labels["prison slang"] = { display = "[[prison]] {{glossary|slang}}", pos_categories = true, } labels["proscribed"] = { glossary = true, pos_categories = "proscribed terms", } labels["puristic"] = { aliases = {"purism"}, Wikipedia = "Linguistic purism", pos_categories = "puristic terms", } labels["radio slang"] = { display = "[[radio]] {{glossary|slang}}", pos_categories = true, } labels["Reddit slang"] = { display = "[[Reddit]] {{glossary|slang}}", pos_categories = true, } labels["rare"] = { aliases = {"rare sense"}, glossary = true, sense_categories = true, } labels["rare form"] = { glossary = "rare", display = "rare", pos_categories = "rare forms", } labels["rare term"] = { display = "rare", -- see comments about "obsolete" pos_categories = "rare terms", } -- cf Cockney rhyming slang labels["rhyming slang"] = { display = "[[rhyming slang]]", pos_categories = true, } labels["religious slur"] = { aliases = {"sectarian slur"}, display = "[[religious]] [[slur]]", pos_categories = "religious slurs", } labels["retronym"] = { glossary = true, pos_categories = "retronyms", } labels["reverential"] = { -- should be "terms with X senses", leaving "X terms" to the term-context temp? display = "[[reverential]]", pos_categories = "reverential terms", } labels["royal"] = { aliases = {"regal"}, pos_categories = "royal terms", } labels["rustic"] = { glossary = true, -- should be "terms with X senses", leaving "X terms" to the term-context temp? aliases = {"rural"}, pos_categories = "rustic terms", } labels["sarcastic"] = { display = "[[sarcastic]]", pos_categories = "sarcastic terms", } labels["school slang"] = { aliases = {"public school slang"}, display = "[[school]] {{glossary|slang}}", pos_categories = true, } labels["self-deprecatory"] = { aliases = {"self-deprecating"}, display = "[[self-deprecatory]]", -- should be "terms with X senses", leaving "X terms" to the term-context temp? pos_categories = "self-deprecatory terms", } -- Swahili Sheng cant / argot -- should this be in a language-specific module? labels["Sheng"] = { Wikipedia = "Sheng slang", plain_categories = true, } labels["siglum"] = { aliases = {"sigla"}, glossary = true, pos_categories = "sigla", } --see also "long scale" labels["short scale"] = { display = "[[w:Long and short scales|short scale]]" } labels["slang"] = { glossary = true, pos_categories = true, } labels["solemn"] = { glossary = true, pos_categories = "solemn terms", } labels["Stenoscript"] = { aliases = {"stenoscript"}, display = "[[Stenoscript]]", pos_categories = "Stenoscript abbreviations", } labels["superseded"] = { glossary = true } labels["swear word"] = { aliases = {"profanity", "expletive"}, pos_categories = "swear words", } labels["syncopated"] = { aliases = {"syncope", "syncopic", "syncopation"}, glossary = true, pos_categories = "syncopic forms", } labels["synecdochically"] = { aliases = {"synecdochic", "synecdochical", "synecdoche"}, glossary = true, pos_categories = "synecdoches", } labels["technical"] = { display = "[[technical]]", pos_categories = "technical terms", } labels["telic"] = { glossary = true, } labels["text messaging"] = { aliases = {"texting"}, display = "[[text messaging]]", pos_categories = "text messaging slang", } labels["tone indicator"] = { display = "[[tone indicator]]", pos_categories = "tone indicators", } labels["trademark"] = { display = "[[trademark]]", pos_categories = "trademarks", } labels["transferred sense"] = { glossary = true, pos_categories = "terms with transferred senses", } labels["transferred senses"] = { display = "[[transferred sense#English|transferred senses]]", pos_categories = "terms with transferred senses", } labels["slang transgender"] = { aliases = {"slang trans"}, display = "{{glossary|slang}} [[transgender]]", pos_categories = "Slang transgender", } labels["Twitch-speak"] = { display = "[[Twitch-speak]]", pos_categories = true, } labels["uds."] = { display = "[[Appendix:Spanish pronouns#Ustedes and vosotros|used formally in Spain]]", } labels["uncommon"] = { glossary = true, sense_categories = true, } labels["uncommon form"] = { glossary = "uncommon", display = "uncommon", pos_categories = "uncommon forms", } labels["slang kampus"] = { aliases = {"slang mahasiswa", "slang universitas"}, display = "[[university]] {{glossary|slang}}", topical_categories = "perguruan tinggi", pos_categories = "Slang kampus", } labels["verlan"] = { glossary = true, plain_categories = true, } labels["very rare"] = { display = "very [[Appendix:Glossary#rare|rare]]", sense_categories = "rare", } labels["kasar"] = { aliases = {"vulgar"}, glossary = true, sense_categories = true, } labels["vesre"] = { Wikipedia = true, plain_categories = true, } labels["slang anak muda"] = { display = "{{glossary|slang}} [[anak muda]]", pos_categories = "Slang", } labels["2channel slang"] = { aliases = {"2channel", "2ch slang"}, display ="[[w:2channel|2channel]] {{glossary|slang}}", pos_categories = {"internet slang" , "2channel slang"}, } -- for Awetí, Karajá, etc., where men & women use different words labels["women's speech"] = { aliases = {"female speech"}, glossary = "women's speech", pos_categories = "women's speech terms", } return require("Module:labels").finalize_data(labels) ech8ojmsk2ioyswbe9g4l85bmbmfciz Modul:language-like 828 3721 26563 8058 2025-11-08T17:11:02Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26563 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local wikibase = mw.wikibase local category_name_has_suffix -- defined as export.categoryNameHasSuffix below local get_entity = wikibase.getEntity local get_entity_id_for_title = wikibase.getEntityIdForTitle local gsub = string.gsub 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 --[==[ 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 -- Implementation of getAliases() for languages, etymology languages, -- families, scripts and writing systems. function export.getAliases(self) local aliases = self._aliases if aliases == nil then aliases = (self._data or self).aliases or {} self._aliases = aliases end return aliases end -- Implementation of getVarieties() for languages, etymology languages, -- families, scripts and writing systems. If `flatten` is passed in, -- flatten down to a list of strings; otherwise, keep the structure. function export.getVarieties(self, flatten) local varieties = self._varieties if varieties == nil then varieties = (self._data or self).varieties or {} self._varieties = varieties end if not flatten then return varieties end local flattened_varieties = self._flattened_varieties if flattened_varieties == nil then flattened_varieties = table_flatten(varieties) self._flattened_varieties = flattened_varieties end return flattened_varieties 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 getAllNames() for languages, etymology languages, -- families, scripts and writing systems. If `notCanonical` is set, -- the canonical name will be excluded. function export.getAllNames(self) local all_names = self._allNames if all_names == nil then all_names = table_flatten{ self:getCanonicalName(), 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 local args = {...} for i = 2, n do if not types[args[i]] then return false end end return true end -- Implementation of template-callable getByCode() function for languages, -- etymology languages, families and scripts. `item` is the language, -- family or script in question; `args` is the arguments passed in by the -- module invocation; `extra_processing`, if specified, is a function of -- one argument (the requested property) and should return the value to -- be returned to the caller, or nil if the property isn't recognized. -- `extra_processing` is called after special-cased properties are handled -- and before general-purpose processing code that works for all string -- properties. function export.templateGetByCode(args, extra_processing) -- The item that the caller wanted to look up. local item, itemname, list = args[1], args[2] if itemname == "getAllNames" then list = item:getAllNames() elseif itemname == "getOtherNames" then list = item:getOtherNames() elseif itemname == "getAliases" then list = item:getAliases() elseif itemname == "getVarieties" then list = item:getVarieties(true) end if list then local index = args[3]; if index == "" then index = nil end index = tonumber(index or error("Numeric index of the desired item in the list (parameter 3) has not been specified.")) return list[index] or "" end if itemname == "getFamily" and item.getFamily then return item:getFamily():getCode() end if extra_processing then local retval = extra_processing(itemname) if retval then return retval end end if item[itemname] then local ret = item[itemname](item) if type(ret) == "string" then 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 -- 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 return true end category_name_has_suffix = export.categoryNameHasSuffix 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 return export j8libp1ojaglkz0xtnky24enrhkrp9l 26564 24229 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:language-like]] 24229 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local wikibase = mw.wikibase local category_name_has_suffix -- defined as export.categoryNameHasSuffix below local get_entity = wikibase.getEntity local get_entity_id_for_title = wikibase.getEntityIdForTitle local gsub = string.gsub 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 --[==[ 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 -- Implementation of getAliases() for languages, etymology languages, -- families, scripts and writing systems. function export.getAliases(self) local aliases = self._aliases if aliases == nil then aliases = (self._data or self).aliases or {} self._aliases = aliases end return aliases end -- Implementation of getVarieties() for languages, etymology languages, -- families, scripts and writing systems. If `flatten` is passed in, -- flatten down to a list of strings; otherwise, keep the structure. function export.getVarieties(self, flatten) local varieties = self._varieties if varieties == nil then varieties = (self._data or self).varieties or {} self._varieties = varieties end if not flatten then return varieties end local flattened_varieties = self._flattened_varieties if flattened_varieties == nil then flattened_varieties = table_flatten(varieties) self._flattened_varieties = flattened_varieties end return flattened_varieties 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 getAllNames() for languages, etymology languages, -- families, scripts and writing systems. If `notCanonical` is set, -- the canonical name will be excluded. function export.getAllNames(self) local all_names = self._allNames if all_names == nil then all_names = table_flatten{ self:getCanonicalName(), 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 local args = {...} for i = 2, n do if not types[args[i]] then return false end end return true end -- Implementation of template-callable getByCode() function for languages, -- etymology languages, families and scripts. `item` is the language, -- family or script in question; `args` is the arguments passed in by the -- module invocation; `extra_processing`, if specified, is a function of -- one argument (the requested property) and should return the value to -- be returned to the caller, or nil if the property isn't recognized. -- `extra_processing` is called after special-cased properties are handled -- and before general-purpose processing code that works for all string -- properties. function export.templateGetByCode(args, extra_processing) -- The item that the caller wanted to look up. local item, itemname, list = args[1], args[2] if itemname == "getAllNames" then list = item:getAllNames() elseif itemname == "getOtherNames" then list = item:getOtherNames() elseif itemname == "getAliases" then list = item:getAliases() elseif itemname == "getVarieties" then list = item:getVarieties(true) end if list then local index = args[3]; if index == "" then index = nil end index = tonumber(index or error("Numeric index of the desired item in the list (parameter 3) has not been specified.")) return list[index] or "" end if itemname == "getFamily" and item.getFamily then return item:getFamily():getCode() end if extra_processing then local retval = extra_processing(itemname) if retval then return retval end end if item[itemname] then local ret = item[itemname](item) if type(ret) == "string" then 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 -- 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 return true end category_name_has_suffix = export.categoryNameHasSuffix 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 return export j8libp1ojaglkz0xtnky24enrhkrp9l Modul:languages/data/3/b 828 3790 26612 8326 2025-11-08T19:46:26Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26612 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared local m = {} m["baa"] = { "Babatana", 2877785, "poz-ocw", "Latn", } m["bab"] = { "Bainouk-Gunyuño", 35508, "alv-bny", "Latn", } m["bac"] = { "Baduy", 3449885, "poz-msa", "Latn, Sund", ancestors = "osn", translit = { Sund = "Sund-translit" }, } m["bae"] = { "Baré", 3504087, "awd", "Latn", } m["baf"] = { "Nubaca", 36270, "nic-ymb", "Latn", } m["bag"] = { "Tuki", 36621, "nic-mba", "Latn", } m["bah"] = { "Bahamian Creole", 2669229, "crp", "Latn", ancestors = "en", } m["baj"] = { "Barakai", 3502030, "poz-cet", "Latn", } m["bal"] = { "Baluchi", 33049, "ira-nwi", "fa-Arab", } m["ban"] = { "Balinese", 33070, "poz-bss", "Latn, Bali", } m["bao"] = { "Waimaha", 2883738, "sai-tuc", "Latn", } m["bap"] = { "Bantawa", 56500, "sit-kic", "Krai, Deva", } m["bar"] = { "Bavarian", 29540, "gmw-hgm", "Latn", ancestors = "gmh", } m["bas"] = { "Basaa", 33093, "bnt-bsa", "Latn", } m["bau"] = { "Badanchi", 11001650, "nic-jrw", "Latn", } m["bav"] = { "Babungo", 34885, "nic-rnn", "Latn", } m["baw"] = { "Bambili-Bambui", 34880, "nic-nge", "Latn", } m["bax"] = { "Bamum", 35280, "nic-nun", "Latn, Bamu", } m["bay"] = { "Batuley", 8828787, "poz", "Latn", } m["bba"] = { "Baatonum", 34889, "alv-sav", "Latn", } m["bbb"] = { "Barai", 4858206, "ngf", "Latn", } m["bbc"] = { "Toba Batak", 33017, "btk", "Latn, Batk", } m["bbd"] = { "Bau", 4873415, "ngf-mad", "Latn", } m["bbe"] = { "Bangba", 34895, "nic-nke", "Latn", } m["bbf"] = { "Baibai", 56902, "paa", "Latn", } m["bbg"] = { "Barama", 34884, "bnt-sir", "Latn", } m["bbh"] = { "Bugan", 3033554, "mkh-pkn", "Latn", } m["bbi"] = { "Barombi", 34985, "bnt-bsa", "Latn", } m["bbj"] = { "Ghomala'", 35271, "bai", "Latn", } m["bbk"] = { "Babanki", 34790, "nic-rnc", "Latn", } m["bbl"] = { "Bats", 33259, "cau-nkh", "Geor", translit = "Geor-translit", override_translit = true, entry_name = { remove_diacritics = c.tilde .. c.macron .. c.breve, from = {"<sup>ნ</sup>"}, to = {"ნ"} }, } m["bbm"] = { -- name includes prefix "Babango", 34819, "bnt-bta", "Latn", } m["bbn"] = { "Uneapa", 7884126, "poz-ocw", "Latn", } m["bbo"] = { "Konabéré", 35371, "dmn-snb", "Latn", } m["bbp"] = { "West Central Banda", 7984377, "bad", "Latn", } m["bbq"] = { "Bamali", 34901, "nic-nun", "Latn", } m["bbr"] = { "Girawa", 5564185, "ngf-mad", "Latn", } m["bbs"] = { "Bakpinka", 3515061, "nic-ucr", "Latn", } m["bbt"] = { "Mburku", 3441324, "cdc-wst", "Latn", } m["bbu"] = { "Bakulung", 35580, "nic-jrn", "Latn", } m["bbv"] = { "Karnai", 6372803, "poz-ocw", "Latn", } m["bbw"] = { "Baba", 34822, "nic-nun", "Latn", } m["bbx"] = { -- cf bvb "Bubia", 34953, "nic-bds", "Latn", ancestors = "bvb", } m["bby"] = { "Befang", 34960, "nic-bds", "Latn", } m["bca"] = { "Central Bai", 12628803, "sit-bai", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bcb"] = { "Bainouk-Samik", 36390, "alv-bny", "Latn", } m["bcd"] = { "North Babar", 7054041, "poz-tim", "Latn", } m["bce"] = { "Bamenyam", 34968, "nic-nun", "Latn", } m["bcf"] = { "Bamu", 3503788, "paa-kiw", "Latn", } m["bcg"] = { "Baga Pokur", 31172660, "alv-nal", "Latn", } m["bch"] = { "Bariai", 2884502, "poz-ocw", "Latn", } m["bci"] = { "Baoule", 35107, "alv-ctn", "Latn", } m["bcj"] = { "Bardi", 3913852, "aus-nyu", "Latn", } m["bck"] = { "Bunaba", 580923, "aus-bub", "Latn", } m["bcl"] = { "Bikol Central", 33284, "phi", "Latn, Tglg", translit = { Tglg = "bcl-translit", }, override_translit = true, entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ, } }, sort_key = { Latn = "tl-sortkey", }, standardChars = { Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy" .. c.punc, }, } m["bcm"] = { "Banoni", 2882857, "poz-ocw", "Latn", } m["bcn"] = { "Bibaali", 34892, "alv-mye", "Latn", } m["bco"] = { "Kaluli", 6354586, "ngf", "Latn", } m["bcp"] = { "Bali", 3515074, "bnt-kbi", "Latn", } m["bcq"] = { "Bench", 35108, "omv", "Latn", } m["bcr"] = { "Babine-Witsuwit'en", 27864, "ath-nor", "Latn", } m["bcs"] = { "Kohumono", 35590, "nic-ucn", "Latn", } m["bct"] = { "Bendi", 8836662, "csu-mle", "Latn", } m["bcu"] = { "Biliau", 2874658, "poz-ocw", "Latn", } m["bcv"] = { "Shoo-Minda-Nye", 36548, "nic-jkn", "Latn", } m["bcw"] = { "Bana", 56272, "cdc-cbm", "Latn", } m["bcy"] = { "Bacama", 56274, "cdc-cbm", "Latn", } m["bcz"] = { "Bainouk-Gunyaamolo", 35506, "alv-bny", "Latn", } m["bda"] = { "Bayot", 35019, "alv-jol", "Latn", } m["bdb"] = { "Basap", 3504208, "poz-bnn", "Latn", } m["bdc"] = { "Emberá-Baudó", 11173166, "sai-chc", "Latn", } m["bdd"] = { "Bunama", 4997416, "poz-ocw", "Latn", } m["bde"] = { "Bade", 56239, "cdc-wst", "Latn", } m["bdf"] = { "Biage", 48037487, "ngf", "Latn", } m["bdg"] = { "Bonggi", 2910053, "poz-bnn", "Latn", } m["bdh"] = { "Tara Baka", 2880165, "csu-bbk", "Latn", } m["bdi"] = { "Burun", 35040, "sdv-niw", "Latn", } m["bdj"] = { "Bai", 34894, "nic-ser", "Latn", } m["bdk"] = { "Budukh", 35397, "cau-ssm", "Cyrl", translit = "cau-nec-translit", override_translit = true, display_text = {Cyrl = s["cau-Cyrl-displaytext"]}, entry_name = {Cyrl = s["cau-Cyrl-entryname"]}, } m["bdl"] = { "Indonesian Bajau", 2880038, "poz", "Latn", } m["bdm"] = { "Buduma", 56287, "cdc-cbm", "Latn", } m["bdn"] = { "Baldemu", 56280, "cdc-cbm", "Latn", } m["bdo"] = { "Morom", 759770, "csu-bgr", "Latn", } m["bdp"] = { "Bende", 8836490, "bnt", "Latn", } m["bdq"] = { "Bahnar", 32924, "mkh-ban", "Latn", } m["bdr"] = { "West Coast Bajau", 2880037, "poz-sbj", "Latn", } m["bds"] = { "Burunge", 56617, "cus-sou", "Latn", } m["bdt"] = { "Bokoto", 4938812, "gba-wes", "Latn", } m["bdu"] = { "Oroko", 36278, "bnt-saw", "Latn", } m["bdv"] = { "Bodo Parja", 8845881, "inc-eas", "Orya", } m["bdw"] = { "Baham", 3513309, "paa", "Latn", } m["bdx"] = { "Budong-Budong", 4985158, "poz-ssw", "Latn", } m["bdy"] = { "Bandjalang", 2980386, "aus-pam", "Latn", } m["bdz"] = { "Badeshi", 33028, "iir", "Arab, Latn", } m["bea"] = { "Beaver", 20826, "ath-nor", "Latn", } m["beb"] = { "Bebele", 34976, "bnt-btb", "Latn", } m["bec"] = { "Iceve-Maci", 35449, "nic-tvc", "Latn", } m["bed"] = { "Bedoanas", 4879330, "poz-hce", "Latn", } m["bee"] = { "Byangsi", 56904, "sit-alm", "Deva", } m["bef"] = { "Benabena", 2895638, "paa-kag", "Latn", } m["beg"] = { "Belait", 2894198, "poz-swa", "Latn", } m["beh"] = { "Biali", 34961, "nic-eov", "Latn", } m["bei"] = { "Bekati'", 3441683, "day", "Latn", } m["bej"] = { "Beja", 33025, "cus", "Arab, Latn", } m["bek"] = { "Bebeli", 4878430, "poz-ocw", "Latn", } m["bem"] = { "Bemba", 33052, "bnt-sbi", "Latn", } m["beo"] = { "Beami", 3504079, "paa", "Latn", } m["bep"] = { "Besoa", 8840465, "poz-kal", "Latn", } m["beq"] = { "Beembe", 3196320, "bnt-kng", "Latn", } m["bes"] = { "Besme", 289832, "alv-kim", "Latn", } m["bet"] = { "Guiberoua Bété", 11019185, "kro-bet", "Latn", } m["beu"] = { "Blagar", 4923846, "ngf", "Latn", } m["bev"] = { "Daloa Bété", 11155819, "kro-bet", "Latn", } m["bew"] = { "Betawi", 33014, "crp", "Latn", ancestors = "ms", } m["bex"] = { "Jur Modo", 56682, "csu-bbk", "Latn", } m["bey"] = { "Akuwagel", 3504170, "qfa-tor", "Latn", } m["bez"] = { "Kibena", 2502949, "bnt-bki", "Latn", } m["bfa"] = { "Bari", 35042, "sdv-bri", "Latn", } m["bfb"] = { "Pauri Bareli", 7155462, "inc-bhi", "Deva", } m["bfc"] = { "Panyi Bai", 12642165, "sit-nba", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bfd"] = { "Bafut", 34888, "nic-nge", "Latn", } m["bfe"] = { "Betaf", 4897329, "paa-tkw", "Latn", } m["bff"] = { "Bofi", 34914, "gba-eas", "Latn", } m["bfg"] = { "Busang Kayan", 9231909, "poz", "Latn", } m["bfh"] = { "Blafe", 12628007, "paa", "Latn", } m["bfi"] = { "British Sign Language", 33000, "sgn", "Latn", -- when documented } m["bfj"] = { "Bafanji", 34890, "nic-nun", "Latn", } m["bfk"] = { "Ban Khor Sign Language", 3441103, "sgn", } m["bfl"] = { "Banda-Ndélé", 34850, "bad-cnt", "Latn", } m["bfm"] = { "Mmen", 36132, "nic-rnc", "Latn", } m["bfn"] = { "Bunak", 35101, "ngf", "Latn", } m["bfo"] = { "Malba Birifor", 11150710, "nic-mre", "Latn", } m["bfp"] = { "Beba", 35050, "nic-nge", "Latn", } m["bfq"] = { "Badaga", 33205, "dra-kan", "Taml, Knda, Mlym", translit = { --Taml = "Taml-translit", Knda = "kn-translit", Mlym = "ml-translit", }, } m["bfr"] = { "Bazigar", 8829558, "inc", } m["bfs"] = { "Southern Bai", 12952250, "sit-bai", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bft"] = { "Balti", 33086, "sit-lab", "fa-Arab, Deva, Tibt", translit = { Tibt = "Tibt-translit", }, override_translit = "Tibt", display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = { ["fa-Arab"] = { from = {"هٔ", "ٱ"}, to = {"ه", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.kashida .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, }, Tibt = s["Tibt-entryname"] }, sort_key = {Tibt = "Tibt-sortkey"}, } m["bfu"] = { "Gahri", 5516952, "sit-whm", "Takr, Tibt", translit = {Tibt = "Tibt-translit"}, override_translit = true, display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = {Tibt = s["Tibt-entryname"]}, sort_key = {Tibt = "Tibt-sortkey"}, } m["bfw"] = { "Bondo", 2567942, "mun", "Orya", } m["bfx"] = { "Bantayanon", 16837866, "phi", "Latn", } m["bfy"] = { "Bagheli", 2356364, "inc-hie", "Deva", ancestors = "inc-oaw", translit = "hi-translit", } m["bfz"] = { "Mahasu Pahari", 6733460, "him", "Deva", translit = "hi-translit", } m["bga"] = { "Gwamhi-Wuri", 6707102, "nic-knn", "Latn", } m["bgb"] = { "Bobongko", 4935896, "poz-slb", "Latn", } m["bgc"] = { "Haryanvi", 33410, "inc-hiw", "Deva", translit = "hi-translit", } m["bgd"] = { "Rathwi Bareli", 7295692, "inc-bhi", "Deva", } m["bge"] = { "Bauria", 4873579, "inc-bhi", "Deva", } m["bgf"] = { "Bangandu", 34938, "gba-sou", "Latn", } m["bgg"] = { "Bugun", 3514220, "sit-khb", "Latn", } m["bgi"] = { "Giangan", 4842057, "phi", "Latn", } m["bgj"] = { "Bangolan", 34862, "nic-nun", "Latn", } m["bgk"] = { "Bit", 2904868, "mkh-pal", "Latn", -- also Hani? } m["bgl"] = { "Bo", 8845514, "mkh-vie", } m["bgo"] = { "Baga Koga", 35695, "alv-bag", "Latn", } m["bgq"] = { "Bagri", 2426319, "raj", "Deva", } m["bgr"] = { "Bawm Chin", 56765, "tbq-kuk", "Latn", } m["bgs"] = { "Tagabawa", 7675121, "mno", "Latn", } m["bgt"] = { "Bughotu", 2927723, "poz-sls", "Latn", } m["bgu"] = { "Mbongno", 36141, "nic-mmb", "Latn", } m["bgv"] = { "Warkay-Bipim", 4915439, "ngf", "Latn", } m["bgw"] = { "Bhatri", 8841054, "inc-eas", "Deva", } m["bgx"] = { "Balkan Gagauz Turkish", 2360396, "trk-ogz", "Latn", ancestors = "trk-oat", } m["bgy"] = { "Benggoi", 4887742, "poz-cma", "Latn", } m["bgz"] = { "Banggai", 3441692, "poz-slb", "Latn", } m["bha"] = { "Bharia", 4901287, "inc", "Deva", } m["bhb"] = { "Bhili", 33229, "inc-bhi", "Deva, Gujr", translit = { Deva = "hi-translit", Gujr = "gu-translit", }, } m["bhc"] = { "Biga", 2902375, "poz-hce", "Latn", } m["bhd"] = { "Bhadrawahi", 4900565, "him", "Arab, Deva", translit = {Deva = "hi-translit"}, } m["bhe"] = { "Bhaya", 8841168, "raj", } m["bhf"] = { "Odiai", 56690, "paa-kwm", "Latn", } m["bhg"] = { "Binandere", 3503802, "ngf", "Latn", } m["bhh"] = { "Bukhari", 56469, "ira-swi", "Cyrl, Hebr, Latn, fa-Arab", ancestors = "tg", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["bhi"] = { "Bhilali", 4901729, "inc-bhi", "Deva", } m["bhj"] = { "Bahing", 56442, "sit-kiw", "Deva, Latn", } m["bhl"] = { "Bimin", 4913743, "ngf-okk", "Latn", } m["bhm"] = { "Bathari", 2586893, "sem-sar", "Arab, Latn", } m["bhn"] = { "Bohtan Neo-Aramaic", 33230, "sem-nna", "Syrc", } m["bho"] = { "Bhojpuri", 33268, "inc-bih", "Deva, Kthi", wikimedia_codes = "bh", translit = { Deva = "bho-translit", Kthi = "bho-Kthi-translit", }, } m["bhp"] = { "Bima", 2796873, "poz-cet", "Latn", } m["bhq"] = { "Tukang Besi South", 12643975, "poz-mun", "Latn", } m["bhs"] = { "Buwal", 3515065, "cdc-cbm", "Latn", } m["bht"] = { "Bhattiyali", 4901452, "him", "Deva", } m["bhu"] = { "Bhunjia", 8841766, "inc-hal", "Deva, Orya", } m["bhv"] = { "Bahau", 3502039, "poz", "Latn", } m["bhw"] = { "Biak", 1961488, "poz-hce", "Latn", } m["bhx"] = { -- spurious? "Bhalay", 8840773, "inc", } m["bhy"] = { "Bhele", 4901671, "bnt-kbi", "Latn", } m["bhz"] = { "Bada", 4840520, "poz-kal", "Latn", } m["bia"] = { "Badimaya", 3442745, "aus-psw", "Latn", } m["bib"] = { "Bissa", 32934, "dmn-bbu", "Latn", } m["bic"] = { "Bikaru", 56342, "paa-eng", "Latn", } m["bid"] = { "Bidiyo", 56258, "cdc-est", "Latn", } m["bie"] = { "Bepour", 4890914, "ngf-mad", "Latn", } m["bif"] = { "Biafada", 35099, "alv-ten", "Latn", } m["big"] = { "Biangai", 8842027, "paa", "Latn", } m["bij"] = { "Kwanka", 35598, "nic-tar", "Latn", } m["bil"] = { "Bile", 34987, "nic-jrn", "Latn", } m["bim"] = { "Bimoba", 34971, "nic-grm", "Latn", } m["bin"] = { "Edo", 35375, "alv-eeo", "Latn", entry_name = {remove_diacritics = c.acute .. c.grave .. c.macron .. c.dgrave}, sort_key = { from = {"ẹ", "gb", "gh", "kh", "kp", "mw", "nw", "ny", "ọ", "rh", "rr", "vb"}, to = {"e" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "k" .. p[2], "m" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "r" .. p[1], "r" .. p[1], "v" .. p[1]} }, } m["bio"] = { "Nai", 3508074, "paa-kwm", "Latn", } m["bip"] = { "Bila", 2902626, "bnt-kbi", "Latn", } m["biq"] = { "Bipi", 2904312, "poz-aay", "Latn", } m["bir"] = { "Bisorio", 8844749, "paa-eng", "Latn", } m["bit"] = { "Berinomo", 56447, "paa-spk", "Latn", } m["biu"] = { "Biete", 4904687, "tbq-kuk", "Latn", } m["biv"] = { "Southern Birifor", 32859745, "nic-mre", "Latn", } m["biw"] = { "Kol (Cameroon)", 35582, "bnt-mka", "Latn", } m["bix"] = { "Bijori", 3450686, "mun", "Deva", } m["biy"] = { "Birhor", 3450469, "mun", "Deva", } m["biz"] = { "Baloi", 3450590, "bnt-ngn", "Latn", } m["bja"] = { "Budza", 3046889, "bnt-bun", "Latn", } m["bjb"] = { "Barngarla", 3439071, "aus-pam", "Latn", } m["bjc"] = { "Bariji", 4690919, "ngf", "Latn", } m["bje"] = { "Biao-Jiao Mien", 3503800, "hmx-mie", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bjf"] = { "Barzani Jewish Neo-Aramaic", 33234, "sem-nna", "Hebr", -- maybe others display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["bjg"] = { "Bidyogo", 35365, "alv-bak", "Latn", } m["bjh"] = { "Bahinemo", 56361, "paa-spk", "Latn", } m["bji"] = { "Burji", 34999, "cus-hec", "Latn, Ethi", } m["bjj"] = { "Kannauji", 2726867, "inc-hiw", "Deva", } m["bjk"] = { "Barok", 2884743, "poz-ocw", "Latn", } m["bjl"] = { "Bulu (New Guinea)", 4997162, "poz-ocw", "Latn", } m["bjm"] = { "Bajelani", 4848866, "ira-zgr", "Latn, Arab", ancestors = "hac", } m["bjn"] = { "Banjarese", 33151, "poz-mly", "Latn, Arab", } m["bjo"] = { "Mid-Southern Banda", 42303990, "bad-cnt", "Latn", } m["bjp"] = { "Fanamaket", 56704263, "poz-oce", "Latn", } m["bjr"] = { "Binumarien", 538364, "paa-kag", "Latn", } m["bjs"] = { "Bajan", 2524014, "crp", "Latn", ancestors = "en", } m["bjt"] = { "Balanta-Ganja", 19359034, "alv-bak", "Arab, Latn", } m["bju"] = { "Busuu", 35046, "nic-fru", "Latn", } m["bjv"] = { "Bedjond", 8829831, "csu-sar", "Latn", } m["bjw"] = { "Bakwé", 34899, "kro-ekr", "Latn", } m["bjx"] = { "Banao Itneg", 12627559, "phi", "Latn", } m["bjy"] = { "Bayali", 4874263, "aus-pam", "Latn", } m["bjz"] = { "Baruga", 2886189, "ngf", "Latn", } m["bka"] = { "Kyak", 35653, "alv-bwj", "Latn", } m["bkc"] = { "Baka", 34905, "nic-nkb", "Latn", } m["bkd"] = { "Binukid", 4914553, "mno", "Latn", } m["bkf"] = { "Beeke", 3441375, "bnt-kbi", "Latn", } m["bkg"] = { "Buraka", 35066, "nic-nkg", "Latn", } m["bkh"] = { "Bakoko", 34866, "bnt-bsa", "Latn", } m["bki"] = { "Baki", 11024697, "poz-vnc", "Latn", } m["bkj"] = { "Pande", 36263, "bnt-ngn", "Latn", } m["bkk"] = { -- written in Balti script "Brokskat", 2925988, "inc-shn", "Tibt, Arab", } m["bkl"] = { "Berik", 378743, "paa-tkw", "Latn", } m["bkm"] = { "Kom (Cameroon)", 1656595, "nic-rnc", "Latn", } m["bkn"] = { "Bukitan", 3446774, "poz-bnn", "Latn", } m["bko"] = { "Kwa'", 35567, "bai", "Latn", } m["bkp"] = { "Iboko", 35089, "bnt-ngn", "Latn", } m["bkq"] = { "Bakairí", 56846, "sai-pek", "Latn", } m["bkr"] = { "Bakumpai", 3436626, "poz-brw", "Latn", } m["bks"] = { "Masbate Sorsogon", 16113356, "phi", "Latn", } m["bkt"] = { "Boloki", 4144560, "bnt-zbi", "Latn", ancestors = "lse", } m["bku"] = { "Buhid", 1002956, "phi", "Latn, Buhd", translit = { Buhd = "bku-translit", }, override_translit = true, entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ, } }, sort_key = { Latn = "tl-sortkey", }, standardChars = { Latn = "AaBbKkDdEeFfGgHhIiLlMmNnOoPpRrSsTtUuWwYy" .. c.punc, }, } m["bkv"] = { "Bekwarra", 34954, "nic-ben", "Latn", } m["bkw"] = { "Bekwel", 34950, "bnt-bek", "Latn", } m["bkx"] = { "Baikeno", 11200640, "poz-tim", "Latn", } m["bky"] = { "Bokyi", 35087, "nic-ben", "Latn", } m["bkz"] = { "Bungku", 2928207, "poz-btk", "Latn", } m["bla"] = { "Blackfoot", 33060, "alg", "Latn, Cans", } m["blb"] = { "Bilua", 35003, "ngf", "Latn", } m["blc"] = { "Bella Coola", 977808, "sal", "Latn", } m["bld"] = { "Bolango", 3450578, "phi", "Latn", } m["ble"] = { "Balanta-Kentohe", 56789, "alv-bak", "Latn", } m["blf"] = { "Buol", 2928278, "phi", "Latn", } m["blg"] = { "Balau", 4850134, "poz-mly", "Latn", } m["blh"] = { "Kuwaa", 35579, "kro", "Latn", } m["bli"] = { "Bolia", 34910, "bnt-mon", "Latn", } m["blj"] = { "Bolongan", 9229310, "poz", "Latn", } m["blk"] = { "Pa'o Karen", 7121294, "kar", "Mymr", } m["bll"] = { "Biloxi", 2903780, "sio-ohv", "Latn", } m["blm"] = { "Beli", 56821, "csu-bbk", "Latn", } m["bln"] = { "Southern Catanduanes Bicolano", 7569754, "phi", "Latn", } m["blo"] = { "Anii", 34838, "alv-ntg", "Latn", } m["blp"] = { "Blablanga", 2905245, "poz-ocw", "Latn", } m["blq"] = { "Baluan-Pam", 2881675, "poz-aay", "Latn", } m["blr"] = { "Blang", 4925096, "mkh-pal", "Latn, Tale, Lana, Thai", sort_key = { -- FIXME: This needs to be converted into the current standardized format. from = {"[%pᪧๆ]", "[᩠ᩳ-᩿]", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", "[็-๎]", "([เแโใไ])([ก-ฮ])"}, to = {"", "", "ᩈᩈ", "ᩁ", "ᩃ", "ᨦ", "%1ᨮ", "%1ᨻ", "ᩣ", "", "%2%1"} }, } m["bls"] = { "Balaesang", 4849796, "poz", "Latn", } m["blt"] = { "Tai Dam", 56407, "tai-swe", "Tavt, Latn", --translit = "Tavt-translit", sort_key = { Tavt = { from = {"[꪿ꫀ꫁ꫂ]", "([ꪵꪶꪹꪻꪼ])([ꪀ-ꪯ])"}, to = {"", "%2%1"} }, }, } m["blv"] = { "Kibala", 4939959, "bnt-kmb", "Latn", } m["blw"] = { "Balangao", 4850033, "phi", "Latn", } m["blx"] = { "Mag-Indi Ayta", 1931221, "phi", "Latn", } m["bly"] = { "Notre", 11009194, "nic-wov", "Latn", } m["blz"] = { "Balantak", 4850053, "poz-slb", "Latn", } m["bma"] = { "Lame", 3913997, "nic-jrn", "Latn", } m["bmb"] = { "Bembe", 4885023, "bnt-lgb", "Latn", } m["bmc"] = { "Biem", 4904523, "poz-ocw", "Latn", } m["bmd"] = { "Baga Manduri", 35815, "alv-bag", "Latn", } m["bme"] = { "Limassa", 11004666, "nic-nkb", "Latn", } m["bmf"] = { "Bom", 35088, "alv-mel", "Latn", } m["bmg"] = { "Bamwe", 34867, "bnt-bun", "Latn", } m["bmh"] = { "Kein", 6383764, "ngf-mad", "Latn", } m["bmi"] = { "Bagirmi", 34903, "csu-bgr", "Latn", } m["bmj"] = { "Bote-Majhi", 9229570, "inc-eas", "Deva", ancestors = "bh", } m["bmk"] = { "Ghayavi", 5555976, "poz-ocw", "Latn", } m["bml"] = { "Bomboli", 35055, "bnt-ngn", "Latn", } m["bmn"] = { "Bina", 8843664, "poz-ocw", "Latn", } m["bmo"] = { "Bambalang", 34868, "nic-nun", "Latn", } m["bmp"] = { "Bulgebi", 4996380, "ngf-fin", "Latn", } m["bmq"] = { "Bomu", 35065, "nic-bwa", "Latn", } m["bmr"] = { "Muinane", 3027894, "sai-bor", "Latn", } m["bmt"] = { "Biao Mon", 8842159, "hmx-mie", } m["bmu"] = { "Somba-Siawari", 5000983, "ngf", "Latn", } m["bmv"] = { "Bum", 35058, "nic-rnc", "Latn", } m["bmw"] = { "Bomwali", 34984, "bnt-ndb", "Latn", } m["bmx"] = { "Baimak", 3450546, "ngf-mad", "Latn", } m["bmz"] = { "Baramu", 4858315, "ngf", "Latn", } m["bna"] = { "Bonerate", 4941729, "poz-mun", "Latn", } m["bnb"] = { "Bookan", 4943150, "poz-san", "Latn", } m["bnd"] = { "Banda", 3504147, "poz-cma", "Latn", } m["bne"] = { "Bintauna", 4914533, "phi", "Latn", } m["bnf"] = { "Masiwang", 6783305, "poz-cma", "Latn", } m["bng"] = { "Benga", 34952, "bnt-saw", "Latn", } m["bni"] = { "Bangi", 34936, "bnt-bmo", "Latn", } m["bnj"] = { "Eastern Tawbuid", 18757427, "phi", "Latn", } m["bnk"] = { "Bierebo", 2902029, "poz-vnc", "Latn", } m["bnl"] = { "Boon", 56616, "cus-eas", "Latn", } m["bnm"] = { "Batanga", 34979, "bnt-saw", "Latn", } m["bnn"] = { "Bunun", 56505, "map", "Latn", } m["bno"] = { "Asi", 29490, "phi", "Latn", } m["bnp"] = { "Bola", 4938876, "poz-ocw", "Latn", } m["bnq"] = { "Bantik", 2883521, "poz", "Latn", } m["bnr"] = { "Butmas-Tur", 2928942, "poz-vnn", "Latn", } m["bns"] = { "Bundeli", 56399, "inc-hiw", "Deva", translit = "hi-translit", } m["bnu"] = { "Bentong", 4890644, "poz-ssw", "Latn", } m["bnv"] = { "Beneraf", 4941733, "paa-tkw", "Latn", } m["bnw"] = { "Bisis", 56356, "paa-spk", "Latn", } m["bnx"] = { "Bangubangu", 3438330, "bnt-lbn", "Latn", } m["bny"] = { "Bintulu", 3450775, "poz-swa", "Latn", } m["bnz"] = { "Beezen", 35083, "nic-ykb", "Latn", } m["boa"] = { "Bora", 2375468, "sai-bor", "Latn", } m["bob"] = { "Aweer", 56526, "cus-som", "Latn", } m["boe"] = { "Mundabli", 36127, "nic-beb", "Latn", } m["bof"] = { "Bolon", 3913301, "dmn-emn", "Latn", } m["bog"] = { "Bamako Sign Language", 4853284, "sgn", } m["boh"] = { "North Boma", 35080, "bnt-bdz", "Latn", } m["boi"] = { "Barbareño", 56391, "nai-chu", "Latn", } m["boj"] = { "Anjam", 3504136, "ngf-mad", "Latn", } m["bok"] = { "Bonjo", 34942, "alv", "Latn", } m["bol"] = { "Bole", 3436680, "cdc-wst", "Latn", } m["bom"] = { "Berom", 35013, "nic-beo", "Latn", } m["bon"] = { "Bine", 4914077, "paa", "Latn", } m["boo"] = { "Tiemacèwè Bozo", 12643582, "dmn-snb", "Latn", -- and others? } m["bop"] = { "Bonkiman", 4942134, "ngf-fin", "Latn", } m["boq"] = { "Bogaya", 7207578, "ngf", "Latn", } m["bor"] = { "Borôro", 32986, "sai-mje", "Latn", } m["bot"] = { "Bongo", 2910067, "csu-bbk", "Latn", } m["bou"] = { "Bondei", 4941378, "bnt-seu", "Latn", } m["bov"] = { "Tuwuli", 36974, "alv-ktg", "Latn", } m["bow"] = { "Rema", 7311502, "paa", "Latn", } m["box"] = { "Buamu", 35157, "nic-bwa", "Latn", } m["boy"] = { "Bodo (Central Africa)", 4936715, "bnt-leb", "Latn", } m["boz"] = { "Tiéyaxo Bozo", 32860401, "dmn-snb", "Latn", } m["bpa"] = { "Daakaka", 1157729, "poz-vnc", "Latn", } m["bpd"] = { "Banda-Banda", 3450674, "bad-cnt", "Latn", } m["bpg"] = { "Bonggo", 4941860, "poz-ocw", "Latn", } m["bph"] = { "Botlikh", 56560, "cau-and", "Cyrl", translit = "cau-nec-translit", override_translit = true, display_text = {Cyrl = s["cau-Cyrl-displaytext"]}, entry_name = {Cyrl = s["cau-Cyrl-entryname"]}, } m["bpi"] = { "Bagupi", 3450697, "ngf-mad", "Latn", } m["bpj"] = { "Binji", 4914403, "bnt-lbn", "Latn", } m["bpk"] = { "Orowe", 7103905, "poz-cln", "Latn", } m["bpl"] = { "Broome Pearling Lugger Pidgin", 4975277, "crp", "Latn", ancestors = "ms", } m["bpm"] = { "Biyom", 4919327, "ngf-mad", "Latn", } m["bpn"] = { "Dzao Min", 3042189, "hmx-mie", } m["bpo"] = { "Anasi", 11207813, "paa-egb", "Latn", } m["bpp"] = { "Kaure", 20526532, "paa", "Latn", } m["bpq"] = { "Banda Malay", 12473442, "crp", "Latn", ancestors = "ms", } m["bpr"] = { "Koronadal Blaan", 16115430, "phi", "Latn", } m["bps"] = { "Sarangani Blaan", 16117272, "phi", "Latn", } m["bpt"] = { "Barrow Point", 2567916, "aus-pmn", "Latn", } m["bpu"] = { "Bongu", 4941930, "ngf-mad", "Latn", } m["bpv"] = { "Bian Marind", 8841889, "ngf", "Latn", } m["bpx"] = { "Palya Bareli", 7128872, "inc-bhi", "Deva", translit = "hi-translit", } m["bpy"] = { "Bishnupriya Manipuri", 37059, "inc-bas", "Beng", ancestors = "inc-obn", } m["bpz"] = { "Bilba", 8843362, "poz-tim", "Latn", } m["bqa"] = { "Tchumbuli", 11008162, "alv-ctn", "Latn", ancestors = "ak", } m["bqb"] = { "Bagusa", 4842178, "paa-tkw", "Latn", } m["bqc"] = { "Boko", 34983, "dmn-bbu", "Latn", } m["bqd"] = { "Bung", 3436612, "nic-bdn", "Latn", } m["bqf"] = { "Baga Kaloum", 3502293, "alv-bag", "Latn", } m["bqg"] = { "Bago-Kusuntu", 34878, "nic-gne", } m["bqh"] = { "Baima", 674990, "sit-qia", } m["bqi"] = { "Bakhtiari", 257829, "ira-swi", "fa-Arab", ancestors = "pal", } m["bqj"] = { "Bandial", 34872, "alv-jol", "Latn", } m["bqk"] = { "Banda-Mbrès", 3450724, "bad-cnt", "Latn", } m["bql"] = { "Bilakura", 4907504, "ngf-mad", "Latn", } m["bqm"] = { "Wumboko", 37051, "bnt-kpw", "Latn", } m["bqn"] = { "Bulgarian Sign Language", 3438325, "sgn", } m["bqo"] = { "Balo", 34865, "nic-grs", "Latn", } m["bqp"] = { "Busa", 35185, "dmn-bbu", "Latn", } m["bqq"] = { "Biritai", 56382, "paa-lkp", "Latn", } m["bqr"] = { "Burusu", 5001028, "poz-san", "Latn", } m["bqs"] = { "Bosngun", 56838, "paa", "Latn", } m["bqt"] = { "Bamukumbit", 35078, "nic-nge", "Latn", } m["bqu"] = { "Boguru", 3438444, "bnt-boa", "Latn", } m["bqv"] = { "Begbere-Ejar", 7194098, "nic-plc", "Latn", } m["bqw"] = { "Buru (Nigeria)", 1017152, "nic-bds", "Latn", } m["bqx"] = { "Baangi", 3450648, "nic-kam", "Latn", } m["bqy"] = { "Bengkala Sign Language", 3322119, "sgn", } m["bqz"] = { "Bakaka", 34855, "bnt-mne", "Latn", } m["bra"] = { "Braj", 35243, "inc-hiw", "Deva", translit = "hi-translit", } m["brb"] = { "Lave", 4957737, "mkh-ban", } m["brc"] = { "Berbice Creole Dutch", 35215, "crp", "Latn", ancestors = "nl", } m["brd"] = { "Baraamu", 56804, "sit-new", "Deva", } m["brf"] = { "Bera", 2896850, "bnt-kbi", "Latn", } m["brg"] = { "Baure", 2839722, "awd", "Latn", } m["brh"] = { "Brahui", 33202, "dra-nor", "ur-Arab, Latn", translit = {["ur-Arab"] = "ur-translit"}, entry_name = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, } m["bri"] = { "Mokpwe", 36428, "bnt-kpw", "Latn", } m["brj"] = { "Bieria", 4904607, "poz-vnc", "Latn", } m["brk"] = { "Birgid", 56823, "nub", "Latn", } m["brl"] = { "Birwa", 3501019, "bnt-sts", "Latn", } m["brm"] = { "Barambu", 34893, "znd", "Latn", } m["brn"] = { "Boruca", 4946773, "cba", "Latn", } m["bro"] = { "Brokkat", 56605, "sit-tib", "Tibt, Latn", translit = {Tibt = "Tibt-translit"}, override_translit = true, display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = {Tibt = s["Tibt-entryname"]}, sort_key = {Tibt = "Tibt-sortkey"}, } m["brp"] = { "Barapasi", 56995, "paa-egb", "Latn", } m["brq"] = { "Breri", 4961835, "paa", "Latn", } m["brr"] = { "Birao", 2904383, "poz-sls", "Latn", } m["brs"] = { "Baras", 8827053, "poz", "Latn", } m["brt"] = { "Bitare", 34946, "nic-tvn", "Latn", } m["bru"] = { "Eastern Bru", 16115463, "mkh-kat", "Latn, Laoo, Thai", sort_key = { Laoo = "Laoo-sortkey", Thai = "Thai-sortkey", }, } m["brv"] = { "Western Bru", 13018531, "mkh-kat", "Latn, Laoo, Thai", sort_key = { Laoo = "Laoo-sortkey", Thai = "Thai-sortkey", }, } m["brw"] = { "Bellari", 4883496, "dra-tlk", "Knda, Mlym", translit = { Knda = "kn-translit", Mlym = "ml-translit", }, } m["brx"] = { "Bodo (India)", 33223, "tbq-bdg", "Deva, Latn", translit = {Deva = "brx-translit"}, } m["bry"] = { "Burui", 5000976, "paa-spk", "Latn", } m["brz"] = { "Bilbil", 4907473, "poz-ocw", "Latn", } m["bsa"] = { "Abinomn", 56648, "qfa-iso", "Latn", } m["bsb"] = { "Brunei Bisaya", 3450611, "poz-san", "Latn", } m["bsc"] = { "Bassari", 35098, "alv-ten", "Latn", } m["bse"] = { "Wushi", 36973, "nic-rnn", "Latn", } m["bsf"] = { "Bauchi", 34974, "nic-shi", "Latn", } m["bsg"] = { "Bashkardi", 33030, "ira-swi", "fa-Arab, Latn", } m["bsh"] = { "Kamkata-viri", 2605045, "nur-nor", "Latn, Arab", } m["bsi"] = { "Bassossi", 34940, "bnt-mne", "Latn", } m["bsj"] = { "Bangwinji", 3446631, "alv-wjk", "Latn", } m["bsk"] = { "Burushaski", 216286, "qfa-iso", "Arab", entry_name = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, } m["bsl"] = { "Basa-Gumna", 4866150, "nic-bas", "Latn", } m["bsm"] = { "Busami", 5001255, "poz-hce", "Latn", } m["bsn"] = { "Barasana", 2883843, "sai-tuc", "Latn", } m["bso"] = { "Buso", 3441370, "cdc-est", "Latn", } m["bsp"] = { "Baga Sitemu", 36466, "alv-bag", "Latn", } m["bsq"] = { "Bassa", 34949, "kro-wkr", "Latn, Bass", } m["bsr"] = { "Bassa-Kontagora", 4866152, "nic-bas", "Latn", } m["bss"] = { "Akoose", 34806, "bnt-mne", "Latn", } m["bst"] = { "Basketo", 56531, "omv-ome", "Ethi", } m["bsu"] = { "Bahonsuai", 2879298, "poz-btk", "Latn", } m["bsv"] = { "Baga Sobané", 3450433, "alv-bag", "Latn", } m["bsw"] = { "Baiso", 56615, "cus-som", "Latn", } m["bsx"] = { "Yangkam", 36922, "nic-tar", "Latn", } m["bsy"] = { "Sabah Bisaya", 12641557, "poz-san", "Latn", } m["bta"] = { "Bata", 56254, "cdc-cbm", "Latn", } m["btc"] = { "Bati (Cameroon)", 34944, "nic-mbw", "Latn", } m["btd"] = { "Dairi Batak", 2891045, "btk", "Latn, Batk", } m["bte"] = { "Gamo-Ningi", 5520366, "nic-jer", "Latn", } m["btf"] = { "Birgit", 56302, "cdc-est", "Latn", } m["btg"] = { "Gagnoa Bété", 5005069, "kro-bet", "Latn", } m["bth"] = { "Biatah Bidayuh", 2900881, "day", "Latn", } m["bti"] = { "Burate", 56900, "paa-egb", "Latn", } m["btj"] = { "Bacanese Malay", 8828608, "poz-mly", "Latn", } m["btm"] = { "Mandailing Batak", 2891049, "btk", "Latn, Batk", } m["btn"] = { "Ratagnon", 13197, "phi", "Latn", } m["bto"] = { "Iriga Bicolano", 12633026, "phi", "Latn", } m["btp"] = { "Budibud", 4985086, "poz-ocw", "Latn", } m["btq"] = { "Batek", 860315, "mkh-asl", "Latn", } m["btr"] = { "Baetora", 2878874, "poz-vnn", "Latn", } m["bts"] = { "Simalungun Batak", 2891054, "btk", "Latn, Batk", } m["btt"] = { "Bete-Bendi", 4887064, "nic-ben", "Latn", } m["btu"] = { "Batu", 34964, "nic-tvn", "Latn", } m["btv"] = { "Bateri", 3812564, "inc-koh", "Deva", } m["btw"] = { "Butuanon", 5003156, "phi", "Latn", } m["btx"] = { "Karo Batak", 33012, "btk", "Latn, Batk", } m["bty"] = { "Bobot", 3446788, "poz-cma", "Latn", } m["btz"] = { "Alas-Kluet Batak", 2891042, "btk", "Latn, Batk", } m["bua"] = { "Buryat", 33120, "xgn-cen", "Cyrl, Mong, Latn", wikimedia_codes = "bxr", ancestors = "cmg", translit = { Cyrl = "bua-translit", Mong = "Mong-translit", }, override_translit = true, display_text = {Mong = s["Mong-displaytext"]}, entry_name = { Cyrl = {remove_diacritics = c.grave .. c.acute}, Mong = s["Mong-entryname"], }, sort_key = { Cyrl = { from = {"ё", "ө", "ү", "һ"}, to = {"е" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1]} }, }, } m["bub"] = { "Bua", 32928, "alv-bua", "Latn", } m["bud"] = { "Ntcham", 36266, "nic-grm", "Latn", } m["bue"] = { "Beothuk", 56234, nil, "Latn", } m["buf"] = { "Bushoong", 3449964, "bnt-bsh", "Latn", } m["bug"] = { "Buginese", 33190, "poz-ssw", "Bugi, Latn", } m["buh"] = { "Younuo Bunu", 56299, "hmn", "Latn", } m["bui"] = { "Bongili", 35084, "bnt-ngn", "Latn", } m["buj"] = { "Basa-Gurmana", 6432515, "nic-bas", "Latn", } m["buk"] = { "Bukawa", 35043, "poz-ocw", "Latn", } m["bum"] = { "Bulu (Cameroon)", 35028, "bnt-btb", "Latn", } m["bun"] = { "Sherbro", 36339, "alv-mel", "Latn", } m["buo"] = { "Terei", 56831, "paa-sbo", "Latn", } m["bup"] = { "Busoa", 5002001, "poz", "Latn", } m["buq"] = { "Brem", 4960502, "ngf", "Latn", } m["bus"] = { "Bokobaru", 9228931, "dmn-bbu", "Latn", } m["but"] = { "Bungain", 3450623, "qfa-tor", "Latn", } m["buu"] = { "Budu", 3450207, "bnt-nya", "Latn", } m["buv"] = { "Bun", 56351, "paa-yua", "Latn", } m["buw"] = { "Bubi", 35017, "bnt-tso", "Latn", } m["bux"] = { "Boghom", 3440412, "cdc-wst", "Latn", } m["buy"] = { "Mmani", 35061, "alv-mel", "Latn", } m["bva"] = { "Barein", 56285, "cdc-est", "Latn", } m["bvb"] = { "Bube", 35110, "nic-bds", "Latn", } m["bvc"] = { "Baelelea", 2878833, "poz-sls", "Latn", } m["bvd"] = { "Baeggu", 2878850, "poz-sls", "Latn", } m["bve"] = { "Berau Malay", 3915770, "poz-mly", "Latn", } m["bvf"] = { "Boor", 56250, "cdc-est", "Latn", } m["bvg"] = { "Bonkeng", 34958, "bnt-bbo", "Latn", } m["bvh"] = { "Bure", 56294, "cdc-wst", "Latn", } m["bvi"] = { "Belanda Viri", 35247, "nic-ser", "Latn", } m["bvj"] = { "Baan", 3515067, "nic-ogo", "Latn", } m["bvk"] = { "Bukat", 4986814, "poz-bnn", "Latn", } m["bvl"] = { "Bolivian Sign Language", 1783590, "sgn", "Latn", -- when documented } m["bvm"] = { "Bamunka", 34882, "nic-rnn", "Latn", } m["bvn"] = { "Buna", 3450516, "qfa-tor", "Latn", } m["bvo"] = { "Bolgo", 35038, "alv-bua", "Latn", } m["bvp"] = { "Bumang", 4997235, "mkh-pal", } m["bvq"] = { "Birri", 56514, "csu-bkr", "Latn", } m["bvr"] = { "Burarra", 4998124, "aus-arn", "Latn", } m["bvt"] = { "Bati (Indonesia)", 4869253, "poz-cma", "Latn", } m["bvu"] = { "Bukit Malay", 9230148, "poz-mly", "Latn", } m["bvv"] = { "Baniva", 3515198, "awd", "Latn", } m["bvw"] = { "Boga", 56262, "cdc-cbm", "Latn", } m["bvx"] = { "Babole", 35180, "bnt-ngn", "Latn", } m["bvy"] = { "Baybayanon", 16839275, "phi", "Latn", } m["bvz"] = { "Bauzi", 56360, "paa-egb", "Latn", } m["bwa"] = { "Bwatoo", 9232446, "poz-cln", "Latn", } m["bwb"] = { "Namosi-Naitasiri-Serua", 3130290, "poz-pcc", "Latn", } m["bwc"] = { "Bwile", 3447440, "bnt-sbi", "Latn", } m["bwd"] = { "Bwaidoka", 2929111, "poz-ocw", "Latn", } m["bwe"] = { "Bwe Karen", 56994, "kar", "Mymr, Latn", } m["bwf"] = { "Boselewa", 4947229, "poz-ocw", "Latn", } m["bwg"] = { "Barwe", 8826802, "bnt-sna", "Latn", } m["bwh"] = { "Bishuo", 34973, "nic-fru", "Latn", } m["bwi"] = { "Baniwa", 3501735, "awd-nwk", "Latn", } m["bwj"] = { "Láá Láá Bwamu", 11017275, "nic-bwa", "Latn", } m["bwk"] = { "Bauwaki", 4873607, "ngf", "Latn", } m["bwl"] = { "Bwela", 5003678, "bnt-bun", "Latn", } m["bwm"] = { "Biwat", 56352, "paa-yua", "Latn", } m["bwn"] = { "Wunai Bunu", 56452, "hmn", } m["bwo"] = { "Shinasha", 56260, "omv-gon", "Latn", } m["bwp"] = { "Mandobo Bawah", 12636155, "ngf", "Latn", } m["bwq"] = { "Southern Bobo", 11001714, "dmn-snb", "Latn", } m["bwr"] = { "Bura", 56552, "cdc-cbm", "Latn", } m["bws"] = { "Bomboma", 9229429, "bnt-bun", "Latn", } m["bwt"] = { "Bafaw", 34853, "bnt-bbo", "Latn", } m["bwu"] = { "Buli (Ghana)", 35085, "nic-buk", "Latn", } m["bww"] = { "Bwa", 3515058, "bnt-bta", "Latn", } m["bwx"] = { "Bu-Nao Bunu", 56411, "hmn", "Latn", } m["bwy"] = { "Cwi Bwamu", 11150714, "nic-bwa", "Latn", } m["bwz"] = { "Bwisi", 35067, "bnt-sir", "Latn", } m["bxa"] = { "Bauro", 2892068, "poz-sls", "Latn", } m["bxb"] = { "Belanda Bor", 56678, "sdv-lon", "Latn", } m["bxc"] = { "Molengue", 13345, "bnt-kel", "Latn", } m["bxd"] = { "Pela", 57000, "tbq-brm", } m["bxe"] = { "Ongota", 36344, nil, "Latn", } m["bxf"] = { "Bilur", 2903788, "poz-ocw", "Latn", } m["bxg"] = { "Bangala", 34989, "bnt-bmo", "Latn", } m["bxh"] = { "Buhutu", 4986329, "poz-ocw", "Latn", } m["bxi"] = { "Pirlatapa", 10632195, "aus-kar", "Latn", } m["bxj"] = { "Bayungu", 10427485, "aus-psw", "Latn", } m["bxk"] = { "Bukusu", 32930, "bnt-msl", "Latn", } m["bxl"] = { "Jalkunan", 11009787, "dmn-jje", "Latn", } m["bxn"] = { "Burduna", 4998313, "aus-psw", "Latn", } m["bxo"] = { "Barikanchi", 3450802, "crp", "Latn", ancestors = "ha", } m["bxp"] = { "Bebil", 34941, "bnt-btb", "Latn", } m["bxq"] = { "Beele", 56238, "cdc-wst", "Latn", } m["bxs"] = { "Busam", 35189, "nic-grs", "Latn", } m["bxv"] = { "Berakou", 56796, "csu-bgr", "Latn", } m["bxw"] = { "Banka", 3438402, "dmn-smg", "Latn", } m["bxz"] = { "Binahari", 4913840, "ngf", "Latn", } m["bya"] = { "Palawan Batak", 3450443, "phi", "Tagb", } m["byb"] = { "Bikya", 33257, "nic-fru", "Latn", } m["byc"] = { "Ubaghara", 36625, "nic-ucn", "Latn", } m["byd"] = { "Benyadu'", 11173588, "day", "Latn", } m["bye"] = { "Pouye", 7235814, "paa-spk", "Latn", } m["byf"] = { "Bete", 32932, "nic-ykb", "Latn", } m["byg"] = { "Baygo", 56836, "sdv-daj", "Latn", } m["byh"] = { "Bujhyal", 56317, "sit-gma", "Deva", } m["byi"] = { "Buyu", 5003401, "bnt-nyb", "Latn", } m["byj"] = { "Binawa", 4913807, "nic-kau", "Latn", } m["byk"] = { "Biao", 4902547, "qfa-tak", "Latn", -- also Hani? } m["byl"] = { "Bayono", 3503856, "ngf", "Latn", } m["bym"] = { "Bidyara", 8842355, "aus-pam", "Latn", } m["byn"] = { "Blin", 56491, "cus-cen", "Ethi, Latn", translit = {Ethi = "Ethi-translit"}, } m["byo"] = { "Biyo", 56848, "tbq-bka", "Latn, Hani", sort_key = {Hani = "Hani-sortkey"}, } m["byp"] = { "Bumaji", 4997234, "nic-ben", "Latn", } m["byq"] = { "Basay", 716647, "map", "Latn", } m["byr"] = { "Baruya", 3450812, "ngf", "Latn", } m["bys"] = { "Burak", 4998097, "alv-bwj", "Latn", } m["byt"] = { "Berti", 35008, "ssa-sah", "Latn", } m["byv"] = { "Medumba", 36019, "bai", "Latn", } m["byw"] = { "Belhariya", 32961, "sit-kie", "Deva", } m["byx"] = { "Qaqet", 3503009, "paa-bng", "Latn", } m["byz"] = { "Banaro", 56858, "paa", "Latn", } m["bza"] = { "Bandi", 34912, "dmn-msw", "Latn", } m["bzb"] = { "Andio", 4754487, "poz-slb", "Latn", } m["bzd"] = { "Bribri", 28400, "cba", "Latn", } m["bze"] = { "Jenaama Bozo", 10950633, "dmn-snb", "Latn", } m["bzf"] = { "Boikin", 56829, "paa-spk", "Latn", } m["bzg"] = { "Babuza", 716615, "map", "Latn", } m["bzh"] = { "Mapos Buang", 2927370, "poz-ocw", "Latn", } m["bzi"] = { "Bisu", 56852, "tbq-bis", "Latn, Thai", sort_key = {Thai = "Thai-sortkey"}, } m["bzj"] = { "Belizean Creole", 1363055, "crp", "Latn", ancestors = "en", } m["bzk"] = { "Nicaraguan Creole", 3504097, "crp", "Latn", ancestors = "en", } m["bzl"] = { -- supposedly also called "Bolano", but I can find no evidence of that "Boano (Sulawesi)", 4931258, "poz", "Latn", } m["bzm"] = { "Bolondo", 35071, "bnt-bun", "Latn", } m["bzn"] = { "Boano (Maluku)", 4931255, "poz-cma", "Latn", } m["bzo"] = { "Bozaba", 4952785, "bnt-ngn", "Latn", } m["bzp"] = { "Kemberano", 12634399, "ngf-sbh", "Latn", } m["bzq"] = { "Buli (Indonesia)", 2927952, "poz-hce", "Latn", } m["bzr"] = { "Biri", 4087011, "aus-pam", "Latn", } m["bzs"] = { "Brazilian Sign Language", 3436689, "sgn", "Latn", } m["bzu"] = { "Burmeso", 56746, "paa-wpa", "Latn", } m["bzv"] = { "Bebe", 34977, "nic-bbe", "Latn", } m["bzw"] = { "Basa", 34898, "nic-bas", "Latn", } m["bzx"] = { "Hainyaxo Bozo", 11159536, "dmn-snb", "Latn", } m["bzy"] = { "Obanliku", 36276, "nic-ben", "Latn", } m["bzz"] = { "Evant", 35259, "nic-tvc", "Latn", } return require("Module:languages").finalizeData(m, "language") 83s5kxpy1ioveq2cp8a0muuv752van6 26613 26612 2026-07-08T01:43:59Z Sibiru45 115 1 ralatan matan [[:id:Modul:languages/data/3/b]] 26612 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared local m = {} m["baa"] = { "Babatana", 2877785, "poz-ocw", "Latn", } m["bab"] = { "Bainouk-Gunyuño", 35508, "alv-bny", "Latn", } m["bac"] = { "Baduy", 3449885, "poz-msa", "Latn, Sund", ancestors = "osn", translit = { Sund = "Sund-translit" }, } m["bae"] = { "Baré", 3504087, "awd", "Latn", } m["baf"] = { "Nubaca", 36270, "nic-ymb", "Latn", } m["bag"] = { "Tuki", 36621, "nic-mba", "Latn", } m["bah"] = { "Bahamian Creole", 2669229, "crp", "Latn", ancestors = "en", } m["baj"] = { "Barakai", 3502030, "poz-cet", "Latn", } m["bal"] = { "Baluchi", 33049, "ira-nwi", "fa-Arab", } m["ban"] = { "Balinese", 33070, "poz-bss", "Latn, Bali", } m["bao"] = { "Waimaha", 2883738, "sai-tuc", "Latn", } m["bap"] = { "Bantawa", 56500, "sit-kic", "Krai, Deva", } m["bar"] = { "Bavarian", 29540, "gmw-hgm", "Latn", ancestors = "gmh", } m["bas"] = { "Basaa", 33093, "bnt-bsa", "Latn", } m["bau"] = { "Badanchi", 11001650, "nic-jrw", "Latn", } m["bav"] = { "Babungo", 34885, "nic-rnn", "Latn", } m["baw"] = { "Bambili-Bambui", 34880, "nic-nge", "Latn", } m["bax"] = { "Bamum", 35280, "nic-nun", "Latn, Bamu", } m["bay"] = { "Batuley", 8828787, "poz", "Latn", } m["bba"] = { "Baatonum", 34889, "alv-sav", "Latn", } m["bbb"] = { "Barai", 4858206, "ngf", "Latn", } m["bbc"] = { "Toba Batak", 33017, "btk", "Latn, Batk", } m["bbd"] = { "Bau", 4873415, "ngf-mad", "Latn", } m["bbe"] = { "Bangba", 34895, "nic-nke", "Latn", } m["bbf"] = { "Baibai", 56902, "paa", "Latn", } m["bbg"] = { "Barama", 34884, "bnt-sir", "Latn", } m["bbh"] = { "Bugan", 3033554, "mkh-pkn", "Latn", } m["bbi"] = { "Barombi", 34985, "bnt-bsa", "Latn", } m["bbj"] = { "Ghomala'", 35271, "bai", "Latn", } m["bbk"] = { "Babanki", 34790, "nic-rnc", "Latn", } m["bbl"] = { "Bats", 33259, "cau-nkh", "Geor", translit = "Geor-translit", override_translit = true, entry_name = { remove_diacritics = c.tilde .. c.macron .. c.breve, from = {"<sup>ნ</sup>"}, to = {"ნ"} }, } m["bbm"] = { -- name includes prefix "Babango", 34819, "bnt-bta", "Latn", } m["bbn"] = { "Uneapa", 7884126, "poz-ocw", "Latn", } m["bbo"] = { "Konabéré", 35371, "dmn-snb", "Latn", } m["bbp"] = { "West Central Banda", 7984377, "bad", "Latn", } m["bbq"] = { "Bamali", 34901, "nic-nun", "Latn", } m["bbr"] = { "Girawa", 5564185, "ngf-mad", "Latn", } m["bbs"] = { "Bakpinka", 3515061, "nic-ucr", "Latn", } m["bbt"] = { "Mburku", 3441324, "cdc-wst", "Latn", } m["bbu"] = { "Bakulung", 35580, "nic-jrn", "Latn", } m["bbv"] = { "Karnai", 6372803, "poz-ocw", "Latn", } m["bbw"] = { "Baba", 34822, "nic-nun", "Latn", } m["bbx"] = { -- cf bvb "Bubia", 34953, "nic-bds", "Latn", ancestors = "bvb", } m["bby"] = { "Befang", 34960, "nic-bds", "Latn", } m["bca"] = { "Central Bai", 12628803, "sit-bai", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bcb"] = { "Bainouk-Samik", 36390, "alv-bny", "Latn", } m["bcd"] = { "North Babar", 7054041, "poz-tim", "Latn", } m["bce"] = { "Bamenyam", 34968, "nic-nun", "Latn", } m["bcf"] = { "Bamu", 3503788, "paa-kiw", "Latn", } m["bcg"] = { "Baga Pokur", 31172660, "alv-nal", "Latn", } m["bch"] = { "Bariai", 2884502, "poz-ocw", "Latn", } m["bci"] = { "Baoule", 35107, "alv-ctn", "Latn", } m["bcj"] = { "Bardi", 3913852, "aus-nyu", "Latn", } m["bck"] = { "Bunaba", 580923, "aus-bub", "Latn", } m["bcl"] = { "Bikol Central", 33284, "phi", "Latn, Tglg", translit = { Tglg = "bcl-translit", }, override_translit = true, entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ, } }, sort_key = { Latn = "tl-sortkey", }, standardChars = { Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy" .. c.punc, }, } m["bcm"] = { "Banoni", 2882857, "poz-ocw", "Latn", } m["bcn"] = { "Bibaali", 34892, "alv-mye", "Latn", } m["bco"] = { "Kaluli", 6354586, "ngf", "Latn", } m["bcp"] = { "Bali", 3515074, "bnt-kbi", "Latn", } m["bcq"] = { "Bench", 35108, "omv", "Latn", } m["bcr"] = { "Babine-Witsuwit'en", 27864, "ath-nor", "Latn", } m["bcs"] = { "Kohumono", 35590, "nic-ucn", "Latn", } m["bct"] = { "Bendi", 8836662, "csu-mle", "Latn", } m["bcu"] = { "Biliau", 2874658, "poz-ocw", "Latn", } m["bcv"] = { "Shoo-Minda-Nye", 36548, "nic-jkn", "Latn", } m["bcw"] = { "Bana", 56272, "cdc-cbm", "Latn", } m["bcy"] = { "Bacama", 56274, "cdc-cbm", "Latn", } m["bcz"] = { "Bainouk-Gunyaamolo", 35506, "alv-bny", "Latn", } m["bda"] = { "Bayot", 35019, "alv-jol", "Latn", } m["bdb"] = { "Basap", 3504208, "poz-bnn", "Latn", } m["bdc"] = { "Emberá-Baudó", 11173166, "sai-chc", "Latn", } m["bdd"] = { "Bunama", 4997416, "poz-ocw", "Latn", } m["bde"] = { "Bade", 56239, "cdc-wst", "Latn", } m["bdf"] = { "Biage", 48037487, "ngf", "Latn", } m["bdg"] = { "Bonggi", 2910053, "poz-bnn", "Latn", } m["bdh"] = { "Tara Baka", 2880165, "csu-bbk", "Latn", } m["bdi"] = { "Burun", 35040, "sdv-niw", "Latn", } m["bdj"] = { "Bai", 34894, "nic-ser", "Latn", } m["bdk"] = { "Budukh", 35397, "cau-ssm", "Cyrl", translit = "cau-nec-translit", override_translit = true, display_text = {Cyrl = s["cau-Cyrl-displaytext"]}, entry_name = {Cyrl = s["cau-Cyrl-entryname"]}, } m["bdl"] = { "Indonesian Bajau", 2880038, "poz", "Latn", } m["bdm"] = { "Buduma", 56287, "cdc-cbm", "Latn", } m["bdn"] = { "Baldemu", 56280, "cdc-cbm", "Latn", } m["bdo"] = { "Morom", 759770, "csu-bgr", "Latn", } m["bdp"] = { "Bende", 8836490, "bnt", "Latn", } m["bdq"] = { "Bahnar", 32924, "mkh-ban", "Latn", } m["bdr"] = { "West Coast Bajau", 2880037, "poz-sbj", "Latn", } m["bds"] = { "Burunge", 56617, "cus-sou", "Latn", } m["bdt"] = { "Bokoto", 4938812, "gba-wes", "Latn", } m["bdu"] = { "Oroko", 36278, "bnt-saw", "Latn", } m["bdv"] = { "Bodo Parja", 8845881, "inc-eas", "Orya", } m["bdw"] = { "Baham", 3513309, "paa", "Latn", } m["bdx"] = { "Budong-Budong", 4985158, "poz-ssw", "Latn", } m["bdy"] = { "Bandjalang", 2980386, "aus-pam", "Latn", } m["bdz"] = { "Badeshi", 33028, "iir", "Arab, Latn", } m["bea"] = { "Beaver", 20826, "ath-nor", "Latn", } m["beb"] = { "Bebele", 34976, "bnt-btb", "Latn", } m["bec"] = { "Iceve-Maci", 35449, "nic-tvc", "Latn", } m["bed"] = { "Bedoanas", 4879330, "poz-hce", "Latn", } m["bee"] = { "Byangsi", 56904, "sit-alm", "Deva", } m["bef"] = { "Benabena", 2895638, "paa-kag", "Latn", } m["beg"] = { "Belait", 2894198, "poz-swa", "Latn", } m["beh"] = { "Biali", 34961, "nic-eov", "Latn", } m["bei"] = { "Bekati'", 3441683, "day", "Latn", } m["bej"] = { "Beja", 33025, "cus", "Arab, Latn", } m["bek"] = { "Bebeli", 4878430, "poz-ocw", "Latn", } m["bem"] = { "Bemba", 33052, "bnt-sbi", "Latn", } m["beo"] = { "Beami", 3504079, "paa", "Latn", } m["bep"] = { "Besoa", 8840465, "poz-kal", "Latn", } m["beq"] = { "Beembe", 3196320, "bnt-kng", "Latn", } m["bes"] = { "Besme", 289832, "alv-kim", "Latn", } m["bet"] = { "Guiberoua Bété", 11019185, "kro-bet", "Latn", } m["beu"] = { "Blagar", 4923846, "ngf", "Latn", } m["bev"] = { "Daloa Bété", 11155819, "kro-bet", "Latn", } m["bew"] = { "Betawi", 33014, "crp", "Latn", ancestors = "ms", } m["bex"] = { "Jur Modo", 56682, "csu-bbk", "Latn", } m["bey"] = { "Akuwagel", 3504170, "qfa-tor", "Latn", } m["bez"] = { "Kibena", 2502949, "bnt-bki", "Latn", } m["bfa"] = { "Bari", 35042, "sdv-bri", "Latn", } m["bfb"] = { "Pauri Bareli", 7155462, "inc-bhi", "Deva", } m["bfc"] = { "Panyi Bai", 12642165, "sit-nba", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bfd"] = { "Bafut", 34888, "nic-nge", "Latn", } m["bfe"] = { "Betaf", 4897329, "paa-tkw", "Latn", } m["bff"] = { "Bofi", 34914, "gba-eas", "Latn", } m["bfg"] = { "Busang Kayan", 9231909, "poz", "Latn", } m["bfh"] = { "Blafe", 12628007, "paa", "Latn", } m["bfi"] = { "British Sign Language", 33000, "sgn", "Latn", -- when documented } m["bfj"] = { "Bafanji", 34890, "nic-nun", "Latn", } m["bfk"] = { "Ban Khor Sign Language", 3441103, "sgn", } m["bfl"] = { "Banda-Ndélé", 34850, "bad-cnt", "Latn", } m["bfm"] = { "Mmen", 36132, "nic-rnc", "Latn", } m["bfn"] = { "Bunak", 35101, "ngf", "Latn", } m["bfo"] = { "Malba Birifor", 11150710, "nic-mre", "Latn", } m["bfp"] = { "Beba", 35050, "nic-nge", "Latn", } m["bfq"] = { "Badaga", 33205, "dra-kan", "Taml, Knda, Mlym", translit = { --Taml = "Taml-translit", Knda = "kn-translit", Mlym = "ml-translit", }, } m["bfr"] = { "Bazigar", 8829558, "inc", } m["bfs"] = { "Southern Bai", 12952250, "sit-bai", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bft"] = { "Balti", 33086, "sit-lab", "fa-Arab, Deva, Tibt", translit = { Tibt = "Tibt-translit", }, override_translit = "Tibt", display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = { ["fa-Arab"] = { from = {"هٔ", "ٱ"}, to = {"ه", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.kashida .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef, }, Tibt = s["Tibt-entryname"] }, sort_key = {Tibt = "Tibt-sortkey"}, } m["bfu"] = { "Gahri", 5516952, "sit-whm", "Takr, Tibt", translit = {Tibt = "Tibt-translit"}, override_translit = true, display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = {Tibt = s["Tibt-entryname"]}, sort_key = {Tibt = "Tibt-sortkey"}, } m["bfw"] = { "Bondo", 2567942, "mun", "Orya", } m["bfx"] = { "Bantayanon", 16837866, "phi", "Latn", } m["bfy"] = { "Bagheli", 2356364, "inc-hie", "Deva", ancestors = "inc-oaw", translit = "hi-translit", } m["bfz"] = { "Mahasu Pahari", 6733460, "him", "Deva", translit = "hi-translit", } m["bga"] = { "Gwamhi-Wuri", 6707102, "nic-knn", "Latn", } m["bgb"] = { "Bobongko", 4935896, "poz-slb", "Latn", } m["bgc"] = { "Haryanvi", 33410, "inc-hiw", "Deva", translit = "hi-translit", } m["bgd"] = { "Rathwi Bareli", 7295692, "inc-bhi", "Deva", } m["bge"] = { "Bauria", 4873579, "inc-bhi", "Deva", } m["bgf"] = { "Bangandu", 34938, "gba-sou", "Latn", } m["bgg"] = { "Bugun", 3514220, "sit-khb", "Latn", } m["bgi"] = { "Giangan", 4842057, "phi", "Latn", } m["bgj"] = { "Bangolan", 34862, "nic-nun", "Latn", } m["bgk"] = { "Bit", 2904868, "mkh-pal", "Latn", -- also Hani? } m["bgl"] = { "Bo", 8845514, "mkh-vie", } m["bgo"] = { "Baga Koga", 35695, "alv-bag", "Latn", } m["bgq"] = { "Bagri", 2426319, "raj", "Deva", } m["bgr"] = { "Bawm Chin", 56765, "tbq-kuk", "Latn", } m["bgs"] = { "Tagabawa", 7675121, "mno", "Latn", } m["bgt"] = { "Bughotu", 2927723, "poz-sls", "Latn", } m["bgu"] = { "Mbongno", 36141, "nic-mmb", "Latn", } m["bgv"] = { "Warkay-Bipim", 4915439, "ngf", "Latn", } m["bgw"] = { "Bhatri", 8841054, "inc-eas", "Deva", } m["bgx"] = { "Balkan Gagauz Turkish", 2360396, "trk-ogz", "Latn", ancestors = "trk-oat", } m["bgy"] = { "Benggoi", 4887742, "poz-cma", "Latn", } m["bgz"] = { "Banggai", 3441692, "poz-slb", "Latn", } m["bha"] = { "Bharia", 4901287, "inc", "Deva", } m["bhb"] = { "Bhili", 33229, "inc-bhi", "Deva, Gujr", translit = { Deva = "hi-translit", Gujr = "gu-translit", }, } m["bhc"] = { "Biga", 2902375, "poz-hce", "Latn", } m["bhd"] = { "Bhadrawahi", 4900565, "him", "Arab, Deva", translit = {Deva = "hi-translit"}, } m["bhe"] = { "Bhaya", 8841168, "raj", } m["bhf"] = { "Odiai", 56690, "paa-kwm", "Latn", } m["bhg"] = { "Binandere", 3503802, "ngf", "Latn", } m["bhh"] = { "Bukhari", 56469, "ira-swi", "Cyrl, Hebr, Latn, fa-Arab", ancestors = "tg", display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["bhi"] = { "Bhilali", 4901729, "inc-bhi", "Deva", } m["bhj"] = { "Bahing", 56442, "sit-kiw", "Deva, Latn", } m["bhl"] = { "Bimin", 4913743, "ngf-okk", "Latn", } m["bhm"] = { "Bathari", 2586893, "sem-sar", "Arab, Latn", } m["bhn"] = { "Bohtan Neo-Aramaic", 33230, "sem-nna", "Syrc", } m["bho"] = { "Bhojpuri", 33268, "inc-bih", "Deva, Kthi", wikimedia_codes = "bh", translit = { Deva = "bho-translit", Kthi = "bho-Kthi-translit", }, } m["bhp"] = { "Bima", 2796873, "poz-cet", "Latn", } m["bhq"] = { "Tukang Besi South", 12643975, "poz-mun", "Latn", } m["bhs"] = { "Buwal", 3515065, "cdc-cbm", "Latn", } m["bht"] = { "Bhattiyali", 4901452, "him", "Deva", } m["bhu"] = { "Bhunjia", 8841766, "inc-hal", "Deva, Orya", } m["bhv"] = { "Bahau", 3502039, "poz", "Latn", } m["bhw"] = { "Biak", 1961488, "poz-hce", "Latn", } m["bhx"] = { -- spurious? "Bhalay", 8840773, "inc", } m["bhy"] = { "Bhele", 4901671, "bnt-kbi", "Latn", } m["bhz"] = { "Bada", 4840520, "poz-kal", "Latn", } m["bia"] = { "Badimaya", 3442745, "aus-psw", "Latn", } m["bib"] = { "Bissa", 32934, "dmn-bbu", "Latn", } m["bic"] = { "Bikaru", 56342, "paa-eng", "Latn", } m["bid"] = { "Bidiyo", 56258, "cdc-est", "Latn", } m["bie"] = { "Bepour", 4890914, "ngf-mad", "Latn", } m["bif"] = { "Biafada", 35099, "alv-ten", "Latn", } m["big"] = { "Biangai", 8842027, "paa", "Latn", } m["bij"] = { "Kwanka", 35598, "nic-tar", "Latn", } m["bil"] = { "Bile", 34987, "nic-jrn", "Latn", } m["bim"] = { "Bimoba", 34971, "nic-grm", "Latn", } m["bin"] = { "Edo", 35375, "alv-eeo", "Latn", entry_name = {remove_diacritics = c.acute .. c.grave .. c.macron .. c.dgrave}, sort_key = { from = {"ẹ", "gb", "gh", "kh", "kp", "mw", "nw", "ny", "ọ", "rh", "rr", "vb"}, to = {"e" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "k" .. p[2], "m" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "r" .. p[1], "r" .. p[1], "v" .. p[1]} }, } m["bio"] = { "Nai", 3508074, "paa-kwm", "Latn", } m["bip"] = { "Bila", 2902626, "bnt-kbi", "Latn", } m["biq"] = { "Bipi", 2904312, "poz-aay", "Latn", } m["bir"] = { "Bisorio", 8844749, "paa-eng", "Latn", } m["bit"] = { "Berinomo", 56447, "paa-spk", "Latn", } m["biu"] = { "Biete", 4904687, "tbq-kuk", "Latn", } m["biv"] = { "Southern Birifor", 32859745, "nic-mre", "Latn", } m["biw"] = { "Kol (Cameroon)", 35582, "bnt-mka", "Latn", } m["bix"] = { "Bijori", 3450686, "mun", "Deva", } m["biy"] = { "Birhor", 3450469, "mun", "Deva", } m["biz"] = { "Baloi", 3450590, "bnt-ngn", "Latn", } m["bja"] = { "Budza", 3046889, "bnt-bun", "Latn", } m["bjb"] = { "Barngarla", 3439071, "aus-pam", "Latn", } m["bjc"] = { "Bariji", 4690919, "ngf", "Latn", } m["bje"] = { "Biao-Jiao Mien", 3503800, "hmx-mie", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } m["bjf"] = { "Barzani Jewish Neo-Aramaic", 33234, "sem-nna", "Hebr", -- maybe others display_text = { Hebr = "Hebr-common", }, entry_name = { Hebr = "Hebr-common", }, sort_key = { Hebr = "Hebr-common", }, } m["bjg"] = { "Bidyogo", 35365, "alv-bak", "Latn", } m["bjh"] = { "Bahinemo", 56361, "paa-spk", "Latn", } m["bji"] = { "Burji", 34999, "cus-hec", "Latn, Ethi", } m["bjj"] = { "Kannauji", 2726867, "inc-hiw", "Deva", } m["bjk"] = { "Barok", 2884743, "poz-ocw", "Latn", } m["bjl"] = { "Bulu (New Guinea)", 4997162, "poz-ocw", "Latn", } m["bjm"] = { "Bajelani", 4848866, "ira-zgr", "Latn, Arab", ancestors = "hac", } m["bjn"] = { "Banjarese", 33151, "poz-mly", "Latn, Arab", } m["bjo"] = { "Mid-Southern Banda", 42303990, "bad-cnt", "Latn", } m["bjp"] = { "Fanamaket", 56704263, "poz-oce", "Latn", } m["bjr"] = { "Binumarien", 538364, "paa-kag", "Latn", } m["bjs"] = { "Bajan", 2524014, "crp", "Latn", ancestors = "en", } m["bjt"] = { "Balanta-Ganja", 19359034, "alv-bak", "Arab, Latn", } m["bju"] = { "Busuu", 35046, "nic-fru", "Latn", } m["bjv"] = { "Bedjond", 8829831, "csu-sar", "Latn", } m["bjw"] = { "Bakwé", 34899, "kro-ekr", "Latn", } m["bjx"] = { "Banao Itneg", 12627559, "phi", "Latn", } m["bjy"] = { "Bayali", 4874263, "aus-pam", "Latn", } m["bjz"] = { "Baruga", 2886189, "ngf", "Latn", } m["bka"] = { "Kyak", 35653, "alv-bwj", "Latn", } m["bkc"] = { "Baka", 34905, "nic-nkb", "Latn", } m["bkd"] = { "Binukid", 4914553, "mno", "Latn", } m["bkf"] = { "Beeke", 3441375, "bnt-kbi", "Latn", } m["bkg"] = { "Buraka", 35066, "nic-nkg", "Latn", } m["bkh"] = { "Bakoko", 34866, "bnt-bsa", "Latn", } m["bki"] = { "Baki", 11024697, "poz-vnc", "Latn", } m["bkj"] = { "Pande", 36263, "bnt-ngn", "Latn", } m["bkk"] = { -- written in Balti script "Brokskat", 2925988, "inc-shn", "Tibt, Arab", } m["bkl"] = { "Berik", 378743, "paa-tkw", "Latn", } m["bkm"] = { "Kom (Cameroon)", 1656595, "nic-rnc", "Latn", } m["bkn"] = { "Bukitan", 3446774, "poz-bnn", "Latn", } m["bko"] = { "Kwa'", 35567, "bai", "Latn", } m["bkp"] = { "Iboko", 35089, "bnt-ngn", "Latn", } m["bkq"] = { "Bakairí", 56846, "sai-pek", "Latn", } m["bkr"] = { "Bakumpai", 3436626, "poz-brw", "Latn", } m["bks"] = { "Masbate Sorsogon", 16113356, "phi", "Latn", } m["bkt"] = { "Boloki", 4144560, "bnt-zbi", "Latn", ancestors = "lse", } m["bku"] = { "Buhid", 1002956, "phi", "Latn, Buhd", translit = { Buhd = "bku-translit", }, override_translit = true, entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ, } }, sort_key = { Latn = "tl-sortkey", }, standardChars = { Latn = "AaBbKkDdEeFfGgHhIiLlMmNnOoPpRrSsTtUuWwYy" .. c.punc, }, } m["bkv"] = { "Bekwarra", 34954, "nic-ben", "Latn", } m["bkw"] = { "Bekwel", 34950, "bnt-bek", "Latn", } m["bkx"] = { "Baikeno", 11200640, "poz-tim", "Latn", } m["bky"] = { "Bokyi", 35087, "nic-ben", "Latn", } m["bkz"] = { "Bungku", 2928207, "poz-btk", "Latn", } m["bla"] = { "Blackfoot", 33060, "alg", "Latn, Cans", } m["blb"] = { "Bilua", 35003, "ngf", "Latn", } m["blc"] = { "Bella Coola", 977808, "sal", "Latn", } m["bld"] = { "Bolango", 3450578, "phi", "Latn", } m["ble"] = { "Balanta-Kentohe", 56789, "alv-bak", "Latn", } m["blf"] = { "Buol", 2928278, "phi", "Latn", } m["blg"] = { "Balau", 4850134, "poz-mly", "Latn", } m["blh"] = { "Kuwaa", 35579, "kro", "Latn", } m["bli"] = { "Bolia", 34910, "bnt-mon", "Latn", } m["blj"] = { "Bolongan", 9229310, "poz", "Latn", } m["blk"] = { "Pa'o Karen", 7121294, "kar", "Mymr", } m["bll"] = { "Biloxi", 2903780, "sio-ohv", "Latn", } m["blm"] = { "Beli", 56821, "csu-bbk", "Latn", } m["bln"] = { "Southern Catanduanes Bicolano", 7569754, "phi", "Latn", } m["blo"] = { "Anii", 34838, "alv-ntg", "Latn", } m["blp"] = { "Blablanga", 2905245, "poz-ocw", "Latn", } m["blq"] = { "Baluan-Pam", 2881675, "poz-aay", "Latn", } m["blr"] = { "Blang", 4925096, "mkh-pal", "Latn, Tale, Lana, Thai", sort_key = { -- FIXME: This needs to be converted into the current standardized format. from = {"[%pᪧๆ]", "[᩠ᩳ-᩿]", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", "[็-๎]", "([เแโใไ])([ก-ฮ])"}, to = {"", "", "ᩈᩈ", "ᩁ", "ᩃ", "ᨦ", "%1ᨮ", "%1ᨻ", "ᩣ", "", "%2%1"} }, } m["bls"] = { "Balaesang", 4849796, "poz", "Latn", } m["blt"] = { "Tai Dam", 56407, "tai-swe", "Tavt, Latn", --translit = "Tavt-translit", sort_key = { Tavt = { from = {"[꪿ꫀ꫁ꫂ]", "([ꪵꪶꪹꪻꪼ])([ꪀ-ꪯ])"}, to = {"", "%2%1"} }, }, } m["blv"] = { "Kibala", 4939959, "bnt-kmb", "Latn", } m["blw"] = { "Balangao", 4850033, "phi", "Latn", } m["blx"] = { "Mag-Indi Ayta", 1931221, "phi", "Latn", } m["bly"] = { "Notre", 11009194, "nic-wov", "Latn", } m["blz"] = { "Balantak", 4850053, "poz-slb", "Latn", } m["bma"] = { "Lame", 3913997, "nic-jrn", "Latn", } m["bmb"] = { "Bembe", 4885023, "bnt-lgb", "Latn", } m["bmc"] = { "Biem", 4904523, "poz-ocw", "Latn", } m["bmd"] = { "Baga Manduri", 35815, "alv-bag", "Latn", } m["bme"] = { "Limassa", 11004666, "nic-nkb", "Latn", } m["bmf"] = { "Bom", 35088, "alv-mel", "Latn", } m["bmg"] = { "Bamwe", 34867, "bnt-bun", "Latn", } m["bmh"] = { "Kein", 6383764, "ngf-mad", "Latn", } m["bmi"] = { "Bagirmi", 34903, "csu-bgr", "Latn", } m["bmj"] = { "Bote-Majhi", 9229570, "inc-eas", "Deva", ancestors = "bh", } m["bmk"] = { "Ghayavi", 5555976, "poz-ocw", "Latn", } m["bml"] = { "Bomboli", 35055, "bnt-ngn", "Latn", } m["bmn"] = { "Bina", 8843664, "poz-ocw", "Latn", } m["bmo"] = { "Bambalang", 34868, "nic-nun", "Latn", } m["bmp"] = { "Bulgebi", 4996380, "ngf-fin", "Latn", } m["bmq"] = { "Bomu", 35065, "nic-bwa", "Latn", } m["bmr"] = { "Muinane", 3027894, "sai-bor", "Latn", } m["bmt"] = { "Biao Mon", 8842159, "hmx-mie", } m["bmu"] = { "Somba-Siawari", 5000983, "ngf", "Latn", } m["bmv"] = { "Bum", 35058, "nic-rnc", "Latn", } m["bmw"] = { "Bomwali", 34984, "bnt-ndb", "Latn", } m["bmx"] = { "Baimak", 3450546, "ngf-mad", "Latn", } m["bmz"] = { "Baramu", 4858315, "ngf", "Latn", } m["bna"] = { "Bonerate", 4941729, "poz-mun", "Latn", } m["bnb"] = { "Bookan", 4943150, "poz-san", "Latn", } m["bnd"] = { "Banda", 3504147, "poz-cma", "Latn", } m["bne"] = { "Bintauna", 4914533, "phi", "Latn", } m["bnf"] = { "Masiwang", 6783305, "poz-cma", "Latn", } m["bng"] = { "Benga", 34952, "bnt-saw", "Latn", } m["bni"] = { "Bangi", 34936, "bnt-bmo", "Latn", } m["bnj"] = { "Eastern Tawbuid", 18757427, "phi", "Latn", } m["bnk"] = { "Bierebo", 2902029, "poz-vnc", "Latn", } m["bnl"] = { "Boon", 56616, "cus-eas", "Latn", } m["bnm"] = { "Batanga", 34979, "bnt-saw", "Latn", } m["bnn"] = { "Bunun", 56505, "map", "Latn", } m["bno"] = { "Asi", 29490, "phi", "Latn", } m["bnp"] = { "Bola", 4938876, "poz-ocw", "Latn", } m["bnq"] = { "Bantik", 2883521, "poz", "Latn", } m["bnr"] = { "Butmas-Tur", 2928942, "poz-vnn", "Latn", } m["bns"] = { "Bundeli", 56399, "inc-hiw", "Deva", translit = "hi-translit", } m["bnu"] = { "Bentong", 4890644, "poz-ssw", "Latn", } m["bnv"] = { "Beneraf", 4941733, "paa-tkw", "Latn", } m["bnw"] = { "Bisis", 56356, "paa-spk", "Latn", } m["bnx"] = { "Bangubangu", 3438330, "bnt-lbn", "Latn", } m["bny"] = { "Bintulu", 3450775, "poz-swa", "Latn", } m["bnz"] = { "Beezen", 35083, "nic-ykb", "Latn", } m["boa"] = { "Bora", 2375468, "sai-bor", "Latn", } m["bob"] = { "Aweer", 56526, "cus-som", "Latn", } m["boe"] = { "Mundabli", 36127, "nic-beb", "Latn", } m["bof"] = { "Bolon", 3913301, "dmn-emn", "Latn", } m["bog"] = { "Bamako Sign Language", 4853284, "sgn", } m["boh"] = { "North Boma", 35080, "bnt-bdz", "Latn", } m["boi"] = { "Barbareño", 56391, "nai-chu", "Latn", } m["boj"] = { "Anjam", 3504136, "ngf-mad", "Latn", } m["bok"] = { "Bonjo", 34942, "alv", "Latn", } m["bol"] = { "Bole", 3436680, "cdc-wst", "Latn", } m["bom"] = { "Berom", 35013, "nic-beo", "Latn", } m["bon"] = { "Bine", 4914077, "paa", "Latn", } m["boo"] = { "Tiemacèwè Bozo", 12643582, "dmn-snb", "Latn", -- and others? } m["bop"] = { "Bonkiman", 4942134, "ngf-fin", "Latn", } m["boq"] = { "Bogaya", 7207578, "ngf", "Latn", } m["bor"] = { "Borôro", 32986, "sai-mje", "Latn", } m["bot"] = { "Bongo", 2910067, "csu-bbk", "Latn", } m["bou"] = { "Bondei", 4941378, "bnt-seu", "Latn", } m["bov"] = { "Tuwuli", 36974, "alv-ktg", "Latn", } m["bow"] = { "Rema", 7311502, "paa", "Latn", } m["box"] = { "Buamu", 35157, "nic-bwa", "Latn", } m["boy"] = { "Bodo (Central Africa)", 4936715, "bnt-leb", "Latn", } m["boz"] = { "Tiéyaxo Bozo", 32860401, "dmn-snb", "Latn", } m["bpa"] = { "Daakaka", 1157729, "poz-vnc", "Latn", } m["bpd"] = { "Banda-Banda", 3450674, "bad-cnt", "Latn", } m["bpg"] = { "Bonggo", 4941860, "poz-ocw", "Latn", } m["bph"] = { "Botlikh", 56560, "cau-and", "Cyrl", translit = "cau-nec-translit", override_translit = true, display_text = {Cyrl = s["cau-Cyrl-displaytext"]}, entry_name = {Cyrl = s["cau-Cyrl-entryname"]}, } m["bpi"] = { "Bagupi", 3450697, "ngf-mad", "Latn", } m["bpj"] = { "Binji", 4914403, "bnt-lbn", "Latn", } m["bpk"] = { "Orowe", 7103905, "poz-cln", "Latn", } m["bpl"] = { "Broome Pearling Lugger Pidgin", 4975277, "crp", "Latn", ancestors = "ms", } m["bpm"] = { "Biyom", 4919327, "ngf-mad", "Latn", } m["bpn"] = { "Dzao Min", 3042189, "hmx-mie", } m["bpo"] = { "Anasi", 11207813, "paa-egb", "Latn", } m["bpp"] = { "Kaure", 20526532, "paa", "Latn", } m["bpq"] = { "Banda Malay", 12473442, "crp", "Latn", ancestors = "ms", } m["bpr"] = { "Koronadal Blaan", 16115430, "phi", "Latn", } m["bps"] = { "Sarangani Blaan", 16117272, "phi", "Latn", } m["bpt"] = { "Barrow Point", 2567916, "aus-pmn", "Latn", } m["bpu"] = { "Bongu", 4941930, "ngf-mad", "Latn", } m["bpv"] = { "Bian Marind", 8841889, "ngf", "Latn", } m["bpx"] = { "Palya Bareli", 7128872, "inc-bhi", "Deva", translit = "hi-translit", } m["bpy"] = { "Bishnupriya Manipuri", 37059, "inc-bas", "Beng", ancestors = "inc-obn", } m["bpz"] = { "Bilba", 8843362, "poz-tim", "Latn", } m["bqa"] = { "Tchumbuli", 11008162, "alv-ctn", "Latn", ancestors = "ak", } m["bqb"] = { "Bagusa", 4842178, "paa-tkw", "Latn", } m["bqc"] = { "Boko", 34983, "dmn-bbu", "Latn", } m["bqd"] = { "Bung", 3436612, "nic-bdn", "Latn", } m["bqf"] = { "Baga Kaloum", 3502293, "alv-bag", "Latn", } m["bqg"] = { "Bago-Kusuntu", 34878, "nic-gne", } m["bqh"] = { "Baima", 674990, "sit-qia", } m["bqi"] = { "Bakhtiari", 257829, "ira-swi", "fa-Arab", ancestors = "pal", } m["bqj"] = { "Bandial", 34872, "alv-jol", "Latn", } m["bqk"] = { "Banda-Mbrès", 3450724, "bad-cnt", "Latn", } m["bql"] = { "Bilakura", 4907504, "ngf-mad", "Latn", } m["bqm"] = { "Wumboko", 37051, "bnt-kpw", "Latn", } m["bqn"] = { "Bulgarian Sign Language", 3438325, "sgn", } m["bqo"] = { "Balo", 34865, "nic-grs", "Latn", } m["bqp"] = { "Busa", 35185, "dmn-bbu", "Latn", } m["bqq"] = { "Biritai", 56382, "paa-lkp", "Latn", } m["bqr"] = { "Burusu", 5001028, "poz-san", "Latn", } m["bqs"] = { "Bosngun", 56838, "paa", "Latn", } m["bqt"] = { "Bamukumbit", 35078, "nic-nge", "Latn", } m["bqu"] = { "Boguru", 3438444, "bnt-boa", "Latn", } m["bqv"] = { "Begbere-Ejar", 7194098, "nic-plc", "Latn", } m["bqw"] = { "Buru (Nigeria)", 1017152, "nic-bds", "Latn", } m["bqx"] = { "Baangi", 3450648, "nic-kam", "Latn", } m["bqy"] = { "Bengkala Sign Language", 3322119, "sgn", } m["bqz"] = { "Bakaka", 34855, "bnt-mne", "Latn", } m["bra"] = { "Braj", 35243, "inc-hiw", "Deva", translit = "hi-translit", } m["brb"] = { "Lave", 4957737, "mkh-ban", } m["brc"] = { "Berbice Creole Dutch", 35215, "crp", "Latn", ancestors = "nl", } m["brd"] = { "Baraamu", 56804, "sit-new", "Deva", } m["brf"] = { "Bera", 2896850, "bnt-kbi", "Latn", } m["brg"] = { "Baure", 2839722, "awd", "Latn", } m["brh"] = { "Brahui", 33202, "dra-nor", "ur-Arab, Latn", translit = {["ur-Arab"] = "ur-translit"}, entry_name = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, } m["bri"] = { "Mokpwe", 36428, "bnt-kpw", "Latn", } m["brj"] = { "Bieria", 4904607, "poz-vnc", "Latn", } m["brk"] = { "Birgid", 56823, "nub", "Latn", } m["brl"] = { "Birwa", 3501019, "bnt-sts", "Latn", } m["brm"] = { "Barambu", 34893, "znd", "Latn", } m["brn"] = { "Boruca", 4946773, "cba", "Latn", } m["bro"] = { "Brokkat", 56605, "sit-tib", "Tibt, Latn", translit = {Tibt = "Tibt-translit"}, override_translit = true, display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = {Tibt = s["Tibt-entryname"]}, sort_key = {Tibt = "Tibt-sortkey"}, } m["brp"] = { "Barapasi", 56995, "paa-egb", "Latn", } m["brq"] = { "Breri", 4961835, "paa", "Latn", } m["brr"] = { "Birao", 2904383, "poz-sls", "Latn", } m["brs"] = { "Baras", 8827053, "poz", "Latn", } m["brt"] = { "Bitare", 34946, "nic-tvn", "Latn", } m["bru"] = { "Eastern Bru", 16115463, "mkh-kat", "Latn, Laoo, Thai", sort_key = { Laoo = "Laoo-sortkey", Thai = "Thai-sortkey", }, } m["brv"] = { "Western Bru", 13018531, "mkh-kat", "Latn, Laoo, Thai", sort_key = { Laoo = "Laoo-sortkey", Thai = "Thai-sortkey", }, } m["brw"] = { "Bellari", 4883496, "dra-tlk", "Knda, Mlym", translit = { Knda = "kn-translit", Mlym = "ml-translit", }, } m["brx"] = { "Bodo (India)", 33223, "tbq-bdg", "Deva, Latn", translit = {Deva = "brx-translit"}, } m["bry"] = { "Burui", 5000976, "paa-spk", "Latn", } m["brz"] = { "Bilbil", 4907473, "poz-ocw", "Latn", } m["bsa"] = { "Abinomn", 56648, "qfa-iso", "Latn", } m["bsb"] = { "Brunei Bisaya", 3450611, "poz-san", "Latn", } m["bsc"] = { "Bassari", 35098, "alv-ten", "Latn", } m["bse"] = { "Wushi", 36973, "nic-rnn", "Latn", } m["bsf"] = { "Bauchi", 34974, "nic-shi", "Latn", } m["bsg"] = { "Bashkardi", 33030, "ira-swi", "fa-Arab, Latn", } m["bsh"] = { "Kamkata-viri", 2605045, "nur-nor", "Latn, Arab", } m["bsi"] = { "Bassossi", 34940, "bnt-mne", "Latn", } m["bsj"] = { "Bangwinji", 3446631, "alv-wjk", "Latn", } m["bsk"] = { "Burushaski", 216286, "qfa-iso", "Arab", entry_name = { -- character "ۂ" code U+06C2 to "ه" and "هٔ"‎ (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif from = {"هٔ", "ۂ", "ٱ"}, to = {"ہ", "ہ", "ا"}, remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef }, } m["bsl"] = { "Basa-Gumna", 4866150, "nic-bas", "Latn", } m["bsm"] = { "Busami", 5001255, "poz-hce", "Latn", } m["bsn"] = { "Barasana", 2883843, "sai-tuc", "Latn", } m["bso"] = { "Buso", 3441370, "cdc-est", "Latn", } m["bsp"] = { "Baga Sitemu", 36466, "alv-bag", "Latn", } m["bsq"] = { "Bassa", 34949, "kro-wkr", "Latn, Bass", } m["bsr"] = { "Bassa-Kontagora", 4866152, "nic-bas", "Latn", } m["bss"] = { "Akoose", 34806, "bnt-mne", "Latn", } m["bst"] = { "Basketo", 56531, "omv-ome", "Ethi", } m["bsu"] = { "Bahonsuai", 2879298, "poz-btk", "Latn", } m["bsv"] = { "Baga Sobané", 3450433, "alv-bag", "Latn", } m["bsw"] = { "Baiso", 56615, "cus-som", "Latn", } m["bsx"] = { "Yangkam", 36922, "nic-tar", "Latn", } m["bsy"] = { "Sabah Bisaya", 12641557, "poz-san", "Latn", } m["bta"] = { "Bata", 56254, "cdc-cbm", "Latn", } m["btc"] = { "Bati (Cameroon)", 34944, "nic-mbw", "Latn", } m["btd"] = { "Dairi Batak", 2891045, "btk", "Latn, Batk", } m["bte"] = { "Gamo-Ningi", 5520366, "nic-jer", "Latn", } m["btf"] = { "Birgit", 56302, "cdc-est", "Latn", } m["btg"] = { "Gagnoa Bété", 5005069, "kro-bet", "Latn", } m["bth"] = { "Biatah Bidayuh", 2900881, "day", "Latn", } m["bti"] = { "Burate", 56900, "paa-egb", "Latn", } m["btj"] = { "Bacanese Malay", 8828608, "poz-mly", "Latn", } m["btm"] = { "Mandailing Batak", 2891049, "btk", "Latn, Batk", } m["btn"] = { "Ratagnon", 13197, "phi", "Latn", } m["bto"] = { "Iriga Bicolano", 12633026, "phi", "Latn", } m["btp"] = { "Budibud", 4985086, "poz-ocw", "Latn", } m["btq"] = { "Batek", 860315, "mkh-asl", "Latn", } m["btr"] = { "Baetora", 2878874, "poz-vnn", "Latn", } m["bts"] = { "Simalungun Batak", 2891054, "btk", "Latn, Batk", } m["btt"] = { "Bete-Bendi", 4887064, "nic-ben", "Latn", } m["btu"] = { "Batu", 34964, "nic-tvn", "Latn", } m["btv"] = { "Bateri", 3812564, "inc-koh", "Deva", } m["btw"] = { "Butuanon", 5003156, "phi", "Latn", } m["btx"] = { "Karo Batak", 33012, "btk", "Latn, Batk", } m["bty"] = { "Bobot", 3446788, "poz-cma", "Latn", } m["btz"] = { "Alas-Kluet Batak", 2891042, "btk", "Latn, Batk", } m["bua"] = { "Buryat", 33120, "xgn-cen", "Cyrl, Mong, Latn", wikimedia_codes = "bxr", ancestors = "cmg", translit = { Cyrl = "bua-translit", Mong = "Mong-translit", }, override_translit = true, display_text = {Mong = s["Mong-displaytext"]}, entry_name = { Cyrl = {remove_diacritics = c.grave .. c.acute}, Mong = s["Mong-entryname"], }, sort_key = { Cyrl = { from = {"ё", "ө", "ү", "һ"}, to = {"е" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1]} }, }, } m["bub"] = { "Bua", 32928, "alv-bua", "Latn", } m["bud"] = { "Ntcham", 36266, "nic-grm", "Latn", } m["bue"] = { "Beothuk", 56234, nil, "Latn", } m["buf"] = { "Bushoong", 3449964, "bnt-bsh", "Latn", } m["bug"] = { "Buginese", 33190, "poz-ssw", "Bugi, Latn", } m["buh"] = { "Younuo Bunu", 56299, "hmn", "Latn", } m["bui"] = { "Bongili", 35084, "bnt-ngn", "Latn", } m["buj"] = { "Basa-Gurmana", 6432515, "nic-bas", "Latn", } m["buk"] = { "Bukawa", 35043, "poz-ocw", "Latn", } m["bum"] = { "Bulu (Cameroon)", 35028, "bnt-btb", "Latn", } m["bun"] = { "Sherbro", 36339, "alv-mel", "Latn", } m["buo"] = { "Terei", 56831, "paa-sbo", "Latn", } m["bup"] = { "Busoa", 5002001, "poz", "Latn", } m["buq"] = { "Brem", 4960502, "ngf", "Latn", } m["bus"] = { "Bokobaru", 9228931, "dmn-bbu", "Latn", } m["but"] = { "Bungain", 3450623, "qfa-tor", "Latn", } m["buu"] = { "Budu", 3450207, "bnt-nya", "Latn", } m["buv"] = { "Bun", 56351, "paa-yua", "Latn", } m["buw"] = { "Bubi", 35017, "bnt-tso", "Latn", } m["bux"] = { "Boghom", 3440412, "cdc-wst", "Latn", } m["buy"] = { "Mmani", 35061, "alv-mel", "Latn", } m["bva"] = { "Barein", 56285, "cdc-est", "Latn", } m["bvb"] = { "Bube", 35110, "nic-bds", "Latn", } m["bvc"] = { "Baelelea", 2878833, "poz-sls", "Latn", } m["bvd"] = { "Baeggu", 2878850, "poz-sls", "Latn", } m["bve"] = { "Berau Malay", 3915770, "poz-mly", "Latn", } m["bvf"] = { "Boor", 56250, "cdc-est", "Latn", } m["bvg"] = { "Bonkeng", 34958, "bnt-bbo", "Latn", } m["bvh"] = { "Bure", 56294, "cdc-wst", "Latn", } m["bvi"] = { "Belanda Viri", 35247, "nic-ser", "Latn", } m["bvj"] = { "Baan", 3515067, "nic-ogo", "Latn", } m["bvk"] = { "Bukat", 4986814, "poz-bnn", "Latn", } m["bvl"] = { "Bolivian Sign Language", 1783590, "sgn", "Latn", -- when documented } m["bvm"] = { "Bamunka", 34882, "nic-rnn", "Latn", } m["bvn"] = { "Buna", 3450516, "qfa-tor", "Latn", } m["bvo"] = { "Bolgo", 35038, "alv-bua", "Latn", } m["bvp"] = { "Bumang", 4997235, "mkh-pal", } m["bvq"] = { "Birri", 56514, "csu-bkr", "Latn", } m["bvr"] = { "Burarra", 4998124, "aus-arn", "Latn", } m["bvt"] = { "Bati (Indonesia)", 4869253, "poz-cma", "Latn", } m["bvu"] = { "Bukit Malay", 9230148, "poz-mly", "Latn", } m["bvv"] = { "Baniva", 3515198, "awd", "Latn", } m["bvw"] = { "Boga", 56262, "cdc-cbm", "Latn", } m["bvx"] = { "Babole", 35180, "bnt-ngn", "Latn", } m["bvy"] = { "Baybayanon", 16839275, "phi", "Latn", } m["bvz"] = { "Bauzi", 56360, "paa-egb", "Latn", } m["bwa"] = { "Bwatoo", 9232446, "poz-cln", "Latn", } m["bwb"] = { "Namosi-Naitasiri-Serua", 3130290, "poz-pcc", "Latn", } m["bwc"] = { "Bwile", 3447440, "bnt-sbi", "Latn", } m["bwd"] = { "Bwaidoka", 2929111, "poz-ocw", "Latn", } m["bwe"] = { "Bwe Karen", 56994, "kar", "Mymr, Latn", } m["bwf"] = { "Boselewa", 4947229, "poz-ocw", "Latn", } m["bwg"] = { "Barwe", 8826802, "bnt-sna", "Latn", } m["bwh"] = { "Bishuo", 34973, "nic-fru", "Latn", } m["bwi"] = { "Baniwa", 3501735, "awd-nwk", "Latn", } m["bwj"] = { "Láá Láá Bwamu", 11017275, "nic-bwa", "Latn", } m["bwk"] = { "Bauwaki", 4873607, "ngf", "Latn", } m["bwl"] = { "Bwela", 5003678, "bnt-bun", "Latn", } m["bwm"] = { "Biwat", 56352, "paa-yua", "Latn", } m["bwn"] = { "Wunai Bunu", 56452, "hmn", } m["bwo"] = { "Shinasha", 56260, "omv-gon", "Latn", } m["bwp"] = { "Mandobo Bawah", 12636155, "ngf", "Latn", } m["bwq"] = { "Southern Bobo", 11001714, "dmn-snb", "Latn", } m["bwr"] = { "Bura", 56552, "cdc-cbm", "Latn", } m["bws"] = { "Bomboma", 9229429, "bnt-bun", "Latn", } m["bwt"] = { "Bafaw", 34853, "bnt-bbo", "Latn", } m["bwu"] = { "Buli (Ghana)", 35085, "nic-buk", "Latn", } m["bww"] = { "Bwa", 3515058, "bnt-bta", "Latn", } m["bwx"] = { "Bu-Nao Bunu", 56411, "hmn", "Latn", } m["bwy"] = { "Cwi Bwamu", 11150714, "nic-bwa", "Latn", } m["bwz"] = { "Bwisi", 35067, "bnt-sir", "Latn", } m["bxa"] = { "Bauro", 2892068, "poz-sls", "Latn", } m["bxb"] = { "Belanda Bor", 56678, "sdv-lon", "Latn", } m["bxc"] = { "Molengue", 13345, "bnt-kel", "Latn", } m["bxd"] = { "Pela", 57000, "tbq-brm", } m["bxe"] = { "Ongota", 36344, nil, "Latn", } m["bxf"] = { "Bilur", 2903788, "poz-ocw", "Latn", } m["bxg"] = { "Bangala", 34989, "bnt-bmo", "Latn", } m["bxh"] = { "Buhutu", 4986329, "poz-ocw", "Latn", } m["bxi"] = { "Pirlatapa", 10632195, "aus-kar", "Latn", } m["bxj"] = { "Bayungu", 10427485, "aus-psw", "Latn", } m["bxk"] = { "Bukusu", 32930, "bnt-msl", "Latn", } m["bxl"] = { "Jalkunan", 11009787, "dmn-jje", "Latn", } m["bxn"] = { "Burduna", 4998313, "aus-psw", "Latn", } m["bxo"] = { "Barikanchi", 3450802, "crp", "Latn", ancestors = "ha", } m["bxp"] = { "Bebil", 34941, "bnt-btb", "Latn", } m["bxq"] = { "Beele", 56238, "cdc-wst", "Latn", } m["bxs"] = { "Busam", 35189, "nic-grs", "Latn", } m["bxv"] = { "Berakou", 56796, "csu-bgr", "Latn", } m["bxw"] = { "Banka", 3438402, "dmn-smg", "Latn", } m["bxz"] = { "Binahari", 4913840, "ngf", "Latn", } m["bya"] = { "Palawan Batak", 3450443, "phi", "Tagb", } m["byb"] = { "Bikya", 33257, "nic-fru", "Latn", } m["byc"] = { "Ubaghara", 36625, "nic-ucn", "Latn", } m["byd"] = { "Benyadu'", 11173588, "day", "Latn", } m["bye"] = { "Pouye", 7235814, "paa-spk", "Latn", } m["byf"] = { "Bete", 32932, "nic-ykb", "Latn", } m["byg"] = { "Baygo", 56836, "sdv-daj", "Latn", } m["byh"] = { "Bujhyal", 56317, "sit-gma", "Deva", } m["byi"] = { "Buyu", 5003401, "bnt-nyb", "Latn", } m["byj"] = { "Binawa", 4913807, "nic-kau", "Latn", } m["byk"] = { "Biao", 4902547, "qfa-tak", "Latn", -- also Hani? } m["byl"] = { "Bayono", 3503856, "ngf", "Latn", } m["bym"] = { "Bidyara", 8842355, "aus-pam", "Latn", } m["byn"] = { "Blin", 56491, "cus-cen", "Ethi, Latn", translit = {Ethi = "Ethi-translit"}, } m["byo"] = { "Biyo", 56848, "tbq-bka", "Latn, Hani", sort_key = {Hani = "Hani-sortkey"}, } m["byp"] = { "Bumaji", 4997234, "nic-ben", "Latn", } m["byq"] = { "Basay", 716647, "map", "Latn", } m["byr"] = { "Baruya", 3450812, "ngf", "Latn", } m["bys"] = { "Burak", 4998097, "alv-bwj", "Latn", } m["byt"] = { "Berti", 35008, "ssa-sah", "Latn", } m["byv"] = { "Medumba", 36019, "bai", "Latn", } m["byw"] = { "Belhariya", 32961, "sit-kie", "Deva", } m["byx"] = { "Qaqet", 3503009, "paa-bng", "Latn", } m["byz"] = { "Banaro", 56858, "paa", "Latn", } m["bza"] = { "Bandi", 34912, "dmn-msw", "Latn", } m["bzb"] = { "Andio", 4754487, "poz-slb", "Latn", } m["bzd"] = { "Bribri", 28400, "cba", "Latn", } m["bze"] = { "Jenaama Bozo", 10950633, "dmn-snb", "Latn", } m["bzf"] = { "Boikin", 56829, "paa-spk", "Latn", } m["bzg"] = { "Babuza", 716615, "map", "Latn", } m["bzh"] = { "Mapos Buang", 2927370, "poz-ocw", "Latn", } m["bzi"] = { "Bisu", 56852, "tbq-bis", "Latn, Thai", sort_key = {Thai = "Thai-sortkey"}, } m["bzj"] = { "Belizean Creole", 1363055, "crp", "Latn", ancestors = "en", } m["bzk"] = { "Nicaraguan Creole", 3504097, "crp", "Latn", ancestors = "en", } m["bzl"] = { -- supposedly also called "Bolano", but I can find no evidence of that "Boano (Sulawesi)", 4931258, "poz", "Latn", } m["bzm"] = { "Bolondo", 35071, "bnt-bun", "Latn", } m["bzn"] = { "Boano (Maluku)", 4931255, "poz-cma", "Latn", } m["bzo"] = { "Bozaba", 4952785, "bnt-ngn", "Latn", } m["bzp"] = { "Kemberano", 12634399, "ngf-sbh", "Latn", } m["bzq"] = { "Buli (Indonesia)", 2927952, "poz-hce", "Latn", } m["bzr"] = { "Biri", 4087011, "aus-pam", "Latn", } m["bzs"] = { "Brazilian Sign Language", 3436689, "sgn", "Latn", } m["bzu"] = { "Burmeso", 56746, "paa-wpa", "Latn", } m["bzv"] = { "Bebe", 34977, "nic-bbe", "Latn", } m["bzw"] = { "Basa", 34898, "nic-bas", "Latn", } m["bzx"] = { "Hainyaxo Bozo", 11159536, "dmn-snb", "Latn", } m["bzy"] = { "Obanliku", 36276, "nic-ben", "Latn", } m["bzz"] = { "Evant", 35259, "nic-tvc", "Latn", } return require("Module:languages").finalizeData(m, "language") 83s5kxpy1ioveq2cp8a0muuv752van6 Modul:parser 828 4668 26628 10258 2025-11-08T21:18:17Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26628 Scribunto text/plain local export = {} local scribunto_metamethods_module = "Module:Scribunto/metamethods" local table_deep_copy_module = "Module:table/deepCopy" local table_get_nested_module = "Module:table/getNested" local table_set_nested_module = "Module:table/setNested" local concat = table.concat local find = string.find local getmetatable = getmetatable local insert = table.insert local next = next local rawget = rawget local rawset = rawset local remove = table.remove local require = require local select = select local setmetatable = setmetatable local sub = string.sub local type = type local unpack = unpack or table.unpack -- Lua 5.2 compatibility local node_classes = {} local function deep_copy(...) deep_copy = require(table_deep_copy_module) return deep_copy(...) end local function get_nested(...) get_nested = require(table_get_nested_module) return get_nested(...) end local function set_nested(...) set_nested = require(table_set_nested_module) return set_nested(...) end --[==[ 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 metamethods local function get_metamethods() -- Use require, since lookup times are much slower with mw.loadData. metamethods, get_metamethods = require(scribunto_metamethods_module), nil return metamethods end ------------------------------------------------------------------------------------ -- -- Helper functions -- ------------------------------------------------------------------------------------ local function inherit_metamethods(child, parent) if parent then for method, value in next, parent do if child[method] == nil and (metamethods or get_metamethods())[method] ~= nil then child[method] = value end end end return child end local function signed_index(t, n) return n and n <= 0 and #t + 1 + n or n end local function is_node(value) if value == nil then return false end local mt = getmetatable(value) return not (mt == nil or node_classes[mt] == nil) end local function node_class(value) if value == nil then return nil end local mt = getmetatable(value) if mt == nil then return nil end return mt ~= nil and node_classes[mt] or nil end local function class_else_type(value) if value == nil then return type(value) end local mt = getmetatable(value) if mt == nil then return type(value) end local class = node_classes[mt] return class == nil and type(value) or class end -- Recursively calling tostring() adds to the C stack (limit: 200), whereas -- calling __tostring metamethods directly does not. Occasionally relevant when -- dealing with very deep nesting. local tostring do local _tostring = _G.tostring function tostring(value) if is_node(value) then return value:__tostring(value) end return _tostring(value) end end ------------------------------------------------------------------------------------ -- -- Nodes -- ------------------------------------------------------------------------------------ local Node = {} Node.__index = Node function Node:next(i) i = i + 1 return self[i], self, i end --[==[ Implements recursive iteration over a node tree. By default, when a node is encountered (which may contain other nodes), it is returned on the first iteration, and then any child nodes are returned on each subsequent iteration; the same process is then followed if any of those children contain nodes themselves. Once a particular node has been fully traversed, the iterator then continues with any sibling nodes. The iterator will use the `next` method of each node to traverse it, which may differ depending on the node class. Each iteration returns three values: `value`, `node` and `key`. Together, these can be used to manipulate the node tree at any given point without needing to know the full structure. Note that when the input node is returned on the first iteration, `node` and `key` will be nil. The optional argument `test` can be used to limit the return values. This should be a function that returns a boolean value, where a return value of true means that the child will be returned by the iterator. If a node is not returned by the iterator, it will still be traversed, as it may contain children that should be returned. The method `iterate_nodes` is provided as a special instance of iterate which uses `is_node` as the test.]==] function Node:iterate(test) local node, k, n, nodes, keys, returned_self = self, 0, 0 -- Special case if `test` is `is_node`. local is_node_is_test = test == is_node return function() if not returned_self then returned_self = true if test == nil or test(self) then return self end end -- Get `v`, which is the value at the last-returned key of the current node; if `v` is a node, it will be iterated over (i.e. recursive iteration). By default, `v` will be the last-returned value, but looking it up here means that any modifications made to the node during the loop will be taken into account. This makes it possible to swap one node out for something else (e.g. another node), or to remove it entirely, without being locked into recursively iterating over the old node; instead, the new node (if any) will be iterated over. This means node trees can be modified on-the-fly during the course of a single loop. local v, node_check = node[k], true while true do -- If `v` is a node, memoize the current node and key, then iterate over it. if node_check and is_node(v) then -- `n` is the current memo level. n = n + 1 if nodes then nodes[n], keys[n] = node, k else nodes, keys = {node}, {k} end node, k = v, 0 end v, node, k = node:next(k) -- If `v` is nil, move down one level, then continue iterating the node on that level (if any), or otherwise terminate the loop. if v == nil then if n == 0 then return nil end node, k, n = nodes[n], keys[n], n - 1 elseif test == nil or test(v) then return v, node, k -- If `test` is `is_node`, there's no point checking it again on the next loop. elseif node_check and is_node_is_test then node_check = false end end end end function Node:iterate_nodes(...) local args_n = select("#", ...) if args_n == 0 then return self:iterate(is_node) elseif args_n == 1 then local class = ... return self:iterate(function(value) return node_class(value) == class end) end local classes = {} for i = 1, args_n do classes[select(i, ...)] = true end return self:iterate(function(value) return classes[node_class(value)] end) end function Node:__tostring() local output = {} for i = 1, #self do insert(output, tostring(self[i])) end return concat(output) end function Node:clone() return deep_copy(self, "keep", true) end function Node:new_class(class) local t = {type = class} t.__index = t t = inherit_metamethods(t, self) node_classes[t] = class return setmetatable(t, self) end function Node:new(t) rawset(t, "_parse_data", nil) return setmetatable(t, self) end do local Proxy = {} function Proxy:__index(k) local v = Proxy[k] if v ~= nil then return v end return self.__chars[k] end function Proxy:__newindex(k, v) local key = self.__keys[k] if key then self.__chars[k] = v self.__parents[key] = v elseif key == false then error("Character is immutable.") else error("Invalid key.") end end function Proxy:build(a, b, c) local len = self.__len + 1 self.__chars[len] = a self.__parents[len] = b self.__keys[len] = c self.__len = len end function Proxy:iter(i) i = i + 1 local char = self.__chars[i] if char ~= nil then return i, self[i], self, self.__parents[i], self.__keys[i] end end function Node:new_proxy() return setmetatable({ __node = self, __chars = {}, __parents = {}, __keys = {}, __len = 0 }, Proxy) end end function export.node() return Node:new_class("node") end ------------------------------------------------------------------------------------ -- -- Parser -- ------------------------------------------------------------------------------------ local Parser = {} Parser.__index = Parser function Parser:get_layer(n) if n ~= nil then return rawget(self, #self + n) end return self.current_layer end function Parser:emit(a, b) local layer = self.current_layer if b ~= nil then insert(layer, signed_index(layer, a), b) else rawset(layer, #layer + 1, a) end end function Parser:emit_tokens(a, b) local layer = self.current_layer if b ~= nil then a = signed_index(layer, a) for i = 1, #b do insert(layer, a + i - 1, b[i]) end else local len = #layer for i = 1, #a do len = len + 1 rawset(layer, len, a[i]) end end end function Parser:remove(n) local layer = self.current_layer if n ~= nil then return remove(layer, signed_index(layer, n)) end local len = #layer local token = layer[len] layer[len] = nil return token end function Parser:replace(a, b) local layer = self.current_layer layer[signed_index(layer, a)] = b end -- Unlike default table.concat, this respects __tostring metamethods. function Parser:concat(a, b, c) if a == nil or a > 0 then return self:concat(0, a, b) end local layer, ret, n = self:get_layer(a), {}, 0 for i = b and signed_index(layer, b) or 1, c and signed_index(layer, c) or #layer do n = n + 1 ret[n] = tostring(layer[i]) end return concat(ret) end function Parser:emitted(delta) if delta == nil then delta = -1 end local get_layer, i = self.get_layer, 0 while true do local layer = get_layer(self, i) if layer == nil then return nil end local layer_len = #layer if -delta <= layer_len then return rawget(layer, layer_len + delta + 1) end delta = delta + layer_len i = i - 1 end end function Parser:push(route) local layer = {_parse_data = { head = self.head, route = route, }} self[#self + 1] = layer self.current_layer = layer end function Parser:push_sublayer(handler, inherit) local pdata = { handler = handler, sublayer = true, } local sublayer = { _parse_data = pdata, } if inherit then local layer_parse_data = self.current_layer._parse_data setmetatable(pdata, inherit_metamethods({ __index = layer_parse_data, __newindex = layer_parse_data }, getmetatable(layer_parse_data))) end self[#self + 1] = sublayer self.current_layer = sublayer end function Parser:pop() local len, layer = #self while true do layer = self[len] self[len] = nil len = len - 1 if len == 0 then self.current_layer = self break elseif layer._parse_data.sublayer == nil then self.current_layer = self[len] break end self:emit_tokens(layer) end return setmetatable(layer, nil) end function Parser:pop_sublayer() local len, layer = #self, self.current_layer self[len] = nil self.current_layer = len == 1 and self or self[len - 1] return setmetatable(layer, nil) end function Parser:get(route, ...) self:push(route) local layer = route(self, ...) if layer == nil then layer = self:traverse() end return layer end function Parser:try(route, ...) local failed_routes = self.failed_routes if failed_routes ~= nil then local failed_layer = get_nested(failed_routes, route, self.head) if failed_layer ~= nil then return false, failed_layer end end local layer = self:get(route, ...) return not layer._parse_data.fail, layer end function Parser:fail_route() local layer = self:pop() local pdata = layer._parse_data pdata.fail = true local layer_head = pdata.head set_nested(self, layer, "failed_routes", pdata.route, layer_head) self.head = layer_head return layer end function Parser:traverse() local consume, advance = self.consume, self.advance while true do local layer = consume(self) if layer ~= nil then return layer end advance(self) end end -- Converts a handler into a switch table the first time it's called, which avoids creating unnecessary objects, and prevents any scoping issues caused by parser methods being assigned to table keys before they've been declared. -- false is used as the default key. do local Switch = {} function Switch:__call(parser, this) return (self[this] or self[false])(parser, this) end function Parser:switch(func, t) local pdata = self.current_layer._parse_data -- Point handler to the new switch table if the calling function is the current handler. if pdata.handler == func then pdata.handler = t end return setmetatable(t, Switch) end end -- Generate a new parser class object, which is used as the template for any parser objects. These should be customized with additional/modified methods as needed. function Parser:new_class() local t = {} t.__index = t return setmetatable(inherit_metamethods(t, self), self) end -- Generate a new parser object, which is used for a specific parse. function Parser:new(text) return setmetatable({ text = text, head = 1 }, self) end function Parser:parse(data) local parser = self:new(data.text) local success, tokens = parser:try(unpack(data.route)) if #parser > 0 then -- This shouldn't happen. error("Parser exited with non-empty stack.") elseif success then local node = data.node return true, node[1]:new(tokens, unpack(node, 2)), parser elseif data.allow_fail then return false, nil, parser end error("Parser exited with failed route.") end export.class_else_type = class_else_type export.is_node = is_node export.tostring = tostring local ArrayParser = Parser:new_class() function ArrayParser:read(delta) local v = self.text[self.head + (delta or 0)] return v == nil and "" or v end function ArrayParser:advance(n) self.head = self.head + (n == nil and 1 or n) end function ArrayParser:jump(head) self.head = head end function ArrayParser:consume(this, ...) if this == nil then this = self:read() end local pdata = self.current_layer._parse_data return pdata.handler(self, this, ...) end function export.array_parser() return ArrayParser:new_class() end local StringParser = Parser:new_class() function StringParser:read(i, j) local head, i = self.head, i or 0 return sub(self.text, head + i, head + (j or i)) end function StringParser:advance(n) self.head = self.head + (n or self.current_layer._parse_data.step or 1) end function StringParser:jump(head) local pdata = self.current_layer._parse_data self.head, pdata.next, pdata.next_len = head, nil, nil end -- If `ignore_nonmatch` is set, any non-match segment before the match will be ignored. function StringParser:set_pattern(pattern, ignore_nonmatch) local pdata = self.current_layer._parse_data pdata.pattern, pdata.next, pdata.next_len = "(" .. pattern .. ")", nil, nil if ignore_nonmatch then pdata.ignore_nonmatch = true end end function StringParser:consume() local pdata = self.current_layer._parse_data local this = pdata.next -- Use `next` and `next_len` from the previous iteration, if available. if this then pdata.step, pdata.next, pdata.next_len = pdata.next_len, nil, nil return pdata.handler(self, this) end local text, head, loc1, loc2 = self.text, self.head loc1, loc2, this = find(text, pdata.pattern, head) -- If there was no match, default to find(text, "$", head), with `this` as -- the empty string. if not loc1 then this, loc1 = "", #text + 1 loc2 = loc1 - 1 -- zero-length matches cause loc2 to be less than loc1 end -- If `this` is at `head`, consume it. if loc1 == head then pdata.step = loc2 - loc1 + 1 -- If `ignore_nonmatch` is set, ignore everything before `this`, then -- consume it. elseif pdata.ignore_nonmatch then self.head, pdata.step = loc1, loc2 - loc1 + 1 -- Otherwise, consume everything before `this`, and memoize the match and -- match length; the length is dealt with separately, as it could be 0 if -- `next` is an index (e.g. if the pattern is the empty string). else this, pdata.step, pdata.next, pdata.next_len = sub(text, head, loc1 - 1), loc1 - head, this, loc2 - loc1 + 1 end return pdata.handler(self, this) end function export.string_parser() return StringParser:new_class() end return export itvslgsv46c1ywldkt63xzu5krykaov 26629 24264 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Modul:parser]] 24264 Scribunto text/plain local export = {} local scribunto_metamethods_module = "Module:Scribunto/metamethods" local table_deep_copy_module = "Module:table/deepCopy" local table_get_nested_module = "Module:table/getNested" local table_set_nested_module = "Module:table/setNested" local concat = table.concat local find = string.find local getmetatable = getmetatable local insert = table.insert local next = next local rawget = rawget local rawset = rawset local remove = table.remove local require = require local select = select local setmetatable = setmetatable local sub = string.sub local type = type local unpack = unpack or table.unpack -- Lua 5.2 compatibility local node_classes = {} local function deep_copy(...) deep_copy = require(table_deep_copy_module) return deep_copy(...) end local function get_nested(...) get_nested = require(table_get_nested_module) return get_nested(...) end local function set_nested(...) set_nested = require(table_set_nested_module) return set_nested(...) end --[==[ 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 metamethods local function get_metamethods() -- Use require, since lookup times are much slower with mw.loadData. metamethods, get_metamethods = require(scribunto_metamethods_module), nil return metamethods end ------------------------------------------------------------------------------------ -- -- Helper functions -- ------------------------------------------------------------------------------------ local function inherit_metamethods(child, parent) if parent then for method, value in next, parent do if child[method] == nil and (metamethods or get_metamethods())[method] ~= nil then child[method] = value end end end return child end local function signed_index(t, n) return n and n <= 0 and #t + 1 + n or n end local function is_node(value) if value == nil then return false end local mt = getmetatable(value) return not (mt == nil or node_classes[mt] == nil) end local function node_class(value) if value == nil then return nil end local mt = getmetatable(value) if mt == nil then return nil end return mt ~= nil and node_classes[mt] or nil end local function class_else_type(value) if value == nil then return type(value) end local mt = getmetatable(value) if mt == nil then return type(value) end local class = node_classes[mt] return class == nil and type(value) or class end -- Recursively calling tostring() adds to the C stack (limit: 200), whereas -- calling __tostring metamethods directly does not. Occasionally relevant when -- dealing with very deep nesting. local tostring do local _tostring = _G.tostring function tostring(value) if is_node(value) then return value:__tostring(value) end return _tostring(value) end end ------------------------------------------------------------------------------------ -- -- Nodes -- ------------------------------------------------------------------------------------ local Node = {} Node.__index = Node function Node:next(i) i = i + 1 return self[i], self, i end --[==[ Implements recursive iteration over a node tree. By default, when a node is encountered (which may contain other nodes), it is returned on the first iteration, and then any child nodes are returned on each subsequent iteration; the same process is then followed if any of those children contain nodes themselves. Once a particular node has been fully traversed, the iterator then continues with any sibling nodes. The iterator will use the `next` method of each node to traverse it, which may differ depending on the node class. Each iteration returns three values: `value`, `node` and `key`. Together, these can be used to manipulate the node tree at any given point without needing to know the full structure. Note that when the input node is returned on the first iteration, `node` and `key` will be nil. The optional argument `test` can be used to limit the return values. This should be a function that returns a boolean value, where a return value of true means that the child will be returned by the iterator. If a node is not returned by the iterator, it will still be traversed, as it may contain children that should be returned. The method `iterate_nodes` is provided as a special instance of iterate which uses `is_node` as the test.]==] function Node:iterate(test) local node, k, n, nodes, keys, returned_self = self, 0, 0 -- Special case if `test` is `is_node`. local is_node_is_test = test == is_node return function() if not returned_self then returned_self = true if test == nil or test(self) then return self end end -- Get `v`, which is the value at the last-returned key of the current node; if `v` is a node, it will be iterated over (i.e. recursive iteration). By default, `v` will be the last-returned value, but looking it up here means that any modifications made to the node during the loop will be taken into account. This makes it possible to swap one node out for something else (e.g. another node), or to remove it entirely, without being locked into recursively iterating over the old node; instead, the new node (if any) will be iterated over. This means node trees can be modified on-the-fly during the course of a single loop. local v, node_check = node[k], true while true do -- If `v` is a node, memoize the current node and key, then iterate over it. if node_check and is_node(v) then -- `n` is the current memo level. n = n + 1 if nodes then nodes[n], keys[n] = node, k else nodes, keys = {node}, {k} end node, k = v, 0 end v, node, k = node:next(k) -- If `v` is nil, move down one level, then continue iterating the node on that level (if any), or otherwise terminate the loop. if v == nil then if n == 0 then return nil end node, k, n = nodes[n], keys[n], n - 1 elseif test == nil or test(v) then return v, node, k -- If `test` is `is_node`, there's no point checking it again on the next loop. elseif node_check and is_node_is_test then node_check = false end end end end function Node:iterate_nodes(...) local args_n = select("#", ...) if args_n == 0 then return self:iterate(is_node) elseif args_n == 1 then local class = ... return self:iterate(function(value) return node_class(value) == class end) end local classes = {} for i = 1, args_n do classes[select(i, ...)] = true end return self:iterate(function(value) return classes[node_class(value)] end) end function Node:__tostring() local output = {} for i = 1, #self do insert(output, tostring(self[i])) end return concat(output) end function Node:clone() return deep_copy(self, "keep", true) end function Node:new_class(class) local t = {type = class} t.__index = t t = inherit_metamethods(t, self) node_classes[t] = class return setmetatable(t, self) end function Node:new(t) rawset(t, "_parse_data", nil) return setmetatable(t, self) end do local Proxy = {} function Proxy:__index(k) local v = Proxy[k] if v ~= nil then return v end return self.__chars[k] end function Proxy:__newindex(k, v) local key = self.__keys[k] if key then self.__chars[k] = v self.__parents[key] = v elseif key == false then error("Character is immutable.") else error("Invalid key.") end end function Proxy:build(a, b, c) local len = self.__len + 1 self.__chars[len] = a self.__parents[len] = b self.__keys[len] = c self.__len = len end function Proxy:iter(i) i = i + 1 local char = self.__chars[i] if char ~= nil then return i, self[i], self, self.__parents[i], self.__keys[i] end end function Node:new_proxy() return setmetatable({ __node = self, __chars = {}, __parents = {}, __keys = {}, __len = 0 }, Proxy) end end function export.node() return Node:new_class("node") end ------------------------------------------------------------------------------------ -- -- Parser -- ------------------------------------------------------------------------------------ local Parser = {} Parser.__index = Parser function Parser:get_layer(n) if n ~= nil then return rawget(self, #self + n) end return self.current_layer end function Parser:emit(a, b) local layer = self.current_layer if b ~= nil then insert(layer, signed_index(layer, a), b) else rawset(layer, #layer + 1, a) end end function Parser:emit_tokens(a, b) local layer = self.current_layer if b ~= nil then a = signed_index(layer, a) for i = 1, #b do insert(layer, a + i - 1, b[i]) end else local len = #layer for i = 1, #a do len = len + 1 rawset(layer, len, a[i]) end end end function Parser:remove(n) local layer = self.current_layer if n ~= nil then return remove(layer, signed_index(layer, n)) end local len = #layer local token = layer[len] layer[len] = nil return token end function Parser:replace(a, b) local layer = self.current_layer layer[signed_index(layer, a)] = b end -- Unlike default table.concat, this respects __tostring metamethods. function Parser:concat(a, b, c) if a == nil or a > 0 then return self:concat(0, a, b) end local layer, ret, n = self:get_layer(a), {}, 0 for i = b and signed_index(layer, b) or 1, c and signed_index(layer, c) or #layer do n = n + 1 ret[n] = tostring(layer[i]) end return concat(ret) end function Parser:emitted(delta) if delta == nil then delta = -1 end local get_layer, i = self.get_layer, 0 while true do local layer = get_layer(self, i) if layer == nil then return nil end local layer_len = #layer if -delta <= layer_len then return rawget(layer, layer_len + delta + 1) end delta = delta + layer_len i = i - 1 end end function Parser:push(route) local layer = {_parse_data = { head = self.head, route = route, }} self[#self + 1] = layer self.current_layer = layer end function Parser:push_sublayer(handler, inherit) local pdata = { handler = handler, sublayer = true, } local sublayer = { _parse_data = pdata, } if inherit then local layer_parse_data = self.current_layer._parse_data setmetatable(pdata, inherit_metamethods({ __index = layer_parse_data, __newindex = layer_parse_data }, getmetatable(layer_parse_data))) end self[#self + 1] = sublayer self.current_layer = sublayer end function Parser:pop() local len, layer = #self while true do layer = self[len] self[len] = nil len = len - 1 if len == 0 then self.current_layer = self break elseif layer._parse_data.sublayer == nil then self.current_layer = self[len] break end self:emit_tokens(layer) end return setmetatable(layer, nil) end function Parser:pop_sublayer() local len, layer = #self, self.current_layer self[len] = nil self.current_layer = len == 1 and self or self[len - 1] return setmetatable(layer, nil) end function Parser:get(route, ...) self:push(route) local layer = route(self, ...) if layer == nil then layer = self:traverse() end return layer end function Parser:try(route, ...) local failed_routes = self.failed_routes if failed_routes ~= nil then local failed_layer = get_nested(failed_routes, route, self.head) if failed_layer ~= nil then return false, failed_layer end end local layer = self:get(route, ...) return not layer._parse_data.fail, layer end function Parser:fail_route() local layer = self:pop() local pdata = layer._parse_data pdata.fail = true local layer_head = pdata.head set_nested(self, layer, "failed_routes", pdata.route, layer_head) self.head = layer_head return layer end function Parser:traverse() local consume, advance = self.consume, self.advance while true do local layer = consume(self) if layer ~= nil then return layer end advance(self) end end -- Converts a handler into a switch table the first time it's called, which avoids creating unnecessary objects, and prevents any scoping issues caused by parser methods being assigned to table keys before they've been declared. -- false is used as the default key. do local Switch = {} function Switch:__call(parser, this) return (self[this] or self[false])(parser, this) end function Parser:switch(func, t) local pdata = self.current_layer._parse_data -- Point handler to the new switch table if the calling function is the current handler. if pdata.handler == func then pdata.handler = t end return setmetatable(t, Switch) end end -- Generate a new parser class object, which is used as the template for any parser objects. These should be customized with additional/modified methods as needed. function Parser:new_class() local t = {} t.__index = t return setmetatable(inherit_metamethods(t, self), self) end -- Generate a new parser object, which is used for a specific parse. function Parser:new(text) return setmetatable({ text = text, head = 1 }, self) end function Parser:parse(data) local parser = self:new(data.text) local success, tokens = parser:try(unpack(data.route)) if #parser > 0 then -- This shouldn't happen. error("Parser exited with non-empty stack.") elseif success then local node = data.node return true, node[1]:new(tokens, unpack(node, 2)), parser elseif data.allow_fail then return false, nil, parser end error("Parser exited with failed route.") end export.class_else_type = class_else_type export.is_node = is_node export.tostring = tostring local ArrayParser = Parser:new_class() function ArrayParser:read(delta) local v = self.text[self.head + (delta or 0)] return v == nil and "" or v end function ArrayParser:advance(n) self.head = self.head + (n == nil and 1 or n) end function ArrayParser:jump(head) self.head = head end function ArrayParser:consume(this, ...) if this == nil then this = self:read() end local pdata = self.current_layer._parse_data return pdata.handler(self, this, ...) end function export.array_parser() return ArrayParser:new_class() end local StringParser = Parser:new_class() function StringParser:read(i, j) local head, i = self.head, i or 0 return sub(self.text, head + i, head + (j or i)) end function StringParser:advance(n) self.head = self.head + (n or self.current_layer._parse_data.step or 1) end function StringParser:jump(head) local pdata = self.current_layer._parse_data self.head, pdata.next, pdata.next_len = head, nil, nil end -- If `ignore_nonmatch` is set, any non-match segment before the match will be ignored. function StringParser:set_pattern(pattern, ignore_nonmatch) local pdata = self.current_layer._parse_data pdata.pattern, pdata.next, pdata.next_len = "(" .. pattern .. ")", nil, nil if ignore_nonmatch then pdata.ignore_nonmatch = true end end function StringParser:consume() local pdata = self.current_layer._parse_data local this = pdata.next -- Use `next` and `next_len` from the previous iteration, if available. if this then pdata.step, pdata.next, pdata.next_len = pdata.next_len, nil, nil return pdata.handler(self, this) end local text, head, loc1, loc2 = self.text, self.head loc1, loc2, this = find(text, pdata.pattern, head) -- If there was no match, default to find(text, "$", head), with `this` as -- the empty string. if not loc1 then this, loc1 = "", #text + 1 loc2 = loc1 - 1 -- zero-length matches cause loc2 to be less than loc1 end -- If `this` is at `head`, consume it. if loc1 == head then pdata.step = loc2 - loc1 + 1 -- If `ignore_nonmatch` is set, ignore everything before `this`, then -- consume it. elseif pdata.ignore_nonmatch then self.head, pdata.step = loc1, loc2 - loc1 + 1 -- Otherwise, consume everything before `this`, and memoize the match and -- match length; the length is dealt with separately, as it could be 0 if -- `next` is an index (e.g. if the pattern is the empty string). else this, pdata.step, pdata.next, pdata.next_len = sub(text, head, loc1 - 1), loc1 - head, this, loc2 - loc1 + 1 end return pdata.handler(self, this) end function export.string_parser() return StringParser:new_class() end return export itvslgsv46c1ywldkt63xzu5krykaov Citakan:anchor 10 4742 26622 10443 2025-12-15T16:19:04Z id>Swarabakti 0 26622 wikitext text/x-wiki {{#if:{{{ 1|}}} |<span id="{{anchorencode:{{{ 1|}}}}}"></span>{{#if:{{{ 2|}}} |<span id="{{anchorencode:{{{ 2|}}}}}"></span>{{#if:{{{ 3|}}} |<span id="{{anchorencode:{{{ 3|}}}}}"></span>{{#if:{{{ 4|}}} |<span id="{{anchorencode:{{{ 4|}}}}}"></span>{{#if:{{{ 5|}}} |<span id="{{anchorencode:{{{ 5|}}}}}"></span>{{#if:{{{ 6|}}} |<span id="{{anchorencode:{{{ 6|}}}}}"></span>{{#if:{{{ 7|}}} |<span id="{{anchorencode:{{{ 7|}}}}}"></span>{{#if:{{{ 8|}}} |<span id="{{anchorencode:{{{ 8|}}}}}"></span>{{#if:{{{ 9|}}} |<span id="{{anchorencode:{{{ 9|}}}}}"></span>{{#if:{{{10|}}} |<span id="{{anchorencode:{{{10|}}}}}"></span>{{#if:{{{11|}}} |<strong class="error">Terlalu banyak jangkar, jumlah maksimal hanya sepuluh</strong>}} }} }} }} }} }} }} }} }} }} }}<noinclude>[[Kategori:Templat umum]]</noinclude> l2yb1elxkm8hp832fxd5oo4w38jb3ky 26623 26622 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Templat:anchor]] 26622 wikitext text/x-wiki {{#if:{{{ 1|}}} |<span id="{{anchorencode:{{{ 1|}}}}}"></span>{{#if:{{{ 2|}}} |<span id="{{anchorencode:{{{ 2|}}}}}"></span>{{#if:{{{ 3|}}} |<span id="{{anchorencode:{{{ 3|}}}}}"></span>{{#if:{{{ 4|}}} |<span id="{{anchorencode:{{{ 4|}}}}}"></span>{{#if:{{{ 5|}}} |<span id="{{anchorencode:{{{ 5|}}}}}"></span>{{#if:{{{ 6|}}} |<span id="{{anchorencode:{{{ 6|}}}}}"></span>{{#if:{{{ 7|}}} |<span id="{{anchorencode:{{{ 7|}}}}}"></span>{{#if:{{{ 8|}}} |<span id="{{anchorencode:{{{ 8|}}}}}"></span>{{#if:{{{ 9|}}} |<span id="{{anchorencode:{{{ 9|}}}}}"></span>{{#if:{{{10|}}} |<span id="{{anchorencode:{{{10|}}}}}"></span>{{#if:{{{11|}}} |<strong class="error">Terlalu banyak jangkar, jumlah maksimal hanya sepuluh</strong>}} }} }} }} }} }} }} }} }} }} }}<noinclude>[[Kategori:Templat umum]]</noinclude> l2yb1elxkm8hp832fxd5oo4w38jb3ky simpun 0 4847 26614 22693 2026-07-08T01:44:49Z Ezagren 26 26614 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|sim|pun}} {{-adj-|bjn}} # rapi; tuntung #* ''kamarnya nyaman banar dilihat, '''simpun''' barataan.'' {{-terjemahan-}} * Basa Indunisia: rapi (tentang keadaan suatu barang) (a) sdi3b6rbztb4r7a784usuawxr93v7zi babalur 0 6913 26589 23905 2026-07-07T23:41:00Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26589 wikitext text/x-wiki [[Barakas:As the days get cooler and the foliage turns from crisp green to brilliant orange and red, The Bertie will be there to help you make the transition too. The washed navy stripe in this classic shirt makes for a timeless, versatile style.jpg|300px|jmpl|al=Binian mamakai baju mal babalur|Binian mamakai baju mal babalur]] =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ba|ba|lur}} {{-adj-|bjn}} # bagaris-garis bapanjang ka bawah #*''bahari baju kiyama [[mal]]nya katia '''babalur''' haja kam'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 0dvktwtbtyrk6wedtkn2te95mzeaaxd hamain 0 6914 26590 23880 2026-07-07T23:50:52Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26590 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ha|ma|in}} {{-n-|bjn}} # kain putih babuncu ampat nang dipakai lawan hatib wayah bakutbah sumbahyang jumahat #*''kai katinggalan hamain sidin'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. oja2q8kf81nrgjka5judy60tdkvzd2o kamija 0 6915 26592 23941 2026-07-07T23:57:07Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26592 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ka|mi|ja}} {{-n-|bjn}} # Baju nang batangan lawan bakima matan atas sampai bawah, rajin bakarah lawan juwa diulah matan katun, linen, dll. #*''kamija hanyar nah si Udin'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. l9j0e7vfma0o19k1hk51sf2yby1wecv kikit 0 6916 26593 23882 2026-07-07T23:58:37Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26593 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ki|kit}} {{-n-|bjn}} # batis hayam #*''adingku katuju banar mamakan kikit nang basambal'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 9voe2r2munhrwuyv2bhbliu41fvszza kuning babanyun 0 6917 26594 23901 2026-07-07T23:59:28Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26594 wikitext text/x-wiki [[Barakas:White-Yellow-Rose-Sitia-Crete.jpg|300px|jmpl|al=Kambang mawar bakalir kuning babanyun|Kambang mawar bakalir kuning babanyun]] =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ku|ning ba|ba|nyun}} {{-adj-|bjn}} # kalir kuning nang kaputih-putihan #*''bahari baju kiyama ampun mama kalirnya iya kuning babanyun'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. [[Tumbung:Ngaran kalir]] 0imrje3k7ih8lk6hkaz0qra9xtb1571 kain padang 0 6918 26591 23884 2026-07-07T23:56:00Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26591 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ka|in pa|dang}} {{-n-|bjn}} # kain sutra nang halus wayah dijapai lawan [[mancarunung]] #*''handak juwa baisi baju kiyama nang bahannya kain padang'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. shzjg4aixb2r0i6rlwujnki7ovg9znk pahadring 0 6919 26600 23899 2026-07-08T00:10:36Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26600 wikitext text/x-wiki [[Barakas:National Consensus Commission members meeting October 4 2025 (PID-0061256).jpg|300px|jmpl|al=Urang wayah pahadring|Urang wayah pahadring]] =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|pa|ha|dring}} {{-v-|bjn}} # bakumpulan nang mambahas ihwal gasan marumusakan masalah, barunding, bacangkurah gasan mancapai tujuan #*''abah disaru urang tadi umpat pahadring di rumah [[pambakal]]'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. e5c6w1p9v3wm64zvgmo1rdmk6201lk8 panggula 0 6920 26602 23886 2026-07-08T00:11:21Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26602 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|pang|gu|la}} {{-n-|bjn}} # tukang ulah gula #*''mulai subuh abah Hadran tulak bagawi panggula'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 6t5eujod2fo57w1vxc3gart3zi6khla paparisan 0 6921 26605 23888 2026-07-08T00:13:03Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26605 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|pa|pa|ri|san}} {{-n-|bjn}} # kain paris mang murah lawan mutunya randah #*''[[kakamban]] ikam matan paparisan kah diulah?'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 9uotdd8hv29rnycrdska9trfnry7uv5 tutungkat 0 6922 26611 23889 2026-07-08T00:19:59Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26611 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ba|ba|lur}} {{-n-|bjn}} # alat nang dipakai gasan manjauahkan sarung nang dipakai matan basunat #*''kada kawa lapas datang tutungkat si Anang imbahnya habis basunat'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. r1il1s6nn1hntfcgm15819yaa1ruaxe tipa 0 6923 26610 23891 2026-07-08T00:19:25Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26610 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ti|pa}} {{-n-|bjn}} # wadah gasan maandak sirih, nasi wan lain-lain #*''jangan dikipaiakan tipa ampun nini lah cu'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. tjosjkxxomdx48rc1s3nkkbkn3x3q6r timbaran 0 6924 26609 23892 2026-07-08T00:18:22Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26609 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|tim|ba|ran}} {{-n-|bjn}} # tali nang diulah matan [[kulipak]] kayu #*''bakalayangan jangan mamakai timbaran, [[mahuhulut]] ngarannya'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 1x2vhqm82ooggyvd9ronhmyiwi4cntt tangkiring 0 6925 26608 23938 2026-07-08T00:17:38Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26608 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|tang|ki|ring}} {{-adj-|bjn}} # wadah nang diulah matan paikat nang hudah diraut badahulu, mahirip bakul #*''bahari baju kiyama [[mal]]nya katia '''babalur''' haja kam'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 73d2p77wpp8t5b11h6rng5lys6ym982 salungkui 0 6926 26606 23894 2026-07-08T00:15:09Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26606 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|sa|lung|kui}} {{-n-|bjn}} # tukup kapala nang diulah matan tapih #*''handak bakakamban kah handak basulungkui'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 14h8grjmg65z10obdrm1jwk4sjxlnvr pangkat 0 6927 26604 23939 2026-07-08T00:12:19Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26604 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|pang|kat}} {{-n-|bjn}} # kamar saurangan gasan kaluarga nang badiam di dalam Balai wadah urang Bukit bagana #*''barapa pangkat di rumah hanyar nitu lah'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. baweu1hbfr1w8rxixtlphloowtbe2ib marait 0 6928 26597 25205 2026-07-08T00:08:19Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26597 wikitext text/x-wiki =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ma|ra|it}} {{-v-|bjn}} # [[mahubungakan]] #*''kartak nang ngini maraitakan lawan timbuk di balakang rumah pambakal'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. qbfl8uv5wf981f9eflw8xxbageki6tr lubau 0 6929 26595 23898 2026-07-08T00:00:59Z InternetArchiveBot 300 Rescuing 1 sources and tagging 0 as dead.) #IABot (v2.0.9.5 26595 wikitext text/x-wiki [[Barakas:Kain Jarik dari Batik Lasem motif Flora.jpg|150px|jmpl|al=Kain batik nang baisi mal lubau|Kain batik nang baisi mal lubau]] =={{basa|bjn}}== {{kapala|bjn}} : {{punggalan|bjn|ba|ba|lur}} {{-adj-|bjn}} # mal ganal-ganal di di tapih lakian #*''tapasakan tapih kai nang lubau nitu lah'' {{-rujukan-}} * Maswan, Syukrani; Umar, Rasyidi; Musaba, Zulkifli. 1987. ''[https://web.archive.org/web/20251025202201/https://repositori.kemendikdasmen.go.id/12698/1/PAKAIAN%20ADAT%20TRADISIONAL%20DAERAH%20KALIMANTAN%20SELATAN.pdf Pakaian Adat Tradisional Daerah Kalimantan Selatan]''. Jakarta: Departemen Pendidikan dan Kebudayaan. 2iadxqgctvzrv68cb0af6jxhxsj2ckl Modul:string/char 828 6936 26567 2025-11-08T16:56:04Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26567 Scribunto text/plain local math_module = "Module:math" local char = string.char local error = error local format = string.format local pcall = pcall local select = select local tonumber = tonumber local type = type local function to_hex(...) to_hex = require(math_module).to_hex return to_hex(...) end local function codepoint_err(cp, i) -- Throw error: to_hex can only return integers, so only show the bad value -- if it can be converted into something that looks like a codepoint. local success, result = pcall(to_hex, cp, true) error(format( "bad argument #%d to 'string/char' (codepoint between 0x0 and 0x10FFFF expected%s)", i, success and "; got " .. result or ""), i + 3) end local function utf8_char(n, i, v, ...) local cp = tonumber(v) if cp == nil then error(format("bad argument #%d to 'char' (number expected; got %s)", i, type(v)), i + 2) elseif cp < 0 then codepoint_err(cp, i) elseif cp < 0x80 then if i == n then return cp end return cp, utf8_char(n, i + 1, ...) elseif cp < 0x800 then if i == n then return 0xC0 + cp / 0x40, 0x80 + cp % 0x40 end return 0xC0 + cp / 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) elseif cp < 0x10000 then -- Don't return "?" for surrogates, like mw.ustring.char does, as they -- have legitimate uses (e.g. in JSON). if i == n then return 0xE0 + cp / 0x1000, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40 end return 0xE0 + cp / 0x1000, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) elseif cp < 0x110000 then if i == n then return 0xF0 + cp / 0x40000, 0x80 + cp / 0x1000 % 0x40, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40 end return 0xF0 + cp / 0x40000, 0x80 + cp / 0x1000 % 0x40, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) end codepoint_err(cp, i) end return function(...) local n = select("#", ...) if n ~= 0 then return char(utf8_char(n, 1, ...)) end end qud4hkutkfwzx4yv3ba5z040h7pzaqb 26568 23972 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/char]] 23972 Scribunto text/plain local math_module = "Module:math" local char = string.char local error = error local format = string.format local pcall = pcall local select = select local tonumber = tonumber local type = type local function to_hex(...) to_hex = require(math_module).to_hex return to_hex(...) end local function codepoint_err(cp, i) -- Throw error: to_hex can only return integers, so only show the bad value -- if it can be converted into something that looks like a codepoint. local success, result = pcall(to_hex, cp, true) error(format( "bad argument #%d to 'string/char' (codepoint between 0x0 and 0x10FFFF expected%s)", i, success and "; got " .. result or ""), i + 3) end local function utf8_char(n, i, v, ...) local cp = tonumber(v) if cp == nil then error(format("bad argument #%d to 'char' (number expected; got %s)", i, type(v)), i + 2) elseif cp < 0 then codepoint_err(cp, i) elseif cp < 0x80 then if i == n then return cp end return cp, utf8_char(n, i + 1, ...) elseif cp < 0x800 then if i == n then return 0xC0 + cp / 0x40, 0x80 + cp % 0x40 end return 0xC0 + cp / 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) elseif cp < 0x10000 then -- Don't return "?" for surrogates, like mw.ustring.char does, as they -- have legitimate uses (e.g. in JSON). if i == n then return 0xE0 + cp / 0x1000, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40 end return 0xE0 + cp / 0x1000, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) elseif cp < 0x110000 then if i == n then return 0xF0 + cp / 0x40000, 0x80 + cp / 0x1000 % 0x40, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40 end return 0xF0 + cp / 0x40000, 0x80 + cp / 0x1000 % 0x40, 0x80 + cp / 0x40 % 0x40, 0x80 + cp % 0x40, utf8_char(n, i + 1, ...) end codepoint_err(cp, i) end return function(...) local n = select("#", ...) if n ~= 0 then return char(utf8_char(n, 1, ...)) end end qud4hkutkfwzx4yv3ba5z040h7pzaqb Modul:memoize 828 6941 26569 2025-11-08T16:52:17Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26569 Scribunto text/plain local math_module = "Module:math" local table_pack_module = "Module:table/pack" local require = require local select = select local unpack = unpack or table.unpack -- Lua 5.2 compatibility -- table.pack: in Lua 5.2+, this is a function that wraps the parameters given -- into a table with the additional key `n` that contains the total number of -- parameters given. This is not available on Lua 5.1, so [[Module:table/pack]] -- provides the same functionality. local function pack(...) pack = require(table_pack_module) return pack(...) end local function sign(...) sign = require(math_module).sign return sign(...) end ----- M E M O I Z A T I O N----- -- Memoizes a function or callable table. -- Supports any number of arguments and return values. -- If the optional parameter `simple` is set, then the memoizer will use a faster implementation, but this is only compatible with one argument and one return value. If `simple` is set, additional arguments will be accepted, but this should only be done if those arguments will always be the same. -- Sentinels. local _nil, neg_0, pos_nan, neg_nan = {}, {}, {}, {} -- Certain values can't be used as table keys, so they require sentinels as well: e.g. f("foo", nil, "bar") would be memoized at memo["foo"][_nil]["bar"][memo]. These values are: -- nil. -- -0, which is equivalent to 0 in most situations, but becomes "-0" on conversion to string; it also behaves differently in some operations (e.g. 1/a evaluates to inf if a is 0, but -inf if a is -0). -- NaN and -NaN, which are the only values for which n == n is false; they only seem to differ on conversion to string ("nan" and "-nan"). local function get_key(x) if x == x then return x == nil and _nil or x == 0 and 1 / x < 0 and neg_0 or x end return sign(x) == 1 and pos_nan or neg_nan end -- Return values are memoized as tables of return values, which are looked up using each input argument as a key, followed by `memo`. e.g. if the input arguments were (1, 2, 3), the memo would be located at t[1][2][3][memo]. `memo` is always used as the final lookup key so that (for example) the memo for f(1, 2, 3), f[1][2][3][memo], doesn't interfere with the memo for f(1, 2), f[1][2][memo]. local function get_memo(memo, n, nargs, key, ...) key = get_key(key) local next_memo = memo[key] if next_memo == nil then next_memo = {} memo[key] = next_memo end memo = next_memo return n == nargs and memo or get_memo(memo, n + 1, nargs, ...) end -- Used to catch the function output values instead of using a table directly, -- since pack() returns a table with the key `n`, giving the number of return -- values, even if they are nil. This ensures that any nil return values after -- the last non-nil value will always be present (e.g. pack() gives {n = 0}, -- pack(nil) gives {n = 1}, pack(nil, "foo", nil) gives {[2] = "foo", n = 3} -- etc.). The distinction between nil and nothing affects some native functions -- (e.g. tostring() throws an error, but tostring(nil) returns "nil"), so it -- needs to be reconstructable from the memo. local function memoize_then_return(memo, _memo, ...) _memo[memo] = pack(...) return ... end return function(func, simple) local memo = {} if simple then return function(...) local key = get_key((...)) local output = memo[key] if output == nil then output = func(...) memo[key] = output == nil and _nil or output return output elseif output == _nil then return nil end return output end end return function(...) local nargs = select("#", ...) -- Since all possible inputs need to be memoized (including true, false -- and nil), the memo table itself is used as a sentinel to ensure that -- the table of arguments will always have a unique key. local _memo = nargs == 0 and memo or get_memo(memo, 1, nargs, ...) local output = _memo[memo] -- If get_memo() returned nil, call `func` with the arguments and catch -- the output with memoize_then_return(); this packs the return values -- into a table to memoize them, then returns them. Since the return -- values are available to it as `...`, this avoids the need to call -- unpack() on the memoized table on the first call, as they can be -- returned directly. if output == nil then return memoize_then_return(memo, _memo, func(...)) end -- Unpack from 1 to the original number of return values (memoized at -- key `n`); unpack() returns nil for any values not in output. return unpack(output, 1, output.n) end end 8gmyvbgmtmwh2pu7neciscs7liw1v30 26570 23981 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:memoize]] 23981 Scribunto text/plain local math_module = "Module:math" local table_pack_module = "Module:table/pack" local require = require local select = select local unpack = unpack or table.unpack -- Lua 5.2 compatibility -- table.pack: in Lua 5.2+, this is a function that wraps the parameters given -- into a table with the additional key `n` that contains the total number of -- parameters given. This is not available on Lua 5.1, so [[Module:table/pack]] -- provides the same functionality. local function pack(...) pack = require(table_pack_module) return pack(...) end local function sign(...) sign = require(math_module).sign return sign(...) end ----- M E M O I Z A T I O N----- -- Memoizes a function or callable table. -- Supports any number of arguments and return values. -- If the optional parameter `simple` is set, then the memoizer will use a faster implementation, but this is only compatible with one argument and one return value. If `simple` is set, additional arguments will be accepted, but this should only be done if those arguments will always be the same. -- Sentinels. local _nil, neg_0, pos_nan, neg_nan = {}, {}, {}, {} -- Certain values can't be used as table keys, so they require sentinels as well: e.g. f("foo", nil, "bar") would be memoized at memo["foo"][_nil]["bar"][memo]. These values are: -- nil. -- -0, which is equivalent to 0 in most situations, but becomes "-0" on conversion to string; it also behaves differently in some operations (e.g. 1/a evaluates to inf if a is 0, but -inf if a is -0). -- NaN and -NaN, which are the only values for which n == n is false; they only seem to differ on conversion to string ("nan" and "-nan"). local function get_key(x) if x == x then return x == nil and _nil or x == 0 and 1 / x < 0 and neg_0 or x end return sign(x) == 1 and pos_nan or neg_nan end -- Return values are memoized as tables of return values, which are looked up using each input argument as a key, followed by `memo`. e.g. if the input arguments were (1, 2, 3), the memo would be located at t[1][2][3][memo]. `memo` is always used as the final lookup key so that (for example) the memo for f(1, 2, 3), f[1][2][3][memo], doesn't interfere with the memo for f(1, 2), f[1][2][memo]. local function get_memo(memo, n, nargs, key, ...) key = get_key(key) local next_memo = memo[key] if next_memo == nil then next_memo = {} memo[key] = next_memo end memo = next_memo return n == nargs and memo or get_memo(memo, n + 1, nargs, ...) end -- Used to catch the function output values instead of using a table directly, -- since pack() returns a table with the key `n`, giving the number of return -- values, even if they are nil. This ensures that any nil return values after -- the last non-nil value will always be present (e.g. pack() gives {n = 0}, -- pack(nil) gives {n = 1}, pack(nil, "foo", nil) gives {[2] = "foo", n = 3} -- etc.). The distinction between nil and nothing affects some native functions -- (e.g. tostring() throws an error, but tostring(nil) returns "nil"), so it -- needs to be reconstructable from the memo. local function memoize_then_return(memo, _memo, ...) _memo[memo] = pack(...) return ... end return function(func, simple) local memo = {} if simple then return function(...) local key = get_key((...)) local output = memo[key] if output == nil then output = func(...) memo[key] = output == nil and _nil or output return output elseif output == _nil then return nil end return output end end return function(...) local nargs = select("#", ...) -- Since all possible inputs need to be memoized (including true, false -- and nil), the memo table itself is used as a sentinel to ensure that -- the table of arguments will always have a unique key. local _memo = nargs == 0 and memo or get_memo(memo, 1, nargs, ...) local output = _memo[memo] -- If get_memo() returned nil, call `func` with the arguments and catch -- the output with memoize_then_return(); this packs the return values -- into a table to memoize them, then returns them. Since the return -- values are available to it as `...`, this avoids the need to call -- unpack() on the memoized table on the first call, as they can be -- returned directly. if output == nil then return memoize_then_return(memo, _memo, func(...)) end -- Unpack from 1 to the original number of return values (memoized at -- key `n`); unpack() returns nil for any values not in output. return unpack(output, 1, output.n) end end 8gmyvbgmtmwh2pu7neciscs7liw1v30 Modul:string/charsetEscape 828 6942 26577 2025-11-08T16:57:02Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26577 Scribunto text/plain local gsub = string.gsub local chars local function get_chars() chars, get_chars = { ["\000"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^", }, nil return chars end --[==[Escapes the magic characters used in pattern character sets: {%-]^}, and converts the null character to {%z}.]==] return function(str) return (gsub(str, "[%z%%%-%]^]", chars or get_chars())) end jrbz2u5ynegbco1b6oqpnqiz7xje0en 26578 23982 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/charsetEscape]] 23982 Scribunto text/plain local gsub = string.gsub local chars local function get_chars() chars, get_chars = { ["\000"] = "%z", ["%"] = "%%", ["-"] = "%-", ["]"] = "%]", ["^"] = "%^", }, nil return chars end --[==[Escapes the magic characters used in pattern character sets: {%-]^}, and converts the null character to {%z}.]==] return function(str) return (gsub(str, "[%z%%%-%]^]", chars or get_chars())) end jrbz2u5ynegbco1b6oqpnqiz7xje0en Modul:fun/isCallable 828 6943 26660 2025-11-08T17:06:21Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26660 Scribunto text/plain local debug_track_module = "Module:debug/track" local table_get_metamethod_module = "Module:table/getMetamethod" local require = require local type = type local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function get_metamethod(...) get_metamethod = require(table_get_metamethod_module) return get_metamethod(...) end --[==[ Return {true} if the input is a function or functor (an object which can be called like a function, because it has a {__call} metamethod). Note: if the input is an object with a {__call} metamethod, but this function is not able to find it because the object's metatable is protected with {__metatable}, then it will return {false} by default, or {nil} if the {allow_maybe} flag is set.]==] return function(obj, allow_maybe) if type(obj) == "function" then return true end -- An object is callable if it has a __call metamethod, so try to get it -- with get_metamethod(). local success, __call = get_metamethod(obj, "__call") -- If this succeeds, `obj` will only be callable if the __call metamethod is -- a function (i.e. it can't itself be a callable table), so don't recurse -- to check it. if __call and type(__call) == "function" then return true -- If not, then the metatable is protected, so it's not possible to know if -- `obj` is callable without actually calling it. elseif not success then debug_track("fun/isCallable/protected metatable") if allow_maybe then return nil end end return false end nr6fmojt64uvmsick8bst0i74ec4d2z 26661 23984 2026-07-08T05:00:43Z Sibiru45 115 1 ralatan matan [[:id:Modul:fun/isCallable]] 23984 Scribunto text/plain local debug_track_module = "Module:debug/track" local table_get_metamethod_module = "Module:table/getMetamethod" local require = require local type = type local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function get_metamethod(...) get_metamethod = require(table_get_metamethod_module) return get_metamethod(...) end --[==[ Return {true} if the input is a function or functor (an object which can be called like a function, because it has a {__call} metamethod). Note: if the input is an object with a {__call} metamethod, but this function is not able to find it because the object's metatable is protected with {__metatable}, then it will return {false} by default, or {nil} if the {allow_maybe} flag is set.]==] return function(obj, allow_maybe) if type(obj) == "function" then return true end -- An object is callable if it has a __call metamethod, so try to get it -- with get_metamethod(). local success, __call = get_metamethod(obj, "__call") -- If this succeeds, `obj` will only be callable if the __call metamethod is -- a function (i.e. it can't itself be a callable table), so don't recurse -- to check it. if __call and type(__call) == "function" then return true -- If not, then the metatable is protected, so it's not possible to know if -- `obj` is callable without actually calling it. elseif not success then debug_track("fun/isCallable/protected metatable") if allow_maybe then return nil end end return false end nr6fmojt64uvmsick8bst0i74ec4d2z Modul:math 828 6945 26585 2025-11-08T16:32:12Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26585 Scribunto text/plain local export = {} local byte = string.byte local ceil = math.ceil local floor = math.floor local format = string.format local is_integer -- defined below local match = string.match local select = select local tonumber = tonumber local tonumber_ext -- defined below local tostring = tostring local type = type local INF = math.huge local function sign(x, signed_0) if x > 0 then return 1 elseif x < 0 then return -1 elseif x == 0 then -- 1/(+0) is infinity and 1/(-0) is -infinity. return signed_0 and (1 / x > 0 and 1 or -1) or 0 end -- NaN: convert to string with a forced sign prefix, and grab the first byte. local sign = byte(format("%+f", x)) return sign == 0x2B and 1 or -- + sign == 0x2D and -1 or -- - -- If there's no sign, throw an error. This shouldn't be possible, but -- avoids silent errors if it does happen. error("Internal error: cannot determine sign of " .. x) end --[==[ An extended version of {tonumber()}, which attempts to convert `x` to a number. Like {tonumber()}, it will convert from base 10 by default, and the optional parameter `base` can be used to specify a different base between 2 and 36, with the letters {A-Z} (case-insensitive) representing additional digits beyond {0-9}. When strings contain hexadecimal notation (e.g. {"0x100"}), base 16 is used as the default instead, but this is overridden if `base` is set to anything other than 16. This function differs from {tonumber()} in the following ways: * If `finite_real` is set, then the function will only return finite real numbers; inputs which would normally produce ±infinity or NaN will instead produce {nil}. * If `no_prefix` is set, then strings which start with {"0x"} will not be interpreted as containing hexadecimal notation, resulting in {nil}. * If `base` is explicitly set to {10}, then strings in hexadecimal notation will always return {nil}. This fixes a bug in {tonumber()}, which treats {base=10} the same as {base} being unset, causing base 16 to be used if `x` contains hexadecimal notation (e.g. {tonumber("0x10", 10)} returns {16}, whereas {tonumber_extended("0x10", 10)} returns {nil}).]==] function export.tonumber_extended(x, base, finite_real, no_prefix) -- TODO: tonumber() maxes out at 2^64 if the base is anything other than 10. -- TODO: support binary (0b) and octal (0o) prefixes. local n = tonumber(x, base) if not n or finite_real and (n ~= n or n == INF or n == -INF) then return nil -- If `base` is explicitly set to 10 (not simply nil), or `no_prefix` is set -- and `base` is nil or 16, filter out inputs that started with hexadecimal -- prefixes. Note that if `base` is anything else, the initial "0x" will -- have been interpreted as digits by tonumber() instead of a prefix (as "x" -- can be a digit from base 34 upwards), so there's no prefix to check for. elseif base == 10 or no_prefix and (base == nil or base == 16) then return not match(x, "^%s*[+-]?0[xX]()") and n or nil end return n end tonumber_ext = export.tonumber_extended --[==[ Converts `x` to an integer by removing the fractional portion (e.g. {3.5} becomes {3}, and {-2.9} becomes {-2}). This is equivalent to rounding down positive numbers and rounding up negative numbers. If conversion is not possible, returns {nil}.]==] function export.to_integer(x) x = tonumber(x) if not (x and x == x and x ~= INF and x ~= -INF) then return nil elseif x % 1 == 0 then return x -- Round-down positives. elseif x >= 0 then return floor(x) end --Round-up negatives. return ceil(x) end --[==[ Returns {1} if `x` is positive, {-1} if `x` is negative, or {0} if `x` is {0}. If `signed_0` is set, this function will only return either {1} or {-1}, and will make a distinction between [[w:signed zero|signed zeroes]] ({+0} and {-0}). This is useful when a {0} result could be disruptive (e.g. {x % 0}).]==] function export.sign(x, signed_0) return sign( tonumber(x) or error(format("bad argument #1 to 'sign' (number expected, got %s)", type(x)), 2), signed_0 ) end --[==[ Returns {true} if `x` is a finite real number, or {false} if not.]==] function export.is_finite_real_number(x) return x and x == x and not (x == INF or x == -INF) and type(x) == "number" end --[==[ Returns {true} if `x` is an integer, or {false} if not.]==] function export.is_integer(x) return x and type(x) == "number" and x % 1 == 0 or false end is_integer = export.is_integer --[==[ Returns {true} if `x` is a positive integer (or zero if the `include_0` flag is set), or {false} if not.]==] function export.is_positive_integer(x, include_0) return x and type(x) == "number" and (x > 0 or include_0 and x == 0) and x % 1 == 0 or false end --[==[ Returns {true} is `x` is [[w:NaN|NaN]] (Not a Number), or {false} if not. NaN is a value that has the type "number", but does not represent an actual numeric value; it has the unique property that if {x} is NaN, {x ~= x} evaluates to {true}.]==] function export.is_NaN(x) return x ~= x end --[==[ Returns the base-10 logarithm of `x`. This function should be used instead of {math.log10}, which is deprecated and may stop working if Scribunto is updated to a more recent Lua version.]==] function export.log10(x) -- Structured like this so that module documentation works. local log10 = math.log10 if log10 ~= nil then return log10 end local log = math.log return log(10, 10) == 1 and function(x) -- Lua 5.2 return log(x, 10) end or function(x) -- Lua 5.1 return log(x) * 0.43429448190325182765112891891660508229439700580367 -- log10(e) end end export.log10 = export.log10() -- Sets the actual returned function. local function integer_error(x, param, func_name) local type_x = type(x) error(format( "bad argument #%d to '%s' (integer expected, got %s)", param, func_name, type_x == "number" and tostring(x) or type_x ), 3) end --[==[ Converts a decimal number to hexadecimal. If `include_prefix` is set, the returned number will include the 0x prefix.]==] function export.to_hex(dec, include_prefix) dec = tonumber(dec) or dec if not is_integer(dec) then integer_error(dec, 1, "to_hex") end local neg = dec < 0 if neg then dec = -dec end -- Inputs >= 2^64 cause string.format to return "0". if dec >= 0x1p64 then error("integer overflow in 'to_hex': cannot convert inputs with a magnitude greater than or equal to 2^64 (18446744073709551616)", 2) end -- string.format treats hex numbers as unsigned, so any sign must be added manually. return format("%s%s%X", neg and "-" or "", include_prefix and "0x" or "", dec) end --[==[ Returns the greatest common divisor of an arbitrary number of input numbers.]==] function export.gcd(x, ...) x = tonumber(x) or x if not is_integer(x) then integer_error(x, 1, "gcd") end local q, args_len, integers = ..., select("#", ...) -- Compute p_1 = gcd(n_1, n_2), p_2 = gcd(p_1, n_3), ... i.e. compute GCD by Euclid's algorithm for the current result and the next number. for i = 2, args_len + 1 do q = tonumber(q) or q if not is_integer(q) then integer_error(q, i, "gcd") elseif x ~= 1 then -- If x is 1, validate remaining inputs. -- GCD of two integers x, q with Euclid's algorithm. while q ~= 0 do x, q = q, x % q end end if i <= args_len then -- Only create a table if absolutely necessary, as it's inefficient. if i == 2 then integers = {...} end q = integers[i] end end return x < 0 and -x or x end --[==[ Returns the least common multiple of an arbitrary number of input numbers.]==] function export.lcm(x, ...) x = tonumber(x) or x if not is_integer(x) then integer_error(x, 1, "lcm") end local q, args_len, integers = ..., select("#", ...) -- Compute the product of all inputs as p and GCD as x. for i = 2, args_len + 1 do q = tonumber(q) or q if not is_integer(q) then integer_error(q, i, "lcm") elseif x ~= 0 then -- If x is 0, validate remaining inputs. -- Compute the product. local p = x * q -- GCD of two integers x, q with Euclid's algorithm. while q ~= 0 do x, q = q, x % q end -- Divide product by the GCD to get new LCM. x = p / x end if i <= args_len then -- Only create a table if absolutely necessary, as it's inefficient. if i == 2 then integers = {...} end q = integers[i] end end return x < 0 and -x or x end return export 9iueib95u6jd0lc3zzrya3gsltprarl 26586 23987 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:math]] 23987 Scribunto text/plain local export = {} local byte = string.byte local ceil = math.ceil local floor = math.floor local format = string.format local is_integer -- defined below local match = string.match local select = select local tonumber = tonumber local tonumber_ext -- defined below local tostring = tostring local type = type local INF = math.huge local function sign(x, signed_0) if x > 0 then return 1 elseif x < 0 then return -1 elseif x == 0 then -- 1/(+0) is infinity and 1/(-0) is -infinity. return signed_0 and (1 / x > 0 and 1 or -1) or 0 end -- NaN: convert to string with a forced sign prefix, and grab the first byte. local sign = byte(format("%+f", x)) return sign == 0x2B and 1 or -- + sign == 0x2D and -1 or -- - -- If there's no sign, throw an error. This shouldn't be possible, but -- avoids silent errors if it does happen. error("Internal error: cannot determine sign of " .. x) end --[==[ An extended version of {tonumber()}, which attempts to convert `x` to a number. Like {tonumber()}, it will convert from base 10 by default, and the optional parameter `base` can be used to specify a different base between 2 and 36, with the letters {A-Z} (case-insensitive) representing additional digits beyond {0-9}. When strings contain hexadecimal notation (e.g. {"0x100"}), base 16 is used as the default instead, but this is overridden if `base` is set to anything other than 16. This function differs from {tonumber()} in the following ways: * If `finite_real` is set, then the function will only return finite real numbers; inputs which would normally produce ±infinity or NaN will instead produce {nil}. * If `no_prefix` is set, then strings which start with {"0x"} will not be interpreted as containing hexadecimal notation, resulting in {nil}. * If `base` is explicitly set to {10}, then strings in hexadecimal notation will always return {nil}. This fixes a bug in {tonumber()}, which treats {base=10} the same as {base} being unset, causing base 16 to be used if `x` contains hexadecimal notation (e.g. {tonumber("0x10", 10)} returns {16}, whereas {tonumber_extended("0x10", 10)} returns {nil}).]==] function export.tonumber_extended(x, base, finite_real, no_prefix) -- TODO: tonumber() maxes out at 2^64 if the base is anything other than 10. -- TODO: support binary (0b) and octal (0o) prefixes. local n = tonumber(x, base) if not n or finite_real and (n ~= n or n == INF or n == -INF) then return nil -- If `base` is explicitly set to 10 (not simply nil), or `no_prefix` is set -- and `base` is nil or 16, filter out inputs that started with hexadecimal -- prefixes. Note that if `base` is anything else, the initial "0x" will -- have been interpreted as digits by tonumber() instead of a prefix (as "x" -- can be a digit from base 34 upwards), so there's no prefix to check for. elseif base == 10 or no_prefix and (base == nil or base == 16) then return not match(x, "^%s*[+-]?0[xX]()") and n or nil end return n end tonumber_ext = export.tonumber_extended --[==[ Converts `x` to an integer by removing the fractional portion (e.g. {3.5} becomes {3}, and {-2.9} becomes {-2}). This is equivalent to rounding down positive numbers and rounding up negative numbers. If conversion is not possible, returns {nil}.]==] function export.to_integer(x) x = tonumber(x) if not (x and x == x and x ~= INF and x ~= -INF) then return nil elseif x % 1 == 0 then return x -- Round-down positives. elseif x >= 0 then return floor(x) end --Round-up negatives. return ceil(x) end --[==[ Returns {1} if `x` is positive, {-1} if `x` is negative, or {0} if `x` is {0}. If `signed_0` is set, this function will only return either {1} or {-1}, and will make a distinction between [[w:signed zero|signed zeroes]] ({+0} and {-0}). This is useful when a {0} result could be disruptive (e.g. {x % 0}).]==] function export.sign(x, signed_0) return sign( tonumber(x) or error(format("bad argument #1 to 'sign' (number expected, got %s)", type(x)), 2), signed_0 ) end --[==[ Returns {true} if `x` is a finite real number, or {false} if not.]==] function export.is_finite_real_number(x) return x and x == x and not (x == INF or x == -INF) and type(x) == "number" end --[==[ Returns {true} if `x` is an integer, or {false} if not.]==] function export.is_integer(x) return x and type(x) == "number" and x % 1 == 0 or false end is_integer = export.is_integer --[==[ Returns {true} if `x` is a positive integer (or zero if the `include_0` flag is set), or {false} if not.]==] function export.is_positive_integer(x, include_0) return x and type(x) == "number" and (x > 0 or include_0 and x == 0) and x % 1 == 0 or false end --[==[ Returns {true} is `x` is [[w:NaN|NaN]] (Not a Number), or {false} if not. NaN is a value that has the type "number", but does not represent an actual numeric value; it has the unique property that if {x} is NaN, {x ~= x} evaluates to {true}.]==] function export.is_NaN(x) return x ~= x end --[==[ Returns the base-10 logarithm of `x`. This function should be used instead of {math.log10}, which is deprecated and may stop working if Scribunto is updated to a more recent Lua version.]==] function export.log10(x) -- Structured like this so that module documentation works. local log10 = math.log10 if log10 ~= nil then return log10 end local log = math.log return log(10, 10) == 1 and function(x) -- Lua 5.2 return log(x, 10) end or function(x) -- Lua 5.1 return log(x) * 0.43429448190325182765112891891660508229439700580367 -- log10(e) end end export.log10 = export.log10() -- Sets the actual returned function. local function integer_error(x, param, func_name) local type_x = type(x) error(format( "bad argument #%d to '%s' (integer expected, got %s)", param, func_name, type_x == "number" and tostring(x) or type_x ), 3) end --[==[ Converts a decimal number to hexadecimal. If `include_prefix` is set, the returned number will include the 0x prefix.]==] function export.to_hex(dec, include_prefix) dec = tonumber(dec) or dec if not is_integer(dec) then integer_error(dec, 1, "to_hex") end local neg = dec < 0 if neg then dec = -dec end -- Inputs >= 2^64 cause string.format to return "0". if dec >= 0x1p64 then error("integer overflow in 'to_hex': cannot convert inputs with a magnitude greater than or equal to 2^64 (18446744073709551616)", 2) end -- string.format treats hex numbers as unsigned, so any sign must be added manually. return format("%s%s%X", neg and "-" or "", include_prefix and "0x" or "", dec) end --[==[ Returns the greatest common divisor of an arbitrary number of input numbers.]==] function export.gcd(x, ...) x = tonumber(x) or x if not is_integer(x) then integer_error(x, 1, "gcd") end local q, args_len, integers = ..., select("#", ...) -- Compute p_1 = gcd(n_1, n_2), p_2 = gcd(p_1, n_3), ... i.e. compute GCD by Euclid's algorithm for the current result and the next number. for i = 2, args_len + 1 do q = tonumber(q) or q if not is_integer(q) then integer_error(q, i, "gcd") elseif x ~= 1 then -- If x is 1, validate remaining inputs. -- GCD of two integers x, q with Euclid's algorithm. while q ~= 0 do x, q = q, x % q end end if i <= args_len then -- Only create a table if absolutely necessary, as it's inefficient. if i == 2 then integers = {...} end q = integers[i] end end return x < 0 and -x or x end --[==[ Returns the least common multiple of an arbitrary number of input numbers.]==] function export.lcm(x, ...) x = tonumber(x) or x if not is_integer(x) then integer_error(x, 1, "lcm") end local q, args_len, integers = ..., select("#", ...) -- Compute the product of all inputs as p and GCD as x. for i = 2, args_len + 1 do q = tonumber(q) or q if not is_integer(q) then integer_error(q, i, "lcm") elseif x ~= 0 then -- If x is 0, validate remaining inputs. -- Compute the product. local p = x * q -- GCD of two integers x, q with Euclid's algorithm. while q ~= 0 do x, q = q, x % q end -- Divide product by the GCD to get new LCM. x = p / x end if i <= args_len then -- Only create a table if absolutely necessary, as it's inefficient. if i == 2 then integers = {...} end q = integers[i] end end return x < 0 and -x or x end return export 9iueib95u6jd0lc3zzrya3gsltprarl Modul:table/numKeys 828 6947 26583 2025-11-12T12:36:45Z id>Bennylin 0 ←Membuat halaman berisi 'local math_module = "Module:math" local pairs = pairs local sort = table.sort local function is_positive_integer(...) is_positive_integer = require(math_module).is_positive_integer return is_positive_integer(...) end --[==[ Given a table, return an array containing all positive integer keys, sorted either in numerical order, or using a custom `keySort` function.]==] return function(t, keySort) local nums, i = {}, 0 for k in pairs(t) do if is_positive_int...' 26583 Scribunto text/plain local math_module = "Module:math" local pairs = pairs local sort = table.sort local function is_positive_integer(...) is_positive_integer = require(math_module).is_positive_integer return is_positive_integer(...) end --[==[ Given a table, return an array containing all positive integer keys, sorted either in numerical order, or using a custom `keySort` function.]==] return function(t, keySort) local nums, i = {}, 0 for k in pairs(t) do if is_positive_integer(k) then i = i + 1 nums[i] = k end end -- No need for [[Module:math/compare]], as the default is adequate for integers. sort(nums, keySort) return nums end 9c7afk02cuh6j5vb8qjjz77xn7dijyy 26584 23990 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/numKeys]] 23990 Scribunto text/plain local math_module = "Module:math" local pairs = pairs local sort = table.sort local function is_positive_integer(...) is_positive_integer = require(math_module).is_positive_integer return is_positive_integer(...) end --[==[ Given a table, return an array containing all positive integer keys, sorted either in numerical order, or using a custom `keySort` function.]==] return function(t, keySort) local nums, i = {}, 0 for k in pairs(t) do if is_positive_integer(k) then i = i + 1 nums[i] = k end end -- No need for [[Module:math/compare]], as the default is adequate for integers. sort(nums, keySort) return nums end 9c7afk02cuh6j5vb8qjjz77xn7dijyy Modul:data/magic words 828 6959 26632 2025-11-08T21:16:31Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26632 Scribunto text/plain local next = next local date_and_time = "mw:Help:Magic words#Date and time" local escaped_characters = "mw:Help:Magic words#Escaped characters" local formatting = "mw:Help:Magic words#Formatting" local labeled_section_transclusion = "mw:Extension:Labeled Section Transclusion" local liquidthreads = "mw:Extension:LiquidThreads" local localization_functions = "mw:Help:Magic words#Localization functions" local localization_variables = "mw:Help:Magic words#Localization variables" local miscellaneous = "mw:Help:Magic words#Miscellaneous" local namespaces = "mw:Help:Magic words#Namespaces" local namespaces_2 = "mw:Help:Magic words#Namespaces 2" local noexternallanglinks = "mw:Wikibase/Installation/Advanced configuration#noexternallanglinks" local page_names = "mw:Help:Magic words#Page names" local parser_functions_ext = "mw:Help:Extension:ParserFunctions##" -- ## is not a typo local statistics = "mw:Help:Magic words#Statistics" local substitution = "mw:Manual:Substitution" local technical_metadata = "mw:Help:Magic words#Technical metadata" local technical_metadata_of_another_page = "mw:Help:Magic words#Technical metadata of another page" local transclusion_modifiers = "mw:Help:Magic words#Transclusion modifiers" local url_data = "mw:Help:Magic words#URL data" local data = {} for k, v in next, { ["!"] = { parser_variable = escaped_characters, case_sensitive = false }, ["#BABEL"] = { parser_function = "mw:Extension:Babel#Usage", case_sensitive = false }, ["#bcp47"] = { -- Case-sensitive lowercase. parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = true }, ["#CATEGORYTREE"] = { parser_function = "mw:Extension:CategoryTree#The {{#categorytree}} parser function", case_sensitive = false }, ["#COMMASEPARATEDLIST"] = { parser_function = formatting, case_sensitive = false }, ["#dir"] = { -- Case-sensitive lowercase. parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = true }, ["#EXPR"] = { parser_function = parser_functions_ext .. "expr", case_sensitive = false }, ["#FORMAL"] = { parser_function = localization_functions, case_sensitive = true }, ["#FORMATDATE"] = { aliases = {"#DATEFORMAT"}, parser_function = formatting, case_sensitive = false }, ["#IF"] = { parser_function = parser_functions_ext .. "if", case_sensitive = false }, ["#IFEQ"] = { parser_function = parser_functions_ext .. "ifeq", case_sensitive = false }, ["#IFERROR"] = { parser_function = parser_functions_ext .. "iferror", case_sensitive = false }, ["#IFEXIST"] = { parser_function = parser_functions_ext .. "ifexist", case_sensitive = false }, ["#IFEXPR"] = { parser_function = parser_functions_ext .. "ifexpr", case_sensitive = false }, ["#interlanguagelink"] = { -- Case-sensitive lowercase. parser_function = miscellaneous, case_sensitive = true }, ["#interwikilink"] = { -- Case-sensitive lowercase. parser_function = miscellaneous, case_sensitive = true }, ["#INVOKE"] = { parser_function = "mw:Extension:Scribunto#Usage", case_sensitive = false }, ["#LANGUAGE"] = { parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = false }, ["#LQTPAGELIMIT"] = { parser_function = liquidthreads, case_sensitive = false }, ["#LST"] = { aliases = {"#SECTION"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#LSTH"] = { aliases = {"#SECTION-H"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#LSTX"] = { aliases = {"#SECTION-X"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#PROPERTY"] = { parser_function = "m:Wikidata/Notes/Inclusion syntax", case_sensitive = false }, ["#REL2ABS"] = { parser_function = parser_functions_ext .. "rel2abs", case_sensitive = false }, ["#SPECIAL"] = { parser_function = miscellaneous, case_sensitive = false }, ["#SPECIALE"] = { parser_function = miscellaneous, case_sensitive = false }, ["#STATEMENTS"] = { parser_function = "d:WD:How to use data on Wikimedia projects#Parser function", case_sensitive = false }, ["#SWITCH"] = { parser_function = parser_functions_ext .. "switch", case_sensitive = false }, ["#TAG"] = { parser_function = miscellaneous, case_sensitive = false }, ["#TARGET"] = { parser_function = "mw:Extension:MassMessage#Parser function delivery lists", case_sensitive = false }, ["#TIME"] = { parser_function = parser_functions_ext .. "time", case_sensitive = false }, ["#timef"] = { -- Case-sensitive lowercase. parser_function = parser_functions_ext, case_sensitive = true }, ["#timefl"] = { -- Case-sensitive lowercase. parser_function = parser_functions_ext, case_sensitive = true }, ["#TIMEL"] = { parser_function = parser_functions_ext .. "timel", case_sensitive = false }, ["#TITLEPARTS"] = { parser_function = parser_functions_ext .. "titleparts", case_sensitive = false }, ["#USELIQUIDTHREADS"] = { parser_function = liquidthreads, case_sensitive = false }, ["="] = { parser_variable = escaped_characters, case_sensitive = false }, ["ANCHORENCODE"] = { parser_function = url_data, case_sensitive = false }, ["ARTICLEPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["BASEPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["BASEPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["BIDI"] = { parser_function = formatting, case_sensitive = false }, ["CANONICALURL"] = { parser_function = url_data, case_sensitive = false }, ["CANONICALURLE"] = { parser_function = url_data, case_sensitive = false }, ["CASCADINGSOURCES"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["CONTENTLANGUAGE"] = { aliases = {"CONTENTLANG"}, parser_variable = technical_metadata, case_sensitive = true }, ["CURRENTDAY"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDAY2"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDAYNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDOW"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTHOUR"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTH"] = { aliases = {"CURRENTMONTH2"}, parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTH1"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHABBREV"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHNAMEGEN"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTTIME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTTIMESTAMP"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTVERSION"] = { parser_variable = technical_metadata, case_sensitive = true }, ["CURRENTWEEK"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTYEAR"] = { parser_variable = date_and_time, case_sensitive = true }, ["DEFAULTSORT"] = { aliases = {"DEFAULTCATEGORYSORT", "DEFAULTSORTKEY"}, parser_function = technical_metadata, case_sensitive = true }, ["DIRECTIONMARK"] = { aliases = {"DIRMARK"}, parser_variable = technical_metadata, case_sensitive = true }, ["DISPLAYTITLE"] = { parser_function = technical_metadata, case_sensitive = true }, ["FILEPATH"] = { parser_function = url_data, case_sensitive = false }, ["FORMATNUM"] = { parser_function = formatting, case_sensitive = false }, ["FULLPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["FULLPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["FULLURL"] = { parser_function = url_data, case_sensitive = false }, ["FULLURLE"] = { parser_function = url_data, case_sensitive = false }, ["GENDER"] = { parser_function = localization_functions, case_sensitive = false }, ["GRAMMAR"] = { parser_function = localization_functions, case_sensitive = false }, ["INT"] = { parser_function = localization_functions, case_sensitive = false }, ["LC"] = { parser_function = formatting, case_sensitive = false }, ["LCFIRST"] = { parser_function = formatting, case_sensitive = false }, ["LOCALDAY"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDAY2"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDAYNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDOW"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALHOUR"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTH"] = { aliases = {"LOCALMONTH2"}, parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTH1"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHABBREV"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHNAMEGEN"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALTIME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALTIMESTAMP"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALURL"] = { parser_function = url_data, case_sensitive = false }, ["LOCALURLE"] = { parser_function = url_data, case_sensitive = false }, ["LOCALWEEK"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALYEAR"] = { parser_variable = date_and_time, case_sensitive = true }, ["MSG"] = { transclusion_modifier = transclusion_modifiers, priority = 2, case_sensitive = false }, ["MSGNW"] = { transclusion_modifier = transclusion_modifiers, priority = 2, case_sensitive = false }, ["NAMESPACE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NAMESPACEE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NAMESPACENUMBER"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NOEXTERNALLANGLINKS"] = { parser_function = noexternallanglinks, parser_variable = noexternallanglinks, case_sensitive = false }, ["NS"] = { parser_function = namespaces_2, case_sensitive = false }, ["NSE"] = { parser_function = namespaces_2, case_sensitive = false }, ["NUMBERINGROUP"] = { aliases = {"NUMINGROUP"}, parser_function = statistics, case_sensitive = true }, ["NUMBEROFACTIVEUSERS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFADMINS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFARTICLES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFEDITS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFFILES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFPAGES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFUSERS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["PADLEFT"] = { parser_function = formatting, case_sensitive = false }, ["PADRIGHT"] = { parser_function = formatting, case_sensitive = false }, ["PAGEID"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = false }, ["PAGELANGUAGE"] = { parser_variable = technical_metadata, case_sensitive = true }, ["PAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["PAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["PAGESINCATEGORY"] = { aliases = {"PAGESINCAT"}, parser_function = statistics, case_sensitive = true }, ["PAGESIZE"] = { parser_function = technical_metadata_of_another_page, case_sensitive = true }, ["PLURAL"] = { parser_function = localization_functions, case_sensitive = false }, ["PROTECTIONEXPIRY"] = { parser_function = { technical_metadata, technical_metadata_of_another_page }, case_sensitive = true }, ["PROTECTIONLEVEL"] = { parser_function = { technical_metadata, technical_metadata_of_another_page }, case_sensitive = true }, ["RAW"] = { transclusion_modifier = transclusion_modifiers, priority = 3, case_sensitive = false }, ["REVISIONDAY"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONDAY2"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONID"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONMONTH"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONMONTH1"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONSIZE"] = { parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONTIMESTAMP"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONUSER"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONYEAR"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["ROOTPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["ROOTPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SAFESUBST"] = { transclusion_modifier = substitution, priority = 1, case_sensitive = false }, ["SCRIPTPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SERVER"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SERVERNAME"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SITENAME"] = { parser_variable = technical_metadata, case_sensitive = true }, ["STYLEPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SUBJECTPAGENAME"] = { aliases = {"ARTICLEPAGENAME"}, parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBJECTPAGENAMEE"] = { aliases = {"ARTICLEPAGENAMEE"}, parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBJECTSPACE"] = { aliases = {"ARTICLESPACE"}, parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["SUBJECTSPACEE"] = { aliases = {"ARTICLESPACEE"}, parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["SUBPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBST"] = { transclusion_modifier = substitution, priority = 1, case_sensitive = false }, ["TALKPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["TALKPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["TALKSPACE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["TALKSPACEE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["UC"] = { parser_function = formatting, case_sensitive = false }, ["UCFIRST"] = { parser_function = formatting, case_sensitive = false }, ["URLENCODE"] = { parser_function = url_data, case_sensitive = false }, ["USERLANGUAGE"] = { parser_variable = localization_variables, case_sensitive = true }, } do data[k] = v if not v.name then v.name = k end local aliases = v.aliases if aliases then for i = 1, #aliases do data[aliases[i]] = v end v.aliases = nil end end return data jkwpl1ihlf560owi79olg91zvhvb1xy 26633 24002 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Modul:data/magic_words]] 24002 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:data/magic words -- License: CC BY-SA local next = next local date_and_time = "mw:Help:Magic words#Date and time" local escaped_characters = "mw:Help:Magic words#Escaped characters" local formatting = "mw:Help:Magic words#Formatting" local labeled_section_transclusion = "mw:Extension:Labeled Section Transclusion" local liquidthreads = "mw:Extension:LiquidThreads" local localization_functions = "mw:Help:Magic words#Localization functions" local localization_variables = "mw:Help:Magic words#Localization variables" local miscellaneous = "mw:Help:Magic words#Miscellaneous" local namespaces = "mw:Help:Magic words#Namespaces" local namespaces_2 = "mw:Help:Magic words#Namespaces 2" local noexternallanglinks = "mw:Wikibase/Installation/Advanced configuration#noexternallanglinks" local page_names = "mw:Help:Magic words#Page names" local parser_functions_ext = "mw:Help:Extension:ParserFunctions##" -- ## is not a typo local statistics = "mw:Help:Magic words#Statistics" local substitution = "mw:Manual:Substitution" local technical_metadata = "mw:Help:Magic words#Technical metadata" local technical_metadata_of_another_page = "mw:Help:Magic words#Technical metadata of another page" local transclusion_modifiers = "mw:Help:Magic words#Transclusion modifiers" local url_data = "mw:Help:Magic words#URL data" local data = {} for k, v in next, { ["!"] = { parser_variable = escaped_characters, case_sensitive = false }, ["#BABEL"] = { parser_function = "mw:Extension:Babel#Usage", case_sensitive = false }, ["#bcp47"] = { -- Case-sensitive lowercase. parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = true }, ["#CATEGORYTREE"] = { parser_function = "mw:Extension:CategoryTree#The {{#categorytree}} parser function", case_sensitive = false }, ["#COMMASEPARATEDLIST"] = { parser_function = formatting, case_sensitive = false }, ["#dir"] = { -- Case-sensitive lowercase. parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = true }, ["#EXPR"] = { parser_function = parser_functions_ext .. "expr", case_sensitive = false }, ["#FORMAL"] = { parser_function = localization_functions, case_sensitive = true }, ["#FORMATDATE"] = { aliases = {"#DATEFORMAT"}, parser_function = formatting, case_sensitive = false }, ["#IF"] = { parser_function = parser_functions_ext .. "if", case_sensitive = false }, ["#IFEQ"] = { parser_function = parser_functions_ext .. "ifeq", case_sensitive = false }, ["#IFERROR"] = { parser_function = parser_functions_ext .. "iferror", case_sensitive = false }, ["#IFEXIST"] = { parser_function = parser_functions_ext .. "ifexist", case_sensitive = false }, ["#IFEXPR"] = { parser_function = parser_functions_ext .. "ifexpr", case_sensitive = false }, ["#interlanguagelink"] = { -- Case-sensitive lowercase. parser_function = miscellaneous, case_sensitive = true }, ["#interwikilink"] = { -- Case-sensitive lowercase. parser_function = miscellaneous, case_sensitive = true }, ["#INVOKE"] = { parser_function = "mw:Extension:Scribunto#Usage", case_sensitive = false }, ["#LANGUAGE"] = { parser_function = localization_functions, parser_variable = localization_functions, -- Not a typo. case_sensitive = false }, ["#LQTPAGELIMIT"] = { parser_function = liquidthreads, case_sensitive = false }, ["#LST"] = { aliases = {"#SECTION"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#LSTH"] = { aliases = {"#SECTION-H"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#LSTX"] = { aliases = {"#SECTION-X"}, parser_function = labeled_section_transclusion, case_sensitive = false }, ["#PROPERTY"] = { parser_function = "m:Wikidata/Notes/Inclusion syntax", case_sensitive = false }, ["#REL2ABS"] = { parser_function = parser_functions_ext .. "rel2abs", case_sensitive = false }, ["#SPECIAL"] = { parser_function = miscellaneous, case_sensitive = false }, ["#SPECIALE"] = { parser_function = miscellaneous, case_sensitive = false }, ["#STATEMENTS"] = { parser_function = "d:WD:How to use data on Wikimedia projects#Parser function", case_sensitive = false }, ["#SWITCH"] = { parser_function = parser_functions_ext .. "switch", case_sensitive = false }, ["#TAG"] = { parser_function = miscellaneous, case_sensitive = false }, ["#TARGET"] = { parser_function = "mw:Extension:MassMessage#Parser function delivery lists", case_sensitive = false }, ["#TIME"] = { parser_function = parser_functions_ext .. "time", case_sensitive = false }, ["#timef"] = { -- Case-sensitive lowercase. parser_function = parser_functions_ext, case_sensitive = true }, ["#timefl"] = { -- Case-sensitive lowercase. parser_function = parser_functions_ext, case_sensitive = true }, ["#TIMEL"] = { parser_function = parser_functions_ext .. "timel", case_sensitive = false }, ["#TITLEPARTS"] = { parser_function = parser_functions_ext .. "titleparts", case_sensitive = false }, ["#USELIQUIDTHREADS"] = { parser_function = liquidthreads, case_sensitive = false }, ["="] = { parser_variable = escaped_characters, case_sensitive = false }, ["ANCHORENCODE"] = { parser_function = url_data, case_sensitive = false }, ["ARTICLEPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["BASEPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["BASEPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["BIDI"] = { parser_function = formatting, case_sensitive = false }, ["CANONICALURL"] = { parser_function = url_data, case_sensitive = false }, ["CANONICALURLE"] = { parser_function = url_data, case_sensitive = false }, ["CASCADINGSOURCES"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["CONTENTLANGUAGE"] = { aliases = {"CONTENTLANG"}, parser_variable = technical_metadata, case_sensitive = true }, ["CURRENTDAY"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDAY2"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDAYNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTDOW"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTHOUR"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTH"] = { aliases = {"CURRENTMONTH2"}, parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTH1"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHABBREV"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTMONTHNAMEGEN"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTTIME"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTTIMESTAMP"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTVERSION"] = { parser_variable = technical_metadata, case_sensitive = true }, ["CURRENTWEEK"] = { parser_variable = date_and_time, case_sensitive = true }, ["CURRENTYEAR"] = { parser_variable = date_and_time, case_sensitive = true }, ["DEFAULTSORT"] = { aliases = {"DEFAULTCATEGORYSORT", "DEFAULTSORTKEY"}, parser_function = technical_metadata, case_sensitive = true }, ["DIRECTIONMARK"] = { aliases = {"DIRMARK"}, parser_variable = technical_metadata, case_sensitive = true }, ["DISPLAYTITLE"] = { parser_function = technical_metadata, case_sensitive = true }, ["FILEPATH"] = { parser_function = url_data, case_sensitive = false }, ["FORMATNUM"] = { parser_function = formatting, case_sensitive = false }, ["FULLPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["FULLPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["FULLURL"] = { parser_function = url_data, case_sensitive = false }, ["FULLURLE"] = { parser_function = url_data, case_sensitive = false }, ["GENDER"] = { parser_function = localization_functions, case_sensitive = false }, ["GRAMMAR"] = { parser_function = localization_functions, case_sensitive = false }, ["INT"] = { parser_function = localization_functions, case_sensitive = false }, ["LC"] = { parser_function = formatting, case_sensitive = false }, ["LCFIRST"] = { parser_function = formatting, case_sensitive = false }, ["LOCALDAY"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDAY2"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDAYNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALDOW"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALHOUR"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTH"] = { aliases = {"LOCALMONTH2"}, parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTH1"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHABBREV"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHNAME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALMONTHNAMEGEN"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALTIME"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALTIMESTAMP"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALURL"] = { parser_function = url_data, case_sensitive = false }, ["LOCALURLE"] = { parser_function = url_data, case_sensitive = false }, ["LOCALWEEK"] = { parser_variable = date_and_time, case_sensitive = true }, ["LOCALYEAR"] = { parser_variable = date_and_time, case_sensitive = true }, ["MSG"] = { transclusion_modifier = transclusion_modifiers, priority = 2, case_sensitive = false }, ["MSGNW"] = { transclusion_modifier = transclusion_modifiers, priority = 2, case_sensitive = false }, ["NAMESPACE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NAMESPACEE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NAMESPACENUMBER"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["NOEXTERNALLANGLINKS"] = { parser_function = noexternallanglinks, parser_variable = noexternallanglinks, case_sensitive = false }, ["NS"] = { parser_function = namespaces_2, case_sensitive = false }, ["NSE"] = { parser_function = namespaces_2, case_sensitive = false }, ["NUMBERINGROUP"] = { aliases = {"NUMINGROUP"}, parser_function = statistics, case_sensitive = true }, ["NUMBEROFACTIVEUSERS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFADMINS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFARTICLES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFEDITS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFFILES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFPAGES"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["NUMBEROFUSERS"] = { parser_function = statistics, parser_variable = statistics, case_sensitive = true }, ["PADLEFT"] = { parser_function = formatting, case_sensitive = false }, ["PADRIGHT"] = { parser_function = formatting, case_sensitive = false }, ["PAGEID"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = false }, ["PAGELANGUAGE"] = { parser_variable = technical_metadata, case_sensitive = true }, ["PAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["PAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["PAGESINCATEGORY"] = { aliases = {"PAGESINCAT"}, parser_function = statistics, case_sensitive = true }, ["PAGESIZE"] = { parser_function = technical_metadata_of_another_page, case_sensitive = true }, ["PLURAL"] = { parser_function = localization_functions, case_sensitive = false }, ["PROTECTIONEXPIRY"] = { parser_function = { technical_metadata, technical_metadata_of_another_page }, case_sensitive = true }, ["PROTECTIONLEVEL"] = { parser_function = { technical_metadata, technical_metadata_of_another_page }, case_sensitive = true }, ["RAW"] = { transclusion_modifier = transclusion_modifiers, priority = 3, case_sensitive = false }, ["REVISIONDAY"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONDAY2"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONID"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONMONTH"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONMONTH1"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONSIZE"] = { parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONTIMESTAMP"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONUSER"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["REVISIONYEAR"] = { parser_function = technical_metadata_of_another_page, parser_variable = technical_metadata, case_sensitive = true }, ["ROOTPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["ROOTPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SAFESUBST"] = { transclusion_modifier = substitution, priority = 1, case_sensitive = false }, ["SCRIPTPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SERVER"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SERVERNAME"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SITENAME"] = { parser_variable = technical_metadata, case_sensitive = true }, ["STYLEPATH"] = { parser_variable = technical_metadata, case_sensitive = false }, ["SUBJECTPAGENAME"] = { aliases = {"ARTICLEPAGENAME"}, parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBJECTPAGENAMEE"] = { aliases = {"ARTICLEPAGENAMEE"}, parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBJECTSPACE"] = { aliases = {"ARTICLESPACE"}, parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["SUBJECTSPACEE"] = { aliases = {"ARTICLESPACEE"}, parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["SUBPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["SUBST"] = { transclusion_modifier = substitution, priority = 1, case_sensitive = false }, ["TALKPAGENAME"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["TALKPAGENAMEE"] = { parser_function = page_names, parser_variable = page_names, case_sensitive = true }, ["TALKSPACE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["TALKSPACEE"] = { parser_function = namespaces, parser_variable = namespaces, case_sensitive = true }, ["UC"] = { parser_function = formatting, case_sensitive = false }, ["UCFIRST"] = { parser_function = formatting, case_sensitive = false }, ["URLENCODE"] = { parser_function = url_data, case_sensitive = false }, ["USERLANGUAGE"] = { parser_variable = localization_variables, case_sensitive = true }, } do data[k] = v if not v.name then v.name = k end local aliases = v.aliases if aliases then for i = 1, #aliases do data[aliases[i]] = v end v.aliases = nil end end return data c0u8d6unslq5su2fh1exhgncvr7gcnx Modul:pages 828 7002 26579 2025-11-08T18:55:42Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26579 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local concat = table.concat local find = string.find local format = string.format local getmetatable = getmetatable local get_current_section -- defined below local get_namespace_shortcut -- defined below local get_pagetype -- defined below local gsub = string.gsub local insert = table.insert local is_internal_title -- defined below local is_title -- defined below local lower = string.lower local match = string.match local new_title = mw.title.new local require = require local sub = string.sub local title_equals = mw.title.equals local tonumber = tonumber local type = type local ufind = mw.ustring.find local unstrip_nowiki = mw.text.unstripNoWiki --[==[ 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end --[==[ 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 current_frame local function get_current_frame() current_frame, get_current_frame = mw.getCurrentFrame(), nil return current_frame end local parent_frame local function get_parent_frame() parent_frame, get_parent_frame = (current_frame or get_current_frame()):getParent(), nil return parent_frame end local namespace_shortcuts local function get_namespace_shortcuts() namespace_shortcuts, get_namespace_shortcuts = { [4] = "WT", [10] = "T", [14] = "CAT", [100] = "AP", [110] = "WS", [118] = "RC", [828] = "MOD", }, nil return namespace_shortcuts end do local transcluded --[==[ Returns {true} if the current {{tl|#invoke:}} is being transcluded, or {false} if not. If the current {{tl|#invoke:}} is part of a template, for instance, this template will therefore return {true}. Note that if a template containing an {{tl|#invoke:}} is used on its own page (e.g. to display a demonstration), this function is still able to detect that this is transclusion. This is an improvement over the other method for detecting transclusion, which is to check the parent frame title against the current page title, which fails to detect transclusion in that instance.]==] function export.is_transcluded() if transcluded == nil then transcluded = (parent_frame or get_parent_frame()) and parent_frame:preprocess("<includeonly>1</includeonly>") == "1" or false end return transcluded end end do local preview --[==[ Returns {true} if the page is currently being viewed in preview, or {false} if not.]==] function export.is_preview() if preview == nil then preview = (current_frame or get_current_frame()):preprocess("{{REVISIONID}}") == "" end return preview end end --[==[ Returns {true} if the input is a title object, or {false} if not. This therefore '''includes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_internal_title` below.]==] function export.is_title(val) if not (val and type(val) == "table") then return false end local mt = getmetatable(val) -- There's no foolproof method for checking for a title object, but the -- __eq metamethod should be mw.title.equals unless the object has been -- seriously messed around with. return mt and type(mt) == "table" and getmetatable(mt) == nil and mt.__eq == title_equals and true or false end is_title = export.is_title --[==[ Returns {true} if the input is an internal title object, or {false} if not. An internal title object is a title object for a page on this wiki, such as [[example]]. This therefore '''excludes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_title` above.]==] function export.is_internal_title(title) -- Note: Mainspace titles starting with "#" should be invalid, but a bug in mw.title.new and mw.title.makeTitle means a title object is returned that has the empty string for prefixedText, so they need to be filtered out. return is_title(title) and #title.prefixedText > 0 and #title.interwiki == 0 end is_internal_title = export.is_internal_title --[==[ Returns {true} if the input string is a valid link target, or {false} if not. This therefore '''includes''' link targets to other wikis, such as [[w:Example]], unlike `is_valid_page_name` below.]==] function export.is_valid_link_target(target) local target_type = type(target) if target_type == "string" then return is_title(new_title(target)) end error(format("bad argument #1 to 'is_valid_link_target' (string expected, got %s)", target_type), 2) end --[==[ Returns {true} if the input string is a valid page name on this wiki, or {false} if not. This therefore '''excludes''' page names on other wikis, such as [[w:Example]], unlike `is_valid_link_target` above.]==] function export.is_valid_page_name(name) local name_type = type(name) if name_type == "string" then return is_internal_title(new_title(name)) end error(format("bad argument #1 to 'is_valid_page_name' (string expected, got %s)", name_type), 2) end --[==[ Given a title object, returns a full link target which will always unambiguously link to it. For instance, the input {"foo"} (for the page [[foo]]) returns {":foo"}, as a leading colon always refers to mainspace, even when other namespaces might be assumed (e.g. when transcluding using `{{ }}` syntax). If `shortcut` is set, then the returned target will use the namespace shortcut, if any; for example, the title for `Template:foo` would return {"T:foo"} instead of {"Template:foo"}.]==] function export.get_link_target(title, shortcut) if not is_title(title) then error(format("bad argument #1 to 'is_valid_link_target' (title object expected, got %s)", type(title))) elseif title.interwiki ~= "" then return title.fullText elseif shortcut then local fragment = title.fragment if fragment == "" then return get_namespace_shortcut(title) .. ":" .. title.text end return get_namespace_shortcut(title) .. ":" .. title.text .. "#" .. fragment elseif title.namespace == 0 then return ":" .. title.fullText end return title.fullText end do local function find_sandbox(text) return find(text, "^User:.") or find(lower(text), "sandbox", 1, true) end local function get_transclusion_subtypes(title, main_type, documentation, page_suffix) local text, subtypes = title.text, {main_type} -- Any template/module with "sandbox" in the title. These are impossible -- to screen for more accurately, as there's no consistent pattern. Also -- any user sandboxes in the form (e.g.) "Template:User:...". local sandbox = find_sandbox(text) if sandbox then insert(subtypes, "sandbox") end -- Any template/module testcases (which can be labelled and/or followed -- by further subpages). local testcase = find(text, "./[Tt]estcases?%f[%L]") if testcase then -- Order "testcase" and "sandbox" based on where the patterns occur -- in the title. local n = sandbox and sandbox < testcase and 3 or 2 insert(subtypes, n, "testcase") end -- Any template/module documentation pages. if documentation then insert(subtypes, "documentation") end local final = subtypes[#subtypes] if not (final == main_type and not page_suffix or final == "sandbox") then insert(subtypes, "page") end return concat(subtypes, " ") end local function get_snippet_subtypes(title, main_type, documentation) local ns = title.namespace return get_transclusion_subtypes(title, ( ns == 2 and "user " or ns == 8 and match(title.text, "^Gadget-.") and "gadget " or "" ) .. main_type, documentation) end --[==[ Returns the page type of the input title object in a format which can be used in running text.]==] function export.get_pagetype(title) if not is_internal_title(title) then error(mw.dumpObject(title.fullText) .. " is not a valid page name.") end -- If possibly a documentation page, get the base title and set the -- `documentation` flag. local content_model, text, documentation = title.contentModel if content_model == "wikitext" then text = title.text if title.isSubpage and title.subpageText == "documentation" then local base_title = title.basePageTitle if base_title then title, content_model, text, documentation = base_title, base_title.contentModel, base_title.text, true end end end -- Content models have overriding priority, as they can appear in -- nonstandard places due to page content model changes. if content_model == "css" or content_model == "sanitized-css" then return get_snippet_subtypes(title, "stylesheet", documentation) elseif content_model == "javascript" then return get_snippet_subtypes(title, "script", documentation) elseif content_model == "json" then return get_snippet_subtypes(title, "JSON data", documentation) elseif content_model == "MassMessageListContent" then return get_snippet_subtypes(title, "mass message delivery list", documentation) -- Modules. elseif content_model == "Scribunto" then return get_transclusion_subtypes(title, "module", documentation, false) elseif content_model == "text" then return "page" -- ??? -- Otherwise, the content model is "wikitext", so check namespaces. elseif title.isTalkPage then return "talk page" end local ns = title.namespace -- Main namespace. if ns == 0 then return "entry" -- Wiktionary: elseif ns == 4 then return find_sandbox(title.text) and "sandbox" or "project page" -- Template: elseif ns == 10 then return get_transclusion_subtypes(title, "template", documentation, false) end -- Convert the namespace to lowercase, unless it contains a capital -- letter after the initial letter (e.g. MediaWiki, TimedText). Also -- normalize any underscores. local ns_text = gsub(title.nsText, "_", " ") if ufind(ns_text, "^%U*$", 2) then ns_text = ulower(ns_text) end -- User: if ns == 2 then return ns_text .. " " .. (title.isSubpage and "subpage" or "page") -- Category: and Appendix: elseif ns == 14 or ns == 100 then return ns_text -- Thesaurus: and Reconstruction: elseif ns == 110 or ns == 118 then return ns_text .. " entry" end return ns_text .. " page" end get_pagetype = export.get_pagetype end --[==[ Returns {true} if the input title object is for a content page, or {false} if not. A content page is a page that is considered part of the dictionary itself, and excludes pages for discussion, administration, maintenance etc.]==] function export.is_content_page(title) if not is_internal_title(title) then error(mw.dumpObject(title.fullText) .. " is not a valid page name.") end local ns = title.namespace -- (main), Appendix, Thesaurus, Citations, Reconstruction. return (ns == 0 or ns == 100 or ns == 110 or ns == 114 or ns == 118) and title.contentModel == "wikitext" end --[==[ Returns {true} if the input title object is for a documentation page, or {false} if not.]==] function export.is_documentation(title) return match(get_pagetype(title), "%f[%w]documentation%f[%W]") and true or false end --[==[ Returns {true} if the input title object is for a sandbox, or {false} if not. By default, sandbox documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==] function export.is_sandbox(title, include_documentation) local pagetype = get_pagetype(title) return match(pagetype, "%f[%w]sandbox%f[%W]") and ( include_documentation or not match(pagetype, "%f[%w]documentation%f[%W]") ) and true or false end --[==[ Returns {true} if the input title object is for a testcase page, or {false} if not. By default, testcase documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==] function export.is_testcase_page(title, include_documentation) local pagetype = get_pagetype(title) return match(pagetype, "%f[%w]testcase%f[%W]") and ( include_documentation or not match(pagetype, "%f[%w]documentation%f[%W]") ) and true or false end --[==[ Returns the namespace shortcut for the input title object, or else the namespace text. For example, a `Template:` title returns {"T"}, a `Module:` title returns {"MOD"}, and a `User:` title returns {"User"}.]==] function export.get_namespace_shortcut(title) return (namespace_shortcuts or get_namespace_shortcuts())[title.namespace] or title.nsText end get_namespace_shortcut = export.get_namespace_shortcut do local function check_level(lvl) if type(lvl) ~= "number" then error("Heading levels must be numbers.") elseif lvl < 1 or lvl > 6 or lvl % 1 ~= 0 then error("Heading levels must be integers between 1 and 6.") end return lvl end --[==[ A helper function which iterates over the headings in `text`, which should be the content of a page or (main) section. Each iteration returns three values: `sec` (the section title), `lvl` (the section level) and `loc` (the index of the section in the given text, from the first equals sign). The section title will be automatically trimmed, and any HTML entities will be resolved. The optional parameter `a` (which should be an integer between 1 and 6) can be used to ensure that only headings of the specified level are iterated over. If `b` is also given, then they are treated as a range. The optional parameters `a` and `b` can be used to specify a range, so that only headings with levels in that range are returned.]==] local function find_headings(text, a, b) a = a and check_level(a) or nil b = b and check_level(b) or a or nil local start, loc, lvl, sec = 1 return function() repeat loc, lvl, sec, start = match(text, "()%f[^%z\n](==?=?=?=?=?)([^\n]+)%2[\t ]*%f[%z\n]()", start) lvl = lvl and #lvl until not (sec and a) or (lvl >= a and lvl <= b) return sec and trim(decode_entities(sec)) or nil, lvl, loc end end local function _get_section(content, name, level) if not (content and name) then return nil elseif find(name, "\n", 1, true) then error("Heading name cannot contain a newline.") end level = level and check_level(level) or nil name = trim(decode_entities(name)) local start for sec, lvl, loc in find_headings(content, level and 1 or nil, level) do if start and lvl <= level then return sub(content, start, loc - 1) elseif not start and (not level or lvl == level) and sec == name then start, level = loc, lvl end end return start and sub(content, start) end --[==[ A helper function to return the content of a page section. `content` is raw wikitext, `name` is the requested section, and `level` is an optional parameter that specifies the required section heading level. If `level` is not supplied, then the first section called `name` is returned. `name` can either be a string or table of section names. If a table, each name represents a section that has the next as a subsection. For example, { {"Spanish", "Noun"}} will return the first matching section called "Noun" under a section called "Spanish". These do not have to be at adjacent levels ("Noun" might be L4, while "Spanish" is L2). If `level` is given, it refers to the last name in the table (i.e. the name of the section to be returned). The returned section includes all of its subsections. If no matching section is found, return {nil}.]==] function export.get_section(content, names, level) if type(names) ~= "table" then return _get_section(content, names, level) end local i = 1 local name = names[i] if not name then error("Must specify at least 1 section.") end while true do local nxt_i = i + 1 local nxt = names[nxt_i] if nxt == nil then return _get_section(content, name, level) end content = _get_section(content, name) if content == nil then return nil elseif i == 6 then error("Not possible specify more than 6 sections: headings only go up to level 6.") end i = nxt_i name = names[i] end return content end end do local current_section --[==[ A function which returns the number of the page section which contains the current {#invoke}.]==] function export.get_current_section() if current_section ~= nil then return current_section end local extension_tag = (current_frame or get_current_frame()).extensionTag -- We determine the section via the heading strip marker count, since they're numbered sequentially, but the only way to do this is to generate a fake heading via frame:preprocess(). The native parser assigns each heading a unique marker, but frame:preprocess() will return copies of older markers if the heading is identical to one further up the page, so the fake heading has to be unique to the page. The best way to do this is to feed it a heading containing a nowiki marker (which we will need later), since those are always unique. local nowiki_marker = extension_tag(current_frame, "nowiki") -- Note: heading strip markers have a different syntax to the ones used for tags. local h = tonumber(match( current_frame:preprocess("=" .. nowiki_marker .. "="), "\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127" )) -- For some reason, [[Special:ExpandTemplates]] doesn't generate a heading strip marker, so if that happens we simply abort early. if not h then return 0 end -- The only way to get the section number is to increment the heading count, so we store the offset in nowiki strip markers which can be retrieved by procedurally unstripping nowiki markers, counting backwards until we find a match. local n, offset = tonumber(match( nowiki_marker, "\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127" ), 16) while not offset and n > 0 do n = n - 1 offset = match( unstrip_nowiki(format("\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127", n)), "^HEADING\1(%d+)" -- Prefix "HEADING\1" prevents collisions. ) end offset = offset and (offset + 1) or 0 extension_tag(current_frame, "nowiki", "HEADING\1" .. offset) current_section = h - offset return current_section end get_current_section = export.get_current_section end do local L2_sections local function get_L2_sections() L2_sections, get_L2_sections = mw.loadData("Module:headword/data").page.L2_sections, nil return L2_sections end --[==[ A function which returns the name of the L2 language section which contains the current {#invoke}.]==] function export.get_current_L2() local section = get_current_section() if section == 0 then return end while section > 0 do local L2 = (L2_sections or get_L2_sections())[section] if L2 then return L2 end section = section - 1 end end end return export fahzb5v4u71j961eqb048ciy8nk4h06 26580 24045 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:pages]] 24045 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:pages -- License: CC BY-SA local export = {} local string_utilities_module = "Module:string utilities" local concat = table.concat local find = string.find local format = string.format local getmetatable = getmetatable local get_current_section -- defined below local get_namespace_shortcut -- defined below local get_pagetype -- defined below local gsub = string.gsub local insert = table.insert local is_internal_title -- defined below local is_title -- defined below local lower = string.lower local match = string.match local new_title = mw.title.new local require = require local sub = string.sub local title_equals = mw.title.equals local tonumber = tonumber local type = type local ufind = mw.ustring.find local unstrip_nowiki = mw.text.unstripNoWiki --[==[ 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end --[==[ 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 current_frame local function get_current_frame() current_frame, get_current_frame = mw.getCurrentFrame(), nil return current_frame end local parent_frame local function get_parent_frame() parent_frame, get_parent_frame = (current_frame or get_current_frame()):getParent(), nil return parent_frame end local namespace_shortcuts local function get_namespace_shortcuts() namespace_shortcuts, get_namespace_shortcuts = { [4] = "WT", [10] = "T", [14] = "CAT", [100] = "AP", [110] = "WS", [118] = "RC", [828] = "MOD", }, nil return namespace_shortcuts end do local transcluded --[==[ Returns {true} if the current {{tl|#invoke:}} is being transcluded, or {false} if not. If the current {{tl|#invoke:}} is part of a template, for instance, this template will therefore return {true}. Note that if a template containing an {{tl|#invoke:}} is used on its own page (e.g. to display a demonstration), this function is still able to detect that this is transclusion. This is an improvement over the other method for detecting transclusion, which is to check the parent frame title against the current page title, which fails to detect transclusion in that instance.]==] function export.is_transcluded() if transcluded == nil then transcluded = (parent_frame or get_parent_frame()) and parent_frame:preprocess("<includeonly>1</includeonly>") == "1" or false end return transcluded end end do local preview --[==[ Returns {true} if the page is currently being viewed in preview, or {false} if not.]==] function export.is_preview() if preview == nil then preview = (current_frame or get_current_frame()):preprocess("{{REVISIONID}}") == "" end return preview end end --[==[ Returns {true} if the input is a title object, or {false} if not. This therefore '''includes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_internal_title` below.]==] function export.is_title(val) if not (val and type(val) == "table") then return false end local mt = getmetatable(val) -- There's no foolproof method for checking for a title object, but the -- __eq metamethod should be mw.title.equals unless the object has been -- seriously messed around with. return mt and type(mt) == "table" and getmetatable(mt) == nil and mt.__eq == title_equals and true or false end is_title = export.is_title --[==[ Returns {true} if the input is an internal title object, or {false} if not. An internal title object is a title object for a page on this wiki, such as [[example]]. This therefore '''excludes''' external title objects (i.e. those for pages on other wikis), such as [[w:Example]], unlike `is_title` above.]==] function export.is_internal_title(title) -- Note: Mainspace titles starting with "#" should be invalid, but a bug in mw.title.new and mw.title.makeTitle means a title object is returned that has the empty string for prefixedText, so they need to be filtered out. return is_title(title) and #title.prefixedText > 0 and #title.interwiki == 0 end is_internal_title = export.is_internal_title --[==[ Returns {true} if the input string is a valid link target, or {false} if not. This therefore '''includes''' link targets to other wikis, such as [[w:Example]], unlike `is_valid_page_name` below.]==] function export.is_valid_link_target(target) local target_type = type(target) if target_type == "string" then return is_title(new_title(target)) end error(format("bad argument #1 to 'is_valid_link_target' (string expected, got %s)", target_type), 2) end --[==[ Returns {true} if the input string is a valid page name on this wiki, or {false} if not. This therefore '''excludes''' page names on other wikis, such as [[w:Example]], unlike `is_valid_link_target` above.]==] function export.is_valid_page_name(name) local name_type = type(name) if name_type == "string" then return is_internal_title(new_title(name)) end error(format("bad argument #1 to 'is_valid_page_name' (string expected, got %s)", name_type), 2) end --[==[ Given a title object, returns a full link target which will always unambiguously link to it. For instance, the input {"foo"} (for the page [[foo]]) returns {":foo"}, as a leading colon always refers to mainspace, even when other namespaces might be assumed (e.g. when transcluding using `{{ }}` syntax). If `shortcut` is set, then the returned target will use the namespace shortcut, if any; for example, the title for `Template:foo` would return {"T:foo"} instead of {"Template:foo"}.]==] function export.get_link_target(title, shortcut) if not is_title(title) then error(format("bad argument #1 to 'is_valid_link_target' (title object expected, got %s)", type(title))) elseif title.interwiki ~= "" then return title.fullText elseif shortcut then local fragment = title.fragment if fragment == "" then return get_namespace_shortcut(title) .. ":" .. title.text end return get_namespace_shortcut(title) .. ":" .. title.text .. "#" .. fragment elseif title.namespace == 0 then return ":" .. title.fullText end return title.fullText end do local function find_sandbox(text) return find(text, "^User:.") or find(lower(text), "sandbox", 1, true) end local function get_transclusion_subtypes(title, main_type, documentation, page_suffix) local text, subtypes = title.text, {main_type} -- Any template/module with "sandbox" in the title. These are impossible -- to screen for more accurately, as there's no consistent pattern. Also -- any user sandboxes in the form (e.g.) "Template:User:...". local sandbox = find_sandbox(text) if sandbox then insert(subtypes, "sandbox") end -- Any template/module testcases (which can be labelled and/or followed -- by further subpages). local testcase = find(text, "./[Tt]estcases?%f[%L]") if testcase then -- Order "testcase" and "sandbox" based on where the patterns occur -- in the title. local n = sandbox and sandbox < testcase and 3 or 2 insert(subtypes, n, "testcase") end -- Any template/module documentation pages. if documentation then insert(subtypes, "documentation") end local final = subtypes[#subtypes] if not (final == main_type and not page_suffix or final == "sandbox") then insert(subtypes, "page") end return concat(subtypes, " ") end local function get_snippet_subtypes(title, main_type, documentation) local ns = title.namespace return get_transclusion_subtypes(title, ( ns == 2 and "user " or ns == 8 and match(title.text, "^Gadget-.") and "gadget " or "" ) .. main_type, documentation) end --[==[ Returns the page type of the input title object in a format which can be used in running text.]==] function export.get_pagetype(title) if not is_internal_title(title) then error(mw.dumpObject(title.fullText) .. " is not a valid page name.") end -- If possibly a documentation page, get the base title and set the -- `documentation` flag. local content_model, text, documentation = title.contentModel if content_model == "wikitext" then text = title.text if title.isSubpage and title.subpageText == "documentation" then local base_title = title.basePageTitle if base_title then title, content_model, text, documentation = base_title, base_title.contentModel, base_title.text, true end end end -- Content models have overriding priority, as they can appear in -- nonstandard places due to page content model changes. if content_model == "css" or content_model == "sanitized-css" then return get_snippet_subtypes(title, "stylesheet", documentation) elseif content_model == "javascript" then return get_snippet_subtypes(title, "script", documentation) elseif content_model == "json" then return get_snippet_subtypes(title, "JSON data", documentation) elseif content_model == "MassMessageListContent" then return get_snippet_subtypes(title, "mass message delivery list", documentation) -- Modules. elseif content_model == "Scribunto" then return get_transclusion_subtypes(title, "module", documentation, false) elseif content_model == "text" then return "page" -- ??? -- Otherwise, the content model is "wikitext", so check namespaces. elseif title.isTalkPage then return "talk page" end local ns = title.namespace -- Main namespace. if ns == 0 then return "entry" -- Wiktionary: elseif ns == 4 then return find_sandbox(title.text) and "sandbox" or "project page" -- Template: elseif ns == 10 then return get_transclusion_subtypes(title, "template", documentation, false) end -- Convert the namespace to lowercase, unless it contains a capital -- letter after the initial letter (e.g. MediaWiki, TimedText). Also -- normalize any underscores. local ns_text = gsub(title.nsText, "_", " ") if ufind(ns_text, "^%U*$", 2) then ns_text = ulower(ns_text) end -- User: if ns == 2 then return ns_text .. " " .. (title.isSubpage and "subpage" or "page") -- Category: and Appendix: elseif ns == 14 or ns == 100 then return ns_text -- Thesaurus: and Reconstruction: elseif ns == 110 or ns == 118 then return ns_text .. " entry" end return ns_text .. " page" end get_pagetype = export.get_pagetype end --[==[ Returns {true} if the input title object is for a content page, or {false} if not. A content page is a page that is considered part of the dictionary itself, and excludes pages for discussion, administration, maintenance etc.]==] function export.is_content_page(title) if not is_internal_title(title) then error(mw.dumpObject(title.fullText) .. " is not a valid page name.") end local ns = title.namespace -- (main), Appendix, Thesaurus, Citations, Reconstruction. return (ns == 0 or ns == 100 or ns == 110 or ns == 114 or ns == 118) and title.contentModel == "wikitext" end --[==[ Returns {true} if the input title object is for a documentation page, or {false} if not.]==] function export.is_documentation(title) return match(get_pagetype(title), "%f[%w]documentation%f[%W]") and true or false end --[==[ Returns {true} if the input title object is for a sandbox, or {false} if not. By default, sandbox documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==] function export.is_sandbox(title, include_documentation) local pagetype = get_pagetype(title) return match(pagetype, "%f[%w]sandbox%f[%W]") and ( include_documentation or not match(pagetype, "%f[%w]documentation%f[%W]") ) and true or false end --[==[ Returns {true} if the input title object is for a testcase page, or {false} if not. By default, testcase documentation pages are excluded, but this can be overridden with the `include_documentation` parameter.]==] function export.is_testcase_page(title, include_documentation) local pagetype = get_pagetype(title) return match(pagetype, "%f[%w]testcase%f[%W]") and ( include_documentation or not match(pagetype, "%f[%w]documentation%f[%W]") ) and true or false end --[==[ Returns the namespace shortcut for the input title object, or else the namespace text. For example, a `Template:` title returns {"T"}, a `Module:` title returns {"MOD"}, and a `User:` title returns {"User"}.]==] function export.get_namespace_shortcut(title) return (namespace_shortcuts or get_namespace_shortcuts())[title.namespace] or title.nsText end get_namespace_shortcut = export.get_namespace_shortcut do local function check_level(lvl) if type(lvl) ~= "number" then error("Heading levels must be numbers.") elseif lvl < 1 or lvl > 6 or lvl % 1 ~= 0 then error("Heading levels must be integers between 1 and 6.") end return lvl end --[==[ A helper function which iterates over the headings in `text`, which should be the content of a page or (main) section. Each iteration returns three values: `sec` (the section title), `lvl` (the section level) and `loc` (the index of the section in the given text, from the first equals sign). The section title will be automatically trimmed, and any HTML entities will be resolved. The optional parameter `a` (which should be an integer between 1 and 6) can be used to ensure that only headings of the specified level are iterated over. If `b` is also given, then they are treated as a range. The optional parameters `a` and `b` can be used to specify a range, so that only headings with levels in that range are returned.]==] local function find_headings(text, a, b) a = a and check_level(a) or nil b = b and check_level(b) or a or nil local start, loc, lvl, sec = 1 return function() repeat loc, lvl, sec, start = match(text, "()%f[^%z\n](==?=?=?=?=?)([^\n]+)%2[\t ]*%f[%z\n]()", start) lvl = lvl and #lvl until not (sec and a) or (lvl >= a and lvl <= b) return sec and trim(decode_entities(sec)) or nil, lvl, loc end end local function _get_section(content, name, level) if not (content and name) then return nil elseif find(name, "\n", 1, true) then error("Heading name cannot contain a newline.") end level = level and check_level(level) or nil name = trim(decode_entities(name)) local start for sec, lvl, loc in find_headings(content, level and 1 or nil, level) do if start and lvl <= level then return sub(content, start, loc - 1) elseif not start and (not level or lvl == level) and sec == name then start, level = loc, lvl end end return start and sub(content, start) end --[==[ A helper function to return the content of a page section. `content` is raw wikitext, `name` is the requested section, and `level` is an optional parameter that specifies the required section heading level. If `level` is not supplied, then the first section called `name` is returned. `name` can either be a string or table of section names. If a table, each name represents a section that has the next as a subsection. For example, { {"Spanish", "Noun"}} will return the first matching section called "Noun" under a section called "Spanish". These do not have to be at adjacent levels ("Noun" might be L4, while "Spanish" is L2). If `level` is given, it refers to the last name in the table (i.e. the name of the section to be returned). The returned section includes all of its subsections. If no matching section is found, return {nil}.]==] function export.get_section(content, names, level) if type(names) ~= "table" then return _get_section(content, names, level) end local i = 1 local name = names[i] if not name then error("Must specify at least 1 section.") end while true do local nxt_i = i + 1 local nxt = names[nxt_i] if nxt == nil then return _get_section(content, name, level) end content = _get_section(content, name) if content == nil then return nil elseif i == 6 then error("Not possible specify more than 6 sections: headings only go up to level 6.") end i = nxt_i name = names[i] end return content end end -- A "safe" replacement for Lua mw.title.getCurrentTitle() / wikitext {{PAGENAME}}. -- Intended for use by pronunciation, headword, inflection and reference -- templates that need to know what term the current page relates to. -- -- safe_page_name takes a pagename and converts it to a term, making it the -- "inverse" of Language:makeEntryName, which takes a term and gets the pagename. -- Examples: -- safe_page_name('a') → 'a' -- safe_page_name('a/languages A to L') → 'a' (since [[a]] is marked as a mammoth page in [[Module:links/data]]) -- safe_page_name('Appendix:Lojban/a') → 'a' -- safe_page_name('Reconstruction:Proto-Slavic/a') → 'a' -- safe_page_name('User:Example/a') → 'a' -- safe_page_name(), with no parameter, returns the safe page name of the -- current page. -- -- Wikitext equivalent: [[Template:safe page name]] function export.safe_page_name(title) -- deal with invocations from wikitext if title ~= nil and title.args ~= nil then title = title.args.title end if title == nil then title = mw.title.getCurrentTitle() elseif not is_title(title) then title = mw.title.new(title) end -- subpageText gives the part after the final slash, EXCEPT in main namespace, -- where subpages are not enabled, in which case it gives the entire page name -- (see [[Special:NamespaceInfo]]) pagename = title.subpageText local slashPos = string.find(pagename, '/') if slashPos then local afterSlash = mw.ustring.sub(pagename, slashPos + 1) local links_data = mw.loadData("Module:links/data") if links_data.mammoth_page_subpages[afterSlash] then -- Looks like we have a mammoth page. If so, act as though we are -- on the root page (e.g. [[a]] instead of [[a/languages A to L]]) local maybePagename = mw.ustring.sub(pagename, 0, slashPos - 1) if links_data.mammoth_pages[maybePagename] then pagename = maybePagename end end end return pagename end do local current_section --[==[ A function which returns the number of the page section which contains the current {#invoke}.]==] function export.get_current_section() if current_section ~= nil then return current_section end local extension_tag = (current_frame or get_current_frame()).extensionTag -- We determine the section via the heading strip marker count, since they're numbered sequentially, but the only way to do this is to generate a fake heading via frame:preprocess(). The native parser assigns each heading a unique marker, but frame:preprocess() will return copies of older markers if the heading is identical to one further up the page, so the fake heading has to be unique to the page. The best way to do this is to feed it a heading containing a nowiki marker (which we will need later), since those are always unique. local nowiki_marker = extension_tag(current_frame, "nowiki") -- Note: heading strip markers have a different syntax to the ones used for tags. local h = tonumber(match( current_frame:preprocess("=" .. nowiki_marker .. "="), "\127'\"`UNIQ%-%-h%-(%d+)%-%-QINU`\"'\127" )) -- For some reason, [[Special:ExpandTemplates]] doesn't generate a heading strip marker, so if that happens we simply abort early. if not h then return 0 end -- The only way to get the section number is to increment the heading count, so we store the offset in nowiki strip markers which can be retrieved by procedurally unstripping nowiki markers, counting backwards until we find a match. local n, offset = tonumber(match( nowiki_marker, "\127'\"`UNIQ%-%-nowiki%-([%dA-F]+)%-QINU`\"'\127" ), 16) while not offset and n > 0 do n = n - 1 offset = match( unstrip_nowiki(format("\127'\"`UNIQ--nowiki-%08X-QINU`\"'\127", n)), "^HEADING\1(%d+)" -- Prefix "HEADING\1" prevents collisions. ) end offset = offset and (offset + 1) or 0 extension_tag(current_frame, "nowiki", "HEADING\1" .. offset) current_section = h - offset return current_section end get_current_section = export.get_current_section end do local L2_sections, current_L2 local function get_L2_sections() L2_sections, get_L2_sections = mw.loadData("Module:headword/data").page.L2_sections, nil return L2_sections end --[==[ A function which returns the name of the L2 language section which contains the current {#invoke}.]==] function export.get_current_L2() if current_L2 ~= nil then return current_L2 or nil -- Return nil if current_L2 is false (i.e. there's no L2). end local section = get_current_section() while section > 0 do local L2 = (L2_sections or get_L2_sections())[section] if L2 then current_L2 = L2 return L2 end section = section - 1 end current_L2 = false return nil end end return export 0af6cj2a0bbt3bgkx7bhg14n51pj3nl Modul:table/getMetamethod 828 7052 26656 2025-11-08T17:07:27Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26656 Scribunto text/plain local table_get_unprotected_metatable = "Module:table/getUnprotectedMetatable" local rawget = rawget local select = select local function get_unprotected_metatable(...) get_unprotected_metatable = require(table_get_unprotected_metatable) return get_unprotected_metatable(...) end local function get_metamethod(n, i, mt, mm, ...) if mt then mm = rawget(mt, mm) else mm = nil end if i == n then return mm end return mm, get_metamethod(n, i + 1, mt, ...) end --[==[ Takes an input value and any number of metamethods, and attempts to retrieve the values at those keys in the value's metatable. Returns a boolean stating whether the value's metamethods are findable, followed by a return value for each metamethod. A value's metamethods are findable if it does not have a protected metatable, so the first return value is {true} if the value either has a metatable which does not contain the {__metatable} metamethod, or it has no metatable at all. If the value does have a protected metatable, the first return value is {false}, and all remaining return values default to {nil}.]==] return function(t, ...) local mt, n = get_unprotected_metatable(t), select("#", ...) -- get_unprotected_metatable() returns the metatable if it's unprotected, -- false if it's protected, or nil if there is no metatable. It checks -- whether a metatable is protected by trying pcall(setmetatable, t), -- so it's always possible to determine accurately. if n == 0 then return mt ~= false end return mt ~= false, get_metamethod(n, 1, mt, ...) end tfl070cq0h5icostaevq3t6kcrhpcyw 26657 24095 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/getMetamethod]] 24095 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:table/getMetamethod -- License: CC BY-SA local table_get_unprotected_metatable = "Module:table/getUnprotectedMetatable" local rawget = rawget local select = select local function get_unprotected_metatable(...) get_unprotected_metatable = require(table_get_unprotected_metatable) return get_unprotected_metatable(...) end local function get_metamethod(n, i, mt, mm, ...) if mt then mm = rawget(mt, mm) else mm = nil end if i == n then return mm end return mm, get_metamethod(n, i + 1, mt, ...) end --[==[ Takes an input value and any number of metamethods, and attempts to retrieve the values at those keys in the value's metatable. Returns a boolean stating whether the value's metamethods are findable, followed by a return value for each metamethod. A value's metamethods are findable if it does not have a protected metatable, so the first return value is {true} if the value either has a metatable which does not contain the {__metatable} metamethod, or it has no metatable at all. If the value does have a protected metatable, the first return value is {false}, and all remaining return values default to {nil}.]==] return function(t, ...) local mt, n = get_unprotected_metatable(t), select("#", ...) -- get_unprotected_metatable() returns the metatable if it's unprotected, -- false if it's protected, or nil if there is no metatable. It checks -- whether a metatable is protected by trying pcall(setmetatable, t), -- so it's always possible to determine accurately. if n == 0 then return mt ~= false end return mt ~= false, get_metamethod(n, 1, mt, ...) end cr9sso1fatchh39qxolpw6512nbz5do Modul:table/getNested 828 7053 26646 2025-11-08T21:20:00Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26646 Scribunto text/plain local error = error local select = select --[==[ Given a table and an arbitrary number of keys, will successively access subtables using each key in turn, returning the value at the final key. For example, if {t} is { {[1] = {[2] = {[3] = "foo"}}}}, {export.getNested(t, 1, 2, 3)} will return {"foo"}. If no subtable exists for a given key value, returns nil, but will throw an error if a non-table is found at an intermediary key.]==] return function(...) local n = select("#", ...) if n < 2 then error("Must provide a table and at least one key.") end local t, k = ... for i = 3, n do local v = t[k] if v == nil then return nil end t, k = v, select(i, ...) end return t[k] end tm1q0pycz7xr0ute9n4h4yhpf1jzo33 26647 24096 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/getNested]] 24096 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:table/getNested -- License: CC BY-SA local error = error local select = select --[==[ Given a table and an arbitrary number of keys, will successively access subtables using each key in turn, returning the value at the final key. For example, if {t} is { {[1] = {[2] = {[3] = "foo"}}}}, {export.getNested(t, 1, 2, 3)} will return {"foo"}. If no subtable exists for a given key value, returns nil, but will throw an error if a non-table is found at an intermediary key.]==] return function(...) local n = select("#", ...) if n < 2 then error("Must provide a table and at least one key.") end local t, k = ... for i = 3, n do local v = t[k] if v == nil then return nil end t, k = v, select(i, ...) end return t[k] end skf7uzi7491x4a62bh3ad8emwpkk3no Modul:table/listToSet 828 7065 26626 2025-11-08T22:31:00Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26626 Scribunto text/plain local fun_is_callable_module = "Module:fun/isCallable" local function is_callable(...) is_callable = require(fun_is_callable_module) return is_callable(...) end --[==[ Convert `list` (a table with a list of values) into a set (a table where those values are keys instead). This is a useful way to create a fast lookup table, since looking up a table key is much, much faster than iterating over the whole list to see if it contains a given value. By default, each item is given the value true. If the optional parameter `value` is a function or functor, then it is called as an iterator, with the list index as the first argument, the item as the second (which will be used as the key), plus any additional arguments passed to {listToSet}; the returned value is used as the value for that list item. If `value` is anything else, then it is used as the fixed value for every item.]==] return function(list, value, ...) local set, i = {}, 1 if value == nil then value = true elseif is_callable(value) then while true do local item = list[i] if item == nil then return set end set[item] = value(i, item, ...) i = i + 1 end end while true do local item = list[i] if item == nil then return set end set[item] = value i = i + 1 end end o2d2ojf8rsrqqaqy0ffn7n4y1a1r9tb 26627 24108 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/listToSet]] 24108 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:table/listToSet -- License: CC BY-SA local fun_is_callable_module = "Module:fun/isCallable" local function is_callable(...) is_callable = require(fun_is_callable_module) return is_callable(...) end --[==[ Convert `list` (a table with a list of values) into a set (a table where those values are keys instead). This is a useful way to create a fast lookup table, since looking up a table key is much, much faster than iterating over the whole list to see if it contains a given value. By default, each item is given the value true. If the optional parameter `value` is a function or functor, then it is called as an iterator, with the list index as the first argument, the item as the second (which will be used as the key), plus any additional arguments passed to {listToSet}; the returned value is used as the value for that list item. If `value` is anything else, then it is used as the fixed value for every item.]==] return function(list, value, ...) local set, i = {}, 1 if value == nil then value = true elseif is_callable(value) then while true do local item = list[i] if item == nil then return set end set[item] = value(i, item, ...) i = i + 1 end end while true do local item = list[i] if item == nil then return set end set[item] = value i = i + 1 end end 2cekhvxh9yynl35mmcd79vb3m8z5z9n Modul:table/setNested 828 7071 26644 2025-11-08T21:20:39Z id>Ekirahardian 0 ←Membuat halaman berisi 'local error = error local select = select --[==[ Given a table, value and an arbitrary number of keys, will successively access subtables using each key in turn, and sets the value at the final key. For example, if {t} is { {} }, {export.setNested(t, "foo", 1, 2, 3)} will modify {t} to { {[1] = {[2] = {[3] = "foo"} } } }. If no subtable exists for a given key value, one will be created, but the function will throw an error if a non-table value is found at an in...' 26644 Scribunto text/plain local error = error local select = select --[==[ Given a table, value and an arbitrary number of keys, will successively access subtables using each key in turn, and sets the value at the final key. For example, if {t} is { {} }, {export.setNested(t, "foo", 1, 2, 3)} will modify {t} to { {[1] = {[2] = {[3] = "foo"} } } }. If no subtable exists for a given key value, one will be created, but the function will throw an error if a non-table value is found at an intermediary key. Note: the parameter order (table, value, keys) differs from functions like rawset, because the number of keys can be arbitrary. This is to avoid situations where an additional argument must be appended to arbitrary lists of variables, which can be awkward and error-prone: for example, when handling variable arguments ({...}) or function return values.]==] return function(...) local n = select("#", ...) if n < 3 then error("Must provide a table, value and at least one key.") end local t, v, k = ... for i = 4, n do local next_t = t[k] if next_t == nil then -- If there's no next table while setting nil, there's nothing more -- to do. if v == nil then return end next_t = {} t[k] = next_t end t, k = next_t, select(i, ...) end t[k] = v end 1jxfjipchypy8qfjkmtb9b9sal1bcc1 26645 24114 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/setNested]] 24114 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:table/setNested -- License: CC BY-SA local error = error local select = select --[==[ Given a table, value and an arbitrary number of keys, will successively access subtables using each key in turn, and sets the value at the final key. For example, if {t} is { {} }, {export.setNested(t, "foo", 1, 2, 3)} will modify {t} to { {[1] = {[2] = {[3] = "foo"} } } }. If no subtable exists for a given key value, one will be created, but the function will throw an error if a non-table value is found at an intermediary key. Note: the parameter order (table, value, keys) differs from functions like rawset, because the number of keys can be arbitrary. This is to avoid situations where an additional argument must be appended to arbitrary lists of variables, which can be awkward and error-prone: for example, when handling variable arguments ({...}) or function return values.]==] return function(...) local n = select("#", ...) if n < 3 then error("Must provide a table, value and at least one key.") end local t, v, k = ... for i = 4, n do local next_t = t[k] if next_t == nil then -- If there's no next table while setting nil, there's nothing more -- to do. if v == nil then return end next_t = {} t[k] = next_t end t, k = next_t, select(i, ...) end t[k] = v end qq1ibtklp6g17c9ztsvp8dnvv8u78vw Modul:table/shallowCopy 828 7073 26581 2025-11-08T21:22:41Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26581 Scribunto text/plain local next = next local pairs = pairs local type = type --[==[ Returns a clone of an object. If the object is a table, the value returned is a new table, but all subtables and functions are shared. Metamethods are respected unless the `raw` flag is set, but the returned table will have no metatable of its own.]==] return function(orig, raw) if type(orig) ~= "table" then return orig end local copy, iter, state, init = {} if raw then iter, state = next, orig else iter, state, init = pairs(orig) end for k, v in iter, state, init do copy[k] = v end return copy end t51fcj6fuqkknha7dzzm33l4y4ohb22 26582 24116 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:table/shallowCopy]] 24116 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:table/shallowCopy -- License: CC BY-SA local next = next local pairs = pairs local type = type --[==[ Returns a clone of an object. If the object is a table, the value returned is a new table, but all subtables and functions are shared. Metamethods are respected unless the `raw` flag is set, but the returned table will have no metatable of its own.]==] return function(orig, raw) if type(orig) ~= "table" then return orig end local copy, iter, state, init = {} if raw then iter, state = next, orig else iter, state, init = pairs(orig) end for k, v in iter, state, init do copy[k] = v end return copy end 2fsmdau3fxn18j6o9znhtwnp3r7lrkf Modul:glossary/data 828 7091 26640 2025-11-24T07:30:17Z id>Swarabakti 0 26640 Scribunto text/plain -- [[Module:glossary]] and [[Module:get IDs]] both process anchor strings with -- normalize_anchor, which handles character escapes, spaces, underscores etc. return require("Module:table/listToSet")(require("Module:get IDs").get("Lampiran:Glosarium")) hslo5mvbgi3qck8areio55pzxc3hdey 26641 24134 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:glossary/data]] 24134 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:glossary/data -- License: CC BY-SA -- [[Module:glossary]] and [[Module:get IDs]] both process anchor strings with -- normalize_anchor, which handles character escapes, spaces, underscores etc. return require("Module:table/listToSet")(require("Module:get IDs").get("Appendix:Glossary")) 904411xx7bgpiyp9xvwd5gstyfkkv44 Modul:Scribunto/metamethods 828 7150 26642 2025-11-08T21:19:04Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26642 Scribunto text/plain return { __add = true, __call = true, __concat = true, __div = true, __eq = true, __gc = true, __index = true, __ipairs = true, __le = true, __len = true, __lt = true, __metatable = true, __mod = true, __mode = true, __mul = true, __newindex = true, __pairs = true, __pow = true, __sub = true, __tostring = true, __unm = true, } 9ldqvu9rhlfkuksyro1b52m6ychbevm 26643 24193 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:Scribunto/metamethods]] 24193 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:Scribunto/metamethods -- License: CC BY-SA return { __add = true, __call = true, __concat = true, __div = true, __eq = true, __gc = true, __index = true, __ipairs = true, __le = true, __len = true, __lt = true, __metatable = true, __mod = true, __mode = true, __mul = true, __newindex = true, __pairs = true, __pow = true, __sub = true, __tostring = true, __unm = true, } 1uviyof0tfx7wnzfowpyxkye92lczpc Modul:string/decodeEntities 828 7177 26575 2025-11-08T18:46:17Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26575 Scribunto text/plain local load_module = "Module:load" local string_char_module = "Module:string/char" local find = string.find local gsub = string.gsub local match = string.match local require = require local tonumber = tonumber local function u(...) u = require(string_char_module) return u(...) end local entities local function get_entities() entities, get_entities = require(load_module).load_data("Module:data/entities"), nil return entities end local function decode_entity(hash, x, code) -- "#" isn't included in "[%w\128-\255]", so if no "#" is found then it's a -- a named entity or a false match. if hash == "" then return (entities or get_entities())[x .. code] end -- Exclude numbers that don't fit the expected format. local cp if x == "" then cp = match(code, "^()%d+$") and tonumber(code) else cp = match(code, "^()%x+$") and tonumber(code, 16) end -- Exclude surrogates (U+D800 to U+DFFF) and codepoints that are too high. return cp and ( cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF ) and u(cp) or nil end return function(str) -- As an optimisation, only do a full search with gsub() if plain searches -- for "&" and ";" find anything. local amp = find(str, "&", nil, true) -- Search for ";" after the point "&" was found. return amp and find(str, ";", amp + 1, true) and -- Non-ASCII characters aren't valid in proper HTML named entities, but -- MediaWiki uses them in some nonstandard aliases (which have also been -- included in [[Module:data/entities]]), so include them anyway. gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str end 1ehplvn1q6ksitguquhvf1khnaq3mxd 26576 24233 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/decodeEntities]] 24233 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:string/decodeEntities -- License: CC BY-SA local load_module = "Module:load" local string_char_module = "Module:string/char" local find = string.find local gsub = string.gsub local match = string.match local require = require local tonumber = tonumber local function u(...) u = require(string_char_module) return u(...) end local entities local function get_entities() entities, get_entities = require(load_module).load_data("Module:data/entities"), nil return entities end local function decode_entity(hash, x, code) -- "#" isn't included in "[%w\128-\255]", so if no "#" is found then it's a -- a named entity or a false match. if hash == "" then return (entities or get_entities())[x .. code] end -- Exclude numbers that don't fit the expected format. local cp if x == "" then cp = match(code, "^()%d+$") and tonumber(code) else cp = match(code, "^()%x+$") and tonumber(code, 16) end -- Exclude surrogates (U+D800 to U+DFFF) and codepoints that are too high. return cp and ( cp <= 0xD7FF or cp >= 0xE000 and cp <= 0x10FFFF ) and u(cp) or nil end return function(str) -- As an optimisation, only do a full search with gsub() if plain searches -- for "&" and ";" find anything. local amp = find(str, "&", nil, true) -- Search for ";" after the point "&" was found. return amp and find(str, ";", amp + 1, true) and -- Non-ASCII characters aren't valid in proper HTML named entities, but -- MediaWiki uses them in some nonstandard aliases (which have also been -- included in [[Module:data/entities]]), so include them anyway. gsub(str, "&(#?)([xX]?)([%w\128-\255]+);", decode_entity) or str end 7lggynrzzf96al2zy00itv5i9fkxwi8 Modul:string/encode entities 828 7178 26565 2025-11-08T18:44:49Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26565 Scribunto text/plain -- TO BE REPLACED BY encode_entities in [[Module:string utilities]]. This function decodes on input by default to prevent double-encoding, which the new function does not, so implementations need to take this into account when being converted. local debug_track_module = "Module:debug/track" local string_decode_entities_module = "Module:string/decodeEntities" local string_utilities_module = "Module:string utilities" local require = require local function decode_entities(...) decode_entities = require(string_decode_entities_module) return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end local function track(...) track = require(debug_track_module) return track(...) end return function(str, charset, raw) if not raw then local decoded = decode_entities(str) if decoded ~= str then track("string/encode entities/decoded first") end str = decoded end return encode_entities(str, charset, nil, true) end bvh4hqobw96dy8gcuv3yoq2nlvj06si 26566 24234 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/encode_entities]] 24234 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:string/encode entities -- License: CC BY-SA -- TO BE REPLACED BY encode_entities in [[Module:string utilities]]. This function decodes on input by default to prevent double-encoding, which the new function does not, so implementations need to take this into account when being converted. local debug_track_module = "Module:debug/track" local string_decode_entities_module = "Module:string/decodeEntities" local string_utilities_module = "Module:string utilities" local require = require local function decode_entities(...) decode_entities = require(string_decode_entities_module) return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end local function track(...) track = require(debug_track_module) return track(...) end return function(str, charset, raw) if not raw then local decoded = decode_entities(str) if decoded ~= str then track("string/encode entities/decoded first") end str = decoded end return encode_entities(str, charset, nil, true) end sawqcx1jng9uei60gt5y8qfld68llsa Modul:string/nowiki 828 7187 26658 2025-11-08T22:30:08Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26658 Scribunto text/plain local table_list_to_set_module = "Module:table/listToSet" local byte = string.byte local char = string.char local find = string.find local format = string.format local gsub = string.gsub local lower = string.lower local sub = string.sub local function list_to_set(...) list_to_set = require(table_list_to_set_module) return list_to_set(...) end local function escape_byte(_, b) return format("&#%d;", b) end local absolute local function get_absolute() absolute, get_absolute = list_to_set({"\"", "&", "'", ";", "<", "=", ">", "[", "]", "{", "|", "}"}, function(_, ch) return format("&#%d;", byte(ch)) end), nil return absolute end local after_newline local function get_after_newline() after_newline, get_after_newline = list_to_set({0x9, 0xA, 0xD, 0x20, 0x21, 0x23, 0x2A, 0x3A}, escape_byte), nil return after_newline end local scheme_chars, unused_scheme_chars, uri_schemes local function get_scheme_chars() local _uri_schemes = {"bitcoin", "geo", "magnet", "mailto", "matrix", "news", "sip", "sips", "sms", "tel", "urn", "xmpp"} uri_schemes, get_scheme_chars = list_to_set(_uri_schemes), nil _uri_schemes = table.concat(_uri_schemes) -- Add alphanumeric characters used in a listed scheme to `scheme_chars`, -- and those that aren't to `unused_scheme_chars`. scheme_chars, unused_scheme_chars = {}, {} for i = 0x61, 0x7A do local chars = find(_uri_schemes, char(i), nil, true) and scheme_chars or unused_scheme_chars chars[i] = true chars[i - 0x20] = true end unused_scheme_chars[0x5F] = true -- _ return scheme_chars end local after_magic_link local function get_after_magic_link() after_magic_link, get_after_magic_link = list_to_set({0x9, 0xA, 0xC, 0xD, 0x20}, escape_byte), nil return after_magic_link end -- Temporary variables. No risk of collisions across stack levels, since there's -- no way for nowiki() to be called recursively. local _str, esc, esc_next, esc_next2 local function nowiki(loc, ch) if esc_next ~= nil then esc, esc_next, esc_next2 = esc_next, esc_next2, nil return esc or nil end esc = (absolute or get_absolute())[ch] if esc then return esc elseif ch == "\n" or ch == "\r" then esc_next = (after_newline or get_after_newline())[byte(_str, loc + 1)] elseif ch == "!" then if byte(_str, loc + 1) == 0x21 then -- ! esc_next = "&#33;" end elseif ch == ":" then if sub(_str, loc + 1, loc + 2) == "//" then return "&#58;" end local n, b = 0 repeat n = n + 1 b = byte(_str, loc - n) until not (scheme_chars or get_scheme_chars())[b] -- Abort on an unused scheme character, as it can't be a scheme. if unused_scheme_chars[b] then return -- Otherwise, check if the the word before the colon matches a scheme. elseif uri_schemes[lower(sub(_str, loc - n + 1, loc - 1))] then return "&#58;" end elseif ch == "-" then local prev = byte(_str, loc - 1) if (prev == 0xA or prev == 0xD) and sub(_str, loc + 1, loc + 3) == "---" then return "&#45;" end elseif ch == "I" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 4)] if esc_sp and sub(_str, loc + 1, loc + 3) == "SBN" then esc_next = esc_sp end elseif ch == "P" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 4)] if esc_sp and sub(_str, loc + 1, loc + 3) == "MID" then esc_next, esc_next2 = false, esc_sp -- to avoid escaping "I" in "PMID" end elseif ch == "R" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 3)] if esc_sp and sub(_str, loc + 1, loc + 2) == "FC" then esc_next = esc_sp end elseif ch == "_" then if byte(_str, loc + 1) == 0x5F then -- _ esc_next = "&#95;" end elseif ch == "~" then if sub(_str, loc + 1, loc + 2) == "~~" then esc_next, esc_next2 = false, "&#126;" end end end local first local function get_first() first, get_first = list_to_set({0x9, 0xA, 0xD, 0x20, 0x21, 0x23, 0x2A, 0x2B, 0x2D, 0x3A, 0x5F, 0x7E}, escape_byte), nil return first end local last local function get_last() last, get_last = list_to_set({0x9, 0xA, 0xC, 0xD, 0x20, 0x21, 0x3A, 0x5F, 0x7E}, escape_byte), nil return last end return function(str) if #str == 0 then return str end _str, esc, esc_next, esc_next2 = str, nil, nil, nil str = gsub(str, "()([%s!\"#&'*%-:;<=>IPR[%]_{|}~])", nowiki) local b = byte(str, 1) local esc_first = (first or get_first())[b] if #str == 1 then return esc_first or (last or get_last())[b] or str end local esc_last = (last or get_last())[byte(str, -1)] if esc_first then if esc_last then return esc_first .. sub(str, 2, -2) .. esc_last end return esc_first .. sub(str, 2) elseif esc_last then return sub(str, 1, -2) .. esc_last end return str end iqdxq0iiw3rpvozlhmhirkfu3sj92s0 26659 24243 2026-07-08T05:00:43Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/nowiki]] 24243 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:string/nowiki -- License: CC BY-SA local table_list_to_set_module = "Module:table/listToSet" local byte = string.byte local char = string.char local find = string.find local format = string.format local gsub = string.gsub local lower = string.lower local sub = string.sub local function list_to_set(...) list_to_set = require(table_list_to_set_module) return list_to_set(...) end local function escape_byte(_, b) return format("&#%d;", b) end local absolute local function get_absolute() absolute, get_absolute = list_to_set({"\"", "&", "'", ";", "<", "=", ">", "[", "]", "{", "|", "}"}, function(_, ch) return format("&#%d;", byte(ch)) end), nil return absolute end local after_newline local function get_after_newline() after_newline, get_after_newline = list_to_set({0x9, 0xA, 0xD, 0x20, 0x21, 0x23, 0x2A, 0x3A}, escape_byte), nil return after_newline end local scheme_chars, unused_scheme_chars, uri_schemes local function get_scheme_chars() local _uri_schemes = {"bitcoin", "geo", "magnet", "mailto", "matrix", "news", "sip", "sips", "sms", "tel", "urn", "xmpp"} uri_schemes, get_scheme_chars = list_to_set(_uri_schemes), nil _uri_schemes = table.concat(_uri_schemes) -- Add alphanumeric characters used in a listed scheme to `scheme_chars`, -- and those that aren't to `unused_scheme_chars`. scheme_chars, unused_scheme_chars = {}, {} for i = 0x61, 0x7A do local chars = find(_uri_schemes, char(i), nil, true) and scheme_chars or unused_scheme_chars chars[i] = true chars[i - 0x20] = true end unused_scheme_chars[0x5F] = true -- _ return scheme_chars end local after_magic_link local function get_after_magic_link() after_magic_link, get_after_magic_link = list_to_set({0x9, 0xA, 0xC, 0xD, 0x20}, escape_byte), nil return after_magic_link end -- Temporary variables. No risk of collisions across stack levels, since there's -- no way for nowiki() to be called recursively. local _str, esc, esc_next, esc_next2 local function nowiki(loc, ch) if esc_next ~= nil then esc, esc_next, esc_next2 = esc_next, esc_next2, nil return esc or nil end esc = (absolute or get_absolute())[ch] if esc then return esc elseif ch == "\n" or ch == "\r" then esc_next = (after_newline or get_after_newline())[byte(_str, loc + 1)] elseif ch == "!" then if byte(_str, loc + 1) == 0x21 then -- ! esc_next = "&#33;" end elseif ch == ":" then if sub(_str, loc + 1, loc + 2) == "//" then return "&#58;" end local n, b = 0 repeat n = n + 1 b = byte(_str, loc - n) until not (scheme_chars or get_scheme_chars())[b] -- Abort on an unused scheme character, as it can't be a scheme. if unused_scheme_chars[b] then return -- Otherwise, check if the the word before the colon matches a scheme. elseif uri_schemes[lower(sub(_str, loc - n + 1, loc - 1))] then return "&#58;" end elseif ch == "-" then local prev = byte(_str, loc - 1) if (prev == 0xA or prev == 0xD) and sub(_str, loc + 1, loc + 3) == "---" then return "&#45;" end elseif ch == "I" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 4)] if esc_sp and sub(_str, loc + 1, loc + 3) == "SBN" then esc_next = esc_sp end elseif ch == "P" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 4)] if esc_sp and sub(_str, loc + 1, loc + 3) == "MID" then esc_next, esc_next2 = false, esc_sp -- to avoid escaping "I" in "PMID" end elseif ch == "R" then local esc_sp = (after_magic_link or get_after_magic_link())[byte(_str, loc + 3)] if esc_sp and sub(_str, loc + 1, loc + 2) == "FC" then esc_next = esc_sp end elseif ch == "_" then if byte(_str, loc + 1) == 0x5F then -- _ esc_next = "&#95;" end elseif ch == "~" then if sub(_str, loc + 1, loc + 2) == "~~" then esc_next, esc_next2 = false, "&#126;" end end end local first local function get_first() first, get_first = list_to_set({0x9, 0xA, 0xD, 0x20, 0x21, 0x23, 0x2A, 0x2B, 0x2D, 0x3A, 0x5F, 0x7E}, escape_byte), nil return first end local last local function get_last() last, get_last = list_to_set({0x9, 0xA, 0xC, 0xD, 0x20, 0x21, 0x3A, 0x5F, 0x7E}, escape_byte), nil return last end return function(str) if #str == 0 then return str end _str, esc, esc_next, esc_next2 = str, nil, nil, nil str = gsub(str, "()([%s!\"#&'*%-:;<=>IPR[%]_{|}~])", nowiki) local b = byte(str, 1) local esc_first = (first or get_first())[b] if #str == 1 then return esc_first or (last or get_last())[b] or str end local esc_last = (last or get_last())[byte(str, -1)] if esc_first then if esc_last then return esc_first .. sub(str, 2, -2) .. esc_last end return esc_first .. sub(str, 2) elseif esc_last then return sub(str, 1, -2) .. esc_last end return str end ez5va707o4cn911lkqggymgpcsm60fr Modul:string/patternEscape 828 7188 26571 2025-11-08T18:48:32Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26571 Scribunto text/plain local gsub = string.gsub local chars local function get_chars() chars, get_chars = { ["\000"] = "%z", ["$"] = "%$", ["%"] = "%%", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+", ["-"] = "%-", ["."] = "%.", ["?"] = "%?", ["["] = "%[", ["]"] = "%]", ["^"] = "%^", }, nil return chars end --[==[Escapes the magic characters used in a pattern: {$%()*+-.?[]^}, and converts the null character to {%z}. For example, {"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving arbitrary text (e.g. from user input).]==] return function(str) return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars or get_chars())) end kdhwp5dohwvh931huz7m0oufqqh05wl 26572 24244 2026-07-07T21:53:37Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/patternEscape]] 24244 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:string/patternEscape -- License: CC BY-SA local gsub = string.gsub local chars local function get_chars() chars, get_chars = { ["\000"] = "%z", ["$"] = "%$", ["%"] = "%%", ["("] = "%(", [")"] = "%)", ["*"] = "%*", ["+"] = "%+", ["-"] = "%-", ["."] = "%.", ["?"] = "%?", ["["] = "%[", ["]"] = "%]", ["^"] = "%^", }, nil return chars end --[==[Escapes the magic characters used in a pattern: {$%()*+-.?[]^}, and converts the null character to {%z}. For example, {"^$()%.[]*+-?\0"} becomes {"%^%$%(%)%%%.%[%]%*%+%-%?%z"}. This is necessary when constructing a pattern involving arbitrary text (e.g. from user input).]==] return function(str) return (gsub(str, "[%z$%%()*+%-.?[%]^]", chars or get_chars())) end tjp8c4dm18t8ga89qltmbh0cnufkp33 Modul:string/replacementEscape 828 7192 26573 2025-11-08T18:49:33Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26573 Scribunto text/plain local gsub = string.gsub --[==[Escapes {%}, which is the only magic character used in replacement strings, which are given as the third argument to {string.gsub} and {mw.ustring.gsub}, as well as format strings given to {string.format} and {mw.ustring.format}.]==] return function(str) return (gsub(str, "%%", "%%%%")) end aid90he3azqkc4qrytnczmfsjczbfe3 26574 24248 2026-07-07T21:53:38Z Sibiru45 115 1 ralatan matan [[:id:Modul:string/replacementEscape]] 24248 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:string/replacementEscape -- License: CC BY-SA local gsub = string.gsub --[==[Escapes {%}, which is the only magic character used in replacement strings, which are given as the third argument to {string.gsub} and {mw.ustring.gsub}, as well as format strings given to {string.format} and {mw.ustring.format}.]==] return function(str) return (gsub(str, "%%", "%%%%")) end sqofsk9xmqjbcy0cnnvq16axnavvane Modul:template parser 828 7199 26630 2025-11-08T21:12:42Z id>Ekirahardian 0 Perbarui dari en.wikipedia.org 26630 Scribunto text/plain --[[ NOTE: This module works by using recursive backtracking to build a node tree, which can then be traversed as necessary. Because it is called by a number of high-use modules, it has been optimised for speed using a profiler, since it is used to scrape data from large numbers of pages very quickly. To that end, it rolls some of its own methods in cases where this is faster than using a function from one of the standard libraries. Please DO NOT "simplify" the code by removing these, since you are almost guaranteed to slow things down, which could seriously impact performance on pages which call this module hundreds or thousands of times. It has also been designed to emulate the native parser's behaviour as much as possible, which in some cases means replicating bugs or unintuitive behaviours in that code; these should not be "fixed", since it is important that the outputs are the same. Most of these originate from deficient regular expressions, which can't be used here, so the bugs have to be manually reintroduced as special cases (e.g. onlyinclude tags being case-sensitive and whitespace intolerant, unlike all other tags). If any of these are fixed, this module should also be updated accordingly. ]] local export = {} local data_module = "Module:template parser/data" local load_module = "Module:load" local magic_words_data_module = "Module:data/magic words" local pages_module = "Module:pages" local parser_extension_tags_data_module = "Module:data/parser extension tags" local parser_module = "Module:parser" local scribunto_module = "Module:Scribunto" local string_pattern_escape_module = "Module:string/patternEscape" local string_replacement_escape_module = "Module:string/replacementEscape" local string_utilities_module = "Module:string utilities" local table_length_module = "Module:table/length" local table_shallow_copy_module = "Module:table/shallowCopy" local table_sorted_pairs_module = "Module:table/sortedPairs" local title_is_title_module = "Module:title/isTitle" local title_make_title_module = "Module:title/makeTitle" local title_new_title_module = "Module:title/newTitle" local title_redirect_target_module = "Module:title/redirectTarget" local require = require local m_parser = require(parser_module) local mw = mw local mw_title = mw.title local mw_uri = mw.uri local string = string local table = table local anchor_encode = mw_uri.anchorEncode local build_template -- defined as export.buildTemplate below local class_else_type = m_parser.class_else_type local concat = table.concat local encode_uri = mw_uri.encode local find = string.find local format = string.format local gsub = string.gsub local html_create = mw.html.create local insert = table.insert local is_node = m_parser.is_node local lower = string.lower local match = string.match local next = next local pairs = pairs local parse -- defined as export.parse below local parse_template_name -- defined below local pcall = pcall local rep = string.rep local select = select local sub = string.sub local title_equals = mw_title.equals local tostring = m_parser.tostring 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end local function get_link_target(...) get_link_target = require(pages_module).get_link_target return get_link_target(...) end local function is_title(...) is_title = require(title_is_title_module) return is_title(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function make_title(...) make_title = require(title_make_title_module) return make_title(...) end local function new_title(...) new_title = require(title_new_title_module) return new_title(...) end local function pattern_escape(...) pattern_escape = require(string_pattern_escape_module) return pattern_escape(...) end local function php_htmlspecialchars(...) php_htmlspecialchars = require(scribunto_module).php_htmlspecialchars return php_htmlspecialchars(...) end local function php_ltrim(...) php_ltrim = require(scribunto_module).php_ltrim return php_ltrim(...) end local function php_trim(...) php_trim = require(scribunto_module).php_trim return php_trim(...) end local function redirect_target(...) redirect_target = require(title_redirect_target_module) return redirect_target(...) end local function replacement_escape(...) replacement_escape = require(string_replacement_escape_module) return replacement_escape(...) end local function scribunto_parameter_key(...) scribunto_parameter_key = require(scribunto_module).scribunto_parameter_key return scribunto_parameter_key(...) end local function shallow_copy(...) shallow_copy = require(table_shallow_copy_module) return shallow_copy(...) end local function sorted_pairs(...) sorted_pairs = require(table_sorted_pairs_module) return sorted_pairs(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function table_len(...) table_len = require(table_length_module) return table_len(...) end local function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end --[==[ 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 data local function get_data() data, get_data = load_data(data_module), nil return data end local frame local function get_frame() frame, get_frame = mw.getCurrentFrame(), nil return frame end local magic_words local function get_magic_words() magic_words, get_magic_words = load_data(magic_words_data_module), nil return magic_words end local parser_extension_tags local function get_parser_extension_tags() parser_extension_tags, get_parser_extension_tags = load_data(parser_extension_tags_data_module), nil return parser_extension_tags end ------------------------------------------------------------------------------------ -- -- Nodes -- ------------------------------------------------------------------------------------ local Node = m_parser.node() local new_node = Node.new local function expand(obj, frame_args) return is_node(obj) and obj:expand(frame_args) or obj end export.expand = expand function Node:expand(frame_args) local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return concat(output) end local Wikitext = Node:new_class("wikitext") -- force_node ensures the output will always be a Wikitext node. function Wikitext:new(this, force_node) if type(this) ~= "table" then return force_node and new_node(self, {this}) or this elseif #this == 1 then local this1 = this[1] return force_node and class_else_type(this1) ~= "wikitext" and new_node(self, this) or this1 end local success, str = pcall(concat, this) if success then return force_node and new_node(self, {str}) or str end return new_node(self, this) end -- First value is the parameter name. -- Second value is the parameter's default value. -- Any additional values are ignored: e.g. "{{{a|b|c}}}" is parameter "a" with default value "b" (*not* "b|c"). local Parameter = Node:new_class("parameter") function Parameter:new(this) local this2 = this[2] if class_else_type(this2) == "argument" then insert(this2, 2, "=") this2 = Wikitext:new(this2) end if this[3] == nil then this[2] = this2 else this = {this[1], this2} end return new_node(self, this) end function Parameter:__tostring() local output = {} for i = 1, #self do output[i] = tostring(self[i]) end return "{{{" .. concat(output, "|") .. "}}}" end function Parameter:get_name(frame_args) return scribunto_parameter_key(expand(self[1], frame_args)) end function Parameter:get_default(frame_args) local default = self[2] if default ~= nil then return expand(default, frame_args) end return "{{{" .. expand(self[1], frame_args) .. "}}}" end function Parameter:expand(frame_args) if frame_args == nil then return self:get_default() end local name = expand(self[1], frame_args) local val = frame_args[scribunto_parameter_key(name)] -- Parameter in use. if val ~= nil then return val end val = self[2] -- Default. if val ~= nil then return expand(val, frame_args) end return "{{{" .. name .. "}}}" end local Argument = Node:new_class("argument") function Argument:new(this) local key = this._parse_data.key this = Wikitext:new(this) if key == nil then return this end return new_node(self, {Wikitext:new(key), this}) end function Argument:__tostring() return tostring(self[1]) .. "=" .. tostring(self[2]) end function Argument:expand(frame_args) return expand(self[1], frame_args) .. "=" .. expand(self[2], frame_args) end local Template = Node:new_class("template") function Template:__tostring() local output = {} for i = 1, #self do output[i] = tostring(self[i]) end return "{{" .. concat(output, "|") .. "}}" end -- Normalize the template name, check it's a valid template, then memoize results (using false for invalid titles). -- Parser functions (e.g. {{#IF:a|b|c}}) need to have the first argument extracted from the title, as it comes after the colon. Because of this, the parser function and first argument are memoized as a table. -- FIXME: Some parser functions have special argument handling (e.g. {{#SWITCH:}}). do local templates, parser_variables, parser_functions = {}, {}, {} local function retrieve_magic_word_data(chunk) local mgw_data = (magic_words or get_magic_words())[chunk] if mgw_data then return mgw_data end local normalized = uupper(chunk) mgw_data = magic_words[normalized] if mgw_data and not mgw_data.case_sensitive then return mgw_data end end -- Returns the name required to transclude the title object `title` using -- template {{ }} syntax. If the `shortcut` flag is set, then any calls -- which require a namespace prefix will use the abbreviated form where one -- exists (e.g. "Template:PAGENAME" becomes "T:PAGENAME"). local function get_template_invocation_name(title, shortcut) if not (is_title(title) and not title.isExternal) then error("Template invocations require a valid page title, which cannot contain an interwiki prefix.") end local namespace = title.namespace -- If not in the template namespace, include the prefix (or ":" if -- mainspace). if namespace ~= 10 then return get_link_target(title, shortcut) end -- If in the template namespace and it shares a name with a magic word, -- it needs the prefix "Template:". local text, fragment = title.text, title.fragment if fragment and fragment ~= "" then text = text .. "#" .. fragment end local colon = find(text, ":", nil, true) if not colon then local mgw_data = retrieve_magic_word_data(text) return mgw_data and mgw_data.parser_variable and get_link_target(title, shortcut) or text end local mgw_data = retrieve_magic_word_data(sub(text, 1, colon - 1)) if mgw_data and (mgw_data.parser_function or mgw_data.transclusion_modifier) then return get_link_target(title, shortcut) end -- Also if "Template:" is necessary for disambiguation (e.g. -- "Template:Category:Foo" can't be called with "Category:Foo"). local check = new_title(text, namespace) return check and title_equals(title, check) and text or get_link_target(title, shortcut) end export.getTemplateInvocationName = get_template_invocation_name function parse_template_name(name, has_args, fragment, force_transclusion) local chunks, colon, start, n, p = {}, find(name, ":", nil, true), 1, 0, 0 while colon do local mgw_data = retrieve_magic_word_data(php_ltrim(sub(name, start, colon - 1))) if not mgw_data then break end local priority = mgw_data.priority if not (priority and priority > p) then local pf = mgw_data.parser_function and mgw_data.name or nil if pf then n = n + 1 chunks[n] = pf .. ":" return chunks, "parser function", sub(name, colon + 1) end break end n = n + 1 chunks[n] = mgw_data.name .. ":" start, p = colon + 1, priority colon = find(name, ":", start, true) end if start > 1 then name = sub(name, start) end name = php_trim(name) -- Parser variables can only take SUBST:/SAFESUBST: as modifiers. if not has_args and p <= 1 then local mgw_data = retrieve_magic_word_data(name) local pv = mgw_data and mgw_data.parser_variable and mgw_data.name or nil if pv then n = n + 1 chunks[n] = pv return chunks, "parser variable" end end -- Get the template title with the custom new_title() function in -- [[Module:title/newTitle]], with `allowOnlyFragment` set to false -- (e.g. "{{#foo}}" is invalid) and `allowRelative` set to true, for -- relative links for namespaces with subpages (e.g. "{{/foo}}"). local title = new_title(name, 10, false, true) if not (title and not title.isExternal) then return nil end -- Resolve any redirects. If the redirect target is an interwiki link, -- the template won't fail, but the redirect does not get resolved (i.e. -- the redirect page itself gets transcluded, so the template name -- should not be normalized to the target). local redirect = redirect_target(title, force_transclusion) if redirect and not redirect.isExternal then title = redirect end -- If `fragment` is not true, unset it from the title object to prevent -- it from being included by get_template_invocation_name. if not fragment then title.fragment = "" end chunks[n + 1] = get_template_invocation_name(title) return chunks, "template" end -- Note: force_transclusion avoids incrementing the expensive parser -- function count by forcing transclusion instead. This should only be used -- when there is a real risk that the expensive parser function limit of -- 500 will be hit. local function process_name(self, frame_args, force_transclusion) local name = expand(self[1], frame_args) local has_args, norm = #self > 1 if not has_args then norm = parser_variables[name] if norm then return norm, "parser variable" end end norm = templates[name] if norm then local pf_arg1 = parser_functions[name] return norm, pf_arg1 and "parser function" or "template", pf_arg1 elseif norm == false then return nil end local chunks, subclass, pf_arg1 = parse_template_name(name, has_args, nil, force_transclusion) -- Fail if invalid. if not chunks then templates[name] = false return nil end local chunk1 = chunks[1] -- Fail on SUBST:. if chunk1 == "SUBST:" then templates[name] = false return nil -- Any modifiers are ignored. elseif subclass == "parser function" then local pf = chunks[#chunks] templates[name] = pf parser_functions[name] = pf_arg1 return pf, "parser function", pf_arg1 end -- Ignore SAFESUBST:, and treat MSGNW: as a parser function with the pagename as its first argument (ignoring any RAW: that comes after). if chunks[chunk1 == "SAFESUBST:" and 2 or 1] == "MSGNW:" then pf_arg1 = chunks[#chunks] local pf = "MSGNW:" templates[name] = pf parser_functions[name] = pf_arg1 return pf, "parser function", pf_arg1 end -- Ignore any remaining modifiers, as they've done their job. local output = chunks[#chunks] if subclass == "parser variable" then parser_variables[name] = output else templates[name] = output end return output, subclass end function Template:get_name(frame_args, force_transclusion) -- Only return the first return value. return (process_name(self, frame_args, force_transclusion)) end function Template:get_arguments(frame_args) local name, subclass, pf_arg1 = process_name(self, frame_args) if name == nil then return nil elseif subclass == "parser variable" then return {} end local template_args = {} if subclass == "parser function" then template_args[1] = pf_arg1 for i = 2, #self do template_args[i] = expand(self[i], frame_args) -- Not trimmed. end return template_args end local implicit = 0 for i = 2, #self do local arg = self[i] if class_else_type(arg) == "argument" then template_args[scribunto_parameter_key(expand(arg[1], frame_args))] = php_trim((expand(arg[2], frame_args))) else implicit = implicit + 1 template_args[implicit] = expand(arg, frame_args) -- Not trimmed. end end return template_args end -- BIG TODO: manual template expansion. function Template:expand(frame_args) local name, subclass, pf_arg1 = process_name(self, frame_args) if name == nil then local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return "{{" .. concat(output, "|") .. "}}" elseif subclass == "parser variable" then return (frame or get_frame()):preprocess("{{" .. name .. "}}") elseif subclass == "parser function" then local f = frame or get_frame() if frame_args ~= nil then local success, new_f = pcall(f.newChild, f, {args = frame_args}) if success then f = new_f end end return f:preprocess(tostring(self)) end local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return (frame or get_frame()):preprocess("{{" .. concat(output, "|") .. "}}") end end local Tag = Node:new_class("tag") function Tag:__tostring() local open_tag, attributes, n = {"<", self.name}, self:get_attributes(), 2 for attr, value in next, attributes do n = n + 1 open_tag[n] = " " .. php_htmlspecialchars(attr) .. "=\"" .. php_htmlspecialchars(value, "compat") .. "\"" end if self.self_closing then return concat(open_tag) .. "/>" end return concat(open_tag) .. ">" .. concat(self) .. "</" .. self.name .. ">" end do local valid_attribute_name local function get_valid_attribute_name() valid_attribute_name, get_valid_attribute_name = (data or get_data()).valid_attribute_name, nil return valid_attribute_name end function Tag:get_attributes() local raw = self.attributes if not raw then self.attributes = {} return self.attributes elseif type(raw) == "table" then return raw end if sub(raw, -1) == "/" then raw = sub(raw, 1, -2) end local attributes, head = {}, 1 -- Semi-manual implementation of the native regex. while true do local name, loc = match(raw, "([^\t\n\f\r />][^\t\n\f\r /=>]*)()", head) if not name then break end head = loc local value loc = match(raw, "^[\t\n\f\r ]*=[\t\n\f\r ]*()", head) if loc then head = loc -- Either "", '' or the value ends on a space/at the end. Missing -- end quotes are repaired by closing the value at the end. value, loc = match(raw, "^\"([^\"]*)\"?()", head) if not value then value, loc = match(raw, "^'([^']*)'?()", head) if not value then value, loc = match(raw, "^([^\t\n\f\r ]*)()", head) end end head = loc end -- valid_attribute_name is a pattern matching a valid attribute name. -- Defined in the data due to its length - see there for more info. if umatch(name, valid_attribute_name or get_valid_attribute_name()) then -- Sanitizer applies PHP strtolower (ASCII-only). attributes[lower(name)] = value and decode_entities( php_trim((gsub(value, "[\t\n\r ]+", " "))) ) or "" end end self.attributes = attributes return attributes end end function Tag:expand() return (frame or get_frame()):preprocess(tostring(self)) end local Heading = Node:new_class("heading") function Heading:new(this) if #this > 1 then local success, str = pcall(concat, this) if success then return new_node(self, { str, level = this.level, section = this.section, index = this.index }) end end return new_node(self, this) end do local node_tostring = Node.__tostring function Heading:__tostring() local eq = rep("=", self.level) return eq .. node_tostring(self) .. eq end end do local expand_node = Node.expand -- Expanded heading names can contain "\n" (e.g. inside nowiki tags), which -- causes any heading containing them to fail. However, in such cases, the -- native parser still treats it as a heading for the purpose of section -- numbers. local function validate_name(self, frame_args) local name = expand_node(self, frame_args) if find(name, "\n", nil, true) then return nil end return name end function Heading:get_name(frame_args) local name = validate_name(self, frame_args) return name ~= nil and php_trim(name) or nil end -- FIXME: account for anchor disambiguation. function Heading:get_anchor(frame_args) local name = validate_name(self, frame_args) return name ~= nil and decode_entities(anchor_encode(name)) or nil end function Heading:expand(frame_args) local eq = rep("=", self.level) return eq .. expand_node(self, frame_args) .. eq end end ------------------------------------------------------------------------------------ -- -- Parser -- ------------------------------------------------------------------------------------ local Parser = m_parser.string_parser() -- Template or parameter. -- Parsed by matching the opening braces innermost-to-outermost (ignoring lone closing braces). Parameters {{{ }}} take priority over templates {{ }} where possible, but a double closing brace will always result in a closure, even if there are 3+ opening braces. -- For example, "{{{{foo}}}}" (4) is parsed as a parameter enclosed by single braces, and "{{{{{foo}}}}}" (5) is a parameter inside a template. However, "{{{{{foo }} }}}" is a template inside a parameter, due to "}}" forcing the closure of the inner node. do -- Handlers. local handle_name local handle_argument local handle_value local function do_template_or_parameter(self, inner_node) self:push_sublayer(handle_name) self:set_pattern("[\n<[{|}]") -- If a node has already been parsed, nest it at the start of the new -- outer node (e.g. when parsing"{{{{foo}}bar}}", the template "{{foo}}" -- is parsed first, since it's the innermost, and becomes the first -- node of the outer template. if inner_node then self:emit(inner_node) end end local function pipe(self) self:emit(Wikitext:new(self:pop_sublayer())) self:push_sublayer(handle_argument) self:set_pattern("[\n<=[{|}]") end local function rbrace(self, this) if self:read(1) == "}" then self:emit(Wikitext:new(self:pop_sublayer())) return self:pop() end self:emit(this) end function handle_name(self, ...) handle_name = self:switch(handle_name, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = pipe, ["}"] = rbrace, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_name(self, ...) end function handle_argument(self, ...) handle_argument = self:switch(handle_argument, { ["\n"] = function(self, this) return self:heading_block(this, "==") end, ["<"] = Parser.tag, ["="] = function(self) local key = self:pop_sublayer() self:push_sublayer(handle_value) self:set_pattern("[\n<[{|}]") self.current_layer._parse_data.key = key end, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = pipe, ["}"] = rbrace, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_argument(self, ...) end function handle_value(self, ...) handle_value = self:switch(handle_value, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = function(self) self:emit(Argument:new(self:pop_sublayer())) self:push_sublayer(handle_argument) self:set_pattern("[\n<=[{|}]") end, ["}"] = function(self, this) if self:read(1) == "}" then self:emit(Argument:new(self:pop_sublayer())) return self:pop() end self:emit(this) end, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_value(self, ...) end function Parser:template_or_parameter() local text, head, node_to_emit, failed = self.text, self.head -- Comments/tags interrupt the brace count. local braces = match(text, "^{+()", head) - head self:advance(braces) while true do local success, node = self:try(do_template_or_parameter, node_to_emit) -- Fail means no "}}" or "}}}" was found, so emit any remaining -- unmatched opening braces before any templates/parameters that -- were found. if not success then self:emit(rep("{", braces)) failed = true break -- If there are 3+ opening and closing braces, it's a parameter. elseif braces >= 3 and self:read(2) == "}" then self:advance(3) braces = braces - 3 node = Parameter:new(node) -- Otherwise, it's a template. else self:advance(2) braces = braces - 2 node = Template:new(node) end local index = head + braces node.index = index node.raw = sub(text, index, self.head - 1) node_to_emit = node -- Terminate once not enough braces remain for further matches. if braces == 0 then break -- Emit any stray opening brace before any matched nodes. elseif braces == 1 then self:emit("{") break end end if node_to_emit then self:emit(node_to_emit) end return braces, failed end end -- Tag. do local end_tags local function get_end_tags() end_tags, get_end_tags = (data or get_data()).end_tags, nil return end_tags end -- Handlers. local handle_start local handle_tag local function do_tag(self) local layer = self.current_layer layer._parse_data.handler, layer.index = handle_start, self.head self:set_pattern("[%s/>]") self:advance() end local function is_ignored_tag(self, this) if self.transcluded then return this == "includeonly" end return this == "noinclude" or this == "onlyinclude" end local function ignored_tag(self, text, head) local loc = find(text, ">", head, true) if not loc then return self:fail_route() end self:jump(loc) local tag = self:pop() tag.ignored = true return tag end function handle_start(self, this) if this == "/" then local text, head = self.text, self.head + 1 local this = match(text, "^[^%s/>]+", head) if this and is_ignored_tag(self, lower(this)) then head = head + #this if not match(text, "^/[^>]", head) then return ignored_tag(self, text, head) end end return self:fail_route() elseif this == "" then return self:fail_route() end -- Tags are only case-insensitive with ASCII characters. local raw_name = this this = lower(this) local end_tag_pattern = (end_tags or get_end_tags())[this] if not end_tag_pattern then -- Validity check. return self:fail_route() end local layer = self.current_layer local pdata = layer._parse_data local text, head = self.text, self.head + pdata.step if match(text, "^/[^>]", head) then return self:fail_route() elseif is_ignored_tag(self, this) then return ignored_tag(self, text, head) -- If an onlyinclude tag is not ignored (and cannot be active since it -- would have triggered special handling earlier), it must be plaintext. elseif this == "onlyinclude" then return self:fail_route() elseif this == "noinclude" or this == "includeonly" then layer.ignored = true -- Ignored block. layer.raw_name = raw_name end layer.name, pdata.handler, pdata.end_tag_pattern = this, handle_tag, end_tag_pattern self:set_pattern(">") end function handle_tag(self, this) if this == "" then return self:fail_route() end local layer = self.current_layer if this ~= ">" then layer.attributes = this return elseif self:read(-1) == "/" then layer.self_closing = true return self:pop() end local text, head = self.text, self.head + 1 local loc1, loc2 = find(text, layer._parse_data.end_tag_pattern, head) if loc1 then if loc1 > head then self:emit(sub(text, head, loc1 - 1)) end self:jump(loc2) return self:pop() -- noinclude and includeonly will tolerate having no closing tag, but -- only if given in lowercase. This is due to a preprocessor bug, as -- it uses a regex with the /i (case-insensitive) flag to check for -- end tags, but a simple array lookup with lowercase tag names when -- looking up which tags should tolerate no closing tag (exact match -- only, so case-sensitive). elseif layer.ignored then local raw_name = layer.raw_name if raw_name == "noinclude" or raw_name == "includeonly" then self:jump(#text) return self:pop() end end return self:fail_route() end function Parser:tag() -- HTML comment. if self:read(1, 3) == "!--" then local text = self.text self:jump(select(2, find(text, "-->", self.head + 4, true)) or #text) -- onlyinclude tags (which must be lowercase with no whitespace). elseif self.onlyinclude and self:read(1, 13) == "/onlyinclude>" then local text = self.text self:jump(select(2, find(text, "<onlyinclude>", self.head + 14, true)) or #text) else local success, tag = self:try(do_tag) if not success then self:emit("<") elseif not tag.ignored then self:emit(Tag:new(tag)) end end end end -- Heading. -- The preparser assigns each heading a number, which is used for things like section edit links. The preparser will only do this for heading blocks which aren't nested inside templates, parameters and parser tags. In some cases (e.g. when template blocks contain untrimmed newlines), a preparsed heading may not be treated as a heading in the final output. That does not affect the preparser, however, which will always count sections based on the preparser heading count, since it can't know what a template's final output will be. do -- Handlers. local handle_start local handle_body local handle_possible_end local function do_heading(self) local layer, head = self.current_layer, self.head layer._parse_data.handler, layer.index = handle_start, head self:set_pattern("[\t\n ]") -- Comments/tags interrupt the equals count. local eq = match(self.text, "^=+()", head) - head layer.level = eq self:advance(eq) end local function do_heading_possible_end(self) self.current_layer._parse_data.handler = handle_possible_end self:set_pattern("[\n<]") end function handle_start(self, ...) -- ===== is "=" as an L2; ======== is "==" as an L3 etc. local function newline(self) local layer = self.current_layer local eq = layer.level if eq <= 2 then return self:fail_route() end -- Calculate which equals signs determine the heading level. local level_eq = eq - (2 - eq % 2) level_eq = level_eq > 12 and 12 or level_eq -- Emit the excess. self:emit(rep("=", eq - level_eq)) layer.level = level_eq / 2 return self:pop() end local function whitespace(self) local success, possible_end = self:try(do_heading_possible_end) if success then self:emit(Wikitext:new(possible_end)) self.current_layer._parse_data.handler = handle_body self:set_pattern("[\n<=[{]") return self:consume() end return newline(self) end handle_start = self:switch(handle_start, { ["\t"] = whitespace, ["\n"] = newline, [" "] = whitespace, [""] = newline, [false] = function(self) -- Emit any excess = signs once we know it's a conventional heading. Up till now, we couldn't know if the heading is just a string of = signs (e.g. ========), so it wasn't guaranteed that the heading text starts after the 6th. local layer = self.current_layer local eq = layer.level if eq > 6 then self:emit(1, rep("=", eq - 6)) layer.level = 6 end layer._parse_data.handler = handle_body self:set_pattern("[\n<=[{]") return self:consume() end }) return handle_start(self, ...) end function handle_body(self, ...) handle_body = self:switch(handle_body, { ["\n"] = Parser.fail_route, ["<"] = Parser.tag, ["="] = function(self) -- Comments/tags interrupt the equals count. local eq = match(self.text, "^=+", self.head) local eq_len = #eq self:advance(eq_len) local success, possible_end = self:try(do_heading_possible_end) if success then self:emit(eq) self:emit(Wikitext:new(possible_end)) return self:consume() end local layer = self.current_layer local level = layer.level if eq_len > level then self:emit(rep("=", eq_len - level)) elseif level > eq_len then layer.level = eq_len self:emit(1, rep("=", level - eq_len)) end return self:pop() end, ["["] = Parser.wikilink_block, ["{"] = function(self, this) return self:braces(this, true) end, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_body(self, ...) end function handle_possible_end(self, ...) handle_possible_end = self:switch(handle_possible_end, { ["\n"] = Parser.fail_route, ["<"] = function(self) if self:read(1, 3) ~= "!--" then return self:pop() end local head = select(2, find(self.text, "-->", self.head + 4, true)) if not head then return self:pop() end self:jump(head) end, [""] = Parser.fail_route, [false] = function(self, this) if not match(this, "^[\t ]+()$") then return self:pop() end self:emit(this) end }) return handle_possible_end(self, ...) end function Parser:heading() local success, heading = self:try(do_heading) if success then local section = self.section + 1 heading.section = section self.section = section self:emit(Heading:new(heading)) return self:consume() else self:emit("=") end end end ------------------------------------------------------------------------------------ -- -- Block handlers -- ------------------------------------------------------------------------------------ -- Block handlers. -- These are blocks which can affect template/parameter parsing, since they're also parsed by Parsoid at the same time (even though they aren't processed until later). -- All blocks (including templates/parameters) can nest inside each other, but an inner block must be closed before the outer block which contains it. This is why, for example, the wikitext "{{template| [[ }}" will result in an unprocessed template, since the inner "[[" is treated as the opening of a wikilink block, which prevents "}}" from being treated as the closure of the template block. On the other hand, "{{template| [[ ]] }}" will process correctly, since the wikilink block is closed before the template closure. It makes no difference whether the block will be treated as valid or not when it's processed later on, so "{{template| [[ }} ]] }}" would also work, even though "[[ }} ]]" is not a valid wikilink. -- Note that nesting also affects pipes and equals signs, in addition to block closures. -- These blocks can be nested to any degree, so "{{template| [[ [[ [[ ]] }}" will not work, since only one of the three wikilink blocks has been closed. On the other hand, "{{template| [[ [[ [[ ]] ]] ]] }}" will work. -- All blocks are implicitly closed by the end of the text, since their validity is irrelevant at this stage. -- Language conversion block. -- Opens with "-{" and closes with "}-". However, templates/parameters take priority, so "-{{" is parsed as "-" followed by the opening of a template/parameter block (depending on what comes after). -- Note: Language conversion blocks aren't actually enabled on the English Wiktionary, but Parsoid still parses them at this stage, so they can affect the closure of outer blocks: e.g. "[[ -{ ]]" is not a valid wikilink block, since the "]]" falls inside the new language conversion block. do --Handler. local handle_language_conversion_block local function do_language_conversion_block(self) self.current_layer._parse_data.handler = handle_language_conversion_block self:set_pattern("[\n<[{}]") end function handle_language_conversion_block(self, ...) handle_language_conversion_block = self:switch(handle_language_conversion_block, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["}"] = function(self, this) if self:read(1) == "-" then self:emit("}-") self:advance() return self:pop() end self:emit(this) end, [""] = Parser.pop, [false] = Parser.emit }) return handle_language_conversion_block(self, ...) end function Parser:braces(this, fail_on_unclosed_braces) local language_conversion_block = self:read(-1) == "-" if self:read(1) == "{" then local braces, failed = self:template_or_parameter() -- Headings will fail if they contain an unclosed brace block. if failed and fail_on_unclosed_braces then return self:fail_route() -- Language conversion blocks cannot begin "-{{", but can begin -- "-{{{" iff parsed as "-{" + "{{". elseif not (language_conversion_block and braces == 1) then return self:consume() end else self:emit(this) if not language_conversion_block then return end self:advance() end self:emit(Wikitext:new(self:get(do_language_conversion_block))) end end --[==[ Headings Opens with "\n=" (or "=" at the start of the text), and closes with "\n" or the end of the text. Note that it doesn't matter whether the heading will fail to process due to a premature newline (e.g. if there are no closing signs), so at this stage the only thing that matters for closure is the newline or end of text. Note: Heading blocks are only parsed like this if they occur inside a template, since they do not iterate the preparser's heading count (i.e. they aren't proper headings). Note 2: if directly inside a template argument with no previous equals signs, a newline followed by a single equals sign is parsed as an argument equals sign, not the opening of a new L1 heading block. This does not apply to any other heading levels. As such, {{template|key\n=}}, {{template|key\n=value}} or even {{template|\n=}} will successfully close, but {{template|key\n==}}, {{template|key=value\n=more value}}, {{template\n=}} etc. will not, since in the latter cases the "}}" would fall inside the new heading block. ]==] do --Handler. local handle_heading_block local function do_heading_block(self) self.current_layer._parse_data.handler = handle_heading_block self:set_pattern("[\n<[{]") end function handle_heading_block(self, ...) handle_heading_block = self:switch(handle_heading_block, { ["\n"] = function(self) self:newline() return self:pop() end, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, [""] = Parser.pop, [false] = Parser.emit }) return handle_heading_block(self, ...) end function Parser:heading_block(this, nxt) self:newline() this = this .. (nxt or "=") local loc = #this - 1 while self:read(0, loc) == this do self:advance() self:emit(Wikitext:new(self:get(do_heading_block))) end end end -- Wikilink block. -- Opens with "[[" and closes with "]]". do -- Handler. local handle_wikilink_block local function do_wikilink_block(self) self.current_layer._parse_data.handler = handle_wikilink_block self:set_pattern("[\n<[%]{]") end function handle_wikilink_block(self, ...) handle_wikilink_block = self:switch(handle_wikilink_block, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["]"] = function(self, this) if self:read(1) == "]" then self:emit("]]") self:advance() return self:pop() end self:emit(this) end, ["{"] = Parser.braces, [""] = Parser.pop, [false] = Parser.emit }) return handle_wikilink_block(self, ...) end function Parser:wikilink_block() if self:read(1) == "[" then self:emit("[[") self:advance(2) self:emit(Wikitext:new(self:get(do_wikilink_block))) else self:emit("[") end end end -- Lines which only contain comments, " " and "\t" are eaten, so long as -- they're bookended by "\n" (i.e. not the first or last line). function Parser:newline() local text, head = self.text, self.head while true do repeat local loc = match(text, "^[\t ]*<!%-%-()", head + 1) if not loc then break end loc = select(2, find(text, "-->", loc, true)) head = loc or head until not loc -- Fail if no comments found. if head == self.head then break end head = match(text, "^[\t ]*()\n", head + 1) if not head then break end self:jump(head) end self:emit("\n") end do -- Handlers. local handle_start local main_handler -- If `transcluded` is true, then the text is checked for a pair of -- onlyinclude tags. If these are found (even if they're in the wrong -- order), then the start of the page is treated as though it is preceded -- by a closing onlyinclude tag. -- Note 1: unlike other parser extension tags, onlyinclude tags are case- -- sensitive and cannot contain whitespace. -- Note 2: onlyinclude tags *can* be implicitly closed by the end of the -- text, but the hard requirement above means this can only happen if -- either the tags are in the wrong order or there are multiple onlyinclude -- blocks. local function do_parse(self, transcluded) self.current_layer._parse_data.handler = handle_start self:set_pattern(".") self.section = 0 if not transcluded then return end self.transcluded = true local text = self.text if find(text, "</onlyinclude>", nil, true) then local head = find(text, "<onlyinclude>", nil, true) if head then self.onlyinclude = true self:jump(head + 13) end end end -- If the first character is "=", try parsing it as a heading. function handle_start(self, this) self.current_layer._parse_data.handler = main_handler self:set_pattern("[\n<{]") if this == "=" then return self:heading() end return self:consume() end function main_handler(self, ...) main_handler = self:switch(main_handler, { ["\n"] = function(self) self:newline() if self:read(1) == "=" then self:advance() return self:heading() end end, ["<"] = Parser.tag, ["{"] = function(self, this) if self:read(1) == "{" then self:template_or_parameter() return self:consume() end self:emit(this) end, [""] = Parser.pop, [false] = Parser.emit }) return main_handler(self, ...) end function export.parse(text, transcluded) local text_type = type(text) return (select(2, Parser:parse{ text = text_type == "string" and text or text_type == "number" and tostring(text) or error("bad argument #1 (string expected, got " .. text_type .. ")"), node = {Wikitext, true}, route = {do_parse, transcluded} })) end parse = export.parse end function export.find_templates(text, not_transcluded) return parse(text, not not_transcluded):iterate_nodes("template") end do local link_parameter_1, link_parameter_2 local function get_link_parameter_1() link_parameter_1, get_link_parameter_1 = (data or get_data()).template_link_param_1, nil return link_parameter_1 end local function get_link_parameter_2() link_parameter_2, get_link_parameter_2 = (data or get_data()).template_link_param_2, nil return link_parameter_2 end -- Generate a link. If the target title doesn't have a fragment, use "#top" -- (which is an implicit anchor at the top of every page), as this ensures -- self-links still display as links, since bold display is distracting and -- unintuitive for template links. local function link_page(title, display) local fragment = title.fragment if fragment == "" then fragment = "top" end return format( "[[:%s|%s]]", encode_uri(title.prefixedText .. "#" .. fragment, "WIKI"), display ) end -- pf_arg1 or pf_arg2 may need to be linked if a given parser function -- treats them as a pagename. If a key exists in `namespace`, the value is -- the namespace for the page: if not 0, then the namespace prefix will -- always be added to the input (e.g. {{#invoke:}} can only target the -- Module: namespace, so inputting "Template:foo" gives -- "Module:Template:foo", and "Module:foo" gives "Module:Module:foo"). -- However, this isn't possible with mainspace (namespace 0), so prefixes -- are respected. make_title() handles all of this automatically. local function finalize_arg(pagename, namespace) if namespace == nil then return pagename end local title = make_title(namespace, pagename) return title and not title.isExternal and link_page(title, pagename) or pagename end local function render_title(name, args) -- parse_template_name returns a table of transclusion modifiers plus -- the normalized template/magic word name, which will be used as link -- targets. The third return value pf_arg1 is the first argument of a -- a parser function, which comes after the colon (e.g. "foo" in -- "{{#IF:foo|bar|baz}}"). This means args[1] (i.e. the first argument -- that comes after a pipe is actually argument 2, and so on. Note: the -- second parameter of parse_template_name checks if there are any -- arguments, since parser variables cannot take arguments (e.g. -- {{CURRENTYEAR}} is a parser variable, but {{CURRENTYEAR|foo}} -- transcludes "Template:CURRENTYEAR"). In such cases, the returned -- table explicitly includes the "Template:" prefix in the template -- name. The third parameter instructs it to retain any fragment in the -- template name in the returned table, if present. local chunks, subclass, pf_arg1 = parse_template_name( name, args and pairs(args)(args) ~= nil, true ) if chunks == nil then return name, args end local chunks_len = #chunks -- Additionally, generate the corresponding table `rawchunks`, which -- is a list of colon-separated chunks in the raw input. This is used -- to retrieve the display forms for each chunk. local rawchunks = split(name, ":") for i = 1, chunks_len - 1 do chunks[i] = format( "[[%s|%s]]", encode_uri((magic_words or get_magic_words())[sub(chunks[i], 1, -2)].transclusion_modifier, "WIKI"), rawchunks[i] ) end local chunk = chunks[chunks_len] -- If it's a template, return a link to it with link_page, concatenating -- the remaining chunks in `rawchunks` to form the display text. -- Use new_title with the default namespace 10 (Template:) to generate -- a target title, which is the same setting used for retrieving -- templates (including those in other namespaces, as prefixes override -- the default). if subclass == "template" then chunks[chunks_len] = link_page( new_title(chunk, 10), concat(rawchunks, "&#58;", chunks_len) -- : ) return concat(chunks, "&#58;"), args -- : elseif subclass == "parser variable" then chunks[chunks_len] = format( "[[%s|%s]]", encode_uri((magic_words or get_magic_words())[chunk].parser_variable, "WIKI"), rawchunks[chunks_len] ) return concat(chunks, "&#58;"), args -- : end -- Otherwise, it must be a parser function. local mgw_data = (magic_words or get_magic_words())[sub(chunk, 1, -2)] local link = mgw_data.parser_function or mgw_data.transclusion_modifier local pf_arg2 = args and args[1] or nil -- Some magic words have different links, depending on whether argument -- 2 is specified (e.g. "baz" in {{foo:bar|baz}}). if type(link) == "table" then link = pf_arg2 and link[2] or link[1] end chunks[chunks_len] = format( "[[%s|%s]]", encode_uri(link, "WIKI"), rawchunks[chunks_len] ) -- #TAG: has special handling, because documentation links for parser -- extension tags come from [[Module:data/parser extension tags]]. if chunk == "#TAG:" then -- Tags are only case-insensitive with ASCII characters. local tag = (parser_extension_tags or get_parser_extension_tags())[lower(php_trim(pf_arg1))] if tag then pf_arg1 = format( "[[%s|%s]]", encode_uri(tag, "WIKI"), pf_arg1 ) end -- Otherwise, finalize pf_arg1 and add it to `chunks`. else pf_arg1 = finalize_arg(pf_arg1, (link_parameter_1 or get_link_parameter_1())[chunk]) end chunks[chunks_len + 1] = pf_arg1 -- Finalize pf_arg2 (if applicable), then return. if pf_arg2 then args = shallow_copy(args) -- Avoid destructively modifying args. args[1] = finalize_arg(pf_arg2, (link_parameter_2 or get_link_parameter_2())[chunk]) end return concat(chunks, "&#58;"), args -- : end function export.buildTemplate(title, args) local output = {title} if not args then return output end -- Iterate over all numbered parameters in order, followed by any -- remaining parameters in codepoint order. Implicit parameters are -- used wherever possible, even if explicit numbers are interpolated -- between them (e.g. 0 would go before any implicit parameters, and -- 2.5 between 2 and 3). -- TODO: handle "=" and "|" in params/values. local implicit for k, v in sorted_pairs(args) do if type(k) == "number" and k >= 1 and k % 1 == 0 then if implicit == nil then implicit = table_len(args) end insert(output, k <= implicit and v or k .. "=" .. v) else insert(output, k .. "=" .. v) end end return output end build_template = export.buildTemplate function export.templateLink(title, args, no_link) if not no_link then title, args = render_title(title, args) end local output = build_template(title, args) for i = 1, #output do output[i] = encode_entities(output[i], "={}", true, true) end return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&#123;&#123;" .. concat(output, "&#124;") .. "&#125;&#125;") -- {{ | }} ) end end do function export.find_parameters(text, not_transcluded) return parse(text, not not_transcluded):iterate_nodes("parameter") end function export.displayParameter(name, default) return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&#123;&#123;&#123;" .. concat({name, default}, "&#124;") .. "&#125;&#125;&#125;") -- {{{ | }}} ) end end do local function check_level(level) if type(level) ~= "number" then error("Heading levels must be numbers.") elseif level < 1 or level > 6 or level % 1 ~= 0 then error("Heading levels must be integers between 1 and 6.") end return level end -- FIXME: should headings which contain "\n" be returned? This may depend -- on variable factors, like template expansion. They iterate the heading -- count number, but fail on rendering. However, in some cases a different -- heading might still be rendered due to intermediate equals signs; it -- may even be of a different heading level: e.g., this is parsed as an -- L2 heading with a newline (due to the wikilink block), but renders as the -- L1 heading "=foo[[". Section edit links are sometimes (but not always) -- present in such cases. -- ==[[= -- ]]== -- TODO: section numbers for edit links seem to also include headings -- nested inside templates and parameters (but apparently not those in -- parser extension tags - need to test this more). If we ever want to add -- section edit links manually, this will need to be accounted for. function export.find_headings(text, i, j) local parsed = parse(text) if i == nil and j == nil then return parse(text):iterate_nodes("heading") end i = i and check_level(i) or 1 j = j and check_level(j) or 6 return parsed:iterate(function(v) if class_else_type(v) == "heading" then local level = v.level return level >= i and level <= j end end) end end do local function make_tag(tag) return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&lt;" .. tag .. "&gt;") ) end -- Note: invalid tags are returned without links. function export.wikitagLink(tag) -- ">" can't appear in tags (including attributes) since the parser -- unconditionally treats ">" as the end of a tag. if find(tag, ">", nil, true) then return make_tag(tag) end -- Tags must start "<tagname..." or "</tagname...", with no whitespace -- after "<" or "</". local slash, tagname, remainder = match(tag, "^(/?)([^/%s]+)(.*)$") if not tagname then return make_tag(tag) end -- Tags are only case-insensitive with ASCII characters. local link = lower(tagname) if ( -- onlyinclude tags must be lowercase and are whitespace intolerant. link == "onlyinclude" and (link ~= tagname or remainder ~= "") or -- Closing wikitags (except onlyinclude) can only have whitespace -- after the tag name. slash == "/" and not match(remainder, "^%s*()$") or -- Tagnames cannot be followed immediately by "/", unless it comes -- at the end (e.g. "<nowiki/>", but not "<nowiki/ >"). remainder ~= "/" and sub(remainder, 1, 1) == "/" ) then -- Output with no link. return make_tag(tag) end -- Partial transclusion tags aren't in the table of parser extension -- tags. if link == "noinclude" or link == "includeonly" or link == "onlyinclude" then link = "mw:Transclusion#Partial transclusion" else link = (parser_extension_tags or get_parser_extension_tags())[link] end if link then tag = gsub(tag, pattern_escape(tagname), "[[" .. replacement_escape(encode_uri(link, "WIKI")) .. "|%0]]", 1) end return make_tag(tag) end end -- For convenience. export.class_else_type = class_else_type return export np5sswrasrwf1dhf3v70cyy64sg3pob 26631 24258 2026-07-08T05:00:41Z Sibiru45 115 1 ralatan matan [[:id:Modul:template_parser]] 24258 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:template parser -- License: CC BY-SA --[[ NOTE: This module works by using recursive backtracking to build a node tree, which can then be traversed as necessary. Because it is called by a number of high-use modules, it has been optimised for speed using a profiler, since it is used to scrape data from large numbers of pages very quickly. To that end, it rolls some of its own methods in cases where this is faster than using a function from one of the standard libraries. Please DO NOT "simplify" the code by removing these, since you are almost guaranteed to slow things down, which could seriously impact performance on pages which call this module hundreds or thousands of times. It has also been designed to emulate the native parser's behaviour as much as possible, which in some cases means replicating bugs or unintuitive behaviours in that code; these should not be "fixed", since it is important that the outputs are the same. Most of these originate from deficient regular expressions, which can't be used here, so the bugs have to be manually reintroduced as special cases (e.g. onlyinclude tags being case-sensitive and whitespace intolerant, unlike all other tags). If any of these are fixed, this module should also be updated accordingly. ]] local export = {} local data_module = "Module:template parser/data" local load_module = "Module:load" local magic_words_data_module = "Module:data/magic words" local pages_module = "Module:pages" local parser_extension_tags_data_module = "Module:data/parser extension tags" local parser_module = "Module:parser" local scribunto_module = "Module:Scribunto" local string_pattern_escape_module = "Module:string/patternEscape" local string_replacement_escape_module = "Module:string/replacementEscape" local string_utilities_module = "Module:string utilities" local table_length_module = "Module:table/length" local table_shallow_copy_module = "Module:table/shallowCopy" local table_sorted_pairs_module = "Module:table/sortedPairs" local title_is_title_module = "Module:title/isTitle" local title_make_title_module = "Module:title/makeTitle" local title_new_title_module = "Module:title/newTitle" local title_redirect_target_module = "Module:title/redirectTarget" local require = require local m_parser = require(parser_module) local mw = mw local mw_title = mw.title local mw_uri = mw.uri local string = string local table = table local anchor_encode = mw_uri.anchorEncode local build_template -- defined as export.buildTemplate below local class_else_type = m_parser.class_else_type local concat = table.concat local encode_uri = mw_uri.encode local find = string.find local format = string.format local gsub = string.gsub local html_create = mw.html.create local insert = table.insert local is_node = m_parser.is_node local lower = string.lower local match = string.match local next = next local pairs = pairs local parse -- defined as export.parse below local parse_template_name -- defined below local pcall = pcall local rep = string.rep local select = select local sub = string.sub local title_equals = mw_title.equals local tostring = m_parser.tostring 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 decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end local function get_link_target(...) get_link_target = require(pages_module).get_link_target return get_link_target(...) end local function is_title(...) is_title = require(title_is_title_module) return is_title(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function make_title(...) make_title = require(title_make_title_module) return make_title(...) end local function new_title(...) new_title = require(title_new_title_module) return new_title(...) end local function pattern_escape(...) pattern_escape = require(string_pattern_escape_module) return pattern_escape(...) end local function php_htmlspecialchars(...) php_htmlspecialchars = require(scribunto_module).php_htmlspecialchars return php_htmlspecialchars(...) end local function php_ltrim(...) php_ltrim = require(scribunto_module).php_ltrim return php_ltrim(...) end local function php_trim(...) php_trim = require(scribunto_module).php_trim return php_trim(...) end local function redirect_target(...) redirect_target = require(title_redirect_target_module) return redirect_target(...) end local function replacement_escape(...) replacement_escape = require(string_replacement_escape_module) return replacement_escape(...) end local function scribunto_parameter_key(...) scribunto_parameter_key = require(scribunto_module).scribunto_parameter_key return scribunto_parameter_key(...) end local function shallow_copy(...) shallow_copy = require(table_shallow_copy_module) return shallow_copy(...) end local function sorted_pairs(...) sorted_pairs = require(table_sorted_pairs_module) return sorted_pairs(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function table_len(...) table_len = require(table_length_module) return table_len(...) end local function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end --[==[ 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 data local function get_data() data, get_data = load_data(data_module), nil return data end local frame local function get_frame() frame, get_frame = mw.getCurrentFrame(), nil return frame end local magic_words local function get_magic_words() magic_words, get_magic_words = load_data(magic_words_data_module), nil return magic_words end local parser_extension_tags local function get_parser_extension_tags() parser_extension_tags, get_parser_extension_tags = load_data(parser_extension_tags_data_module), nil return parser_extension_tags end ------------------------------------------------------------------------------------ -- -- Nodes -- ------------------------------------------------------------------------------------ local Node = m_parser.node() local new_node = Node.new local function expand(obj, frame_args) return is_node(obj) and obj:expand(frame_args) or obj end export.expand = expand function Node:expand(frame_args) local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return concat(output) end local Wikitext = Node:new_class("wikitext") -- force_node ensures the output will always be a Wikitext node. function Wikitext:new(this, force_node) if type(this) ~= "table" then return force_node and new_node(self, {this}) or this elseif #this == 1 then local this1 = this[1] return force_node and class_else_type(this1) ~= "wikitext" and new_node(self, this) or this1 end local success, str = pcall(concat, this) if success then return force_node and new_node(self, {str}) or str end return new_node(self, this) end -- First value is the parameter name. -- Second value is the parameter's default value. -- Any additional values are ignored: e.g. "{{{a|b|c}}}" is parameter "a" with default value "b" (*not* "b|c"). local Parameter = Node:new_class("parameter") function Parameter:new(this) local this2 = this[2] if class_else_type(this2) == "argument" then insert(this2, 2, "=") this2 = Wikitext:new(this2) end if this[3] == nil then this[2] = this2 else this = {this[1], this2} end return new_node(self, this) end function Parameter:__tostring() local output = {} for i = 1, #self do output[i] = tostring(self[i]) end return "{{{" .. concat(output, "|") .. "}}}" end function Parameter:get_name(frame_args) return scribunto_parameter_key(expand(self[1], frame_args)) end function Parameter:get_default(frame_args) local default = self[2] if default ~= nil then return expand(default, frame_args) end return "{{{" .. expand(self[1], frame_args) .. "}}}" end function Parameter:expand(frame_args) if frame_args == nil then return self:get_default() end local name = expand(self[1], frame_args) local val = frame_args[scribunto_parameter_key(name)] -- Parameter in use. if val ~= nil then return val end val = self[2] -- Default. if val ~= nil then return expand(val, frame_args) end return "{{{" .. name .. "}}}" end local Argument = Node:new_class("argument") function Argument:new(this) local key = this._parse_data.key this = Wikitext:new(this) if key == nil then return this end return new_node(self, {Wikitext:new(key), this}) end function Argument:__tostring() return tostring(self[1]) .. "=" .. tostring(self[2]) end function Argument:expand(frame_args) return expand(self[1], frame_args) .. "=" .. expand(self[2], frame_args) end local Template = Node:new_class("template") function Template:__tostring() local output = {} for i = 1, #self do output[i] = tostring(self[i]) end return "{{" .. concat(output, "|") .. "}}" end -- Normalize the template name, check it's a valid template, then memoize results (using false for invalid titles). -- Parser functions (e.g. {{#IF:a|b|c}}) need to have the first argument extracted from the title, as it comes after the colon. Because of this, the parser function and first argument are memoized as a table. -- FIXME: Some parser functions have special argument handling (e.g. {{#SWITCH:}}). do local templates, parser_variables, parser_functions = {}, {}, {} local function retrieve_magic_word_data(chunk) local mgw_data = (magic_words or get_magic_words())[chunk] if mgw_data then return mgw_data end local normalized = uupper(chunk) mgw_data = magic_words[normalized] if mgw_data and not mgw_data.case_sensitive then return mgw_data end end -- Returns the name required to transclude the title object `title` using -- template {{ }} syntax. If the `shortcut` flag is set, then any calls -- which require a namespace prefix will use the abbreviated form where one -- exists (e.g. "Template:PAGENAME" becomes "T:PAGENAME"). local function get_template_invocation_name(title, shortcut) if not (is_title(title) and not title.isExternal) then error("Template invocations require a valid page title, which cannot contain an interwiki prefix.") end local namespace = title.namespace -- If not in the template namespace, include the prefix (or ":" if -- mainspace). if namespace ~= 10 then return get_link_target(title, shortcut) end -- If in the template namespace and it shares a name with a magic word, -- it needs the prefix "Template:". local text, fragment = title.text, title.fragment if fragment and fragment ~= "" then text = text .. "#" .. fragment end local colon = find(text, ":", nil, true) if not colon then local mgw_data = retrieve_magic_word_data(text) return mgw_data and mgw_data.parser_variable and get_link_target(title, shortcut) or text end local mgw_data = retrieve_magic_word_data(sub(text, 1, colon - 1)) if mgw_data and (mgw_data.parser_function or mgw_data.transclusion_modifier) then return get_link_target(title, shortcut) end -- Also if "Template:" is necessary for disambiguation (e.g. -- "Template:Category:Foo" can't be called with "Category:Foo"). local check = new_title(text, namespace) return check and title_equals(title, check) and text or get_link_target(title, shortcut) end export.getTemplateInvocationName = get_template_invocation_name function parse_template_name(name, has_args, fragment, force_transclusion) local chunks, colon, start, n, p = {}, find(name, ":", nil, true), 1, 0, 0 while colon do local mgw_data = retrieve_magic_word_data(php_ltrim(sub(name, start, colon - 1))) if not mgw_data then break end local priority = mgw_data.priority if not (priority and priority > p) then local pf = mgw_data.parser_function and mgw_data.name or nil if pf then n = n + 1 chunks[n] = pf .. ":" return chunks, "parser function", sub(name, colon + 1) end break end n = n + 1 chunks[n] = mgw_data.name .. ":" start, p = colon + 1, priority colon = find(name, ":", start, true) end if start > 1 then name = sub(name, start) end name = php_trim(name) -- Parser variables can only take SUBST:/SAFESUBST: as modifiers. if not has_args and p <= 1 then local mgw_data = retrieve_magic_word_data(name) local pv = mgw_data and mgw_data.parser_variable and mgw_data.name or nil if pv then n = n + 1 chunks[n] = pv return chunks, "parser variable" end end -- Get the template title with the custom new_title() function in -- [[Module:title/newTitle]], with `allowOnlyFragment` set to false -- (e.g. "{{#foo}}" is invalid) and `allowRelative` set to true, for -- relative links for namespaces with subpages (e.g. "{{/foo}}"). local title = new_title(name, 10, false, true) if not (title and not title.isExternal) then return nil end if force_transclusion ~= "no_redirect" then -- Resolve any redirects. If the redirect target is an interwiki link, -- the template won't fail, but the redirect does not get resolved (i.e. -- the redirect page itself gets transcluded, so the template name -- should not be normalized to the target). local redirect = redirect_target(title, force_transclusion) if redirect and not redirect.isExternal then title = redirect end end -- If `fragment` is not true, unset it from the title object to prevent -- it from being included by get_template_invocation_name. if not fragment then title.fragment = "" end chunks[n + 1] = get_template_invocation_name(title) return chunks, "template" end -- Note: `force_transclusion` avoids incrementing the expensive parser function count by forcing transclusion -- instead. This should only be used when there is a real risk that the expensive parser function limit of -- 500 will be hit. If `force_transclusion` has the value "no_redirect", redirect checking is turned off -- entirely. This should only be used in very limited circumstances when it is otherwise impossible to avoid -- hitting the expensive parser limit and we are willing to handle the possible redirects ourselves. local function process_name(self, frame_args, force_transclusion) local name = expand(self[1], frame_args) local has_args, norm = #self > 1 if not has_args then norm = parser_variables[name] if norm then return norm, "parser variable" end end norm = templates[name] if norm then local pf_arg1 = parser_functions[name] return norm, pf_arg1 and "parser function" or "template", pf_arg1 elseif norm == false then return nil end local chunks, subclass, pf_arg1 = parse_template_name(name, has_args, nil, force_transclusion) -- Fail if invalid. if not chunks then templates[name] = false return nil end local chunk1 = chunks[1] -- Fail on SUBST:. if chunk1 == "SUBST:" then templates[name] = false return nil -- Any modifiers are ignored. elseif subclass == "parser function" then local pf = chunks[#chunks] templates[name] = pf parser_functions[name] = pf_arg1 return pf, "parser function", pf_arg1 end -- Ignore SAFESUBST:, and treat MSGNW: as a parser function with the pagename as its first argument (ignoring any RAW: that comes after). if chunks[chunk1 == "SAFESUBST:" and 2 or 1] == "MSGNW:" then pf_arg1 = chunks[#chunks] local pf = "MSGNW:" templates[name] = pf parser_functions[name] = pf_arg1 return pf, "parser function", pf_arg1 end -- Ignore any remaining modifiers, as they've done their job. local output = chunks[#chunks] if subclass == "parser variable" then parser_variables[name] = output else templates[name] = output end return output, subclass end function Template:get_name(frame_args, force_transclusion) -- Only return the first return value. return (process_name(self, frame_args, force_transclusion)) end function Template:get_arguments(frame_args) local name, subclass, pf_arg1 = process_name(self, frame_args) if name == nil then return nil elseif subclass == "parser variable" then return {} end local template_args = {} if subclass == "parser function" then template_args[1] = pf_arg1 for i = 2, #self do template_args[i] = expand(self[i], frame_args) -- Not trimmed. end return template_args end local implicit = 0 for i = 2, #self do local arg = self[i] if class_else_type(arg) == "argument" then template_args[scribunto_parameter_key(expand(arg[1], frame_args))] = php_trim((expand(arg[2], frame_args))) else implicit = implicit + 1 template_args[implicit] = expand(arg, frame_args) -- Not trimmed. end end return template_args end -- BIG TODO: manual template expansion. function Template:expand(frame_args) local name, subclass, pf_arg1 = process_name(self, frame_args) if name == nil then local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return "{{" .. concat(output, "|") .. "}}" elseif subclass == "parser variable" then return (frame or get_frame()):preprocess("{{" .. name .. "}}") elseif subclass == "parser function" then local f = frame or get_frame() if frame_args ~= nil then local success, new_f = pcall(f.newChild, f, {args = frame_args}) if success then f = new_f end end return f:preprocess(tostring(self)) end local output = {} for i = 1, #self do output[i] = expand(self[i], frame_args) end return (frame or get_frame()):preprocess("{{" .. concat(output, "|") .. "}}") end end local Tag = Node:new_class("tag") function Tag:__tostring() local open_tag, attributes, n = {"<", self.name}, self:get_attributes(), 2 for attr, value in next, attributes do n = n + 1 open_tag[n] = " " .. php_htmlspecialchars(attr) .. "=\"" .. php_htmlspecialchars(value, "compat") .. "\"" end if self.self_closing then return concat(open_tag) .. "/>" end return concat(open_tag) .. ">" .. concat(self) .. "</" .. self.name .. ">" end do local valid_attribute_name local function get_valid_attribute_name() valid_attribute_name, get_valid_attribute_name = (data or get_data()).valid_attribute_name, nil return valid_attribute_name end function Tag:get_attributes() local raw = self.attributes if not raw then self.attributes = {} return self.attributes elseif type(raw) == "table" then return raw end if sub(raw, -1) == "/" then raw = sub(raw, 1, -2) end local attributes, head = {}, 1 -- Semi-manual implementation of the native regex. while true do local name, loc = match(raw, "([^\t\n\f\r />][^\t\n\f\r /=>]*)()", head) if not name then break end head = loc local value loc = match(raw, "^[\t\n\f\r ]*=[\t\n\f\r ]*()", head) if loc then head = loc -- Either "", '' or the value ends on a space/at the end. Missing -- end quotes are repaired by closing the value at the end. value, loc = match(raw, "^\"([^\"]*)\"?()", head) if not value then value, loc = match(raw, "^'([^']*)'?()", head) if not value then value, loc = match(raw, "^([^\t\n\f\r ]*)()", head) end end head = loc end -- valid_attribute_name is a pattern matching a valid attribute name. -- Defined in the data due to its length - see there for more info. if umatch(name, valid_attribute_name or get_valid_attribute_name()) then -- Sanitizer applies PHP strtolower (ASCII-only). attributes[lower(name)] = value and decode_entities( php_trim((gsub(value, "[\t\n\r ]+", " "))) ) or "" end end self.attributes = attributes return attributes end end function Tag:expand() return (frame or get_frame()):preprocess(tostring(self)) end local Heading = Node:new_class("heading") function Heading:new(this) if #this > 1 then local success, str = pcall(concat, this) if success then return new_node(self, { str, level = this.level, section = this.section, index = this.index }) end end return new_node(self, this) end do local node_tostring = Node.__tostring function Heading:__tostring() local eq = rep("=", self.level) return eq .. node_tostring(self) .. eq end end do local expand_node = Node.expand -- Expanded heading names can contain "\n" (e.g. inside nowiki tags), which -- causes any heading containing them to fail. However, in such cases, the -- native parser still treats it as a heading for the purpose of section -- numbers. local function validate_name(self, frame_args) local name = expand_node(self, frame_args) if find(name, "\n", nil, true) then return nil end return name end function Heading:get_name(frame_args) local name = validate_name(self, frame_args) return name ~= nil and php_trim(name) or nil end -- FIXME: account for anchor disambiguation. function Heading:get_anchor(frame_args) local name = validate_name(self, frame_args) return name ~= nil and decode_entities(anchor_encode(name)) or nil end function Heading:expand(frame_args) local eq = rep("=", self.level) return eq .. expand_node(self, frame_args) .. eq end end ------------------------------------------------------------------------------------ -- -- Parser -- ------------------------------------------------------------------------------------ local Parser = m_parser.string_parser() -- Template or parameter. -- Parsed by matching the opening braces innermost-to-outermost (ignoring lone closing braces). Parameters {{{ }}} take priority over templates {{ }} where possible, but a double closing brace will always result in a closure, even if there are 3+ opening braces. -- For example, "{{{{foo}}}}" (4) is parsed as a parameter enclosed by single braces, and "{{{{{foo}}}}}" (5) is a parameter inside a template. However, "{{{{{foo }} }}}" is a template inside a parameter, due to "}}" forcing the closure of the inner node. do -- Handlers. local handle_name local handle_argument local handle_value local function do_template_or_parameter(self, inner_node) self:push_sublayer(handle_name) self:set_pattern("[\n<[{|}]") -- If a node has already been parsed, nest it at the start of the new -- outer node (e.g. when parsing"{{{{foo}}bar}}", the template "{{foo}}" -- is parsed first, since it's the innermost, and becomes the first -- node of the outer template. if inner_node then self:emit(inner_node) end end local function pipe(self) self:emit(Wikitext:new(self:pop_sublayer())) self:push_sublayer(handle_argument) self:set_pattern("[\n<=[{|}]") end local function rbrace(self, this) if self:read(1) == "}" then self:emit(Wikitext:new(self:pop_sublayer())) return self:pop() end self:emit(this) end function handle_name(self, ...) handle_name = self:switch(handle_name, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = pipe, ["}"] = rbrace, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_name(self, ...) end function handle_argument(self, ...) handle_argument = self:switch(handle_argument, { ["\n"] = function(self, this) return self:heading_block(this, "==") end, ["<"] = Parser.tag, ["="] = function(self) local key = self:pop_sublayer() self:push_sublayer(handle_value) self:set_pattern("[\n<[{|}]") self.current_layer._parse_data.key = key end, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = pipe, ["}"] = rbrace, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_argument(self, ...) end function handle_value(self, ...) handle_value = self:switch(handle_value, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["|"] = function(self) self:emit(Argument:new(self:pop_sublayer())) self:push_sublayer(handle_argument) self:set_pattern("[\n<=[{|}]") end, ["}"] = function(self, this) if self:read(1) == "}" then self:emit(Argument:new(self:pop_sublayer())) return self:pop() end self:emit(this) end, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_value(self, ...) end function Parser:template_or_parameter() local text, head, node_to_emit, failed = self.text, self.head -- Comments/tags interrupt the brace count. local braces = match(text, "^{+()", head) - head self:advance(braces) while true do local success, node = self:try(do_template_or_parameter, node_to_emit) -- Fail means no "}}" or "}}}" was found, so emit any remaining -- unmatched opening braces before any templates/parameters that -- were found. if not success then self:emit(rep("{", braces)) failed = true break -- If there are 3+ opening and closing braces, it's a parameter. elseif braces >= 3 and self:read(2) == "}" then self:advance(3) braces = braces - 3 node = Parameter:new(node) -- Otherwise, it's a template. else self:advance(2) braces = braces - 2 node = Template:new(node) end local index = head + braces node.index = index node.raw = sub(text, index, self.head - 1) node_to_emit = node -- Terminate once not enough braces remain for further matches. if braces == 0 then break -- Emit any stray opening brace before any matched nodes. elseif braces == 1 then self:emit("{") break end end if node_to_emit then self:emit(node_to_emit) end return braces, failed end end -- Tag. do local end_tags local function get_end_tags() end_tags, get_end_tags = (data or get_data()).end_tags, nil return end_tags end -- Handlers. local handle_start local handle_tag local function do_tag(self) local layer = self.current_layer layer._parse_data.handler, layer.index = handle_start, self.head self:set_pattern("[%s/>]") self:advance() end local function is_ignored_tag(self, this) if self.transcluded then return this == "includeonly" end return this == "noinclude" or this == "onlyinclude" end local function ignored_tag(self, text, head) local loc = find(text, ">", head, true) if not loc then return self:fail_route() end self:jump(loc) local tag = self:pop() tag.ignored = true return tag end function handle_start(self, this) if this == "/" then local text, head = self.text, self.head + 1 local this = match(text, "^[^%s/>]+", head) if this and is_ignored_tag(self, lower(this)) then head = head + #this if not match(text, "^/[^>]", head) then return ignored_tag(self, text, head) end end return self:fail_route() elseif this == "" then return self:fail_route() end -- Tags are only case-insensitive with ASCII characters. local raw_name = this this = lower(this) local end_tag_pattern = (end_tags or get_end_tags())[this] if not end_tag_pattern then -- Validity check. return self:fail_route() end local layer = self.current_layer local pdata = layer._parse_data local text, head = self.text, self.head + pdata.step if match(text, "^/[^>]", head) then return self:fail_route() elseif is_ignored_tag(self, this) then return ignored_tag(self, text, head) -- If an onlyinclude tag is not ignored (and cannot be active since it -- would have triggered special handling earlier), it must be plaintext. elseif this == "onlyinclude" then return self:fail_route() elseif this == "noinclude" or this == "includeonly" then layer.ignored = true -- Ignored block. layer.raw_name = raw_name end layer.name, pdata.handler, pdata.end_tag_pattern = this, handle_tag, end_tag_pattern self:set_pattern(">") end function handle_tag(self, this) if this == "" then return self:fail_route() end local layer = self.current_layer if this ~= ">" then layer.attributes = this return elseif self:read(-1) == "/" then layer.self_closing = true return self:pop() end local text, head = self.text, self.head + 1 local loc1, loc2 = find(text, layer._parse_data.end_tag_pattern, head) if loc1 then if loc1 > head then self:emit(sub(text, head, loc1 - 1)) end self:jump(loc2) return self:pop() -- noinclude and includeonly will tolerate having no closing tag, but -- only if given in lowercase. This is due to a preprocessor bug, as -- it uses a regex with the /i (case-insensitive) flag to check for -- end tags, but a simple array lookup with lowercase tag names when -- looking up which tags should tolerate no closing tag (exact match -- only, so case-sensitive). elseif layer.ignored then local raw_name = layer.raw_name if raw_name == "noinclude" or raw_name == "includeonly" then self:jump(#text) return self:pop() end end return self:fail_route() end function Parser:tag() -- HTML comment. if self:read(1, 3) == "!--" then local text = self.text self:jump(select(2, find(text, "-->", self.head + 4, true)) or #text) -- onlyinclude tags (which must be lowercase with no whitespace). elseif self.onlyinclude and self:read(1, 13) == "/onlyinclude>" then local text = self.text self:jump(select(2, find(text, "<onlyinclude>", self.head + 14, true)) or #text) else local success, tag = self:try(do_tag) if not success then self:emit("<") elseif not tag.ignored then self:emit(Tag:new(tag)) end end end end -- Heading. -- The preparser assigns each heading a number, which is used for things like section edit links. The preparser will only do this for heading blocks which aren't nested inside templates, parameters and parser tags. In some cases (e.g. when template blocks contain untrimmed newlines), a preparsed heading may not be treated as a heading in the final output. That does not affect the preparser, however, which will always count sections based on the preparser heading count, since it can't know what a template's final output will be. do -- Handlers. local handle_start local handle_body local handle_possible_end local function do_heading(self) local layer, head = self.current_layer, self.head layer._parse_data.handler, layer.index = handle_start, head self:set_pattern("[\t\n ]") -- Comments/tags interrupt the equals count. local eq = match(self.text, "^=+()", head) - head layer.level = eq self:advance(eq) end local function do_heading_possible_end(self) self.current_layer._parse_data.handler = handle_possible_end self:set_pattern("[\n<]") end function handle_start(self, ...) -- ===== is "=" as an L2; ======== is "==" as an L3 etc. local function newline(self) local layer = self.current_layer local eq = layer.level if eq <= 2 then return self:fail_route() end -- Calculate which equals signs determine the heading level. local level_eq = eq - (2 - eq % 2) level_eq = level_eq > 12 and 12 or level_eq -- Emit the excess. self:emit(rep("=", eq - level_eq)) layer.level = level_eq / 2 return self:pop() end local function whitespace(self) local success, possible_end = self:try(do_heading_possible_end) if success then self:emit(Wikitext:new(possible_end)) self.current_layer._parse_data.handler = handle_body self:set_pattern("[\n<=[{]") return self:consume() end return newline(self) end handle_start = self:switch(handle_start, { ["\t"] = whitespace, ["\n"] = newline, [" "] = whitespace, [""] = newline, [false] = function(self) -- Emit any excess = signs once we know it's a conventional heading. Up till now, we couldn't know if the heading is just a string of = signs (e.g. ========), so it wasn't guaranteed that the heading text starts after the 6th. local layer = self.current_layer local eq = layer.level if eq > 6 then self:emit(1, rep("=", eq - 6)) layer.level = 6 end layer._parse_data.handler = handle_body self:set_pattern("[\n<=[{]") return self:consume() end }) return handle_start(self, ...) end function handle_body(self, ...) handle_body = self:switch(handle_body, { ["\n"] = Parser.fail_route, ["<"] = Parser.tag, ["="] = function(self) -- Comments/tags interrupt the equals count. local eq = match(self.text, "^=+", self.head) local eq_len = #eq self:advance(eq_len) local success, possible_end = self:try(do_heading_possible_end) if success then self:emit(eq) self:emit(Wikitext:new(possible_end)) return self:consume() end local layer = self.current_layer local level = layer.level if eq_len > level then self:emit(rep("=", eq_len - level)) elseif level > eq_len then layer.level = eq_len self:emit(1, rep("=", level - eq_len)) end return self:pop() end, ["["] = Parser.wikilink_block, ["{"] = function(self, this) return self:braces(this, true) end, [""] = Parser.fail_route, [false] = Parser.emit }) return handle_body(self, ...) end function handle_possible_end(self, ...) handle_possible_end = self:switch(handle_possible_end, { ["\n"] = Parser.fail_route, ["<"] = function(self) if self:read(1, 3) ~= "!--" then return self:pop() end local head = select(2, find(self.text, "-->", self.head + 4, true)) if not head then return self:pop() end self:jump(head) end, [""] = Parser.fail_route, [false] = function(self, this) if not match(this, "^[\t ]+()$") then return self:pop() end self:emit(this) end }) return handle_possible_end(self, ...) end function Parser:heading() local success, heading = self:try(do_heading) if success then local section = self.section + 1 heading.section = section self.section = section self:emit(Heading:new(heading)) return self:consume() else self:emit("=") end end end ------------------------------------------------------------------------------------ -- -- Block handlers -- ------------------------------------------------------------------------------------ -- Block handlers. -- These are blocks which can affect template/parameter parsing, since they're also parsed by Parsoid at the same time (even though they aren't processed until later). -- All blocks (including templates/parameters) can nest inside each other, but an inner block must be closed before the outer block which contains it. This is why, for example, the wikitext "{{template| [[ }}" will result in an unprocessed template, since the inner "[[" is treated as the opening of a wikilink block, which prevents "}}" from being treated as the closure of the template block. On the other hand, "{{template| [[ ]] }}" will process correctly, since the wikilink block is closed before the template closure. It makes no difference whether the block will be treated as valid or not when it's processed later on, so "{{template| [[ }} ]] }}" would also work, even though "[[ }} ]]" is not a valid wikilink. -- Note that nesting also affects pipes and equals signs, in addition to block closures. -- These blocks can be nested to any degree, so "{{template| [[ [[ [[ ]] }}" will not work, since only one of the three wikilink blocks has been closed. On the other hand, "{{template| [[ [[ [[ ]] ]] ]] }}" will work. -- All blocks are implicitly closed by the end of the text, since their validity is irrelevant at this stage. -- Language conversion block. -- Opens with "-{" and closes with "}-". However, templates/parameters take priority, so "-{{" is parsed as "-" followed by the opening of a template/parameter block (depending on what comes after). -- Note: Language conversion blocks aren't actually enabled on the English Wiktionary, but Parsoid still parses them at this stage, so they can affect the closure of outer blocks: e.g. "[[ -{ ]]" is not a valid wikilink block, since the "]]" falls inside the new language conversion block. do --Handler. local handle_language_conversion_block local function do_language_conversion_block(self) self.current_layer._parse_data.handler = handle_language_conversion_block self:set_pattern("[\n<[{}]") end function handle_language_conversion_block(self, ...) handle_language_conversion_block = self:switch(handle_language_conversion_block, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, ["}"] = function(self, this) if self:read(1) == "-" then self:emit("}-") self:advance() return self:pop() end self:emit(this) end, [""] = Parser.pop, [false] = Parser.emit }) return handle_language_conversion_block(self, ...) end function Parser:braces(this, fail_on_unclosed_braces) local language_conversion_block = self:read(-1) == "-" if self:read(1) == "{" then local braces, failed = self:template_or_parameter() -- Headings will fail if they contain an unclosed brace block. if failed and fail_on_unclosed_braces then return self:fail_route() -- Language conversion blocks cannot begin "-{{", but can begin -- "-{{{" iff parsed as "-{" + "{{". elseif not (language_conversion_block and braces == 1) then return self:consume() end else self:emit(this) if not language_conversion_block then return end self:advance() end self:emit(Wikitext:new(self:get(do_language_conversion_block))) end end --[==[ Headings Opens with "\n=" (or "=" at the start of the text), and closes with "\n" or the end of the text. Note that it doesn't matter whether the heading will fail to process due to a premature newline (e.g. if there are no closing signs), so at this stage the only thing that matters for closure is the newline or end of text. Note: Heading blocks are only parsed like this if they occur inside a template, since they do not iterate the preparser's heading count (i.e. they aren't proper headings). Note 2: if directly inside a template argument with no previous equals signs, a newline followed by a single equals sign is parsed as an argument equals sign, not the opening of a new L1 heading block. This does not apply to any other heading levels. As such, {{template|key\n=}}, {{template|key\n=value}} or even {{template|\n=}} will successfully close, but {{template|key\n==}}, {{template|key=value\n=more value}}, {{template\n=}} etc. will not, since in the latter cases the "}}" would fall inside the new heading block. ]==] do --Handler. local handle_heading_block local function do_heading_block(self) self.current_layer._parse_data.handler = handle_heading_block self:set_pattern("[\n<[{]") end function handle_heading_block(self, ...) handle_heading_block = self:switch(handle_heading_block, { ["\n"] = function(self) self:newline() return self:pop() end, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["{"] = Parser.braces, [""] = Parser.pop, [false] = Parser.emit }) return handle_heading_block(self, ...) end function Parser:heading_block(this, nxt) self:newline() this = this .. (nxt or "=") local loc = #this - 1 while self:read(0, loc) == this do self:advance() self:emit(Wikitext:new(self:get(do_heading_block))) end end end -- Wikilink block. -- Opens with "[[" and closes with "]]". do -- Handler. local handle_wikilink_block local function do_wikilink_block(self) self.current_layer._parse_data.handler = handle_wikilink_block self:set_pattern("[\n<[%]{]") end function handle_wikilink_block(self, ...) handle_wikilink_block = self:switch(handle_wikilink_block, { ["\n"] = Parser.heading_block, ["<"] = Parser.tag, ["["] = Parser.wikilink_block, ["]"] = function(self, this) if self:read(1) == "]" then self:emit("]]") self:advance() return self:pop() end self:emit(this) end, ["{"] = Parser.braces, [""] = Parser.pop, [false] = Parser.emit }) return handle_wikilink_block(self, ...) end function Parser:wikilink_block() if self:read(1) == "[" then self:emit("[[") self:advance(2) self:emit(Wikitext:new(self:get(do_wikilink_block))) else self:emit("[") end end end -- Lines which only contain comments, " " and "\t" are eaten, so long as -- they're bookended by "\n" (i.e. not the first or last line). function Parser:newline() local text, head = self.text, self.head while true do repeat local loc = match(text, "^[\t ]*<!%-%-()", head + 1) if not loc then break end loc = select(2, find(text, "-->", loc, true)) head = loc or head until not loc -- Fail if no comments found. if head == self.head then break end head = match(text, "^[\t ]*()\n", head + 1) if not head then break end self:jump(head) end self:emit("\n") end do -- Handlers. local handle_start local main_handler -- If `transcluded` is true, then the text is checked for a pair of -- onlyinclude tags. If these are found (even if they're in the wrong -- order), then the start of the page is treated as though it is preceded -- by a closing onlyinclude tag. -- Note 1: unlike other parser extension tags, onlyinclude tags are case- -- sensitive and cannot contain whitespace. -- Note 2: onlyinclude tags *can* be implicitly closed by the end of the -- text, but the hard requirement above means this can only happen if -- either the tags are in the wrong order or there are multiple onlyinclude -- blocks. local function do_parse(self, transcluded) self.current_layer._parse_data.handler = handle_start self:set_pattern(".") self.section = 0 if not transcluded then return end self.transcluded = true local text = self.text if find(text, "</onlyinclude>", nil, true) then local head = find(text, "<onlyinclude>", nil, true) if head then self.onlyinclude = true self:jump(head + 13) end end end -- If the first character is "=", try parsing it as a heading. function handle_start(self, this) self.current_layer._parse_data.handler = main_handler self:set_pattern("[\n<{]") if this == "=" then return self:heading() end return self:consume() end function main_handler(self, ...) main_handler = self:switch(main_handler, { ["\n"] = function(self) self:newline() if self:read(1) == "=" then self:advance() return self:heading() end end, ["<"] = Parser.tag, ["{"] = function(self, this) if self:read(1) == "{" then self:template_or_parameter() return self:consume() end self:emit(this) end, [""] = Parser.pop, [false] = Parser.emit }) return main_handler(self, ...) end function export.parse(text, transcluded) local text_type = type(text) return (select(2, Parser:parse{ text = text_type == "string" and text or text_type == "number" and tostring(text) or error("bad argument #1 (string expected, got " .. text_type .. ")"), node = {Wikitext, true}, route = {do_parse, transcluded} })) end parse = export.parse end function export.find_templates(text, not_transcluded) return parse(text, not not_transcluded):iterate_nodes("template") end do local link_parameter_1, link_parameter_2 local function get_link_parameter_1() link_parameter_1, get_link_parameter_1 = (data or get_data()).template_link_param_1, nil return link_parameter_1 end local function get_link_parameter_2() link_parameter_2, get_link_parameter_2 = (data or get_data()).template_link_param_2, nil return link_parameter_2 end -- Generate a link. If the target title doesn't have a fragment, use "#top" -- (which is an implicit anchor at the top of every page), as this ensures -- self-links still display as links, since bold display is distracting and -- unintuitive for template links. local function link_page(title, display) local fragment = title.fragment if fragment == "" then fragment = "top" end return format( "[[:%s|%s]]", encode_uri(title.prefixedText .. "#" .. fragment, "WIKI"), display ) end -- pf_arg1 or pf_arg2 may need to be linked if a given parser function -- treats them as a pagename. If a key exists in `namespace`, the value is -- the namespace for the page: if not 0, then the namespace prefix will -- always be added to the input (e.g. {{#invoke:}} can only target the -- Module: namespace, so inputting "Template:foo" gives -- "Module:Template:foo", and "Module:foo" gives "Module:Module:foo"). -- However, this isn't possible with mainspace (namespace 0), so prefixes -- are respected. make_title() handles all of this automatically. local function finalize_arg(pagename, namespace) if namespace == nil then return pagename end local title = make_title(namespace, pagename) return title and not title.isExternal and link_page(title, pagename) or pagename end local function render_title(name, args) -- parse_template_name returns a table of transclusion modifiers plus -- the normalized template/magic word name, which will be used as link -- targets. The third return value pf_arg1 is the first argument of a -- a parser function, which comes after the colon (e.g. "foo" in -- "{{#IF:foo|bar|baz}}"). This means args[1] (i.e. the first argument -- that comes after a pipe is actually argument 2, and so on. Note: the -- second parameter of parse_template_name checks if there are any -- arguments, since parser variables cannot take arguments (e.g. -- {{CURRENTYEAR}} is a parser variable, but {{CURRENTYEAR|foo}} -- transcludes "Template:CURRENTYEAR"). In such cases, the returned -- table explicitly includes the "Template:" prefix in the template -- name. The third parameter instructs it to retain any fragment in the -- template name in the returned table, if present. local chunks, subclass, pf_arg1 = parse_template_name( name, args and pairs(args)(args) ~= nil, true ) if chunks == nil then return name, args end local chunks_len = #chunks -- Additionally, generate the corresponding table `rawchunks`, which -- is a list of colon-separated chunks in the raw input. This is used -- to retrieve the display forms for each chunk. local rawchunks = split(name, ":") for i = 1, chunks_len - 1 do chunks[i] = format( "[[%s|%s]]", encode_uri((magic_words or get_magic_words())[sub(chunks[i], 1, -2)].transclusion_modifier, "WIKI"), rawchunks[i] ) end local chunk = chunks[chunks_len] -- If it's a template, return a link to it with link_page, concatenating -- the remaining chunks in `rawchunks` to form the display text. -- Use new_title with the default namespace 10 (Template:) to generate -- a target title, which is the same setting used for retrieving -- templates (including those in other namespaces, as prefixes override -- the default). if subclass == "template" then chunks[chunks_len] = link_page( new_title(chunk, 10), concat(rawchunks, "&#58;", chunks_len) -- : ) return concat(chunks, "&#58;"), args -- : elseif subclass == "parser variable" then chunks[chunks_len] = format( "[[%s|%s]]", encode_uri((magic_words or get_magic_words())[chunk].parser_variable, "WIKI"), rawchunks[chunks_len] ) return concat(chunks, "&#58;"), args -- : end -- Otherwise, it must be a parser function. local mgw_data = (magic_words or get_magic_words())[sub(chunk, 1, -2)] local link = mgw_data.parser_function or mgw_data.transclusion_modifier local pf_arg2 = args and args[1] or nil -- Some magic words have different links, depending on whether argument -- 2 is specified (e.g. "baz" in {{foo:bar|baz}}). if type(link) == "table" then link = pf_arg2 and link[2] or link[1] end chunks[chunks_len] = format( "[[%s|%s]]", encode_uri(link, "WIKI"), rawchunks[chunks_len] ) -- #TAG: has special handling, because documentation links for parser -- extension tags come from [[Module:data/parser extension tags]]. if chunk == "#TAG:" then -- Tags are only case-insensitive with ASCII characters. local tag = (parser_extension_tags or get_parser_extension_tags())[lower(php_trim(pf_arg1))] if tag then pf_arg1 = format( "[[%s|%s]]", encode_uri(tag, "WIKI"), pf_arg1 ) end -- Otherwise, finalize pf_arg1 and add it to `chunks`. else pf_arg1 = finalize_arg(pf_arg1, (link_parameter_1 or get_link_parameter_1())[chunk]) end chunks[chunks_len + 1] = pf_arg1 -- Finalize pf_arg2 (if applicable), then return. if pf_arg2 then args = shallow_copy(args) -- Avoid destructively modifying args. args[1] = finalize_arg(pf_arg2, (link_parameter_2 or get_link_parameter_2())[chunk]) end return concat(chunks, "&#58;"), args -- : end function export.buildTemplate(title, args) local output = {title} if not args then return output end -- Iterate over all numbered parameters in order, followed by any -- remaining parameters in codepoint order. Implicit parameters are -- used wherever possible, even if explicit numbers are interpolated -- between them (e.g. 0 would go before any implicit parameters, and -- 2.5 between 2 and 3). -- TODO: handle "=" and "|" in params/values. local implicit for k, v in sorted_pairs(args) do if type(k) == "number" and k >= 1 and k % 1 == 0 then if implicit == nil then implicit = table_len(args) end insert(output, k <= implicit and v or k .. "=" .. v) else insert(output, k .. "=" .. v) end end return output end build_template = export.buildTemplate function export.templateLink(title, args, no_link) if not no_link then title, args = render_title(title, args) end local output = build_template(title, args) for i = 1, #output do output[i] = encode_entities(output[i], "={}", true, true) end return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&#123;&#123;" .. concat(output, "&#124;") .. "&#125;&#125;") -- {{ | }} ) end end do function export.find_parameters(text, not_transcluded) return parse(text, not not_transcluded):iterate_nodes("parameter") end function export.displayParameter(name, default) return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&#123;&#123;&#123;" .. concat({name, default}, "&#124;") .. "&#125;&#125;&#125;") -- {{{ | }}} ) end end do local function check_level(level) if type(level) ~= "number" then error("Heading levels must be numbers.") elseif level < 1 or level > 6 or level % 1 ~= 0 then error("Heading levels must be integers between 1 and 6.") end return level end -- FIXME: should headings which contain "\n" be returned? This may depend -- on variable factors, like template expansion. They iterate the heading -- count number, but fail on rendering. However, in some cases a different -- heading might still be rendered due to intermediate equals signs; it -- may even be of a different heading level: e.g., this is parsed as an -- L2 heading with a newline (due to the wikilink block), but renders as the -- L1 heading "=foo[[". Section edit links are sometimes (but not always) -- present in such cases. -- ==[[= -- ]]== -- TODO: section numbers for edit links seem to also include headings -- nested inside templates and parameters (but apparently not those in -- parser extension tags - need to test this more). If we ever want to add -- section edit links manually, this will need to be accounted for. function export.find_headings(text, i, j) local parsed = parse(text) if i == nil and j == nil then return parse(text):iterate_nodes("heading") end i = i and check_level(i) or 1 j = j and check_level(j) or 6 return parsed:iterate(function(v) if class_else_type(v) == "heading" then local level = v.level return level >= i and level <= j end end) end end do local function make_tag(tag) return tostring(html_create("code") :css("white-space", "pre-wrap") :wikitext("&lt;" .. tag .. "&gt;") ) end -- Note: invalid tags are returned without links. function export.wikitagLink(tag) -- ">" can't appear in tags (including attributes) since the parser -- unconditionally treats ">" as the end of a tag. if find(tag, ">", nil, true) then return make_tag(tag) end -- Tags must start "<tagname..." or "</tagname...", with no whitespace -- after "<" or "</". local slash, tagname, remainder = match(tag, "^(/?)([^/%s]+)(.*)$") if not tagname then return make_tag(tag) end -- Tags are only case-insensitive with ASCII characters. local link = lower(tagname) if ( -- onlyinclude tags must be lowercase and are whitespace intolerant. link == "onlyinclude" and (link ~= tagname or remainder ~= "") or -- Closing wikitags (except onlyinclude) can only have whitespace -- after the tag name. slash == "/" and not match(remainder, "^%s*()$") or -- Tagnames cannot be followed immediately by "/", unless it comes -- at the end (e.g. "<nowiki/>", but not "<nowiki/ >"). remainder ~= "/" and sub(remainder, 1, 1) == "/" ) then -- Output with no link. return make_tag(tag) end -- Partial transclusion tags aren't in the table of parser extension -- tags. if link == "noinclude" or link == "includeonly" or link == "onlyinclude" then link = "mw:Transclusion#Partial transclusion" else link = (parser_extension_tags or get_parser_extension_tags())[link] end if link then tag = gsub(tag, pattern_escape(tagname), "[[" .. replacement_escape(encode_uri(link, "WIKI")) .. "|%0]]", 1) end return make_tag(tag) end end -- For convenience. export.class_else_type = class_else_type return export nbyiw08f29469vkrod60gnnlf8rdfuh Modul:title/getCurrentNamespace 828 7206 26650 2025-11-08T21:27:15Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26650 Scribunto text/plain --[==[ Returns the data table for the current namespace from {mw.site.namespaces}. This module may be loaded with {mw.loadData}.]==] return mw.site.namespaces[mw.title.getCurrentTitle().namespace] 2udpe5a40x351nzks01by6n1mixwd3o 26651 24266 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:title/getCurrentNamespace]] 24266 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:title/getCurrentNamespace -- License: CC BY-SA --[==[ Returns the data table for the current namespace from {mw.site.namespaces}. This module may be loaded with {mw.loadData}.]==] return mw.site.namespaces[mw.title.getCurrentTitle().namespace] 6i6ggxo6t5utg3jrmchlfb31hh5z9y8 Modul:title/isTitle 828 7210 26654 2025-11-08T21:25:15Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26654 Scribunto text/plain local table_get_metamethod_module = "Module:table/getMetamethod" local error = error local rawequal = rawequal local type = type local function get_metamethod(...) get_metamethod = require(table_get_metamethod_module) return get_metamethod(...) end local title_eq, title_lt local function get_title_mm() local success, eq, lt = get_metamethod(mw.title.getCurrentTitle(), "__eq", "__lt") if not success then error("Failed to fetch current title") -- this should never happen end title_eq, title_lt, get_title_mm = eq, lt, nil return eq end --[==[ Returns {true} if the input is a title object, or {false} if not.]==] return function(obj) if not (obj and type(obj) == "table") then return false end local success, eq, lt = get_metamethod(obj, "__eq", "__lt") -- There's no foolproof method for checking for a title object, but the -- __eq and __lt metamethods should always be the same. Also discount titles -- that only have fragments (returned by mw.title.new() and -- mw.title.makeTitle() if the input starts with "#"), since they cannot -- represent a valid page, and are broken in various ways (e.g. attempting -- to access certain keys results in an error); see [[phab:T240678]]. return success and eq ~= nil and lt ~= nil and rawequal(eq, (title_eq or get_title_mm())) and rawequal(lt, title_lt) and obj.prefixedText ~= "" end j1ejjc7c8trmnla3tstyr2or7aay9ft 26655 24270 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:title/isTitle]] 24270 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:title/isTitle -- License: CC BY-SA local table_get_metamethod_module = "Module:table/getMetamethod" local error = error local rawequal = rawequal local type = type local function get_metamethod(...) get_metamethod = require(table_get_metamethod_module) return get_metamethod(...) end local title_eq, title_lt local function get_title_mm() local success, eq, lt = get_metamethod(mw.title.getCurrentTitle(), "__eq", "__lt") if not success then error("Failed to fetch current title") -- this should never happen end title_eq, title_lt, get_title_mm = eq, lt, nil return eq end --[==[ Returns {true} if the input is a title object, or {false} if not.]==] return function(obj) if not (obj and type(obj) == "table") then return false end local success, eq, lt = get_metamethod(obj, "__eq", "__lt") -- There's no foolproof method for checking for a title object, but the -- __eq and __lt metamethods should always be the same. Also discount titles -- that only have fragments (returned by mw.title.new() and -- mw.title.makeTitle() if the input starts with "#"), since they cannot -- represent a valid page, and are broken in various ways (e.g. attempting -- to access certain keys results in an error); see [[phab:T240678]]. return success and eq ~= nil and lt ~= nil and rawequal(eq, (title_eq or get_title_mm())) and rawequal(lt, title_lt) and obj.prefixedText ~= "" end 6f51a7ly3rxw6bs3l7x0ecdve302p9g Modul:title/newTitle 828 7213 26648 2025-11-08T21:26:29Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26648 Scribunto text/plain local load_module = "Module:load" local scribunto_module = "Module:Scribunto" local title_get_current_namespace_module = "Module:title/getCurrentNamespace" local title_get_current_title_module = "Module:title/getCurrentTitle" local title_get_main_page_title_module = "Module:title/getMainPageTitle" local byte = string.byte local find = string.find local match = string.match local new_title = mw.title.new local reverse = string.reverse local sub = string.sub local type = type local function get_current_title(...) get_current_title = require(title_get_current_title_module) return get_current_title(...) end local function get_main_page_title(...) get_main_page_title = require(title_get_main_page_title_module) return get_main_page_title(...) end local function php_ltrim(...) php_ltrim = require(scribunto_module).php_ltrim return php_ltrim(...) end local function php_rtrim(...) php_rtrim = require(scribunto_module).php_rtrim return php_rtrim(...) end local current_pagename local function get_current_pagename() -- Call mw.title.getCurrentTitle() directly rather than the modified version -- at [[Module:title/getCurrentTitle]], as it doesn't do anything extra when -- no fragment argument is given, so there's no point in loading it. current_pagename, get_current_pagename = mw.title.getCurrentTitle().prefixedText, nil return current_pagename end local namespace_has_subpages local function get_namespace_has_subpages() namespace_has_subpages, get_namespace_has_subpages = require(load_module).load_data(title_get_current_namespace_module).hasSubpages, nil return namespace_has_subpages end local function split_text(text) -- Split off the fragment. local hash, target, fragment = find(text, "#", nil, true) if hash then target, fragment = sub(text, 1, hash - 1), sub(text, hash) else target, fragment = text, "" end return php_rtrim(target), fragment end --[==[ A modified version of {mw.title.new}: * It is no longer possible to generate title objects for the empty string by inputting a title starting with {"#"}. Such empty string titles do not represent a valid page, and are broken in various ways (e.g. attempting to access certain keys results in an error); see [[phab:T240678]]. * There are two additional boolean flags: ** If {allowOnlyFragment} is set, string inputs starting with {#} are handled analogously to links (e.g. the input {"#foo"} returns a title object for the current page with the addition of the fragment {"foo"}, analogous to the link [[#foo]]). As a special case, the input {"#"} returns the title for the main page (see TitleValue.php). ** If {allowRelative} is set, inputs representing relative titles will work (e.g. {"/foo"} and {"../"}, analogous to the relative links [[/foo]] and [[../]]).]==] return function(text_or_id, defaultNamespace, allowOnlyFragment, allowRelative) -- Process relative titles in the same way as normalizeSubpageLink() in -- Linker.php. if ( allowRelative and type(text_or_id) == "string" and -- Distinguish nil and false for the purposes of calling the getter. (namespace_has_subpages == nil and get_namespace_has_subpages() or namespace_has_subpages) ) then -- For both kinds of relative title, `text_or_id` has to be split into -- `target` and `fragment` (if any). `target` has to be trimmed, but -- as an optimisation, only do a left-trim on `text_or_id`, which is -- sufficient for the initial checks for potential relative titles, as -- this avoids unnecessary splitting/trimming in the vast majority of -- cases where the title won't be relative. In the cases where it is, -- `target` will then be right-trimmed once it has been split out of -- `text_or_id`. text_or_id = php_ltrim(text_or_id) local init = byte(text_or_id) -- If the target starts with "/", it's treated as a subpage of the -- current page. Final slashes are trimmed, but this can't affect the -- intervening slash (e.g. "[[///]]" refers to "[[{{PAGENAME}}/]]"). if init == 0x2F then -- / local target, fragment = split_text(text_or_id) text_or_id, defaultNamespace = (current_pagename or get_current_pagename()) .. (match(target, "^/.*[^/]") or "/") .. fragment, nil -- If the title starts with "../", trim it and any further "../" that -- follow, and go up that many subpage levels. Then, treat any -- additional text as a subpage of that page. Final slashes are trimmed. elseif init == 0x2E and sub(text_or_id, 2, 3) == "./" then -- ../ local n, target, fragment = 4, split_text(text_or_id) while sub(target, n, n + 2) == "../" do n = n + 3 end -- Retain an initial "/". target = sub(target, n - 1) -- Trim the relevant number of subpages from the pagename. local pagename, i = reverse(current_pagename or get_current_pagename()), 0 for _ = 1, (n - 1) / 3 do i = find(pagename, "/", i + 1, true) -- Fail if there aren't enough slashes. if not i then return nil end end -- Add the subpage text; since the intervening "/" is retained in -- `target`, it can be trimmed along with any other final slashes -- (e.g. [[..///]] refers to "{{BASEPAGENAME}}".) text_or_id, defaultNamespace = reverse(sub(pagename, i + 1)) .. (match(target, "^.*[^/]") or "") .. fragment, nil end end local title = new_title(text_or_id, defaultNamespace) if not title then return nil elseif title.prefixedText ~= "" then return title -- If `prefixedText` is the empty string, the input only has a fragment. elseif not allowOnlyFragment then return nil end -- Retrieve the fragment: if it's the empty string, return a title object -- for the main page (which is where the link [[#]] resolves); otherwise, -- return a current title object using [[Module:title/getCurrentTitle]], -- which sets the fragment on the returned title to the string passed in. -- (Note that inputs like "##foo" aren't interpreted as the main page with -- the fragment "foo"; instead, it's a fragment for the section "#foo" on -- the current page, since "#" is itself a valid fragment character.) local fragment = title.fragment return fragment == "" and get_main_page_title() or get_current_title(fragment) end aooqpfbxewgzf96rcljwg1e7vf0j43b 26649 24273 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:title/newTitle]] 24273 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:title/newTitle -- License: CC BY-SA local load_module = "Module:load" local scribunto_module = "Module:Scribunto" local title_get_current_namespace_module = "Module:title/getCurrentNamespace" local title_get_current_title_module = "Module:title/getCurrentTitle" local title_get_main_page_title_module = "Module:title/getMainPageTitle" local byte = string.byte local find = string.find local match = string.match local new_title = mw.title.new local reverse = string.reverse local sub = string.sub local type = type local function get_current_title(...) get_current_title = require(title_get_current_title_module) return get_current_title(...) end local function get_main_page_title(...) get_main_page_title = require(title_get_main_page_title_module) return get_main_page_title(...) end local function php_ltrim(...) php_ltrim = require(scribunto_module).php_ltrim return php_ltrim(...) end local function php_rtrim(...) php_rtrim = require(scribunto_module).php_rtrim return php_rtrim(...) end local current_pagename local function get_current_pagename() -- Call mw.title.getCurrentTitle() directly rather than the modified version -- at [[Module:title/getCurrentTitle]], as it doesn't do anything extra when -- no fragment argument is given, so there's no point in loading it. current_pagename, get_current_pagename = mw.title.getCurrentTitle().prefixedText, nil return current_pagename end local namespace_has_subpages local function get_namespace_has_subpages() namespace_has_subpages, get_namespace_has_subpages = require(load_module).load_data(title_get_current_namespace_module).hasSubpages, nil return namespace_has_subpages end local function split_text(text) -- Split off the fragment. local hash, target, fragment = find(text, "#", nil, true) if hash then target, fragment = sub(text, 1, hash - 1), sub(text, hash) else target, fragment = text, "" end return php_rtrim(target), fragment end --[==[ A modified version of {mw.title.new}: * It is no longer possible to generate title objects for the empty string by inputting a title starting with {"#"}. Such empty string titles do not represent a valid page, and are broken in various ways (e.g. attempting to access certain keys results in an error); see [[phab:T240678]]. * There are two additional boolean flags: ** If {allowOnlyFragment} is set, string inputs starting with {#} are handled analogously to links (e.g. the input {"#foo"} returns a title object for the current page with the addition of the fragment {"foo"}, analogous to the link [[#foo]]). As a special case, the input {"#"} returns the title for the main page (see TitleValue.php). ** If {allowRelative} is set, inputs representing relative titles will work (e.g. {"/foo"} and {"../"}, analogous to the relative links [[/foo]] and [[../]]).]==] return function(text_or_id, defaultNamespace, allowOnlyFragment, allowRelative) -- Process relative titles in the same way as normalizeSubpageLink() in -- Linker.php. if ( allowRelative and type(text_or_id) == "string" and -- Distinguish nil and false for the purposes of calling the getter. (namespace_has_subpages == nil and get_namespace_has_subpages() or namespace_has_subpages) ) then -- For both kinds of relative title, `text_or_id` has to be split into -- `target` and `fragment` (if any). `target` has to be trimmed, but -- as an optimisation, only do a left-trim on `text_or_id`, which is -- sufficient for the initial checks for potential relative titles, as -- this avoids unnecessary splitting/trimming in the vast majority of -- cases where the title won't be relative. In the cases where it is, -- `target` will then be right-trimmed once it has been split out of -- `text_or_id`. text_or_id = php_ltrim(text_or_id) local init = byte(text_or_id) -- If the target starts with "/", it's treated as a subpage of the -- current page. Final slashes are trimmed, but this can't affect the -- intervening slash (e.g. "[[///]]" refers to "[[{{PAGENAME}}/]]"). if init == 0x2F then -- / local target, fragment = split_text(text_or_id) text_or_id, defaultNamespace = (current_pagename or get_current_pagename()) .. (match(target, "^/.*[^/]") or "/") .. fragment, nil -- If the title starts with "../", trim it and any further "../" that -- follow, and go up that many subpage levels. Then, treat any -- additional text as a subpage of that page. Final slashes are trimmed. elseif init == 0x2E and sub(text_or_id, 2, 3) == "./" then -- ../ local n, target, fragment = 4, split_text(text_or_id) while sub(target, n, n + 2) == "../" do n = n + 3 end -- Retain an initial "/". target = sub(target, n - 1) -- Trim the relevant number of subpages from the pagename. local pagename, i = reverse(current_pagename or get_current_pagename()), 0 for _ = 1, (n - 1) / 3 do i = find(pagename, "/", i + 1, true) -- Fail if there aren't enough slashes. if not i then return nil end end -- Add the subpage text; since the intervening "/" is retained in -- `target`, it can be trimmed along with any other final slashes -- (e.g. [[..///]] refers to "{{BASEPAGENAME}}".) text_or_id, defaultNamespace = reverse(sub(pagename, i + 1)) .. (match(target, "^.*[^/]") or "") .. fragment, nil end end local title = new_title(text_or_id, defaultNamespace) if not title then return nil elseif title.prefixedText ~= "" then return title -- If `prefixedText` is the empty string, the input only has a fragment. elseif not allowOnlyFragment then return nil end -- Retrieve the fragment: if it's the empty string, return a title object -- for the main page (which is where the link [[#]] resolves); otherwise, -- return a current title object using [[Module:title/getCurrentTitle]], -- which sets the fragment on the returned title to the string passed in. -- (Note that inputs like "##foo" aren't interpreted as the main page with -- the fragment "foo"; instead, it's a fragment for the section "#foo" on -- the current page, since "#" is itself a valid fragment character.) local fragment = title.fragment return fragment == "" and get_main_page_title() or get_current_title(fragment) end 9v5rs5tti813047teeuwfiwbdv9zske Modul:title/redirectTarget 828 7214 26652 2025-11-08T21:30:54Z id>Ekirahardian 0 Salin dari en.wikipedia.org 26652 Scribunto text/plain local pcall = pcall local at_limit local function is_redirect(title) return title.isRedirect end --[==[ Returns the title object of the redirect target if title page is a redirect. Checking {title.redirectTarget} will transclude the title page, which may be undesirable when checking large numbers of titles. To avoid this, this function will attempt to check the {title.isRedirect} key first, only checking {title.redirectTarget} if it is confirmed that the title is a redirect. However, doing so will increment the expensive function count, which has a limit of 500. Once the limit has been reached, this function reverts to checking {title.redirectTarget} directly instead. The {force_transclusion} flag may be set to force the use of transclusion ({title.redirectTarget}) in all instances, which can be used to avoid incrementing the expensive function count; this is sometimes useful when making a large number of checks, as hitting the expensive function limit can be disruptive to other modules or templates.]==] return function(title, force_transclusion) if not (force_transclusion or at_limit) then local success, result = pcall(is_redirect, title) if not success then at_limit = true elseif not result then return false end end local redirect = title.redirectTarget if not redirect then return false end -- If the original title had a fragment, carry it over to the redirect. local fragment = title.fragment if fragment and fragment ~= "" then redirect.fragment = fragment end return redirect end 0fmvtjkqug22ktp797jksqoi89g47pw 26653 24274 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:title/redirectTarget]] 24274 Scribunto text/plain -- Imported from enwiktionary -- Source: https://en.wiktionary.org/wiki/Module:title/redirectTarget -- License: CC BY-SA local pcall = pcall local at_limit local function is_redirect(title) return title.isRedirect end --[==[ Returns the title object of the redirect target if title page is a redirect. Checking {title.redirectTarget} will transclude the title page, which may be undesirable when checking large numbers of titles. To avoid this, this function will attempt to check the {title.isRedirect} key first, only checking {title.redirectTarget} if it is confirmed that the title is a redirect. However, doing so will increment the expensive function count, which has a limit of 500. Once the limit has been reached, this function reverts to checking {title.redirectTarget} directly instead. The {force_transclusion} flag may be set to force the use of transclusion ({title.redirectTarget}) in all instances, which can be used to avoid incrementing the expensive function count; this is sometimes useful when making a large number of checks, as hitting the expensive function limit can be disruptive to other modules or templates.]==] return function(title, force_transclusion) if not (force_transclusion or at_limit) then local success, result = pcall(is_redirect, title) if not success then at_limit = true elseif not result then return false end end local redirect = title.redirectTarget if not redirect then return false end -- If the original title had a fragment, carry it over to the redirect. local fragment = title.fragment if fragment and fragment ~= "" then redirect.fragment = fragment end return redirect end 68rz2o2xry4sq6ui8fn5ljv2y5s5a93 mokondo 0 7573 26596 26490 2026-07-08T00:07:35Z Sibiru45 115 /* Basa Indunisia */ 26596 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|cakapan|hinaan}} {{akronim dari|id|modal kontol doang}} rtxybopwsklahtr9nx2tejk7ctvjwwf 26598 26596 2026-07-08T00:09:28Z Sibiru45 115 /* Basa Indunisia */ 26598 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|cakapan|hinaan}} {{singkatan matan|id|modal kontol doang}} r49h0xsx5kcjy3tk9ww3hqbol4imjib 26599 26598 2026-07-08T00:10:25Z Sibiru45 115 /* Basa Indunisia */ 26599 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|cakapan|hinaan}} {{singkatan matan|id|''modal kontol doang''}} l7agq8kjdysju1111su2sj9vu3tob2l 26601 26599 2026-07-08T00:10:54Z Sibiru45 115 /* Basa Indunisia */ 26601 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|cakapan|hinaan}} {{singkatan matan|id|''modal kontol doang''}} #:mudal palir haja bz11ymvi0f7u6rxpwxytpoc862782jq 26663 26601 2026-07-08T05:14:32Z Sibiru45 115 /* Basa Indunisia */ 26663 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|sambatan|hinaan}} {{singkatan matan|id|''modal kontol doang''}} #:mudal palir haja g4tnkqctad8u45y6tiwt26xac776dcu 26664 26663 2026-07-08T05:16:23Z Sibiru45 115 /* Basa Indunisia */ 26664 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|sambatan|hinaan}} {{singkatan matan|id|''modal kontol doang''}} #:mudal [[palir]] haja 96z9320bpnkwjljafrr585txrleezg1 26667 26664 2026-07-08T07:20:12Z Swarabakti 404 /* Basa Indunisia */ 26667 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|sambatan|hinaan}} {{singkatan matan|id|''modal kontol doang''}} 0gif8af4ac9ld2u5urxpiz1a8d0vag0 26668 26667 2026-07-08T07:20:43Z Swarabakti 404 /* Basa Indunisia */ jangan garis miring, bukan glos 26668 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # {{label|id|sambatan|hinaan}} {{singkatan matan|id|modal kontol doang}} 3uiwetfy7pohx4ilr8nsd8h61q4qkpx Modul:labels/data/lang/id 828 7576 26531 2025-12-15T08:28:30Z id>Swarabakti 0 26531 Scribunto text/plain local labels = {} ----Dialects go here--- labels["Bandung"] = { aliases = {"cakapan Bandung"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } labels["Jakarta"] = { aliases = {"cakapan Jakarta"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } labels["Jawa"] = { aliases = {"cakapan Jawa"}, Wikipedia = true, regional_categories = "Jawa", prep = "di", region = "pulau [[Jawa]]", parent = "Indonesia", } labels["Kalimantan"] = { aliases = {"cakapan Kalimantan"}, Wikipedia = true, regional_categories = "Kalimantan", prep = "di", region = "pulau [[Kalimantan]]", parent = "Indonesia", } labels["Maluku"] = { aliases = {"cakapan Maluku"}, Wikipedia = true, regional_categories = "Maluku", prep = "di", region = "kepulauan [[Maluku]]", parent = "Indonesia", } labels["Medan"] = { aliases = {"cakapan Medan"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Padang"] = { aliases = {"cakapan Padang"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Palembang"] = { aliases = {"cakapan Palembang"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Papua"] = { aliases = {"cakapan Papua"}, Wikipedia = true, regional_categories = "Papua", prep = "di", region = "bagian barat pulau [[Papua]]", parent = "Indonesia", } labels["Riau"] = { aliases = {"cakapan Riau"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Sumatra"] = { aliases = {"cakapan Sumatra"}, Wikipedia = true, regional_categories = "Sumatra", prep = "di", region = "pulau [[Sumatra]]", parent = "Indonesia", } labels["Surabaya"] = { aliases = {"cakapan Surabaya"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } ----Other labels go here---- labels["Van Ophuijsen"] = { aliases = {"1901-1947", "pra-1947", "ejaan Van Ophuijsen", "ejaan Belanda", "ejaan lama"}, Wikipedia = "Ejaan Van Ophuijsen", plain_categories = "id:Ragam ejaan Van Ophuijsen", } labels["Republik"] = { aliases = {"1947-1972", "ejaan Republik", "ejaan Soewandi", "Soewandi"}, Wikipedia = "Republican Spelling System", plain_categories = "id:Ragam ejaan Republik", } labels["prokem"] = { aliases = {"Prokem"}, Wiktionary = "prokem", parent = "Jakarta", region = "ragam slang bahasa Indonesia yang pada awalnya digunakan oleh {{l|id|preman}}" .. "di wilayah Jakarta dan menyebar di kalangan kaum muda secara umum pada dasawarsa 1970-an", noreg = true, sense_categories = true, } return require("Module:labels").finalize_data(labels) 18lyzgeclv6tw45jkmaiakc17n44o65 26532 26531 2026-07-07T21:50:43Z Sibiru45 115 1 ralatan matan [[:id:Modul:labels/data/lang/id]] 26531 Scribunto text/plain local labels = {} ----Dialects go here--- labels["Bandung"] = { aliases = {"cakapan Bandung"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } labels["Jakarta"] = { aliases = {"cakapan Jakarta"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } labels["Jawa"] = { aliases = {"cakapan Jawa"}, Wikipedia = true, regional_categories = "Jawa", prep = "di", region = "pulau [[Jawa]]", parent = "Indonesia", } labels["Kalimantan"] = { aliases = {"cakapan Kalimantan"}, Wikipedia = true, regional_categories = "Kalimantan", prep = "di", region = "pulau [[Kalimantan]]", parent = "Indonesia", } labels["Maluku"] = { aliases = {"cakapan Maluku"}, Wikipedia = true, regional_categories = "Maluku", prep = "di", region = "kepulauan [[Maluku]]", parent = "Indonesia", } labels["Medan"] = { aliases = {"cakapan Medan"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Padang"] = { aliases = {"cakapan Padang"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Palembang"] = { aliases = {"cakapan Palembang"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Papua"] = { aliases = {"cakapan Papua"}, Wikipedia = true, regional_categories = "Papua", prep = "di", region = "bagian barat pulau [[Papua]]", parent = "Indonesia", } labels["Riau"] = { aliases = {"cakapan Riau"}, Wikipedia = true, regional_categories = true, parent = "Sumatra", } labels["Sumatra"] = { aliases = {"cakapan Sumatra"}, Wikipedia = true, regional_categories = "Sumatra", prep = "di", region = "pulau [[Sumatra]]", parent = "Indonesia", } labels["Surabaya"] = { aliases = {"cakapan Surabaya"}, Wikipedia = true, regional_categories = true, parent = "Jawa", } ----Other labels go here---- labels["Van Ophuijsen"] = { aliases = {"1901-1947", "pra-1947", "ejaan Van Ophuijsen", "ejaan Belanda", "ejaan lama"}, Wikipedia = "Ejaan Van Ophuijsen", plain_categories = "id:Ragam ejaan Van Ophuijsen", } labels["Republik"] = { aliases = {"1947-1972", "ejaan Republik", "ejaan Soewandi", "Soewandi"}, Wikipedia = "Republican Spelling System", plain_categories = "id:Ragam ejaan Republik", } labels["prokem"] = { aliases = {"Prokem"}, Wiktionary = "prokem", parent = "Jakarta", region = "ragam slang bahasa Indonesia yang pada awalnya digunakan oleh {{l|id|preman}}" .. "di wilayah Jakarta dan menyebar di kalangan kaum muda secara umum pada dasawarsa 1970-an", noreg = true, sense_categories = true, } return require("Module:labels").finalize_data(labels) 18lyzgeclv6tw45jkmaiakc17n44o65 Citakan:singkatan matan 10 7577 26533 2025-12-27T05:25:22Z id>Swarabakti 0 26533 wikitext text/x-wiki <includeonly><i>akronim dari</i> <b>{{l|{{{1}}}|{{{2}}}|{{{3|{{{2}}}}}}|tr={{{tr|}}}|t={{{t|}}}|id={{{id|}}}|lit={{{lit|}}}}}</b></includeonly><noinclude> # {{akronim dari|id|contoh}} ---- Untuk menampilkan pengalihan tidak langsung dari baris definisi akronim ke entri untuk ragam utama dengan penjabaran lengkap. Apabila akronim tersebut punya makna tambahan yang khas dan tidak terdapat pada entri yang menjadi tujuan pengalihan, berikan penjabaran definisi selayaknya lema biasa, dan jabarkan penurunan akronimnya pada subjudul "Etimologi". </noinclude> d2iz4o67qavroiq8qxlfjxdalmyk25g 26534 26533 2026-07-07T21:53:34Z Sibiru45 115 1 ralatan matan [[:id:Templat:akronim_dari]] 26533 wikitext text/x-wiki <includeonly><i>akronim dari</i> <b>{{l|{{{1}}}|{{{2}}}|{{{3|{{{2}}}}}}|tr={{{tr|}}}|t={{{t|}}}|id={{{id|}}}|lit={{{lit|}}}}}</b></includeonly><noinclude> # {{akronim dari|id|contoh}} ---- Untuk menampilkan pengalihan tidak langsung dari baris definisi akronim ke entri untuk ragam utama dengan penjabaran lengkap. Apabila akronim tersebut punya makna tambahan yang khas dan tidak terdapat pada entri yang menjadi tujuan pengalihan, berikan penjabaran definisi selayaknya lema biasa, dan jabarkan penurunan akronimnya pada subjudul "Etimologi". </noinclude> d2iz4o67qavroiq8qxlfjxdalmyk25g 26587 26534 2026-07-07T21:59:05Z Sibiru45 115 Sibiru45 maugahakan laman [[Citakan:akronim dari]] ka [[Citakan:singkatan matan]] 26533 wikitext text/x-wiki <includeonly><i>akronim dari</i> <b>{{l|{{{1}}}|{{{2}}}|{{{3|{{{2}}}}}}|tr={{{tr|}}}|t={{{t|}}}|id={{{id|}}}|lit={{{lit|}}}}}</b></includeonly><noinclude> # {{akronim dari|id|contoh}} ---- Untuk menampilkan pengalihan tidak langsung dari baris definisi akronim ke entri untuk ragam utama dengan penjabaran lengkap. Apabila akronim tersebut punya makna tambahan yang khas dan tidak terdapat pada entri yang menjadi tujuan pengalihan, berikan penjabaran definisi selayaknya lema biasa, dan jabarkan penurunan akronimnya pada subjudul "Etimologi". </noinclude> d2iz4o67qavroiq8qxlfjxdalmyk25g 26666 26587 2026-07-08T05:20:45Z Sibiru45 115 /* */ 26666 wikitext text/x-wiki <includeonly><i>singkatan matan</i> <b>{{l|{{{1}}}|{{{2}}}|{{{3|{{{2}}}}}}|tr={{{tr|}}}|t={{{t|}}}|id={{{id|}}}|lit={{{lit|}}}}}</b></includeonly><noinclude> # {{singkatan matan|id|contoh}} ---- Untuk menampilkan pengalihan tidak langsung dari baris definisi akronim ke entri untuk ragam utama dengan penjabaran lengkap. Apabila akronim tersebut punya makna tambahan yang khas dan tidak terdapat pada entri yang menjadi tujuan pengalihan, berikan penjabaran definisi selayaknya lema biasa, dan jabarkan penurunan akronimnya pada subjudul "Etimologi". </noinclude> fvvo7zgp7495erp9tp5w87lhrw1bbzm Citakan:redlink category 10 7578 26551 2022-05-15T23:07:24Z id>Taylor 49 0 qq 26551 wikitext text/x-wiki <!-- This is a list of entries that won't be checked for redlinks. Usually, they are large entries, where redlink checking can cause module errors. -->{{#switch:{{PAGENAME}}|-ere|a|box|do|dog|heart|e|gold|green|I|iron|language|man|mies|one|smoke|sun|water|一|人|母|Spanish diminutives of given names|Common Russian verbs|Ancient Greek Swadesh list|Frequency dictionary of the modern Russian language (the Russian National Corpus)/1|Frequency dictionary of the modern Russian language (the Russian National Corpus)/8|Romance doublets|=|<!-- The last five refer to Appendix:Spanish diminutives of given names, Appendix:Common Russian verbs, Appendix:Frequency dictionary of the modern Russian language (the Russian National Corpus)/1, Appendix:Frequency dictionary of the modern Russian language (the Russian National Corpus)/8, Appendix:Romance doublets; the namespace has been stripped. -->{{#switch:{{NAMESPACE}}||Reconstruction|Appendix=<!-- This is the list of languages with redlink checking enabled. -->{{#switch:{{{1}}}|es|fi|gml|grc|iir-pro|it|pt|ru|te=<!-- testing -->{{#ifeq:{{isValidPageName|{{{2|}}}}}|valid|<!-- --><!--{{#invoke:redlink category|cat|{{{1}}}|{{{2}}}|template={{{template|-}}}}}--><!-- -->}}<!-- -->}}<!-- -->}}<!-- -->}}<!-- --><noinclude>{{dokumentasi}}</noinclude> fgwkponxdg8ad8pz51otf8yqgloix8i 26552 26551 2026-07-07T21:53:36Z Sibiru45 115 1 ralatan matan [[:id:Templat:redlink_category]] 26551 wikitext text/x-wiki <!-- This is a list of entries that won't be checked for redlinks. Usually, they are large entries, where redlink checking can cause module errors. -->{{#switch:{{PAGENAME}}|-ere|a|box|do|dog|heart|e|gold|green|I|iron|language|man|mies|one|smoke|sun|water|一|人|母|Spanish diminutives of given names|Common Russian verbs|Ancient Greek Swadesh list|Frequency dictionary of the modern Russian language (the Russian National Corpus)/1|Frequency dictionary of the modern Russian language (the Russian National Corpus)/8|Romance doublets|=|<!-- The last five refer to Appendix:Spanish diminutives of given names, Appendix:Common Russian verbs, Appendix:Frequency dictionary of the modern Russian language (the Russian National Corpus)/1, Appendix:Frequency dictionary of the modern Russian language (the Russian National Corpus)/8, Appendix:Romance doublets; the namespace has been stripped. -->{{#switch:{{NAMESPACE}}||Reconstruction|Appendix=<!-- This is the list of languages with redlink checking enabled. -->{{#switch:{{{1}}}|es|fi|gml|grc|iir-pro|it|pt|ru|te=<!-- testing -->{{#ifeq:{{isValidPageName|{{{2|}}}}}|valid|<!-- --><!--{{#invoke:redlink category|cat|{{{1}}}|{{{2}}}|template={{{template|-}}}}}--><!-- -->}}<!-- -->}}<!-- -->}}<!-- -->}}<!-- --><noinclude>{{dokumentasi}}</noinclude> fgwkponxdg8ad8pz51otf8yqgloix8i Citakan:akronim dari 10 7579 26588 2026-07-07T21:59:05Z Sibiru45 115 Sibiru45 maugahakan laman [[Citakan:akronim dari]] ka [[Citakan:singkatan matan]] 26588 wikitext text/x-wiki #ALIH [[Citakan:singkatan matan]] hhsdd344ggfzo5pnxcx3bkptekymekg Tumbung:Basa Banjar Banjar Hulu 14 7580 26616 2026-07-08T04:23:56Z Sibiru45 115 Maulah laman nang isinya ''[[Tumbung:Basa Banjar Banjar Hulu]]'' 26616 wikitext text/x-wiki [[Tumbung:Basa Banjar Banjar Hulu]] cel20hfrys3osxmrhgniyzyzufuqz0v Tumbung:Basa Banjar Banjar Kuala 14 7581 26617 2026-07-08T04:24:51Z Sibiru45 115 Maulah laman nang isinya ''[[Tumbung:Basa Banjar Banjar Kuala]]'' 26617 wikitext text/x-wiki [[Tumbung:Basa Banjar Banjar Kuala]] dtufrx1h6g7y9itiuii54x8s6kx6voj Lampiran:Glosarium 0 7582 26620 2026-04-22T14:39:27Z id>Swarabakti 0 /* S */ 26620 wikitext text/x-wiki ==A== ; {{anchor|adj.|adjective|adjektiva|Adjektiva|kata sifat}}[[adjektiva]] : Kata ; {{anchor|adv.|adverb|adverbia|Adverbia|kata keterangan}}[[adverbia]] : Kata ==K== ; {{anchor|kiasan}}[[kiasan]] : Tidak harfiah, dalam hal majas bahasa. Termasuk ke dalam kiasan adalah istilah atau ungkapan yang berupa {{glossary|metafora}} atau {{glossary|simile}} (misal, memanggil {{sebut|id|koruptor}} sebagai {{sebut|id|tikus}} atau ''seperti tikus''), atau berupa {{glossary|metonimia}} (misal, menggunakan {{sebut|id|Jakarta}} untuk merujuk pada {{sebut|id|Indonesia}}). ; {{anchor|kog.|cog.|kognat|cognate|seumpun|Kognat|kata serupa|kata sama|kata berhubungan|kata serumpun}}[[kognat]] : Kata serupa berasal dari {{l|id|leksem}} sumber yang sama dari {{l|id|bahasa moyang}}. ; {{anchor|kon.|conjunction|konjungsi|Konjungsi|kata hubung}}[[konjungsi]] : Kata ==N== ; {{anchor|n.|noun|nomina|Nomina|kata benda}}[[nomina]] : Kata yang merujuk pada [[seseorang]], sebuah [[tempat]], sebuah [[benda]] yang [[wujud]] ataupun berupa [[gagasan]]. ==P== ; {{anchor|prep.|preposition|preposisi|Preposisi|kata depan}}[[preposisi]] : Kata ; {{anchor|bor.|borrowing|borrowed|borrowed from|Pinjaman|kata pinjaman}}[[kata pinjaman|pinjaman]] : Lihat ''[[#serapan|serapan]]'' ; {{anchor|pron.|pronoun|pronomina|Pronomina|kata ganti}}[[pronomina]] : Kata ==S== ; {{anchor|kata serapan|serapan}}[[kata serapan|serapan]] : Bentuk yang diambil dari bahasa lain, alih-alih dibentuk dalam bahasa itu sendiri atau diwarisi dari leluhurnya. Serapan bisa diadopsi secara utuh, atau diadaptasi sehingga lebur ke dalam sistem kebahasaan sebuah bahasa. Misalnya, dalam bahasa Indonesia, {{sebut|id|sushi}} diserap utuh dari bahasa Jepang, sedangkan {{sebut|id|nastar}} telah lebur dan tidak lagi dapat dikenali sebagai serapan dari bahasa Belanda {{sebut|nl|ananastaart}}. Lihat pula {{glossary|serapan terjemahan}}. ==T== ; {{anchor|turunan|derivatif}}[[turunan]] : Bentuk yang diturunkan melalui proses pembentukan morfologis dalam satu bahasa. Mesti dibedakan dari {{glossary|keturunan}}, yakni bentuk yang diturunkan melalui proses perubahan lintas waktu atau pertukaran lintas bahasa. ==V== ; {{anchor|v.|verb|verba|Verba|kata kerja}}[[verba]] : Kata yang menunjukkan [[perlakuan]], [[kejadian]], atau [[keadaan]]. Proses [[infleksi]] verba umumnya disebut [[konjugasi]]. i446cv2y3uz0n4r8hcue3nvqk1e9hh8 26621 26620 2026-07-08T05:00:40Z Sibiru45 115 1 ralatan matan [[:id:Lampiran:Glosarium]] 26620 wikitext text/x-wiki ==A== ; {{anchor|adj.|adjective|adjektiva|Adjektiva|kata sifat}}[[adjektiva]] : Kata ; {{anchor|adv.|adverb|adverbia|Adverbia|kata keterangan}}[[adverbia]] : Kata ==K== ; {{anchor|kiasan}}[[kiasan]] : Tidak harfiah, dalam hal majas bahasa. Termasuk ke dalam kiasan adalah istilah atau ungkapan yang berupa {{glossary|metafora}} atau {{glossary|simile}} (misal, memanggil {{sebut|id|koruptor}} sebagai {{sebut|id|tikus}} atau ''seperti tikus''), atau berupa {{glossary|metonimia}} (misal, menggunakan {{sebut|id|Jakarta}} untuk merujuk pada {{sebut|id|Indonesia}}). ; {{anchor|kog.|cog.|kognat|cognate|seumpun|Kognat|kata serupa|kata sama|kata berhubungan|kata serumpun}}[[kognat]] : Kata serupa berasal dari {{l|id|leksem}} sumber yang sama dari {{l|id|bahasa moyang}}. ; {{anchor|kon.|conjunction|konjungsi|Konjungsi|kata hubung}}[[konjungsi]] : Kata ==N== ; {{anchor|n.|noun|nomina|Nomina|kata benda}}[[nomina]] : Kata yang merujuk pada [[seseorang]], sebuah [[tempat]], sebuah [[benda]] yang [[wujud]] ataupun berupa [[gagasan]]. ==P== ; {{anchor|prep.|preposition|preposisi|Preposisi|kata depan}}[[preposisi]] : Kata ; {{anchor|bor.|borrowing|borrowed|borrowed from|Pinjaman|kata pinjaman}}[[kata pinjaman|pinjaman]] : Lihat ''[[#serapan|serapan]]'' ; {{anchor|pron.|pronoun|pronomina|Pronomina|kata ganti}}[[pronomina]] : Kata ==S== ; {{anchor|kata serapan|serapan}}[[kata serapan|serapan]] : Bentuk yang diambil dari bahasa lain, alih-alih dibentuk dalam bahasa itu sendiri atau diwarisi dari leluhurnya. Serapan bisa diadopsi secara utuh, atau diadaptasi sehingga lebur ke dalam sistem kebahasaan sebuah bahasa. Misalnya, dalam bahasa Indonesia, {{sebut|id|sushi}} diserap utuh dari bahasa Jepang, sedangkan {{sebut|id|nastar}} telah lebur dan tidak lagi dapat dikenali sebagai serapan dari bahasa Belanda {{sebut|nl|ananastaart}}. Lihat pula {{glossary|serapan terjemahan}}. ==T== ; {{anchor|turunan|derivatif}}[[turunan]] : Bentuk yang diturunkan melalui proses pembentukan morfologis dalam satu bahasa. Mesti dibedakan dari {{glossary|keturunan}}, yakni bentuk yang diturunkan melalui proses perubahan lintas waktu atau pertukaran lintas bahasa. ==V== ; {{anchor|v.|verb|verba|Verba|kata kerja}}[[verba]] : Kata yang menunjukkan [[perlakuan]], [[kejadian]], atau [[keadaan]]. Proses [[infleksi]] verba umumnya disebut [[konjugasi]]. i446cv2y3uz0n4r8hcue3nvqk1e9hh8 Citakan:glossary 10 7583 26634 2025-11-24T07:29:48Z id>Swarabakti 0 26634 wikitext text/x-wiki {{#invoke:glossary|link}}<!-- --><noinclude> {{dokumentasi}} </noinclude> b10yueeyizs06pk9bgr4pt2oidio3k9 26635 26634 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Templat:glossary]] 26634 wikitext text/x-wiki {{#invoke:glossary|link}}<!-- --><noinclude> {{dokumentasi}} </noinclude> b10yueeyizs06pk9bgr4pt2oidio3k9 Modul:glossary 828 7584 26636 2025-11-24T07:35:40Z id>Swarabakti 0 26636 Scribunto text/plain local export = {} local get_ids_module = "Module:get IDs" local glossary_data_module = "Module:glossary/data" local parameters_module = "Module:parameters" local string_nowiki_module = "Module:string/nowiki" local anchor_encode = mw.uri.anchorEncode local require = require --[==[ 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 normalize_anchor(...) normalize_anchor = require(get_ids_module).normalize_anchor return normalize_anchor(...) end local function nowiki(...) nowiki = require(string_nowiki_module) return nowiki(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end --[==[ 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 data local function get_data() data, get_data = mw.loadData(glossary_data_module), nil return data end function export.def(frame) local required_default_ = {required = true, default = ""} local args = process_params(frame:getParent().args, { [1] = required_default_, [2] = required_default_, }) local term = args[1] return "; <span id=\"" .. anchor_encode(term) .. "\">" .. term .. "</span>\n: " .. args[2] end local function get_link(formatted_anchor, text, anchor) return "[[Lampiran:Glosarium#" .. nowiki(formatted_anchor) .. "|" .. (text or anchor) .. "]]" end function export.link(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, [2] = true, }) local anchor, text = args[1], args[2] local formatted_anchor = normalize_anchor(anchor) if (data or get_data())[formatted_anchor] then return get_link(formatted_anchor, text, anchor) end local lower_anchor = anchor:ulower() formatted_anchor = normalize_anchor(lower_anchor) local link = get_link(formatted_anchor, text, anchor) if data[formatted_anchor] or formatted_anchor == "" then return link end mw.log("Pautan tujuan bagi " .. lower_anchor .. (lower_anchor ~= anchor and " or " .. anchor or "") .. " tidak tersedia di halaman Lampiran:Glosarium.") return link .. "[[Category:Halaman yang dipranalakan pada tujuan yang tak tersedia di Lampiran:Glosarium|" .. lower_anchor .. "]]" end return export 9e8zo5mkbn89non3cqx11p0wr77jys2 26637 26636 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:glossary]] 26636 Scribunto text/plain local export = {} local get_ids_module = "Module:get IDs" local glossary_data_module = "Module:glossary/data" local parameters_module = "Module:parameters" local string_nowiki_module = "Module:string/nowiki" local anchor_encode = mw.uri.anchorEncode local require = require --[==[ 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 normalize_anchor(...) normalize_anchor = require(get_ids_module).normalize_anchor return normalize_anchor(...) end local function nowiki(...) nowiki = require(string_nowiki_module) return nowiki(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end --[==[ 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 data local function get_data() data, get_data = mw.loadData(glossary_data_module), nil return data end function export.def(frame) local required_default_ = {required = true, default = ""} local args = process_params(frame:getParent().args, { [1] = required_default_, [2] = required_default_, }) local term = args[1] return "; <span id=\"" .. anchor_encode(term) .. "\">" .. term .. "</span>\n: " .. args[2] end local function get_link(formatted_anchor, text, anchor) return "[[Lampiran:Glosarium#" .. nowiki(formatted_anchor) .. "|" .. (text or anchor) .. "]]" end function export.link(frame) local args = process_params(frame:getParent().args, { [1] = {required = true, default = ""}, [2] = true, }) local anchor, text = args[1], args[2] local formatted_anchor = normalize_anchor(anchor) if (data or get_data())[formatted_anchor] then return get_link(formatted_anchor, text, anchor) end local lower_anchor = anchor:ulower() formatted_anchor = normalize_anchor(lower_anchor) local link = get_link(formatted_anchor, text, anchor) if data[formatted_anchor] or formatted_anchor == "" then return link end mw.log("Pautan tujuan bagi " .. lower_anchor .. (lower_anchor ~= anchor and " or " .. anchor or "") .. " tidak tersedia di halaman Lampiran:Glosarium.") return link .. "[[Category:Halaman yang dipranalakan pada tujuan yang tak tersedia di Lampiran:Glosarium|" .. lower_anchor .. "]]" end return export 9e8zo5mkbn89non3cqx11p0wr77jys2 Modul:get IDs 828 7585 26638 2025-07-08T09:12:21Z 2001:448A:2012:5211:48A0:D7D5:5991:1001 ←Membuat halaman berisi 'local export = {} local parameters_module = "Module:parameters" local string_nowiki_module = "Module:string/nowiki" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local template_parser_module = "Module:template parser" local anchor_encode = mw.uri.anchorEncode local byte = string.byte local concat = table.concat local format = string.format local get -- Defined below. local gsub = string.gsub local lower = string.l...' 26638 Scribunto text/plain local export = {} local parameters_module = "Module:parameters" local string_nowiki_module = "Module:string/nowiki" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local template_parser_module = "Module:template parser" local anchor_encode = mw.uri.anchorEncode local byte = string.byte local concat = table.concat local format = string.format local get -- Defined below. local gsub = string.gsub local lower = string.lower local new_title = mw.title.new local normalize_anchor -- Defined below. local pcall = pcall local require = require --[==[ 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 class_else_type(...) class_else_type = require(template_parser_module).class_else_type return class_else_type(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function nowiki(...) nowiki = require(string_nowiki_module) return nowiki(...) end local function parse(...) parse = require(template_parser_module).parse return parse(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end --[==[ 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 parameters_data local function get_parameters_data() parameters_data, get_parameters_data = mw.loadData("Module:parameters/data"), nil return parameters_data end local template_names local function get_template_names() template_names = require(table_module).listToSet{ "anchor", "etymid", "etymon", "senseid", "trans-see", "trans-top", "trans-top-also" } get_template_names = nil return template_names end function export.normalize_anchor(str) return decode_entities(anchor_encode(str)) end normalize_anchor = export.normalize_anchor local function handle_heading(name, seen, ids) -- Repeated IDs are disambiguated by appending _N, where N is an -- incremented integer. When determining this, ASCII characters are case- -- insensitive, but all other characters are case-sensitive. local check = lower(name) if seen[check] then local i, name_lower = 1, check repeat i = i + 1 check = format("%s_%d", name_lower, i) until not seen[check] name = format("%s_%d", name, i) end seen[check] = true ids[#ids + 1] = name end local function pseudo_percent_encode(ch) return format(".%02X", byte(ch)) end local function handle_template(name, node, ids) local args, success = node:get_arguments() success, args = pcall(process_params, args, (parameters_data or get_parameters_data())[name]) if not success then return elseif name == "anchor" then args = args[1] for i = 1, #args do ids[#ids + 1] = normalize_anchor(args[i]) end return end local id1, id2 if name == "trans-top" or name == "trans-see" or name == "trans-top-also" then id1 = "Translations-" if name == "trans-top" then id2 = args.id or args[1] else id2 = args.id.default or args[1] end else id1 = args[1]:getCanonicalName() .. ": " id2 = args[name == "etymon" and "id" or 2] end if id2 then ids[#ids + 1] = normalize_anchor(id1 .. id2) end end function export.get(pagename, force_transclusion) local page, seen, ids = new_title(pagename), {}, {} for node in parse((page.redirectTarget or page):getContent() or error("Could not retrieve the page content of \"" .. pagename .. "\".")):iterate_nodes() do local node_class = class_else_type(node) if node_class == "heading" then local name = node:get_anchor() if name ~= nil then handle_heading(name, seen, ids) -- Headings get a fallback ID, which uses pseudo-percent-encoding -- where "%" is replaced by "." (e.g. "!" is ".21"). local name2 = gsub(name, "[^%w%-.:_]", pseudo_percent_encode) if name2 ~= name then handle_heading(name2, seen, ids) end end elseif node_class == "template" then local name = node:get_name(nil, force_transclusion) if (template_names or get_template_names())[name] then handle_template(name, node, ids) end end end return ids end get = export.get -- Used by [[MediaWiki:Gadget-OrangeLinks.js]]. function export.show(frame) local output = {} for i, pagename in ipairs(frame.args) do output[i] = nowiki(concat(get(pagename, true), " ")) end return concat(output, "\n\n") end return export d8zn8g5odxk8ronhfi0bazeah9zg01h 26639 26638 2026-07-08T05:00:42Z Sibiru45 115 1 ralatan matan [[:id:Modul:get_IDs]] 26638 Scribunto text/plain local export = {} local parameters_module = "Module:parameters" local string_nowiki_module = "Module:string/nowiki" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local template_parser_module = "Module:template parser" local anchor_encode = mw.uri.anchorEncode local byte = string.byte local concat = table.concat local format = string.format local get -- Defined below. local gsub = string.gsub local lower = string.lower local new_title = mw.title.new local normalize_anchor -- Defined below. local pcall = pcall local require = require --[==[ 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 class_else_type(...) class_else_type = require(template_parser_module).class_else_type return class_else_type(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function nowiki(...) nowiki = require(string_nowiki_module) return nowiki(...) end local function parse(...) parse = require(template_parser_module).parse return parse(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end --[==[ 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 parameters_data local function get_parameters_data() parameters_data, get_parameters_data = mw.loadData("Module:parameters/data"), nil return parameters_data end local template_names local function get_template_names() template_names = require(table_module).listToSet{ "anchor", "etymid", "etymon", "senseid", "trans-see", "trans-top", "trans-top-also" } get_template_names = nil return template_names end function export.normalize_anchor(str) return decode_entities(anchor_encode(str)) end normalize_anchor = export.normalize_anchor local function handle_heading(name, seen, ids) -- Repeated IDs are disambiguated by appending _N, where N is an -- incremented integer. When determining this, ASCII characters are case- -- insensitive, but all other characters are case-sensitive. local check = lower(name) if seen[check] then local i, name_lower = 1, check repeat i = i + 1 check = format("%s_%d", name_lower, i) until not seen[check] name = format("%s_%d", name, i) end seen[check] = true ids[#ids + 1] = name end local function pseudo_percent_encode(ch) return format(".%02X", byte(ch)) end local function handle_template(name, node, ids) local args, success = node:get_arguments() success, args = pcall(process_params, args, (parameters_data or get_parameters_data())[name]) if not success then return elseif name == "anchor" then args = args[1] for i = 1, #args do ids[#ids + 1] = normalize_anchor(args[i]) end return end local id1, id2 if name == "trans-top" or name == "trans-see" or name == "trans-top-also" then id1 = "Translations-" if name == "trans-top" then id2 = args.id or args[1] else id2 = args.id.default or args[1] end else id1 = args[1]:getCanonicalName() .. ": " id2 = args[name == "etymon" and "id" or 2] end if id2 then ids[#ids + 1] = normalize_anchor(id1 .. id2) end end function export.get(pagename, force_transclusion) local page, seen, ids = new_title(pagename), {}, {} for node in parse((page.redirectTarget or page):getContent() or error("Could not retrieve the page content of \"" .. pagename .. "\".")):iterate_nodes() do local node_class = class_else_type(node) if node_class == "heading" then local name = node:get_anchor() if name ~= nil then handle_heading(name, seen, ids) -- Headings get a fallback ID, which uses pseudo-percent-encoding -- where "%" is replaced by "." (e.g. "!" is ".21"). local name2 = gsub(name, "[^%w%-.:_]", pseudo_percent_encode) if name2 ~= name then handle_heading(name2, seen, ids) end end elseif node_class == "template" then local name = node:get_name(nil, force_transclusion) if (template_names or get_template_names())[name] then handle_template(name, node, ids) end end end return ids end get = export.get -- Used by [[MediaWiki:Gadget-OrangeLinks.js]]. function export.show(frame) local output = {} for i, pagename in ipairs(frame.args) do output[i] = nowiki(concat(get(pagename, true), " ")) end return concat(output, "\n\n") end return export d8zn8g5odxk8ronhfi0bazeah9zg01h modal kontol doang 0 7586 26669 2026-07-08T07:21:15Z Swarabakti 404 [[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [id] 26669 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # [[mudal]] [[palir]] haja kou5kvd5lkwvjbqp9l57dhbx7k4vyk3 26670 26669 2026-07-08T07:22:47Z Swarabakti 404 /* Basa Indunisia */ 26670 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-ragam-}} * {{l|bjn|mokondo}} (''singkatan'') {{-adj-|id}} # [[mudal]] [[palir]] haja kf6u0c9nuo0na29uwcnolhld7r724wk