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", "[[")
:gsub("\2", "]]")
:gsub("%[", "[")
:gsub("]", "]")
-- 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", "[[")
:gsub("\2", "]]")
:gsub("%[", "[")
:gsub("]", "]")
-- 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 (' → '),
-- as they contain #, which causes the numeric character reference to be
-- misparsed (wa'a → wa'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 = "]" .. link.display .. "["
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, " " .. 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 <
-- and > 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),
["<"] = "<",
[">"] = ">",
}
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%;\"> / </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> → <code><nowiki>displayed text</nowiki></code>
* <code><nowiki>[[page and displayed text]]</nowiki></code> → <code><nowiki>page and displayed text</nowiki></code>
* <code><nowiki>[[Kategori:id:Lema|WORD]]</nowiki></code> → ''(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 .. " § " .. 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 (' → '),
-- as they contain #, which causes the numeric character reference to be
-- misparsed (wa'a → wa'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 = "]" .. link.display .. "["
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, " " .. 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 <
-- and > 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),
["<"] = "<",
[">"] = ">",
}
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%;\"> / </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> → <code><nowiki>displayed text</nowiki></code>
* <code><nowiki>[[page and displayed text]]</nowiki></code> → <code><nowiki>page and displayed text</nowiki></code>
* <code><nowiki>[[Kategori:id:Lema|WORD]]</nowiki></code> → ''(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 .. " § " .. 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;",
["λοπαδοτεμαχοσελαχογαλεοκρανιολειψανοδριμυποτριμματοσιλφιοκαραβομελιτοκατακεχυμενοκιχλεπικοσσυφοφαττοπεριστεραλεκτρυονοπτοκεφαλλιοκιγκλοπελειολαγῳοσιραιοβαφητραγανοπτερύγων"] = "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;",
["λοπαδοτεμαχοσελαχογαλεοκρανιολειψανοδριμυποτριμματοσιλφιοκαραβομελιτοκατακεχυμενοκιχλεπικοσσυφοφαττοπεριστεραλεκτρυονοπτοκεφαλλιοκιγκλοπελειολαγῳοσιραιοβαφητραγανοπτερύγων"] = "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 > by a call to encode_entities() in
-- make_link() in [[Module:links]] (near the bottom of the function).
display = display:gsub(">", "")
-- '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(">", "")
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 > by a call to encode_entities() in
-- make_link() in [[Module:links]] (near the bottom of the function).
display = display:gsub(">", "")
-- '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(">", "")
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 = {
["\""] = """,
["&"] = "&",
["'"] = "'",
["<"] = "<",
[">"] = ">",
["\194\160"] = " ",
}, 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 = {
["\""] = """,
["&"] = "&",
["'"] = "'",
["<"] = "<",
[">"] = ">",
["\194\160"] = " ",
}, 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 = "!"
end
elseif ch == ":" then
if sub(_str, loc + 1, loc + 2) == "//" then
return ":"
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 ":"
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 "-"
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 = "_"
end
elseif ch == "~" then
if sub(_str, loc + 1, loc + 2) == "~~" then
esc_next, esc_next2 = false, "~"
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 = "!"
end
elseif ch == ":" then
if sub(_str, loc + 1, loc + 2) == "//" then
return ":"
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 ":"
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 "-"
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 = "_"
end
elseif ch == "~" then
if sub(_str, loc + 1, loc + 2) == "~~" then
esc_next, esc_next2 = false, "~"
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, ":", chunks_len) -- :
)
return concat(chunks, ":"), 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, ":"), 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, ":"), 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("{{" .. concat(output, "|") .. "}}") -- {{ | }}
)
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("{{{" .. concat({name, default}, "|") .. "}}}") -- {{{ | }}}
)
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("<" .. tag .. ">")
)
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, ":", chunks_len) -- :
)
return concat(chunks, ":"), 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, ":"), 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, ":"), 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("{{" .. concat(output, "|") .. "}}") -- {{ | }}
)
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("{{{" .. concat({name, default}, "|") .. "}}}") -- {{{ | }}}
)
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("<" .. tag .. ">")
)
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