ဝိက်ရှေန်နရဳ
mnwwiktionary
https://mnw.wiktionary.org/wiki/%E1%80%9D%E1%80%AD%E1%80%80%E1%80%BA%E1%80%9B%E1%80%BE%E1%80%B1%E1%80%94%E1%80%BA%E1%80%94%E1%80%9B%E1%80%B3:%E1%80%99%E1%80%AF%E1%80%80%E1%80%BA%E1%80%9C%E1%80%AD%E1%80%80%E1%80%BA%E1%80%90%E1%80%99%E1%80%BA
MediaWiki 1.45.0-wmf.9
case-sensitive
မဳဒဳယာ
တၟေင်
ဓရီုကျာ
ညးလွပ်
ညးလွပ် ဓရီုကျာ
ဝိက်ရှေန်နရဳ
ဝိက်ရှေန်နရဳ ဓရီုကျာ
ဝှာင်
ဝှာင် ဓရီုကျာ
မဳဒဳယာဝဳကဳ
မဳဒဳယာဝဳကဳ ဓရီုကျာ
ထာမ်ပလိက်
ထာမ်ပလိက် ဓရီုကျာ
ရီု
ရီု ဓရီုကျာ
ကဏ္ဍ
ကဏ္ဍ ဓရီုကျာ
အဆက်လက္ကရဴ
အဆက်လက္ကရဴ ဓရီုကျာ
ကာရန်
ကာရန် ဓရီုကျာ
အဘိဓာန်
အဘိဓာန် ဓရီုကျာ
ဗီုပြင်သိုင်တၟိ
ဗီုပြင်သိုင်တၟိ ဓရီုကျာ
TimedText
TimedText talk
မဝ်ဂျူ
မဝ်ဂျူ ဓရီုကျာ
မဝ်ဂျူ:IPA
828
772
157716
133489
2025-07-10T10:34:56Z
咽頭べさ
33
157716
Scribunto
text/plain
local export = {}
local force_cat = false -- for testing
local pron_qualifier_module = "Module:pron qualifier"
local qualifier_module = "Module:qualifier"
local references_module = "Module:references"
local string_utilities_module = "Module:string utilities"
local syllables_module = "Module:syllables"
local utilities_module = "Module:utilities"
local m_data = mw.loadData("Module:IPA/data")
local m_str_utils = require(string_utilities_module)
local m_syllables -- [[Module:syllables]]; loaded below if needed
local m_symbols = mw.loadData("Module:IPA/data/symbols")
local concat = table.concat
local decode_entities = m_str_utils.decode_entities
local find = string.find
local gmatch = m_str_utils.gmatch
local gsub = string.gsub
local insert = table.insert
local len = m_str_utils.len
local listToText = mw.text.listToText
local match = string.match
local sub = string.sub
local u = m_str_utils.char
local ugsub = m_str_utils.gsub
local umatch = m_str_utils.match
local usub = m_str_utils.sub
local namespace = mw.title.getCurrentTitle().namespace
local is_content_page = namespace == 0 or namespace == 118
local function track(page)
require("Module:debug/track")("IPA/" .. page)
return true
end
local function process_maybe_split_categories(split_output, categories, prontext, lang, errtext)
if split_output ~= "raw" then
if categories[1] then
categories = require(utilities_module).format_categories(categories, lang, nil, nil, force_cat)
else
categories = ""
end
end
if split_output then -- for use of IPA in links, etc.
if errtext then
return prontext, categories, errtext
else
return prontext, categories
end
else
return prontext .. (errtext or "") .. categories
end
end
--[==[
Format a line of one or more IPA pronunciations as {{tl|IPA}} would do it, i.e. with a preceding {"IPA:"} followed by
the word {"key"} linking to an Appendix page describing the language's phonology, and with an added category
{{cd|<var>lang</var> terms with IPA pronunciation}}. Other than the extra preceding text and category, this is identical
to {format_IPA_multiple()}, and the considerations described there in the documentation apply here as well. There is a
single parameter `data`, an object with the following fields:
* `lang`: Object representing the language of the pronunciations, which is used when adding cleanup categories for
pronunciations with invalid phonemes; for determining how many syllables the pronunciations have in them, in order to
add a category such as [[:Category:Italian 2-syllable words]] (for certain languages only); for adding a category
{{cd|<var>lang</var> terms with IPA pronunciation}}; and for determining the proper sort keys for categories. Unlike
for {format_IPA_multiple()}, `lang` may not be {nil}.
* `items`: List of pronunciations, in exactly the same format as for {format_IPA_multiple()}.
* `err`: If not {nil}, a string containing an error message to use in place of the link to the language's phonology.
* `separator`: The default separator to use when separating formatted items. Defaults to {", "}. Does not apply to the
first item, where the default separator is always the empty string. Overridden by the per-item `separator` field in
`items`.
* `sort_key`: Explicit sort key used for categories.
* `no_count`: Suppress adding a {#-syllable words} category such as [[:Category:Italian 2-syllable words]]. Note that
only certain languages add such categories to begin with, because it depends on knowing how to count syllables in a
given language, which depends on the phonology of the language. Also, this does not suppress the addition of cleanup
or other categories. If you need them suppressed, use `split_output` to return the categories separately and ignore
them.
* `split_output`: If not given, the return value is a concatenation of the formatted pronunciation and formatted
categories. Otherwise, two values are returned: the formatted pronunciation and the categories. If `split_output` is
the value {"raw"}, the categories are returned in list form, where the list elements are a combination of category
strings and category objects of the form suitable for passing to {format_categories()} in [[Module:utilities]]. If
`split_output` is any other value besides {nil}, the categories are returned as a pre-formatted concatenated string.
* `include_langname`: If specified, prefix the result with the language name, followed by a colon.
* `q`: {nil} or a list of left qualifiers (as in {{tl|q}}) to display at the beginning, before the formatted
pronunciations and preceding {"IPA:"}.
* `qq`: {nil} or a list of right qualifiers to display after all formatted pronunciations.
* `a`: {nil} or a list of left accent qualifiers (as in {{tl|a}}) to display at the beginning, before the formatted
pronunciations and preceding {"IPA:"}.
* `aa`: {nil} or a list of right accent qualifiers to display after all formatted pronunciations.
]==]
function export.format_IPA_full(data)
if type(data) ~= "table" or data.getCode then
error("Must now supply a table of arguments to format_IPA_full(); first argument should be that table, not a language object")
end
local lang = data.lang
local items = data.items
local err = data.err
local separator = data.separator
local sort_key = data.sort_key
local no_count = data.no_count
local split_output = data.split_output
local q = data.q
local qq = data.qq
local a = data.a
local aa = data.aa
local include_langname = data.include_langname
local hasKey = m_data.langs_with_infopages
if not lang or not lang.getCode then
error("Must specify language to format_IPA_full()")
end
local langname = lang:getCanonicalName()
local prefix_text
if err then
prefix_text = '<span class="error">' .. err .. '</span>'
else
if hasKey[lang:getCode()] then
prefix_text = "Appendix:" .. langname .. " pronunciation"
else
prefix_text = "wikipedia:" .. langname .. " phonology"
end
prefix_text = "[[" .. prefix_text .. "|key]]"
end
local prefix = "[[ဝိက်ရှေန်နရဳ:ဂကောံအက္ခရ်ဗွဟ်ရမျာၚ်|IPA]]<sup>(" .. prefix_text .. ")</sup>: "
local IPAs, categories = export.format_IPA_multiple(lang, items, separator, no_count, "raw")
if is_content_page then
insert(categories, {
cat ="ဝေါဟာ" .. langname .. "ပ္တိတ်ရမျာၚ် IPA ဂမၠိုၚ်",
sort_key = sort_key
})
end
local prontext = prefix .. IPAs
if q and q[1] or qq and qq[1] or a and a[1] or aa and aa[1] then
prontext = require(pron_qualifier_module).format_qualifiers {
lang = lang,
text = prontext,
q = q,
qq = qq,
a = a,
aa = aa,
}
end
if include_langname then
prontext = langname .. ": " .. prontext
end
return process_maybe_split_categories(split_output, categories, prontext, lang)
end
local function split_phonemic_phonetic(pron)
local reconstructed, phonemic, phonetic = match(pron, "^(%*?)(/.-/)%s+(%[.-%])$")
if reconstructed then
return reconstructed .. phonemic, reconstructed .. phonetic
else
return pron, nil
end
end
local function determine_repr(pron)
local reconstructed
-- remove initial asterisk before representation marks, used on some Reconstruction pages
if sub(pron, 1, 1) == "*" then
reconstructed = true
pron = sub(pron, 2)
end
local opening = match(pron, "^.[\128-\191]*")
local data = m_data.representation_types[opening]
if data then
local closing = data[2]
if data and match(pron, closing .. "$", #opening + 1) then
return data[1], opening, closing, reconstructed
end
end
return nil, "", "", reconstructed
end
local function hasInvalidSeparators(transcription)
if umatch(transcription, "%.[ˈˌ]") or umatch(transcription, "[ˈˌ][ .]") then
return true
else
return false
end
end
--[==[
Format a line of one or more bare IPA pronunciations (i.e. without any preceding {"IPA:"} and without adding to a
category {{cd|<var>lang</var> terms with IPA pronunciation}}). Individual pronunciations are formatted using
{format_IPA()} and are combined with separators, qualifiers, pre-text, post-text, etc. to form a line of pronunciations.
Parameters accepted are:
* `lang` is an object representing the language of the pronunciations, which is used when adding cleanup categories for
pronunciations with invalid phonemes; for determining how many syllables the pronunciations have in them, in order to
add a category such as [[:Category:Italian 2-syllable words]] (for certain languages only); and for computing the
proper sort keys for categories. `lang` may be {nil}.
* `items` is a list of pronunciations, each of which is an object with the following properties:
** `pron`: the pronunciation, in the same format as is accepted by {format_IPA()}, i.e. it should be either phonemic
(surrounded by {/.../}), phonetic (surrounded by {[...]}), orthographic (surrounded by {⟨...⟩}) or a rhyme
(beginning with a hyphen);
** `pretext`: text to display directly before the formatted pronunciation, inside of any qualifiers or accent
qualifiers;
** `posttext`: text to display directly after the formatted pronunciation, inside of any qualifiers or accent
qualifiers;
** `q` or `qualifiers`: {nil} or a list of left qualifiers (as in {{tl|q}}) to display before the formatted
pronunciation; note that `qualifiers` is deprecated;
** `qq`: {nil} or a list of right qualifiers to display after the formatted pronunciation;
** `a`: {nil} or a list of left accent qualifiers (as in {{tl|a}}) to display before the formatted pronunciation;
** `aa`: {nil} or a list of right accent qualifiers to after before the formatted pronunciation;
** `refs`: {nil} or a list of references or reference specs to add after the pronunciation and any posttext and
qualifiers; the value of a list item is either a string containing the reference text (typically a call to a
citation template such as {{tl|cite-book}}, or a template wrapping such a call), or an object with fields `text`
(the reference text), `name` (the name of the reference, as in {{cd|<nowiki><ref name="foo">...</ref></nowiki>}}
or {{cd|<nowiki><ref name="foo" /></nowiki>}}) and/or `group` (the group of the reference, as in
{{cd|<nowiki><ref name="foo" group="bar">...</ref></nowiki>}} or
{{cd|<nowiki><ref name="foo" group="bar"/></nowiki>}}); this uses a parser function to format the reference
appropriately and insert a footnote number that hyperlinks to the actual reference, located in the
{{cd|<nowiki><references /></nowiki>}} section;
** `gloss`: {nil} or a gloss (definition) for this item, if different definitions have different pronunciations;
** `pos`: {nil} or a part of speech for this item, if different parts of speech have different pronunciations;
** `separator`: the separator text to insert directly before the formatted pronunciation and all qualifiers, accent
qualifiers and pre-text; defaults to the outer `separator` parameter.
* `separator`: The default separator to use when separating formatted items. Defaults to {", "}. Does not apply to the
first item, where the default separator is always the empty string. Overridden by the per-item `separator` field in
`items`.
* `no_count`: Suppress adding a {#-syllable words} category such as [[:Category:Italian 2-syllable words]]. Note that
only certain languages add such categories to begin with, because it depends on knowing how to count syllables in a
given language, which depends on the phonology of the language. Also, this does not suppress the addition of cleanup
categories. If you need them suppressed, use `split_output` to return the categories separately and ignore them.
* `split_output`: If not given, the return value is a concatenation of the formatted pronunciation and formatted
categories. Otherwise, two values are returned: the formatted pronunciation and the categories. If `split_output` is
the value {"raw"}, the categories are returned in list form, where the list elements are a combination of category
strings and category objects of the form suitable for passing to {format_categories()} in [[Module:utilities]]. If
`split_output` is any other value besides {nil}, the categories are returned as a pre-formatted concatenated string.
]==]
function export.format_IPA_multiple(lang, items, separator, no_count, split_output)
local categories = {}
separator = separator or ", "
if not lang then
track("format-multiple-nolang")
end
-- Format
if not items[1] then
if namespace == 10 then -- Template
insert(items, {pron = "/aɪ piː ˈeɪ/"})
else
insert(categories, "Pronunciation templates without a pronunciation")
end
end
local bits = {}
for i, item in ipairs(items) do
local bit
-- If the pronunciation is entirely empty, allow this and don't do anything, so that e.g. the pretext and/or
-- posttext can be specified to force something like ''unknown'' to appear in place of the pronunciation
-- (as happens e.g. when ? is used as a respelling in [[Module:ca-IPA]]; see [[guèiser]] for an example).
if item.pron == "" then
bit = ""
else
local item_categories, errtext
bit, item_categories, errtext = export.format_IPA(lang, item.pron, "raw")
bit = bit .. errtext
for _, cat in ipairs(item_categories) do
insert(categories, cat)
end
end
if item.pretext then
bit = item.pretext .. bit
end
if item.posttext then
bit = bit .. item.posttext
end
local has_qualifiers = item.q and item.q[1] or item.qq and item.qq[1] or item.qualifiers and item.qualifiers[1]
or item.a and item.a[1] or item.aa and item.aa[1]
local has_gloss_or_pos = item.gloss or item.pos
if has_qualifiers or has_gloss_or_pos then
-- FIXME: Currently we tack the gloss and POS (in that order) onto the end of the regular left qualifiers.
-- Should we do something different?
local q = item.q
if has_gloss_or_pos then
q = mw.clone(item.q) or {}
if item.gloss then
local m_qualifier = require(qualifier_module)
insert(q, m_qualifier.wrap_qualifier_css("“", "quote") .. item.gloss ..
m_qualifier.wrap_qualifier_css("”", "quote"))
end
if item.pos then
-- FIXME: Consider expanding aliases as found in [[Module:headword/data]] or similar.
insert(q, item.pos)
end
end
bit = require("Module:pron qualifier").format_qualifiers {
lang = lang,
text = bit,
q = q,
qq = item.qq,
qualifiers = item.qualifiers,
a = item.a,
aa = item.aa,
}
end
if item.note then
-- Support removed on 2024-06-15.
error("Support for `.note` has been removed; switch to `.refs` (which must be a list)")
end
if item.refs then
local refspecs = item.refs
if #refspecs > 0 then
bit = bit .. require(references_module).format_references(refspecs)
end
end
bit = (item.separator or (i == 1 and "" or separator)) .. bit
insert(bits, bit)
--[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/IPA/syntax-error]]
The length or gemination symbol should not appear after a syllable break or stress symbol. ]=]
-- The nature of the following pattern match is such that we don't have to split a combined '/.../ [...]' spec
-- into its parts in order to process.
if match(item.pron, "[.\203][\136\140]?\203[\144\145]") then -- [.ˈˌ][ːˑ]
track("syntax-error")
end
if lang then
-- Add syllable count if the language's diphthongs are listed in [[Module:syllables]].
-- Don't do this if the term has spaces, a liaison mark (‿) or isn't in mainspace.
if not no_count and namespace == 0 then
m_syllables = m_syllables or require(syllables_module)
local langcode = lang:getCode()
if m_data.langs_to_generate_syllable_count_categories[langcode] then
local phonemic, phonetic, use_it = split_phonemic_phonetic(item.pron)
local repr = determine_repr(phonemic)
if not phonetic then -- not a '/.../ [...]' combined pronunciation
if m_data.langs_to_use_phonetic_notation[langcode] then
use_it = repr == "phonetic" and phonemic or nil
else
use_it = repr == "phonemic" and phonemic or nil
end
elseif repr == "phonetic" then
use_it = phonetic
elseif repr == "phonemic" then
use_it = phonemic
end
-- Note: two uses of find with plain patterns is much faster than umatch with [ ‿].
if use_it and not (find(use_it, " ") or find(use_it, "‿")) then
local syllable_count = m_syllables.getVowels(use_it, lang)
if syllable_count then
end
end
end
end
-- The nature of hasInvalidSeparators() is such that we don't have to split a combined '/.../ [...]' spec
-- into its parts in order to process.
if lang:getCode() == "en" and hasInvalidSeparators(item.pron) then
insert(categories, "English IPA pronunciations with invalid separators")
end
end
end
return process_maybe_split_categories(split_output, categories, concat(bits), lang)
end
--[=[
Format a single IPA pronunciation, which cannot be a combined spec (such as {/.../ [...]}). This has been extracted from
{format_IPA()} to allow the latter to handle such combined specs. This works like {format_IPA()} but requires that
pre-created {err} (for error messages) and {categories} lists be passed in, and adds any generated error messages and
categories to those lists. A single value is returned, the pronunciation, which is usually the same as passed in, but
may have HTML added surrounding invalid characters so they appear in red.
]=]
local function format_one_IPA(lang, pron, err, categories)
-- Disallow wikilinks.
if match(pron, "%[%[.-%]%]") then
error("IPA input must not contain wikilinks.")
end
pron = decode_entities(pron)
-- Detect the type of transcription.
local repr, opening, closing, reconstructed = determine_repr(pron)
-- Strip any reconstruction asterisk and representation marks.
pron = sub(pron, #opening + 1 + (reconstructed and 1 or 0), -#closing - 1)
if not repr then
insert(categories, "IPA pronunciations with invalid representation marks")
-- insert(err, "invalid representation marks")
-- Removed because it's annoying when previewing pronunciation pages.
end
if pron == "" then
insert(categories, "IPA pronunciations with no pronunciation present")
end
-- Check for obsolete and nonstandard symbols
for _, symbol in ipairs(m_data.nonstandard) do
local result
for nonstandard in gmatch(pron, symbol) do
if not result then
result = {}
end
insert(result, nonstandard)
insert(categories,
{cat = "IPA pronunciations with obsolete or nonstandard characters", sort_key = nonstandard}
)
end
if result then
insert(err, "obsolete or nonstandard characters (" .. concat(result) .. ")")
break
end
end
--[[ Check for invalid symbols after removing the following:
1. wikilinks (handled above)
2. paired HTML tags
3. bolding
4. italics
5. asterisk at beginning of transcription
6. comma followed by spacing characters
7. superscripts enclosed in superscript parentheses ]]
local found_HTML
local result = gsub(pron, "<(%a+)[^>]*>([^<]+)</%1>",
function(tagName, content)
found_HTML = true
return content
end)
result = gsub(result, "'''([^']*)'''", "%1")
result = gsub(result, "''([^']*)''", "%1")
result = gsub(result, "^%*", "")
result = ugsub(result, ",%s+", "")
-- VS15
local vs15_class = "[" .. m_symbols.add_vs15 .. "]"
if umatch(pron, vs15_class) then
local vs15 = u(0xFE0E)
if find(result, vs15) then
result = gsub(result, vs15, "")
pron = gsub(pron, vs15, "")
end
pron = ugsub(pron, vs15_class, "%0" .. vs15)
end
if result ~= "" then
local suggestions = {}
for k, v in pairs(m_symbols.invalid) do
if find(result, k, 1, true) then
insert(suggestions, k .. " with " .. v)
end
end
if suggestions[1] then
suggestions = listToText(suggestions)
if is_content_page then
error("Invalid IPA: replace " .. suggestions)
else
insert(err, "replace " .. suggestions)
end
end
result = ugsub(result, "⁽[".. m_symbols.superscripts .. "]+⁾", "")
local per_lang_valid
if lang then
per_lang_valid = m_symbols.per_lang_valid[lang:getCode()]
end
per_lang_valid = per_lang_valid or ""
result = ugsub(result, "[" .. m_symbols.valid .. per_lang_valid .. "]", "")
if result ~= "" then
local category = "IPA pronunciations with invalid IPA characters"
if not is_content_page then
category = category .. "/non_mainspace"
end
insert(categories, category)
insert(err, "invalid IPA characters (" .. result .. ")")
end
end
if found_HTML then
insert(categories, "IPA pronunciations with paired HTML tags")
end
if (repr == "phonemic" or repr == "rhyme") and lang and m_data.phonemes[lang:getCode()] then
local valid_phonemes = m_data.phonemes[lang:getCode()]
local rest = pron
local phonemes = {}
while #rest > 0 do
local longestmatch, longestmatch_len = "", 0
local rest_init = sub(rest, 1, 1)
if rest_init == "(" or rest_init == ")" then
longestmatch = rest_init
longestmatch_len = 1
else
for _, phoneme in ipairs(valid_phonemes) do
local phoneme_len = len(phoneme)
if phoneme_len > longestmatch_len and usub(rest, 1, phoneme_len) == phoneme then
longestmatch = phoneme
longestmatch_len = len(longestmatch)
end
end
end
if longestmatch_len > 0 then
insert(phonemes, longestmatch)
rest = usub(rest, longestmatch_len + 1)
else
local phoneme = usub(rest, 1, 1)
insert(phonemes, "<span style=\"color: red\">" .. phoneme .. "</span>")
rest = usub(rest, 2)
insert(categories, "IPA pronunciations with invalid phonemes/" .. lang:getCode())
track("invalid phonemes/" .. phoneme)
end
end
pron = concat(phonemes)
end
return (reconstructed and "*" or "") .. opening .. pron .. closing
end
--[==[
Format an IPA pronunciation. This wraps the pronunciation in appropriate CSS classes and adds cleanup categories and
error messages as needed. The pronunciation `pron` should be either phonemic (surrounded by {/.../}), phonetic
(surrounded by {[...]}), orthographic (surrounded by {⟨...⟩}), a rhyme (beginning with a hyphen) or a combined
phonemic/phonetic spec (of the form {/.../ [...]}). `lang` indicates the language of the pronunciation and can be {nil}.
If not {nil}, and the specified language has data in [[Module:IPA/data]] indicating the allowed phonemes, then the page
will be added to a cleanup category and an error message displayed next to the outputted pronunciation. Note that {lang}
also determines sort key processing in the added cleanup categories. If `split_output` is not given, the return value is
a concatenation of the formatted pronunciation, error messages and formatted cleanup categories. Otherwise, three values
are returned: the formatted pronunciation, the cleanup categories and the concatenated error messages. If `split_output`
is the value {"raw"}, the cleanup categories are returned in list form, where the list elements are a combination of
category strings and category objects of the form suitable for passing to {format_categories()} in [[Module:utilities]].
If `split_output` is any other value besides {nil}, the cleanup categories are returned as a pre-formatted concatenated
string.
]==]
function export.format_IPA(lang, pron, split_output)
local err = {}
local categories = {}
-- `pron` shouldn't contain ref tags.
if match(pron, "\127'\"`UNIQ%-%-ref%-[%dA-F]+%-QINU`\"'\127") then
error("<ref> tags found inside pronunciation parameter.")
end
if not lang then
track("format-nolang")
end
local phonemic, phonetic = split_phonemic_phonetic(pron)
pron = format_one_IPA(lang, phonemic, err, categories)
if phonetic then
phonetic = format_one_IPA(lang, phonetic, err, categories)
pron = pron .. " " .. phonetic
end
if err[1] then
err = '<span class="previewonly error" style="font-size: small;> ' .. concat(err, ", ") .. "</span>"
else
err = ""
end
return process_maybe_split_categories(split_output, categories, '<span class="IPA">' .. pron .. "</span>", lang,
err)
end
--[==[
Format a line of one or more enPR pronunciations as {{tl|enPR}} would do it, i.e. with a preceding {"enPR:"} (linked to
[[Appendix:English pronunciation]]) followed by one or more formatted, comma-separated enPR pronunciations. The
pronunciations are formatted by wrapping them in the {{cd|AHD}} and {{cd|enPR}} CSS classes and adding any left and
right regular and accent qualifiers. In addition, the overall result is wrapped in any overall left and right regular
and accent qualifiers. There is a single parameter `data`, an object with the following fields:
* `items` is a list of enPR pronunciations, each of which is an object with the following properties:
** `pron`: the enPR pronunciation;
** `q`: {nil} or a list of left qualifiers (as in {{tl|q}}) to display before the formatted pronunciation;
** `qq`: {nil} or a list of right qualifiers to display after the formatted pronunciation;
** `a`: {nil} or a list of left accent qualifiers (as in {{tl|a}}) to display before the formatted pronunciation;
** `aa`: {nil} or a list of right accent qualifiers to after before the formatted pronunciation.
* `q`: {nil} or a list of left qualifiers (as in {{tl|q}}) to display at the beginning, before the formatted
pronunciations and preceding {"enPR:"}.
* `qq`: {nil} or a list of right qualifiers to display after all formatted pronunciations.
* `a`: {nil} or a list of left accent qualifiers (as in {{tl|a}}) to display at the beginning, before the formatted
pronunciations and preceding {"enPR:"}.
* `aa`: {nil} or a list of right accent qualifiers to display after all formatted pronunciations.
]==]
function export.format_enPR_full(data)
local prefix = "[[အဆက်လက္ကရဴ:ပ္တိတ်ရမျာၚ်အင်္ဂလိက်|enPR]]: "
local lang = require("Module:languages").getByCode("en")
local parts = {}
for _, item in ipairs(data.items) do
local part = '<span class="AHD enPR">' .. item.pron .. "</span>"
if item.q and item.q[1] or item.qq and item.qq[1] or item.a and item.a[1] or item.aa and item.aa[1] then
part = require("Module:pron qualifier").format_qualifiers {
lang = lang,
text = part,
q = item.q,
qq = item.qq,
a = item.a,
aa = item.aa,
}
end
insert(parts, part)
end
local prontext = prefix .. concat(parts, ", ")
if data.q and data.q[1] or data.qq and data.qq[1] or data.a and data.a[1] or data.aa and data.aa[1] then
prontext = require(pron_qualifier_module).format_qualifiers {
lang = lang,
text = prontext,
q = data.q,
qq = data.qq,
a = data.a,
aa = data.aa,
}
end
return prontext
end
return export
n5h2a5unm5z1t8jpzrnpssu2vzc6gb5
မဝ်ဂျူ:etymology
828
911
157715
148162
2025-07-10T10:31:59Z
咽頭べさ
33
157715
Scribunto
text/plain
local export = {}
-- For testing
local force_cat = false
local function term_error(terminfo)
if terminfo.lang:hasType("family") then
if terminfo.term and terminfo.term ~= "-" then
require("Module:debug/track")("etymology/family/has-term")
end
terminfo.term = "-"
end
return terminfo
end
local function create_link(terminfo, template_name)
local link = ""
if terminfo.term == "-" then
--[=[
[[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]]
]=]
require("Module:debug/track")(template_name .. "/no-term")
else
-- mw.log(terminfo.term)
link = require("Module:links").full_link(terminfo, "term")
if (link ~= "") then link = " " .. link end
end
return link
end
function export.process_and_create_link(terminfo, template_name)
terminfo = term_error(terminfo)
return create_link(terminfo, template_name or "derived")
end
function export.get_display_and_cat_name(source, raw)
local display, cat_name
if source:getCode() == "und" then
display = "ဟွံသောင်ကၠး"
cat_name = "ဘာသာတၞဟ်ဂမၠိုၚ်"
elseif source:getCode() == "mul" then
display = "[[w:Translingualism|translingual]]"
cat_name = "Translingual"
elseif source:getCode() == "mul-tax" then
display = "[[w:taxonomic name|taxonomic name]]"
cat_name = "taxonomic names"
else
display = raw and source:getCanonicalName() or source:makeWikipediaLink()
cat_name = source:getDisplayForm()
end
return display, cat_name
end
function export.insert_source_cat_get_display(data)
local categories, lang, source = data.categories, data.lang, data.source
local display, cat_name = export.get_display_and_cat_name(source, data.raw)
if lang and not data.nocat then
-- Add the category, but only if there is a current language
if not categories then
categories = {}
end
local langname = lang:getFullName()
-- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`.
-- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a
-- category 'Latin terms derived from Latin'.
if lang:getCode() == source:getCode() or lang:getFullCode() == source:getCode() then
table.insert(categories,"ဝေါဟာ" .. langname .. "မကလေၚ်လွဳလဝ်အပ္ဍဲဝေါဟာ" .. langname .. "ဂမၠိုၚ်")
else
table.insert(categories,"ဝေါဟာ" .. langname .. (data.borrowing_type or "ကၠုၚ်နူ") .. "ဝေါဟာ" ..
cat_name .. "ဂမၠိုၚ်")
end
end
return display, categories
end
function export.format_source(data)
local lang, sort_key = data.lang, data.sort_key
-- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]]
if sort_key then
require("Module:debug/track")("etymology/sortkey")
end
local display, categories = export.insert_source_cat_get_display(data)
if lang and not data.nocat then
-- Format categories, but only if there is a current language; {{cog}} currently gets no categories
categories = require("Module:utilities").format_categories(categories, lang, sort_key, nil,
data.force_cat or force_cat)
else
categories = ""
end
return "<span class=\"etyl\">" .. display .. categories .. "</span>"
end
-- Internal implementation of {{cognate|...}} template
function export.format_cognate(data)
return export.format_derived {
terminfo = data.terminfo,
sort_key = data.sort_key,
template_name = "cognate",
}
end
-- Internal implementation of {{derived|...}} template
function export.format_derived(data)
local lang, terminfo, sort_key, nocat, template_name =
data.lang, data.terminfo, data.sort_key, data.nocat, data.template_name
return export.format_source {
lang = lang,
source = terminfo.lang,
sort_key = sort_key,
nocat = nocat,
borrowing_type = data.borrowing_type,
force_cat = data.force_cat,
} .. export.process_and_create_link(terminfo, template_name)
end
do
-- Generate the non-ancestor error message.
local function showLanguage(lang)
local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode())
if lang:hasType("etymology-only") then
retval = retval .. (" (an etymology-only language whose regular parent is %s)"):format(
showLanguage(lang:getParent()))
end
return retval
end
-- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if not.
function export.check_ancestor(lang, otherlang)
-- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up
-- the module link code appropriately (June 2024) but the remaining logic is untouched.
if lang:hasAncestor(otherlang) or mw.title.getCurrentTitle().nsText == "ထာမ်ပလိက်" then
return
end
local ancestors, postscript = lang:getAncestors()
local etymModuleLink = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or ""
local moduleLink = "[[Module:"
.. require("Module:languages").getDataModuleName(lang:getFullCode())
.. "]]"
if not ancestors[1] then
postscript = showLanguage(lang) .. " has no ancestors."
else
local ancestorList = table.concat(
require("Module:fun").map(
showLanguage,
ancestors),
" and ")
postscript = ("The ancestor%s of %s %s %s."):format(
ancestors[2] and "s" or "", lang:getCanonicalName(),
ancestors[2] and "are" or "is", ancestorList)
end
error(("%s is not set as an ancestor of %s in %s%s. %s")
:format(showLanguage(otherlang), showLanguage(lang), etymModuleLink, moduleLink, postscript))
end
end
-- Internal implementation of {{inherited|...}} template
function export.format_inherited(data)
local lang, terminfo, sort_key, nocat = data.lang, data.terminfo, data.sort_key, data.nocat
local source = terminfo.lang
local categories = {}
if not nocat then
table.insert(categories, "ဝေါဟာ" .. lang:getFullName() .. "ဂွံလဝ်အာဲကၟာဲနူဝေါဟာ" .. source:getCanonicalName() .. "ဂမၠိုၚ်")
end
local link = export.process_and_create_link(terminfo, "inherited")
export.check_ancestor(lang, source)
return export.format_source {
lang = lang,
source = source,
sort_key = sort_key,
categories = categories,
nocat = nocat,
force_cat = data.force_cat,
} .. link
end
function export.insert_borrowed_cat(categories, lang, source)
local category
-- Do the same check as in insert_source_cat_get_display() (inverted).
if not (lang:getCode() == source:getCode() or lang:getFullCode() == source:getCode()) then
-- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not
-- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source().
category = "လွဳလဝ် နူဝေါဟာ" .. source:getDisplayForm()
end
if category then
table.insert(categories, "ဝေါဟာ" .. lang:getFullName() .. category .. "ဂမၠိုၚ်")
end
end
-- Internal implementation of {{borrowed|...}} template.
function export.format_borrowed(data)
local lang, terminfo, sort_key, nocat = data.lang, data.terminfo, data.sort_key, data.nocat
local source = terminfo.lang
local categories = {}
if not nocat then
export.insert_borrowed_cat(categories, lang, source)
end
return export.format_source {
lang = lang,
source = source,
sort_key = sort_key,
categories = categories,
nocat = nocat,
force_cat = data.force_cat,
} .. export.process_and_create_link(terminfo, "borrowed")
end
return export
4833scw7ijxfrzduqx5pf68ysgnd3m6
မဝ်ဂျူ:category tree
828
1140
157638
157603
2025-07-09T12:58:19Z
咽頭べさ
33
157638
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("ဗီုပြင်သိုင်တၟိ") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%ဂမၠိုၚ်]]: %ဂမၠိုၚ်"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[ကဏ္ဍ:%ဂမၠိုၚ်|%ဂမၠိုၚ်]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%ဂမၠိုၚ်|%ဂမၠိုၚ်]]"):format(umbrella, sortkey))
else
insert(categories, ("[[ကဏ္ဍ:%ဂမၠိုၚ်|%ဂမၠိုၚ်]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[ကဏ္ဍ:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[ကဏ္ဍ:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[ကဏ္ဍ:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[ကဏ္ဍ:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[ကဏ္ဍ:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:ကဏ္ဍ:%ဂမၠိုၚ်]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above)
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
mkmppi91nmw4moiufxqp9ipzdi00hdt
157640
157638
2025-07-09T13:06:07Z
咽頭べさ
33
157640
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("ဗီုပြင်သိုင်တၟိ") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[%s|%s]]"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, (" [[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[ကဏ္ဍ:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[ကဏ္ဍ:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[ကဏ္ဍ:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[ကဏ္ဍ:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[ကဏ္ဍ:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:ကဏ္ဍ:%ဂမၠိုၚ်]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above)
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
dgnthr52ynh0san16snxkr4v804mjhp
157641
157640
2025-07-09T13:11:02Z
咽頭べさ
33
157641
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("ဗီုပြင်သိုင်တၟိ") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[%s|%s]]"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, (" [[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[ကဏ္ဍ:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[ကဏ္ဍ:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[ကဏ္ဍ:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[ကဏ္ဍ:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[ကဏ္ဍ:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:ကဏ္ဍ:%]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above)
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
ocbi55dma4h8glbajvk9xo1gfamp8av
157642
157641
2025-07-09T13:28:23Z
咽頭べさ
33
157642
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible" style="float: right; clear: both; margin: 0 0 .5em 1em;"
! Newest and oldest pages
|-
| id="recent-additions" style="font-size:0.9em;" | '''မုက်လိက်တၟိအိုတ်မပလေဝ်ဒါန်လဝ်နူ[[mw:Manual:Categorylinks table#cl_timestamp|ကဏ္ဍလေန်ပ္တိုန်တၟိ]]:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''မုက်လိက်တြေံအိုတ်မပလေဝ်ဒါန်လဝ်လက္ကရဴအိုတ်:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[Category:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[Category:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[Category:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[Category:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[Category:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:Category:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
if not hugeCategory then
insert(boxes, show_pagelist(current))
end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
rhpu0rx2guosa12giw321md4hix9oep
157643
157642
2025-07-09T13:33:07Z
咽頭べさ
33
157643
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible" style="float: right; clear: both; margin: 0 0 .5em 1em;"
! မုက်လိက်တၟိကဵုတြေံအိုတ်
|-
| id="recent-additions" style="font-size:0.9em;" | '''မုက်လိက်တၟိအိုတ်မပလေဝ်ဒါန်လဝ်နူ[[mw:Manual:Categorylinks table#cl_timestamp|ကဏ္ဍလေန်ပ္တိုန်တၟိ]]:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''မုက်လိက်တြေံအိုတ်မပလေဝ်ဒါန်လဝ်လက္ကရဴအိုတ်:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[Category:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[Category:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[Category:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[Category:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[Category:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:Category:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
if not hugeCategory then
insert(boxes, show_pagelist(current))
end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
fe5h8pf0go10qacho9nmppervgk3928
157646
157643
2025-07-09T13:47:11Z
咽頭べさ
33
157646
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[Category:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[Category:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[Category:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[Category:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[Category:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:Category:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
if not hugeCategory then
insert(boxes, show_pagelist(current))
end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
os9nhhm49tjmnqviasc0gcb9t1vy197
157647
157646
2025-07-09T13:48:24Z
咽頭べさ
33
မကလေၚ်ပလီုထောံ[[Special:Diff/157646|157646]]နူကဵု[[Special:Contributions/咽頭べさ|咽頭べさ]] ([[User talk:咽頭べさ|ဓရီုကျာ]])မပလေဝ်ဒါန်လဝ်
157647
Scribunto
text/plain
-- Prevent substitution.
if mw.isSubsting() then
return require("Module:unsubst")
end
local export = {}
local category_tree_submodule_prefix = "Module:category tree/"
local category_tree_styles_css = "Module:category tree/styles.css"
local m_str_utils = require("Module:string utilities")
local m_template_parser = require("Module:template parser")
local m_utilities = require("Module:utilities")
local ceil = math.ceil
local class_else_type = m_template_parser.class_else_type
local concat = table.concat
local deep_copy = require("Module:table").deepCopy
local full_url = mw.uri.fullUrl
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local log10 = math.log10 or require("Module:math").log10
local new_title = mw.title.new
local pages_in_category = mw.site.stats.pagesInCategory
local parse = m_template_parser.parse
local remove_comments = require("Module:string/removeComments")
local sort = table.sort
local split = m_str_utils.split
local string_compare = require("Module:string/compare")
local trim = m_str_utils.trim
local uupper = m_str_utils.upper
local yesno = require("Module:yesno")
local current_frame = mw.getCurrentFrame()
local current_title = mw.title.getCurrentTitle()
local namespace = current_title.namespace
local poscatboiler_subsystem = "poscatboiler"
local extra_args_error = "Extra arguments to {{((}}auto cat{{))}} are not allowed for this category."
-- Generates a sortkey for a numeral `n`, adding leading zeroes to avoid the "1, 10, 2, 3" sorting problem. `max_n` is the greatest expected value of `n`, and is used to determine how many leading zeroes are needed. If not supplied, it defaults to the number of languages.
function export.numeral_sortkey(n, max_n)
max_n = max_n or require("Module:list of languages").count()
return ("#%%0%dd"):format(ceil(log10(max_n + 1))):format(n)
end
function export.split_lang_label(title_text)
local getByCanonicalName = require("Module:languages").getByCanonicalName
-- Progressively remove a word from the potential canonical name until it
-- matches an actual canonical name.
local words = split(title_text, " ", true)
for i = #words - 1, 1, -1 do
local lang = getByCanonicalName(concat(words, " ", 1, i))
if lang then
return lang, concat(words, " ", i + 1)
end
end
return nil, title_text
end
local function show_error(text)
return require("Module:message box").maintenance(
"red",
"[[File:Ambox warning pn.svg|50px]]",
"This category is not defined in Wiktionary's category tree.",
text
)
end
-- Show the text that goes at the very top right of the page.
local function show_topright(current)
return current.getTopright and current:getTopright() or nil
end
local function link_box(content)
return ("<div class=\"noprint plainlinks\" style=\"float: right; clear: both; margin: 0 0 .5em 1em; background: var(--wikt-palette-paleblue, #f9f9f9); border: 1px var(--border-color-base, #aaaaaa) solid; margin-top: -1px; padding: 5px; font-weight: bold;\">%s</div>"):format(content)
end
local function show_editlink(current)
return link_box(("[%s စၟတ်သမ္တီပလေဝ်ဒါန်ကဏ္ဍ]"):format(tostring(full_url(current:getDataModule(), "action=edit"))))
end
function show_related_changes()
local title = current_title.fullText
return link_box(("[%s <span title=\"Recent edits and other changes to pages in %s\">အပြံၚ်လှာဲလက္ကရဴအိုတ်</span>]"):format(
tostring(full_url("Special:RecentChangesLinked", {
target = title,
showlinkedto = 0,
})),
title
))
end
local function show_pagelist(current)
local namespace = "namespace="
local info = current:getInfo()
local lang_code = info.code
if info.label == "citations" or info.label == "citations of undefined terms" then
namespace = namespace .. "Citations"
elseif lang_code then
local lang = require("Module:languages").getByCode(lang_code, true)
if lang then
-- Proto-Norse (gmq-pro) is the probably language with a code ending in -pro
-- that's intended to have mostly non-reconstructed entries.
if (lang_code:find("%-pro$") and lang_code ~= "gmq-pro") or lang:hasType("reconstructed") then
namespace = namespace .. "ဗီုပြင်သိုင်တၟိ"
elseif lang:hasType("appendix-constructed") then
namespace = namespace .. "အဆက်လက္ကရဴ"
end
end
elseif info.label:match("ထာမ်ပလိက်") then
namespace = namespace .. "ထာမ်ပလိက်"
elseif info.label:match("မဝ်ဂျူ") then
namespace = namespace .. "မဝ်ဂျူ"
elseif info.label:match("^ဝိက်ရှေန်နရဳ") or info.label:match("^မုက်လိက်") then
namespace = ""
end
return ([=[
{| id="newest-and-oldest-pages" class="wikitable mw-collapsible" style="float: right; clear: both; margin: 0 0 .5em 1em;"
! မုက်လိက်တၟိကဵုတြေံအိုတ်
|-
| id="recent-additions" style="font-size:0.9em;" | '''မုက်လိက်တၟိအိုတ်မပလေဝ်ဒါန်လဝ်နူ[[mw:Manual:Categorylinks table#cl_timestamp|ကဏ္ဍလေန်ပ္တိုန်တၟိ]]:'''
%s
|-
| id="oldest-pages" style="font-size:0.9em;" | '''မုက်လိက်တြေံအိုတ်မပလေဝ်ဒါန်လဝ်လက္ကရဴအိုတ်:'''
%s
|}]=]):format(
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=categoryadd
order=descending]=]
):format(current_title.text, namespace)
),
current_frame:extensionTag(
"DynamicPageList",
([=[
category=%s
%s
count=10
mode=ordered
ordermethod=lastedit
order=ascending]=]
):format(current_title.text, namespace)
)
)
end
-- Show navigational "breadcrumbs" at the top of the page.
local function show_breadcrumbs(current)
local steps = {}
-- Start at the current label and move our way up the "chain" from child to parent, until we can't go further.
while current do
local category, display_name, nocap
if type(current) == "string" then
category = current
display_name = current:gsub("^ကဏ္ဍ:", "")
else
if not current.getCategoryName then
error("Internal error: Bad format in breadcrumb chain structure, probably a misformatted value for `parents`: " ..
mw.dumpObject(current))
end
category = "ကဏ္ဍ:" .. current:getCategoryName()
display_name, nocap = current:getBreadcrumbName()
end
if not nocap then
display_name = mw.getContentLanguage():ucfirst(display_name)
end
insert(steps, 1, ("[[:%s|%s]]"):format(category, display_name))
-- Move up the "chain" by one level.
if type(current) == "string" then
current = nil
else
current = current:getParents()
end
if current then
current = current[1].name
end
end
local templateStyles = require("Module:TemplateStyles")(category_tree_styles_css)
local ol = mw.html.create("ol")
for i, step in ipairs(steps) do
local li = mw.html.create("li")
if i ~= 1 then
local span = mw.html.create("span")
:attr("aria-hidden", "true")
:addClass("ts-categoryBreadcrumbs-separator")
:wikitext(" » ")
li:node(span)
end
li:wikitext(step)
ol:node(li)
end
return templateStyles .. tostring(mw.html.create("div")
:attr("role", "navigation")
:attr("aria-label", "Breadcrumb")
:addClass("ts-categoryBreadcrumbs")
:node(ol))
end
local function show_also(current)
local also = current._info.also
if also and #also > 0 then
return ('<div style="margin-top:-1em;margin-bottom:1.5em">%s</div>'):format(require("Module:also").main(also))
end
return nil
end
-- Show a short description text for the category.
local function show_description(current)
return current.getDescription and current:getDescription() or nil
end
local function show_appendix(current)
local appendix = current.getAppendix and current:getAppendix()
return appendix and ("ယဝ်ရထပ်နွံပၟိက်မိက်ဂွံတီဏီတှ်ေ၊ ဆက်ဗဵုအာ [[%s]]။"):format(appendix) or nil
end
local function sort_children(child1, child2)
return string_compare(uupper(child1.sort), uupper(child2.sort))
end
-- Show a list of child categories.
local function show_children(current)
local children = current.getChildren and current:getChildren() or nil
if not children then
return nil
end
sort(children, sort_children)
local children_list = {}
for _, child in ipairs(children) do
local child_name, child_pagetitle = child.name
if type(child_name) == "string" then
child_pagetitle = child_name
else
child_pagetitle = "ကဏ္ဍ:" .. child_name:getCategoryName()
end
if new_title(child_pagetitle).exists then
insert(children_list, ("* [[:%s]]: %s"):format(
child_pagetitle,
child.description or
type(child_name) == "string" and child_name:gsub("^ကဏ္ဍ:", "") .. "." or
child_name:getDescription("child")
))
end
end
return concat(children_list, "\n")
end
-- Show a table of contents with links to each letter in the language's script.
local function show_TOC(current)
local titleText = current_title.text
local inCategoryPages = pages_in_category(titleText, "pages")
local inCategorySubcats = pages_in_category(titleText, "subcats")
local TOC_type
-- Compute type of table of contents required.
if inCategoryPages > 2500 or inCategorySubcats > 2500 then
TOC_type = "full"
elseif inCategoryPages > 200 or inCategorySubcats > 200 then
TOC_type = "normal"
else
-- No (usual) need for a TOC if all pages or subcategories can fit on one page;
-- but allow this to be overridden by a custom TOC handler.
TOC_type = "none"
end
if current.getTOC then
local TOC_text = current:getTOC(TOC_type)
if TOC_text ~= true then
return TOC_text or nil
end
end
if TOC_type ~= "none" then
local templatename = current:getTOCTemplateName()
local TOC_template
if TOC_type == "full" then
-- This category is very large, see if there is a "full" version of the TOC.
local TOC_template_full = new_title(templatename .. "/full")
if TOC_template_full.exists then
TOC_template = TOC_template_full
end
end
if not TOC_template then
local TOC_template_normal = new_title(templatename)
if TOC_template_normal.exists then
TOC_template = TOC_template_normal
end
end
if TOC_template then
return current_frame:expandTemplate{title = TOC_template.text, args = {}}
end
end
return nil
end
-- Show the "catfix" that adds language attributes and script classes to the page.
local function show_catfix(current)
local lang, sc = current:getCatfixInfo()
return lang and m_utilities.catfix(lang, sc) or nil
end
-- Show the parent categories that the current category should be placed in.
local function show_categories(current, categories)
local parents = current.getParents and current:getParents() or nil
if not parents then
return nil
end
for _, parent in ipairs(parents) do
local parent_name = parent.name
local sortkey = type(parent.sort) == "table" and parent.sort:makeSortKey() or parent.sort
if type(parent_name) == "string" then
insert(categories, ("[[%s|%s]]"):format(parent_name, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(parent_name:getCategoryName(), sortkey))
end
end
-- Also put the category in its corresponding "umbrella" or "by language" category.
local umbrella = current:getUmbrella()
if umbrella then
-- FIXME: use a language-neutral sorting function like the Unicode Collation Algorithm.
local sortkey = current._lang and current._lang:getCanonicalName() or current:getCategoryName()
sortkey = require("Module:languages").getByCode("en", true):makeSortKey(sortkey)
if type(umbrella) == "string" then
insert(categories, ("[[%s|%s]]"):format(umbrella, sortkey))
else
insert(categories, ("[[Category:%s|%s]]"):format(umbrella:getCategoryName(), sortkey))
end
end
-- Check for various unwanted parser functions, which should be integrated into the category tree data instead.
-- Note: HTML comments shouldn't be removed from `content` until after this step, as they can affect the result.
local content = current_title:getContent()
if not content then
-- This happens when using [[Special:ExpandTemplates]] to call {{auto cat}} on a nonexistent category page,
-- which is needed by Benwing's create_wanted_categories.py script.
return
end
local defaultsort, displaytitle, page_has_param
for node in parse(content):iterate_nodes() do
local node_class = class_else_type(node)
if node_class == "ထာမ်ပလိက်" then
local name = node:get_name()
if name == "DEFAULTSORT:" and not defaultsort then
insert(categories, "[[Category:Pages with DEFAULTSORT conflicts]]")
defaultsort = true
elseif name == "DISPLAYTITLE:" and not displaytitle then
insert(categories,"[[Category:Pages with DISPLAYTITLE conflicts]]")
displaytitle = true
end
elseif node_class == "parameter" and not page_has_param then
insert(categories,"[[Category:Pages with raw triple-brace template parameters]]")
page_has_param = true
end
end
-- Check for raw category markup, which should also be integrated into the category tree data.
content = remove_comments(content, "BOTH")
local head = content:find("[[", 1, true)
while head do
local close = content:find("]]", head + 2, true)
if not close then
break
end
-- Make sure there are no intervening "[[" between head and close.
local open = content:find("[[", head + 2, true)
while open and open < close do
head = open
open = content:find("[[", head + 2, true)
end
local cat = content:sub(head + 2, close - 1)
local colon = cat:match("^[ _\128-\244]*[Cc][Aa][Tt][EeGgOoRrYy _\128-\244]*():")
if colon then
local pipe = cat:find("|", colon + 1, true)
if pipe ~= #cat then
local title = new_title(pipe and cat:sub(1, pipe - 1) or cat)
if title and title.namespace == 14 then
insert(categories,"[[Category:Categories with categories using raw markup]]")
break
end
end
end
head = open
end
end
local function generate_output(current)
if current then
for _, functionName in pairs{
"getBreadcrumbName",
"getDataModule",
"canBeEmpty",
"getDescription",
"getParents",
"getChildren",
"getUmbrella",
"getAppendix",
"getTOCTemplateName",
} do
if not is_callable(current[functionName]) then
require("Module:debug").track{"category tree/missing function", "category tree/missing function/" .. functionName}
end
end
end
local boxes, display, categories = {}, {}, {}
-- Categories should never show files as a gallery.
insert(categories, "__NOGALLERY__")
if current_frame:getParent():getTitle() == "ထာမ်ပလိက်:auto cat" then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍပွမမကော်ခဴ ထာမ်ပလိက်:ဗ္ဂဲအဝ်တဝ်ဂမၠိုၚ်]]")
end
-- Check if the category is empty
local totalPages = pages_in_category(current_title.text, "all")
local hugeCategory = totalPages > 1000000 -- 1 million
-- Categorize huge categories, as they cause DynamicPageList to time out and make the category inaccessible.
if hugeCategory then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍၝောံယာဲဂမၠိုၚ်]]")
end
-- Are the parameters valid?
if not current then
insert(categories, "[[Category:Categories that are not defined in the category tree]]")
insert(categories, totalPages == 0 and "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]" or nil)
insert(display, show_error(
"Double-check the category name for typos. <br>" ..
"[[Special:Search/Category: " .. current_title.text:gsub("^.+:", ""):gsub(" ", "~2 ") .. '~2|Search existing categories]] to check if this category should be created under a different name (for example, "Fruits" instead of "Fruit"). <br>' ..
"To add a new category to Wiktionary's category tree, please consult " .. current_frame:expandTemplate{title = "section link", args = {
"Help:Category#How_to_create_a_category",
}} .. "."))
-- Exit here, as all code beyond here relies on current not being nil
return concat(categories, "") .. concat(display, "\n\n"), true
end
-- Does the category have the correct name?
local currentName = current:getCategoryName()
local correctName = current_title.text == currentName
if not correctName then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍမနွံကဵုယၟုဟွံဒးရးဂမၠိုၚ်]]")
insert(display, show_error(("Based on the data in the category tree, this category should be called '''[[:Category:%s]]'''."):format(currentName)))
end
-- Add cleanup category for empty categories.
local canBeEmpty = current:canBeEmpty()
if canBeEmpty and correctName then
insert(categories, " __EXPECTUNUSEDCATEGORY__")
elseif totalPages == 0 then
insert(categories, "[[ကဏ္ဍ:ကဏ္ဍသၠးဒၟံၚ်ဂမၠိုၚ်]]")
end
if current:isHidden() then
insert(categories, "__HIDDENCAT__")
end
-- Put all the float-right stuff into a <div> that does not clear, so that float-left stuff like the breadcrumbs and
-- description can go opposite the float-right stuff without vertical space.
insert(boxes, "<div style=\"float: right;\">")
insert(boxes, show_topright(current))
insert(boxes, show_editlink(current))
insert(boxes, show_related_changes())
-- Show pagelist, unless it's a huge category (since they can't use DynamicPageList - see above).
if not hugeCategory then
insert(boxes, show_pagelist(current))
end
insert(boxes, "</div>")
-- Generate the displayed information
insert(display, show_breadcrumbs(current))
insert(display, show_also(current))
insert(display, show_description(current))
insert(display, show_appendix(current))
insert(display, show_children(current))
insert(display, show_TOC(current))
insert(display, show_catfix(current))
insert(display, '<br class="clear-both-in-vector-2022-only">')
show_categories(current, categories)
return concat(boxes, "\n") .. "\n" .. concat(display, "\n\n") .. concat(categories, "")
end
--[==[
List of handler functions that try to match the page name. A handler should return the name of a submodule to
[[Module:category tree]] and an info table which is passed as an argument to the submodule. If a handler does not
recognize the page name, it should return nil. Note that the order of handlers matters!
]==]
local handlers = {}
-- Thesaurus per-language category
insert(handlers, function(title)
local code, label = title:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Topic per-language category
insert(handlers, function(title)
local code, label = title:match("^(%l[%a-]*%a):(.+)")
if code then
return poscatboiler_subsystem, {label = title, raw = true}
end
end)
-- Lect category e.g. for [[:Category:New Zealand English]] or [[:Category:Issime Walser]]
insert(handlers, function(title, args)
local lect = args.lect or args.dialect
if lect ~= "" and yesno(lect, true) then -- Same as boolean in [[Module:parameters]].
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end
end)
-- poscatboiler per-language label, e.g. [[Category:English non-lemma forms]]
insert(handlers, function(title, args)
local lang, label = export.split_lang_label(title)
if not lang then
return
end
local baseLabel, script = label:match("(.+) in (.-) script$")
if script and baseLabel ~= "ဝေါဟာ" then
local scriptObj = require("Module:scripts").getByCanonicalName(script)
if scriptObj then
return poscatboiler_subsystem, {label = baseLabel, code = lang:getCode(), sc = scriptObj:getCode(), args = args}
end
end
return poscatboiler_subsystem, {label = label, code = lang:getCode(), args = args}
end)
-- poscatboiler label umbrella category
insert(handlers, function(title, args)
local label = title:match("(.+) by language$")
if label then
-- The poscatboiler code will appropriately lowercase if needed.
return poscatboiler_subsystem, {label = label, args = args}
end
end)
-- poscatboiler raw handlers
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args, raw = true}
end)
-- poscatboiler umbrella handlers without 'by language'
insert(handlers, function(title, args)
return poscatboiler_subsystem, {label = title, args = args}
end)
function export.show(frame)
local args, other_args = require("Module:parameters").process(frame:getParent().args, {
["also"] = {type = "title", sublist = "comma without whitespace", namespace = 14}
}, true)
if args.also then
for k, arg in next, args.also do
args.also[k] = arg.prefixedText
end
end
for k, arg in next, other_args do
other_args[k] = trim(arg)
end
if namespace == 10 then -- Template
return "(This template should be used on pages in the [[Help:Namespaces#Category|Category:]] namespace.)"
elseif namespace ~= 14 then -- Category
error("This template/module can only be used on pages in the [[mw:Help:Namespaces#Category|Category:]] namespace.")
end
local first_fail_args_handled, first_fail_cattext
-- Go through each handler in turn. If a handler doesn't recognize the format of the category, it will return nil,
-- and we will consider the next handler. Otherwise, it returns a template name and arguments to call it with, but
-- even then, that template might return an error, and we need to consider the next handler. This happens, for
-- example, with the category "CAT:Mato Grosso, Brazil", where "Mato" is the name of a language, so the poscatboiler
-- per-language label handler fires and tries to find a label "Grosso, Brazil". This throws an error, and
-- previously, this blocked fruther handler consideration, but now we check for the error and continue checking
-- handlers; eventually, the topic umbrella handler will fire and correctly handle the category.
for _, handler in ipairs(handlers) do
-- Use a new title object and args table for each handler, to keep them isolated.
local submodule, info = handler(current_title.text, deep_copy(other_args))
if submodule then
info.also = deep_copy(args.also)
require("Module:debug").track("auto cat/" .. submodule)
-- `failed` is true if no match was found.
submodule = require(category_tree_submodule_prefix .. submodule)
local cattext, failed = generate_output(submodule.main(info))
if failed then
if not first_fail_cattext then
first_fail_cattext = cattext
first_fail_args_handled = info.args and true or false
end
elseif not info.args and next(other_args) then
error(extra_args_error)
else
return cattext
end
end
end
-- If there were no matches, throw an error if any arguments were given, or otherwise return the cattext
-- from the first fail encountered. The final handlers call the boilers unconditionally, so there should
-- always be something to return.
if not first_fail_args_handled and next(other_args) then
error(extra_args_error)
end
return first_fail_cattext
end
-- TODO: new test entrypoint.
return export
fe5h8pf0go10qacho9nmppervgk3928
မဝ်ဂျူ:category tree/poscatboiler
828
1144
157651
157542
2025-07-09T14:19:55Z
咽頭べさ
33
157651
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
error("No label was specified.")
end
self:initCommon()
if not self._data then
error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local langs_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
repeat
if langs_with_modules[obj:getCode()] then
local module = lang_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
until not obj or seen[obj:getCode()]
end
-- Then check lang-independent labels.
if not self._data then
local labels = lang_independent_data["LABELS"]
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
error("Internal error: `desc` must be a string, number, function, callable table or nil; received a " .. desc_type)
end
desc = desc{
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
error("Internal error: the value returned by `desc` must be a string or nil; received a " .. desc_type)
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "This is an umbrella category. It contains no dictionary entries, but only other, language-specific categories, which in turn contain relevant terms in a given language."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb
else
ret = self._data.umbrella and self._data.umbrella.breadcrumb
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " in " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return mw.getCurrentFrame():expandTemplate{title = template_obj.text, args = {}}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "en"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Latn"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(sccode, tocname))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s"):format(sccode, tocname))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._lang:getCanonicalName() .. " " .. self._info.label
if self._sc then
ret = ret .. " in " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. " by language"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "ကဏ္ဍ:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^terms with (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec)
if spec == false then
return nil
end
return self:substitute_template_specs(spec or parent_spec)
end
function Category:canonicalize_parents_children(cats, is_children)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil)
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil)
-- Get the sortkey.
local sortkey = cat.sort
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang)
sortkey.sc = self:inherit_spec(sortkey.sc, sc)
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^ကဏ္ဍ:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^ကဏ္ဍ:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "terms in " .. self._sc:getCanonicalName() .. " script"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
else
parents = self._data.parents
end
ret = self:canonicalize_parents_children(parents)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
error(("Internal error: Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, label .. lang:getCanonicalName().. "ဂမၠိုၚ်")
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
error("Internal error: This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
rc8d22p952qrj96rpeqk5jp616b7hbg
157652
157651
2025-07-09T15:19:09Z
咽頭べさ
33
157652
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local expand_template = require("Module:frame").expandTemplate
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
error("No label was specified.")
end
self:initCommon()
if not self._data then
error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local langs_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
repeat
if langs_with_modules[obj:getCode()] then
local module = lang_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
until not obj or seen[obj:getCode()]
end
-- Then check lang-independent labels.
if not self._data then
local labels = lang_independent_data["LABELS"]
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
error("Internal error: `desc` must be a string, number, function, callable table or nil; received a " .. desc_type)
end
desc = desc{
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
error("Internal error: the value returned by `desc` must be a string or nil; received a " .. desc_type)
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "This is an umbrella category. It contains no dictionary entries, but only other, language-specific categories, which in turn contain relevant terms in a given language."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb
else
ret = self._data.umbrella and self._data.umbrella.breadcrumb
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " ပ္ဍဲ " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return expand_template{title = template_obj.text}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "mnw"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Mymr"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(sccode, tocname))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(langcode, tocname))
insert(default_toc_templates_to_check, ("%s-%s"):format(sccode, tocname))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._info.label .. self._lang:getCanonicalName()
if self._sc then
ret = ret .. " ပ္ဍဲ " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. "ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "ကဏ္ဍ:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^ဝေါဟာမနွံ (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec)
if spec == false then
return nil
end
return self:substitute_template_specs(spec or parent_spec)
end
function Category:canonicalize_parents_children(cats, is_children)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil)
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil)
-- Get the sortkey.
local sortkey = cat.sort
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang)
sortkey.sc = self:inherit_spec(sortkey.sc, sc)
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^Category:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^ကဏ္ဍ:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "ဝေါဟာအပ္ဍဲ" .. self._sc:getCanonicalName() .. "ဂမၠိုၚ်"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
else
parents = self._data.parents
end
ret = self:canonicalize_parents_children(parents)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
error(("Internal error: Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, label .. lang:getCanonicalName())
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
error("Internal error: This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
8uznlvc0e85wxsrt4n69s2i54xnk6wl
157653
157652
2025-07-09T15:23:39Z
咽頭べさ
33
157653
Scribunto
text/plain
local lang_independent_data = require("Module:category tree/data")
local lang_specific_module = "Module:category tree/lang"
local lang_specific_module_prefix = lang_specific_module .. "/"
local labels_utilities_module = "Module:labels/utilities"
local template_parser_module = "Module:template parser"
local concat = table.concat
local dump = mw.dumpObject
local expand_template = require("Module:frame").expandTemplate
local insert = table.insert
local is_callable = require("Module:fun").is_callable
local lcfirst = require("Module:string utilities").lcfirst
local list_to_set = require("Module:table").listToSet
local make_title = mw.title.makeTitle
local new_title = mw.title.new
local parse = require(template_parser_module).parse
local sparse_concat = require("Module:table").sparseConcat
local tostring = tostring
local type = type
local ucfirst = require("Module:string utilities").ucfirst
local uupper = require("Module:string utilities").upper
local function get_lang(...)
local _get_lang = require("Module:languages").getByCode
function get_lang(...)
return _get_lang(...) or require("Module:languages/errorGetBy").code(...)
end
return get_lang(...)
end
local function get_script(...)
local _get_script = require("Module:scripts").getByCode
function get_script(code)
return _get_script(code) or require("Module:languages/error")(code, true, "script code")
end
return get_script(...)
end
-- Category object
local Category = {}
Category.__index = Category
function Category:get_originating_info()
local originating_info = ""
if self._info.originating_label then
originating_info = " (originating from label \"" .. self._info.originating_label .. "\" in module [[" .. self._info.originating_module .. "]])"
end
return originating_info
end
local valid_keys = list_to_set{"code", "label", "sc", "raw", "args", "also", "called_from_inside", "originating_label", "originating_module"}
function Category.new(info)
for key in pairs(info) do
if not valid_keys[key] then
error("The parameter \"" .. key .. "\" was not recognized.")
end
end
local self = setmetatable({}, Category)
self._info = info
if not self._info.label then
error("No label was specified.")
end
self:initCommon()
if not self._data then
error("The " .. (self._info.raw and "raw " or "") .. "label \"" .. self._info.label .. "\" does not exist" .. self:get_originating_info() .. ".")
end
return self
end
function Category:initCommon()
local args_handled = false
if self._info.raw then
-- Check if the category exists
local raw_categories = lang_independent_data["RAW_CATEGORIES"]
self._data = raw_categories[self._info.label]
if self._data then
if self._data.lang then
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
else
-- Go through raw handlers
local data = {
category = self._info.label,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["RAW_HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
if self._data then
-- Update the label if the handler specified a canonical name for it.
if self._data.canonical_name then
self._info.canonical_name = self._data.canonical_name
end
if self._data.lang then
if type(self._data.lang) ~= "string" then
error("Received non-string value " .. dump(self._data.lang) .. " for self._data.lang, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._lang = get_lang(self._data.lang)
self._info.code = self._lang:getCode()
end
if self._data.sc then
if type(self._data.sc) ~= "string" then
error("Received non-string value " .. dump(self._data.sc) .. " for self._data.sc, label \"" .. self._info.label .. "\"" .. self:get_originating_info() .. ".")
end
self._sc = get_script(self._data.sc)
self._info.sc = self._sc:getCode()
end
end
end
else
-- Already parsed into language + label
if self._info.code then
self._lang = get_lang(self._info.code)
else
self._lang = nil
end
if self._info.sc then
self._sc = get_script(self._info.sc)
else
self._sc = nil
end
self._info.orig_label = self._info.label
if not self._lang then
-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be
-- lowercase (cf. [[:Category:Nouns by language]] with label 'nouns' with per-language [[:Category:English nouns]];
-- but [[:Category:Reddit slang by language]] with label 'Reddit slang' with per-language
-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella
-- categories, storing the original into `orig_label`, and correct it later if needed.
self._info.label = lcfirst(self._info.label)
end
-- First, check lang-specific labels and handlers if this is not an umbrella category.
if self._lang then
local langs_with_modules = require(lang_specific_module)
local obj, seen = self._lang, {}
repeat
if langs_with_modules[obj:getCode()] then
local module = lang_specific_module_prefix .. obj:getCode()
local labels_and_handlers = require(module)
if labels_and_handlers.LABELS then
self._data = labels_and_handlers.LABELS[self._info.label]
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
end
end
if not self._data and labels_and_handlers.HANDLERS then
for _, handler in ipairs(labels_and_handlers.HANDLERS) do
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
self._data, args_handled = handler(data)
if self._data then
if self._data.umbrella == nil and self._data.umbrella_parents == nil then
self._data.umbrella = false
end
self._data.module = self._data.module or module
break
end
end
end
if self._data then
break
end
end
seen[obj:getCode()] = true
obj = obj:getFamily()
until not obj or seen[obj:getCode()]
end
-- Then check lang-independent labels.
if not self._data then
local labels = lang_independent_data["LABELS"]
self._data = labels[self._info.label]
-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable
-- in umbrella categories.
if not self._data then
self._data = labels[self._info.orig_label]
if self._data then
self._info.label = self._info.orig_label
end
end
end
-- Then check lang-independent handlers.
if not self._data then
local data = {
label = self._info.label,
lang = self._lang,
sc = self._sc,
args = self._info.args or {},
called_from_inside = self._info.called_from_inside,
}
for _, handler in ipairs(lang_independent_data["HANDLERS"]) do
self._data, args_handled = handler.handler(data)
if self._data then
self._data.module = self._data.module or handler.module
break
end
end
end
end
if not args_handled and self._data and self._info.args and next(self._info.args) then
local module_text = " (handled in [[" .. (self._data.module or "UNKNOWN").. "]])"
local args_text = {}
for k, v in pairs(self._info.args) do
insert(args_text, k .. "=" .. ((type(v) == "string" or type(v) == "number") and v or dump(v)))
end
error("poscatboiler label '" .. self._info.label .. "' " .. module_text .. " doesn't accept extra args " ..
concat(args_text, ", "))
end
if self._sc and not self._lang then
error("Umbrella categories cannot have a script specified.")
end
end
function Category:convert_spec_to_string(desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
error("Internal error: `desc` must be a string, number, function, callable table or nil; received a " .. desc_type)
end
desc = desc{
lang = self._lang,
sc = self._sc,
label = self._info.label,
raw = self._info.raw,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
error("Internal error: the value returned by `desc` must be a string or nil; received a " .. desc_type)
end
local function add_obj_args(args, obj, obj_type)
if obj then
args[obj_type .. "code"] = obj:getCode()
args[obj_type .. "name"] = obj:getCanonicalName()
args[obj_type .. "disp"] = obj:getDisplayForm()
args[obj_type .. "cat"] = obj:getCategoryName()
args[obj_type .. "link"] = obj:makeCategoryLink()
end
end
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.
function Category:substitute_template_specs(desc)
-- This may end up happening twice but that's OK as the function is (usually) idempotent.
-- FIXME: Not idempotent if a preprocessed template returns wikicode.
desc = self:convert_spec_to_string(desc)
if not desc then
return nil
end
-- Populate the substitution arguments.
local args = {}
args.umbrella_msg = "This is an umbrella category. It contains no dictionary entries, but only other, language-specific categories, which in turn contain relevant terms in a given language."
args.umbrella_meta_msg = "This is an umbrella metacategory, covering a general area such as \"lemmas\", \"names\" or \"terms by etymology\". It contains no dictionary entries, but holds only umbrella (\"by language\") categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic."
add_obj_args(args, self._lang, "lang")
add_obj_args(args, self._sc, "sc")
return parse(desc, true):expand(args)
end
function Category:substitute_template_specs_in_args(args)
if not args then
return args
end
local pinfo = {}
for k, v in pairs(args) do
pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)
end
return pinfo
end
function Category:make_new(info)
info.originating_label = self._info.label
info.originating_module = self._data.module
info.called_from_inside = true
return Category.new(info)
end
function Category:getBreadcrumbName()
local ret
if self._lang or self._info.raw then
ret = self._data.breadcrumb
else
ret = self._data.umbrella and self._data.umbrella.breadcrumb
end
if not ret then
ret = self._info.label
end
if type(ret) ~= "table" then
ret = {name = ret}
end
local name = self:substitute_template_specs(ret.name)
local nocap = ret.nocap
if self._sc then
name = name .. " ပ္ဍဲ " .. self._sc:getDisplayForm()
end
return name, nocap
end
local function expand_toc_template_if(template)
local template_obj = new_title(template, 10)
if template_obj.exists then
return expand_template{title = template_obj.text}
end
return nil
end
-- Return the textual expansion of the first existing template among the given templates, first performing
-- substitutions on the template name such as replacing {{{langcode}}} with the current language's code (if any).
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,
-- treat it like a one-element list consisting of that string.
function Category:get_template_text(templates)
if templates == nil then
return nil
elseif type(templates) ~= "table" then
templates = {templates}
end
for _, template in ipairs(templates) do
if template == false then
return false
end
template = self:substitute_template_specs(template)
return expand_toc_template_if(template)
end
return nil
end
function Category:getTOC(toc_type)
-- Type "none" means everything fits on a single page; in that case, display nothing.
if toc_type == "none" then
return nil
end
local templates, fallback_templates
-- If TOC type is "full" (more than 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);
-- 3. do the default behavior, which is as follows:
-- 3a. look up a language-specific "full" template according to the current language (using English if there
-- is no current language);
-- 3b. look up a script-specific "full" template according to the first script of current language (using English
-- if there is no current language);
-- 3c. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 3d. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 3e. display nothing.
--
-- If TOC type is "normal" (between 200 and 2500 entries), do the following, in order:
-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is
-- a current language);
-- 2. do the default behavior, which is as follows:
-- 2a. look up a language-specific "normal" template according to the current language (using English if there
-- is no current language);
-- 2b. look up a script-specific "normal" template according to the first script of the current language (using
-- English if there is no current language);
-- 2c. display nothing.
local data_source
if self._lang or self._info.raw then
data_source = self._data
else
data_source = self._data.umbrella
end
if data_source then
if toc_type == "full" then
templates = data_source.toc_template_full
fallback_templates = data_source.toc_template
else
templates = data_source.toc_template
end
end
local text = self:get_template_text(templates)
if text then
return text
elseif text == false then
return nil
end
text = self:get_template_text(fallback_templates)
if text then
return text
elseif text == false then
return nil
end
local default_toc_templates_to_check = {}
local lang, sc = self:getCatfixInfo()
local langcode = lang and lang:getCode() or "mnw"
local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or "Mymr"
-- FIXME: What is toctemplateprefix used for?
local tocname = (self._data.toctemplateprefix or "") .. "categoryTOC"
if toc_type == "full" then
insert(default_toc_templates_to_check, ("%s-%s/full"):format(tocname, langcode))
insert(default_toc_templates_to_check, ("%s-%s/full"):format(tocname, sccode))
end
insert(default_toc_templates_to_check, ("%s-%s"):format(tocname, langcode))
insert(default_toc_templates_to_check, ("%s-%s"):format(tocname, sccode))
for _, toc_template in ipairs(default_toc_templates_to_check) do
local toc_template_text = expand_toc_template_if(toc_template)
if toc_template_text then
return toc_template_text
end
end
return nil
end
function Category:getInfo()
return self._info
end
function Category:getDataModule()
return self._data.module
end
function Category:canBeEmpty()
if self._lang or self._info.raw then
return self._data.can_be_empty
end
return self._data.umbrella and self._data.umbrella.can_be_empty
end
function Category:isHidden()
if self._lang or self._info.raw then
return self._data.hidden
end
return self._data.umbrella and self._data.umbrella.hidden
end
function Category:getCategoryName()
if self._info.raw then
return self._info.canonical_name or self._info.label
elseif self._lang then
local ret = self._info.label .. self._lang:getCanonicalName()
if self._sc then
ret = ret .. " ပ္ဍဲ " .. self._sc:getDisplayForm()
end
return ucfirst(ret)
end
local ret = ucfirst(self._info.label)
if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then
ret = ret .. "ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်"
end
return ret
end
function Category:getTopright()
if self._lang or self._info.raw then
return self:substitute_template_specs(self._data.topright)
end
return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)
end
function Category:display_title(displaytitle, lang)
if type(displaytitle) == "string" then
displaytitle = self:substitute_template_specs(displaytitle)
else
displaytitle = displaytitle(self:getCategoryName(), lang)
end
mw.getCurrentFrame():callParserFunction("DISPLAYTITLE", "ကဏ္ဍ:" .. displaytitle)
end
function Category:get_labels_categorizing()
local m_labels_utilities = require(labels_utilities_module)
local pos_cat_labels, sense_cat_labels, use_tlb
pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, "pos", self._lang)
local sense_label = self._info.label:match("^(.*) terms$")
if sense_label then
use_tlb = true
else
sense_label = self._info.label:match("^ဝေါဟာမနွံ (.*) senses$")
end
if not sense_label then
return nil
end
sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, "sense", self._lang)
if use_tlb then
return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)
end
local all_labels = pos_cat_labels
for k, v in pairs(sense_cat_labels) do
all_labels[k] = v
end
return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)
end
-- FIXME: this is clunky.
local function remove_lang_params(desc)
-- Simply remove a language name/code/category from the beginning of the string, but replace the language name
-- in the middle of the string with either "specific languages" or "specific-language" depending on whether the
-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,
-- in which case the category in question should supply its own umbrella description.
desc = desc:gsub("^{{{langname}}} ", "")
:gsub("{{{langname}}} %(", "specific languages (")
:gsub("{{{langname}}}([.,])", "specific languages%1")
:gsub("{{{langname}}} ", "specific-language ")
:gsub("{{{langdisp}}}", "specific languages")
:gsub("{{{langlink}}}", "specific languages")
return desc
end
function Category:getDescription(isChild)
-- Allows different text in the list of a category's children
local isChild = isChild == "child"
if self._lang or self._info.raw then
if not isChild and self._data.displaytitle then
self:display_title(self._data.displaytitle, self._lang)
end
if self._sc then
return self:getCategoryName() .. "."
end
local desc = self:substitute_template_specs(self._data.description)
if not desc then
return nil
elseif isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(self._data.preceding),
desc,
self:substitute_template_specs(self._data.additional),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
local umbrella = self._data.umbrella
if not isChild and umbrella and umbrella.displaytitle then
self:display_title(umbrella.displaytitle)
end
local desc = self:substitute_template_specs(umbrella and umbrella.description)
local has_umbrella_desc = not not desc
if not desc then
desc = self:convert_spec_to_string(self._data.description)
if desc then
desc = remove_lang_params(desc)
desc = lcfirst(desc)
desc = desc:gsub("%.$", "")
desc = "Categories with " .. desc .. "."
else
desc = "Categories with " .. self._info.label .. " in various specific languages."
end
desc = self:substitute_template_specs(desc)
end
if isChild then
return desc
end
return sparse_concat({
self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),
desc,
self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),
self:substitute_template_specs("{{{umbrella_msg}}}"),
self:substitute_template_specs(self:get_labels_categorizing()),
}, "\n\n")
end
function Category:new_sortkey(sortkey)
local sortkey_type = type(sortkey)
if sortkey_type == "string" then
sortkey = uupper(sortkey)
elseif sortkey_type == "table" then
function sortkey:makeSortKey()
local sort_func = self.sort_func
if sort_func ~= nil then
return sort_func(self.sort_base)
end
local lang = self.lang
if lang == nil then
return self.sort_base
end
lang = get_lang(lang, nil, true)
if lang == nil then
return self.sort_base
end
local sc = self.sc
if sc ~= nil then
sc = get_script(sc)
end
return lang:makeSortKey(self.sort_base, sc)
end
end
return sortkey
end
function Category:inherit_spec(spec, parent_spec)
if spec == false then
return nil
end
return self:substitute_template_specs(spec or parent_spec)
end
function Category:canonicalize_parents_children(cats, is_children)
if not cats then
return nil
elseif type(cats) == "table" then
if cats.name or cats.module then
cats = {cats}
elseif #cats == 0 then
return nil
end
else
cats = {cats}
end
local ret = {}
for _, cat in ipairs(cats) do
if type(cat) ~= "table" or not cat.name and not cat.module then
cat = {name = cat}
end
insert(ret, cat)
end
local is_umbrella = not self._lang and not self._info.raw
local table_type = is_children and "extra_children" or "parents"
for i, cat in ipairs(ret) do
local raw
if self._info.raw or is_umbrella then
raw = not cat.is_label
else
raw = cat.raw
end
local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil)
local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil)
-- Get the sortkey.
local sortkey = cat.sort
if type(sortkey) == "table" then
sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or
error("Missing .sort_base in '" .. table_type .. "' .sort table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
if sortkey.sort_func then
-- Not allowed to give a lang and/or script if sort_func is given.
local bad_spec = sortkey.lang and "lang" or sortkey.sc and "sc" or nil
if bad_spec then
error("Cannot specify both ." .. bad_spec .. " and .sort_func in '" .. table_type ..
"' .sort table for '" .. self._info.label .. "' category entry in module '" ..
(self._data.module or "unknown") .. "'")
end
else
sortkey.lang = self:inherit_spec(sortkey.lang, lang)
sortkey.sc = self:inherit_spec(sortkey.sc, sc)
end
else
sortkey = self:substitute_template_specs(sortkey)
end
local name
if cat.module then
-- A reference to a category using another category tree module.
if not cat.args then
error("Missing .args in '" .. table_type .. "' table with module=\"" .. cat.module .. "\" for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
end
name = require("Module:category tree/" .. cat.module).new(self:substitute_template_specs_in_args(cat.args))
else
name = cat.name
if not name then
error("Missing .name in " .. (is_umbrella and "umbrella " or "") .. "'" .. table_type .. "' table for '" ..
self._info.label .. "' category entry in module '" .. (self._data.module or "unknown") .. "'")
elseif type(name) == "string" then -- otherwise, assume it's a category object and use it directly
name = self:substitute_template_specs(name)
if name:find("^Category:") then
-- It's a non-poscatboiler category name.
sortkey = sortkey or is_children and name:gsub("^ကဏ္ဍ:", "") or self:getCategoryName()
else
-- It's a label.
sortkey = sortkey or is_children and name or self._info.label
name = self:make_new{
label = name, code = lang, sc = sc,
raw = raw, args = self:substitute_template_specs_in_args(cat.args)
}
end
end
end
sortkey = sortkey or is_children and " " or self._info.label
ret[i] = {
name = name,
description = is_children and self:substitute_template_specs(cat.description) or nil,
sort = self:new_sortkey(sortkey)
}
end
return ret
end
function Category:getParents()
local is_umbrella, ret = not self._lang and not self._info.raw
if self._sc then
local parent1 = self:make_new{code = self._info.code, label = "ဝေါဟာအပ္ဍဲ" .. self._sc:getCanonicalName() .. "ဂမၠိုၚ်"}
local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}
ret = {
{name = parent1, sort = self._sc:getCanonicalName()},
{name = parent2, sort = self._sc:getCanonicalName()},
}
else
local parents
if is_umbrella then
parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents
else
parents = self._data.parents
end
ret = self:canonicalize_parents_children(parents)
if not ret then
return nil
end
end
local self_cat = self:getCategoryName()
for _, parent in ipairs(ret) do
local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()
if self_cat == parent_cat then
error(("Internal error: Infinite loop would occur, as parent category '%s' is the same as the child category"):format(self_cat))
end
end
return ret
end
function Category:getChildren()
local is_umbrella = not self._lang and not self._info.raw
local children = self._data.children
local ret = {}
if not is_umbrella and children then
for _, child in ipairs(children) do
child = mw.clone(child)
if type(child) ~= "table" then
child = {name = child}
end
if not child.sort then
child.sort = child.name
end
-- FIXME, is preserving the script correct?
child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}
insert(ret, child)
end
end
local extra_children
if is_umbrella then
extra_children = self._data.umbrella and self._data.umbrella.extra_children
else
extra_children = self._data.extra_children
end
extra_children = self:canonicalize_parents_children(extra_children, "children")
if extra_children then
for _, child in ipairs(extra_children) do
insert(ret, child)
end
end
return #ret > 0 and ret or nil
end
function Category:getUmbrella()
local umbrella = self._data.umbrella
if umbrella == false or self._info.raw or not self._lang or self._sc then
return nil
end
-- If `umbrella` is a string, use that; otherwise, use the label.
return self:make_new({label = type(umbrella) == "string" and umbrella or self._info.label})
end
function Category:getAppendix()
-- FIXME, this should be customizable.
local lang, label = self._lang, self._info.label
if self._info.raw or not (lang and label) then
return nil
end
local appendix = make_title(100, label .. lang:getCanonicalName())
return appendix.exists and appendix.fullText or nil
end
function Category:getCatfixInfo()
if self._lang or self._sc or self._info.raw then
local langcode, sccode, lang, sc = self._data.catfix, self._data.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
elseif langcode == nil then -- not false
lang = self._lang
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
elseif sccode == nil then -- not false
sc = self._sc
end
return lang, sc
elseif not self._data.umbrella then
return
end
-- umbrella
local langcode, sccode, lang, sc = self._data.umbrella.catfix, self._data.umbrella.catfix_sc
if langcode then
langcode = self:substitute_template_specs(langcode)
lang = get_lang(langcode)
end
if sccode then
sccode = self:substitute_template_specs(sccode)
sc = get_script(sccode)
end
return lang, sc
end
function Category:getTOCTemplateName()
-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()
-- implements its own default algorithm.
error("Internal error: This should never get called")
end
local export = {}
function export.main(info)
local self = setmetatable({_info = info}, Category)
self:initCommon()
return self._data and self or nil
end
export.new = Category.new
return export
14fvaycpvipxm8cd09jh9kp10zirshi
မဝ်ဂျူ:category tree/data
828
1148
157688
157540
2025-07-10T05:36:58Z
咽頭べさ
33
157688
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local subpages = {
-- It should not matter much what order we do the handlers in, but topic handling historically
-- preceded "poscatboiler" handling (i.e. everything else), so keep it that way for the moment.
"lects",
"miscellaneous",
"templates",
"wiktionary maintenance",
"wiktionary users",
}
-- Import subpages
for _, subpage in ipairs(subpages) do
local datamodule = "Module:category tree/" .. subpage
local retval = require(datamodule)
if retval["LABELS"] then
for label, data in pairs(retval["LABELS"]) do
if labels[label] and not retval["IGNOREDUP"] then
error("Label " .. label .. " defined in both [["
.. datamodule .. "]] and [[" .. labels[label].module .. "]].")
end
data.module = datamodule
labels[label] = data
end
end
if retval["RAW_CATEGORIES"] then
for category, data in pairs(retval["RAW_CATEGORIES"]) do
if raw_categories[category] and not retval["IGNOREDUP"] then
error("Raw category " .. category .. " defined in both [["
.. datamodule .. "]] and [[" .. raw_categories[category].module .. "]].")
end
data.module = datamodule
raw_categories[category] = data
end
end
if retval["HANDLERS"] then
for _, handler in ipairs(retval["HANDLERS"]) do
table.insert(handlers, { module = datamodule, handler = handler })
end
end
if retval["RAW_HANDLERS"] then
for _, handler in ipairs(retval["RAW_HANDLERS"]) do
table.insert(raw_handlers, { module = datamodule, handler = handler })
end
end
end
-- Add child categories to their parents
local function add_children_to_parents(hierarchy, raw)
for key, data in pairs(hierarchy) do
local parents = data.parents
if parents then
if type(parents) ~= "table" then
parents = {parents}
end
if parents.name or parents.module then
parents = {parents}
end
for _, parent in ipairs(parents) do
if type(parent) ~= "table" or not parent.name and not parent.module then
parent = {name = parent}
end
if parent.name and not parent.module and type(parent.name) == "string" and not parent.name:find("^ကဏ္ဍ:") then
local parent_is_raw
if raw then
parent_is_raw = not parent.is_label
else
parent_is_raw = parent.raw
end
-- Don't do anything if the child is raw and the parent is lang-specific, otherwise e.g.
-- "Lemmas subcategories by language" will be listed as a child of every "LANG lemmas" category.
-- FIXME: We need to rethink this mechanism.
if not raw or parent_is_raw then
local child_hierarchy = parent_is_raw and raw_categories or labels
if child_hierarchy[parent.name] then
local child = {name = key, sort = parent.sort, raw = raw}
if child_hierarchy[parent.name].children then
table.insert(child_hierarchy[parent.name].children, child)
else
child_hierarchy[parent.name].children = {child}
end
end
end
end
end
end
end
end
add_children_to_parents(labels)
add_children_to_parents("ကဏ္ဍ:" .. raw_categories, true)
return {
LABELS = labels, RAW_CATEGORIES = raw_categories,
HANDLERS = handlers, RAW_HANDLERS = raw_handlers
}
85h8spaq6ar09mxr2cbpmejy5io631t
157689
157688
2025-07-10T05:38:29Z
咽頭べさ
33
မကလေၚ်ပလီုထောံ[[Special:Diff/157688|157688]]နူကဵု[[Special:Contributions/咽頭べさ|咽頭べさ]] ([[User talk:咽頭べさ|ဓရီုကျာ]])မပလေဝ်ဒါန်လဝ်
157689
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local subpages = {
-- It should not matter much what order we do the handlers in, but topic handling historically
-- preceded "poscatboiler" handling (i.e. everything else), so keep it that way for the moment.
"lects",
"miscellaneous",
"templates",
"wiktionary maintenance",
"wiktionary users",
}
-- Import subpages
for _, subpage in ipairs(subpages) do
local datamodule = "Module:category tree/" .. subpage
local retval = require(datamodule)
if retval["LABELS"] then
for label, data in pairs(retval["LABELS"]) do
if labels[label] and not retval["IGNOREDUP"] then
error("Label " .. label .. " defined in both [["
.. datamodule .. "]] and [[" .. labels[label].module .. "]].")
end
data.module = datamodule
labels[label] = data
end
end
if retval["RAW_CATEGORIES"] then
for category, data in pairs(retval["RAW_CATEGORIES"]) do
if raw_categories[category] and not retval["IGNOREDUP"] then
error("Raw category " .. category .. " defined in both [["
.. datamodule .. "]] and [[" .. raw_categories[category].module .. "]].")
end
data.module = datamodule
raw_categories[category] = data
end
end
if retval["HANDLERS"] then
for _, handler in ipairs(retval["HANDLERS"]) do
table.insert(handlers, { module = datamodule, handler = handler })
end
end
if retval["RAW_HANDLERS"] then
for _, handler in ipairs(retval["RAW_HANDLERS"]) do
table.insert(raw_handlers, { module = datamodule, handler = handler })
end
end
end
-- Add child categories to their parents
local function add_children_to_parents(hierarchy, raw)
for key, data in pairs(hierarchy) do
local parents = data.parents
if parents then
if type(parents) ~= "table" then
parents = {parents}
end
if parents.name or parents.module then
parents = {parents}
end
for _, parent in ipairs(parents) do
if type(parent) ~= "table" or not parent.name and not parent.module then
parent = {name = parent}
end
if parent.name and not parent.module and type(parent.name) == "string" and not parent.name:find("^ကဏ္ဍ:") then
local parent_is_raw
if raw then
parent_is_raw = not parent.is_label
else
parent_is_raw = parent.raw
end
-- Don't do anything if the child is raw and the parent is lang-specific, otherwise e.g.
-- "Lemmas subcategories by language" will be listed as a child of every "LANG lemmas" category.
-- FIXME: We need to rethink this mechanism.
if not raw or parent_is_raw then
local child_hierarchy = parent_is_raw and raw_categories or labels
if child_hierarchy[parent.name] then
local child = {name = key, sort = parent.sort, raw = raw}
if child_hierarchy[parent.name].children then
table.insert(child_hierarchy[parent.name].children, child)
else
child_hierarchy[parent.name].children = {child}
end
end
end
end
end
end
end
end
add_children_to_parents(labels)
add_children_to_parents(raw_categories, true)
return {
LABELS = labels, RAW_CATEGORIES = raw_categories,
HANDLERS = handlers, RAW_HANDLERS = raw_handlers
}
s555a5x1itcmn5f5sl4agq320wr1xxe
157690
157689
2025-07-10T05:44:57Z
咽頭べさ
33
157690
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local subpages = {
-- It should not matter much what order we do the handlers in, but topic handling historically
-- preceded "poscatboiler" handling (i.e. everything else), so keep it that way for the moment.
"topic",
"affixes and compounds",
"characters",
"entry maintenance",
"etymology",
"families",
"figures of speech",
"grammatical classes",
"lang-specific-raw",
"languages",
"lects",
"ဝေါဟာအဓိက",
"lexical properties",
"miscellaneous",
"မဝ်ဂျူ",
"names",
"non-lemma forms",
"phrases",
"pragmatic properties",
"rhymes",
"scripts",
"semantic classes",
"shortenings",
"speech acts",
"symbols",
"templates",
"terms by script",
"transliterations",
"unicode",
"wiktionary maintenance",
"wiktionary users",
"word of the day",
}
-- Import subpages
for _, subpage in ipairs(subpages) do
local datamodule = "Module:category tree/" .. subpage
local retval = require(datamodule)
if retval["LABELS"] then
for label, data in pairs(retval["LABELS"]) do
if labels[label] and not retval["IGNOREDUP"] then
error("Label " .. label .. " defined in both [["
.. datamodule .. "]] and [[" .. labels[label].module .. "]].")
end
data.module = datamodule
labels[label] = data
end
end
if retval["RAW_CATEGORIES"] then
for category, data in pairs(retval["RAW_CATEGORIES"]) do
if raw_categories[category] and not retval["IGNOREDUP"] then
error("Raw category " .. category .. " defined in both [["
.. datamodule .. "]] and [[" .. raw_categories[category].module .. "]].")
end
data.module = datamodule
raw_categories[category] = data
end
end
if retval["HANDLERS"] then
for _, handler in ipairs(retval["HANDLERS"]) do
table.insert(handlers, { module = datamodule, handler = handler })
end
end
if retval["RAW_HANDLERS"] then
for _, handler in ipairs(retval["RAW_HANDLERS"]) do
table.insert(raw_handlers, { module = datamodule, handler = handler })
end
end
end
-- Add child categories to their parents
local function add_children_to_parents(hierarchy, raw)
for key, data in pairs(hierarchy) do
local parents = data.parents
if parents then
if type(parents) ~= "table" then
parents = {parents}
end
if parents.name or parents.module then
parents = {parents}
end
for _, parent in ipairs(parents) do
if type(parent) ~= "table" or not parent.name and not parent.module then
parent = {name = parent}
end
if parent.name and not parent.module and type(parent.name) == "string" and not parent.name:find("^ကဏ္ဍ:") then
local parent_is_raw
if raw then
parent_is_raw = not parent.is_label
else
parent_is_raw = parent.raw
end
-- Don't do anything if the child is raw and the parent is lang-specific, otherwise e.g.
-- "Lemmas subcategories by language" will be listed as a child of every "LANG lemmas" category.
-- FIXME: We need to rethink this mechanism.
if not raw or parent_is_raw then
local child_hierarchy = parent_is_raw and raw_categories or labels
if child_hierarchy[parent.name] then
local child = {name = key, sort = parent.sort, raw = raw}
if child_hierarchy[parent.name].children then
table.insert(child_hierarchy[parent.name].children, child)
else
child_hierarchy[parent.name].children = {child}
end
end
end
end
end
end
end
end
add_children_to_parents(labels)
add_children_to_parents(raw_categories, true)
return {
LABELS = labels, RAW_CATEGORIES = raw_categories,
HANDLERS = handlers, RAW_HANDLERS = raw_handlers
}
1k2lsrrlayvho1qfq45ckme4ef4wfk7
157694
157690
2025-07-10T05:54:21Z
咽頭べさ
33
157694
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local subpages = {
-- It should not matter much what order we do the handlers in, but topic handling historically
-- preceded "poscatboiler" handling (i.e. everything else), so keep it that way for the moment.
"topic",
"affixes and compounds",
"characters",
"entry maintenance",
"etymology",
"families",
"figures of speech",
"grammatical classes",
"lang-specific-raw",
"အရေဝ်ဘာသာ",
"lects",
"ဝေါဟာအဓိက",
"lexical properties",
"miscellaneous",
"မဝ်ဂျူ",
"names",
"non-lemma forms",
"phrases",
"pragmatic properties",
"rhymes",
"scripts",
"semantic classes",
"shortenings",
"speech acts",
"symbols",
"templates",
"terms by script",
"transliterations",
"unicode",
"wiktionary maintenance",
"wiktionary users",
"word of the day",
}
-- Import subpages
for _, subpage in ipairs(subpages) do
local datamodule = "Module:category tree/" .. subpage
local retval = require(datamodule)
if retval["LABELS"] then
for label, data in pairs(retval["LABELS"]) do
if labels[label] and not retval["IGNOREDUP"] then
error("Label " .. label .. " defined in both [["
.. datamodule .. "]] and [[" .. labels[label].module .. "]].")
end
data.module = datamodule
labels[label] = data
end
end
if retval["RAW_CATEGORIES"] then
for category, data in pairs(retval["RAW_CATEGORIES"]) do
if raw_categories[category] and not retval["IGNOREDUP"] then
error("Raw category " .. category .. " defined in both [["
.. datamodule .. "]] and [[" .. raw_categories[category].module .. "]].")
end
data.module = datamodule
raw_categories[category] = data
end
end
if retval["HANDLERS"] then
for _, handler in ipairs(retval["HANDLERS"]) do
table.insert(handlers, { module = datamodule, handler = handler })
end
end
if retval["RAW_HANDLERS"] then
for _, handler in ipairs(retval["RAW_HANDLERS"]) do
table.insert(raw_handlers, { module = datamodule, handler = handler })
end
end
end
-- Add child categories to their parents
local function add_children_to_parents(hierarchy, raw)
for key, data in pairs(hierarchy) do
local parents = data.parents
if parents then
if type(parents) ~= "table" then
parents = {parents}
end
if parents.name or parents.module then
parents = {parents}
end
for _, parent in ipairs(parents) do
if type(parent) ~= "table" or not parent.name and not parent.module then
parent = {name = parent}
end
if parent.name and not parent.module and type(parent.name) == "string" and not parent.name:find("^ကဏ္ဍ:") then
local parent_is_raw
if raw then
parent_is_raw = not parent.is_label
else
parent_is_raw = parent.raw
end
-- Don't do anything if the child is raw and the parent is lang-specific, otherwise e.g.
-- "Lemmas subcategories by language" will be listed as a child of every "LANG lemmas" category.
-- FIXME: We need to rethink this mechanism.
if not raw or parent_is_raw then
local child_hierarchy = parent_is_raw and raw_categories or labels
if child_hierarchy[parent.name] then
local child = {name = key, sort = parent.sort, raw = raw}
if child_hierarchy[parent.name].children then
table.insert(child_hierarchy[parent.name].children, child)
else
child_hierarchy[parent.name].children = {child}
end
end
end
end
end
end
end
end
add_children_to_parents(labels)
add_children_to_parents(raw_categories, true)
return {
LABELS = labels, RAW_CATEGORIES = raw_categories,
HANDLERS = handlers, RAW_HANDLERS = raw_handlers
}
30d70qv33gmcdhlc1u0k8b8ewj3tt8h
မဝ်ဂျူ:category tree/semantic classes
828
1714
157706
5104
2025-07-10T10:01:42Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[မဝ်ဂျူ:category tree/poscatboiler/data/terms by semantic function]] ဇရေင် [[မဝ်ဂျူ:category tree/semantic classes]]
5104
Scribunto
text/plain
local labels = {}
local raw_categories = {}
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["terms by semantic function"] = {
description = "{{{langname}}} terms by their semantic function, regardless of part of speech.",
umbrella_parents = "Fundamental",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["cardinal numbers"] = {
description = "{{{langname}}} terms that are used to count objects.",
parents = {"numbers"},
}
labels["demonstrative pro-forms"] = {
description = "{{{langname}}} terms that refer to specified entities or qualities.",
parents = {"pro-forms"},
}
labels["fractional numbers"] = {
description = "{{{langname}}} terms that indicate proportioned parts of a whole.",
parents = {"numbers"},
}
labels["hedges"] = {
description = "{{{langname}}} expressions that are used to qualify statements so as to lessen impact, e.g. to appear polite or modest or to soften a blow.",
parents = {"terms by semantic function"},
}
labels["indefinite pro-forms"] = {
description = "{{{langname}}} terms that refer to unspecified entities or qualities.",
parents = {"pro-forms"},
}
labels["intensifiers"] = {
description = "{{{langname}}} terms that serve to intensify.",
parents = {"terms by semantic function"},
}
labels["interrogative pro-forms"] = {
description = "{{{langname}}} terms that request the listener to specify.",
parents = {"pro-forms"},
}
labels["imperative sentences"] = {
description = "{{{langname}}} free-standing expressions that are in the grammatical form of commands, though often with a [[precative]] or [[hortatory]] force.",
parents = {"sentences"},
}
labels["mnemonics"] = {
description = "{{{langname}}} terms used for remembering something more easily.",
parents = {"terms by semantic function"},
}
labels["negative polarity items"] = {
description = "{{{langname}}} terms that are chiefly or always used with a negation.",
parents = {"terms by semantic function"},
}
labels["nominal numbers"] = {
description = "{{{langname}}} terms that represent numbers as entities in themselves.",
parents = {"numbers"},
}
labels["numbers"] = {
description = "{{{langname}}} terms that represent or relate to numbers of various kinds.",
parents = {"terms by semantic function"},
}
labels["oaths"] = {
description = "",
parents = {"terms by semantic function"},
}
labels["ordinal numbers"] = {
description = "{{{langname}}} terms that specify the ordering of objects within a sequence.",
parents = {"numbers"},
}
labels["pro-forms"] = {
description = "{{{langname}}} terms that refer to other parts of speech.",
parents = {"terms by semantic function"},
}
labels["pro-sentences"] = {
description = "{{{langname}}} terms that substitute for full [[sentences]].",
parents = {"pro-forms"},
}
labels["questions"] = {
description = "{{{langname}}} terms that usually or notably used as questions.",
parents = {"terms by semantic function", "sentences"},
}
labels["relative pro-forms"] = {
description = "{{{langname}}} terms that indicate [[relative clause]]s.",
parents = {"pro-forms"},
}
labels["rhetorical questions"] = {
description = "{{{langname}}} questions posed only for dramatic or persuasive effect.",
parents = {"idioms", "sentences", "questions"},
}
for label, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Terms by semantic function subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Terms by semantic function subcategories by language"] = {
description = "Umbrella categories covering topics related to terms categorized by their semantic function, such as types of numbers or questions.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "terms by semantic function", is_label = true, sort = " "},
},
}
return {LABELS = labels, RAW_CATEGORIES = raw_categories}
hm74vtsve0cc82j607mzen6kg7tohbx
157708
157706
2025-07-10T10:03:16Z
咽頭べさ
33
157708
Scribunto
text/plain
local labels = {}
local raw_categories = {}
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["terms by semantic function"] = {
description = "{{{langname}}} terms by their semantic function, regardless of part of speech.",
umbrella_parents = "Fundamental",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["cardinal numbers"] = {
description = "{{{langname}}} terms that are used to count objects.",
parents = {"numbers"},
}
labels["collective numbers"] = {
description = "{{{langname}}} terms used to indicate a set of items of a particular size.",
parents = {"numbers"},
}
labels["demonstrative pro-forms"] = {
description = "{{{langname}}} terms that refer to specified entities or qualities.",
parents = {"pro-forms"},
}
labels["distributive numbers"] = {
description = "{{{langname}}} terms that expresses the amount or quantity of something as it pertains to each member of a set, such as the number of times something happens at once, or the number of members affected each time.",
parents = {"numbers"},
}
labels["fractional numbers"] = {
description = "{{{langname}}} terms that indicate proportioned parts of a whole.",
parents = {"numbers"},
}
labels["hedges"] = {
description = "{{{langname}}} expressions that are used to qualify statements so as to lessen impact, e.g. to appear polite or modest or to soften a blow.",
parents = {"terms by semantic function"},
}
labels["indefinite pro-forms"] = {
description = "{{{langname}}} terms that refer to unspecified entities or qualities.",
parents = {"pro-forms"},
}
labels["intensifiers"] = {
description = "{{{langname}}} terms that serve to intensify.",
parents = {"terms by semantic function"},
}
labels["interrogative pro-forms"] = {
description = "{{{langname}}} terms that request the listener to specify.",
parents = {"pro-forms"},
}
labels["imperative sentences"] = {
description = "{{{langname}}} free-standing expressions that are in the grammatical form of commands, though often with a [[precative]] or [[hortatory]] force.",
parents = {"sentences"},
}
labels["negative polarity items"] = {
description = "{{{langname}}} terms that are chiefly or always used with a negation.",
additional = "These are the opposite of positive polarity items; see [[:Category:{{{langname}}} positive polarity items]]. See also {{pedia|Polarity items}} for a general discussion and also {{w|Irrealis mood}} for grammatical constructions in which these can be used without an explicit negative.",
umbrella = {
additional = "These are the opposite of positive polarity items; see [[:Category:Positive polarity items by language]]. See also {{pedia|Polarity items}}",
},
parents = {"terms by semantic function"},
}
labels["multiplicative numbers"] = {
description = "{{{langname}}} terms that are used to multiply the amount or quantity of something.",
parents = {"numbers"},
}
labels["nominal numbers"] = {
description = "{{{langname}}} terms that represent numbers as entities in themselves.",
parents = {"numbers"},
}
labels["numbers"] = {
description = "{{{langname}}} terms that represent or relate to numbers of various kinds.",
parents = {"terms by semantic function"},
}
labels["ordinal numbers"] = {
description = "{{{langname}}} terms that specify the ordering of objects within a sequence.",
parents = {"numbers"},
}
labels["positive polarity items"] = {
description = "{{{langname}}} terms that are chiefly or always used in an affirmative sentence, and not with a negation.",
additional = "These are the opposite of negative polarity items; see [[:Category:{{{langname}}} negative polarity items]]. See also {{pedia|Polarity items}}",
umbrella = {
additional = "These are the opposite of negative polarity items; see [[:Category:Negative polarity items by language]]. See also {{pedia|Polarity items}}",
},
parents = {"terms by semantic function"},
}
labels["pro-forms"] = {
description = "{{{langname}}} terms that refer to other parts of speech.",
parents = {"terms by semantic function"},
}
labels["pro-sentences"] = {
description = "{{{langname}}} terms that substitute for full [[sentences]].",
parents = {"pro-forms"},
}
labels["questions"] = {
description = "{{{langname}}} terms that are usually or notably used as questions.",
parents = {"sentences"},
}
labels["relative pro-forms"] = {
description = "{{{langname}}} terms that indicate [[relative clause]]s.",
parents = {"pro-forms"},
}
labels["rhetorical questions"] = {
description = "{{{langname}}} questions posed only for dramatic or persuasive effect.",
parents = {"idioms", "sentences", "questions"},
}
labels["subjunctive expressions"] = {
description = "{{{langname}}} expressions containing grammatically [[subjunctive]] verbs.",
parents = {"terms by semantic function"},
}
for label, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Terms by semantic function subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Terms by semantic function subcategories by language"] = {
description = "Umbrella categories covering topics related to terms categorized by their semantic function, such as types of numbers or questions.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "terms by semantic function", is_label = true, sort = " "},
},
}
return {LABELS = labels, RAW_CATEGORIES = raw_categories}
ip3q6oba014cfheyt1lpfwesi3p1clv
မဝ်ဂျူ:category tree/topic
828
1738
157712
157525
2025-07-10T10:16:26Z
咽頭べさ
33
157712
Scribunto
text/plain
local raw_handlers = {}
local raw_categories = {}
--[=[
This module implements the topic category subsystem. It is currently implemented with a single raw handler that
handlers both language-specific and umbrella topic categories, and a corresponding handler for thesaurus categories.
The topmost topic category [[:Category:All topics]] is special and potentially could be handled as a separate raw
category, but currently it's handled as part of the raw topic handler. The topmost thesaurus category
[[:Category:Thesaurus]] is in fact handled as a raw category.
]=]
local functions_module = "Module:fun"
local labels_utilities_module = "Module:labels/utilities"
local languages_module = "Module:languages"
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_module = "Module:table"
local topic_data_module = "Module:category tree/topic/data"
local topic_utilities_module = "Module:category tree/topic/utilities"
local thesaurus_data_module = "Module:category tree/topic/thesaurus data"
local concat = table.concat
local insert = table.insert
local dump = mw.dumpObject
local is_callable = require(functions_module).is_callable
local pattern_escape = require(string_pattern_escape_module)
local replacement_escape = require(string_replacement_escape_module)
local split = require(string_utilities_module).split
local type_data = {
["related-to"] = {
desc = "terms related to",
additional = "'''NOTE''': This is a \"related-to\" category. It should contain terms directly related to " ..
"{{{topic}}}. Please do not include terms that merely have a tangential connection to {{{topic}}}. " ..
"Be aware that terms for types or instances of this topic often go in a separate category.",
},
set = {
desc = "terms for types or instances of",
additional = "'''NOTE''': This is a set category. It should contain terms for {{{topic}}}, not merely " ..
"terms related to {{{topic}}}. It may contain more general terms (e.g. types of {{{topic}}}) or more " ..
"specific terms (e.g. names of specific {{{topic}}}), although there may be related categories "..
"specifically for these types of terms.",
},
name = {
desc = "names of specific",
additional = "'''NOTE''': This is a name category. It should contain names of specific {{{topic}}}, not " ..
"merely terms related to {{{topic}}}, and should also not contain general terms for types of {{{topic}}}.",
},
type = {
desc = "terms for types of",
additional = "'''NOTE''': This is a type category. It should contain terms for types of {{{topic}}}, not " ..
"merely terms related to {{{topic}}}, and should also not contain names of specific {{{topic}}}.",
},
grouping = {
desc = "categories concerning more specific variants of",
additional = "'''NOTE''': This is a grouping category. It should not directly contain any terms, but " ..
"only subcategories. If there are any terms directly in this category, please move them to a subcategory.",
},
toplevel = {
desc = "UNUSED", -- all categories of this type hardcode their description
additional = "'''NOTE''': This is a top-level list category. It should not directly contain any terms, but " ..
"only a {{{topic}}}.",
},
}
local function invalid_type(types)
local valid_types = {}
for typ, _ in pairs(type_data) do
insert(valid_types, ("'%s'"):format(typ))
end
error(("Invalid type '%s', should be one or more of %s, comma-separated")
:format(types, mw.text.listToText(valid_types)))
end
local function split_types(types)
types = types or "related-to"
local splitvals = split(types, "%s*,%s*")
for i, typ in ipairs(splitvals) do
-- FIXME: Temporary
if typ == "topic" then
typ = "related-to"
end
if not type_data[typ] then
invalid_type(types)
end
splitvals[i] = typ
end
return splitvals
end
local function gsub_escaping_replacement(str, from, to)
return (str:gsub(pattern_escape(from), replacement_escape(to)))
end
function ucfirst(txt)
local italics, raw_txt = txt:match("^('*)(.-)$")
return italics .. mw.getContentLanguage():ucfirst(raw_txt)
end
function lcfirst(txt)
local italics, raw_txt = txt:match("^('*)(.-)$")
return italics .. mw.getContentLanguage():lcfirst(raw_txt)
end
local function convert_spec_to_string(data, desc)
if not desc then
return desc
end
local desc_type = type(desc)
if desc_type == "string" then
return desc
elseif desc_type == "number" then
return tostring(desc)
elseif not is_callable(desc) then
error("Internal error: `desc` must be a string, number, function, callable table or nil; received a " ..
desc_type)
end
desc = desc {
lang = data.lang,
sc = data.sc,
label = data.label,
category = data.category,
topic_data = data.topdata,
}
if not desc then
return desc
end
desc_type = type(desc)
if desc_type == "string" then
return desc
end
error("Internal error: the value returned by `desc` must be a string or nil; received a " .. desc_type)
end
local function get_and_cache(data, obj, key)
local val = convert_spec_to_string(data, obj[key])
obj[key] = val
return val
end
local function process_default(desc)
local stripped_desc = desc
local no_singularize, wikify, add_the
while true do
local new_stripped_desc = stripped_desc:match("^(.+) no singularize$")
if new_stripped_desc then
no_singularize = true
end
if not new_stripped_desc then
new_stripped_desc = stripped_desc:match("^(.+) wikify$")
if new_stripped_desc then
wikify = true
end
end
if not new_stripped_desc then
new_stripped_desc = stripped_desc:match("^(.+) with the$")
if new_stripped_desc then
add_the = true
end
end
if new_stripped_desc then
stripped_desc = new_stripped_desc
else
break
end
end
if stripped_desc == "default" then
return true, no_singularize, wikify, add_the
else
return false
end
end
local function format_desc(data, desc)
local desc_parts = {}
local types = split_types(data.topdata.type)
for _, typ in ipairs(types) do
insert(desc_parts, type_data[typ].desc .. " " .. desc)
end
return "{{{langname}}} " .. require(table_module).serialCommaJoin(desc_parts) .. "."
end
local substitute_template_specs
local function format_displaytitle(data, include_lang_prefix, upcase)
local topdata, lang, label = data.topdata, data.lang, data.label
local displaytitle = substitute_template_specs(data, topdata.displaytitle)
if not displaytitle then
return nil
end
if upcase then
displaytitle = ucfirst(displaytitle)
end
if include_lang_prefix and lang then
displaytitle = ("%s:%s"):format(lang:getCode(), displaytitle)
end
return displaytitle
end
local function get_breadcrumb(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local ret
if lang then
ret = topdata.breadcrumb or format_displaytitle(data, false, "upcase")
else
ret = topdata.umbrella and topdata.umbrella.breadcrumb or
topdata.breadcrumb or format_displaytitle(data, false, "upcase")
end
if not ret then
ret = label
end
if type(ret) == "string" or type(ret) == "number" then
ret = {name = ret}
end
local name = substitute_template_specs(data, ret.name)
local nocap = ret.nocap
return {name = name, nocap = nocap}
end
local function make_category_name(lang, label)
if lang then
return lang:getCode() .. ":" .. ucfirst(label)
else
return ucfirst(label)
end
end
local function replace_special_descriptions(data, desc)
if not desc then
return desc
end
if desc:find("^=") then
desc = desc:gsub("^=", "")
return format_desc(data, desc)
end
local is_default, no_singularize, wikify, add_the = process_default(desc)
if is_default then
local linked_label = require(topic_utilities_module).link_label(data.label, no_singularize, wikify)
if add_the then
linked_label = "the " .. linked_label
end
return format_desc(data, linked_label)
else
return desc
end
end
local function get_displaytitle_or_label(data)
return format_displaytitle(data, false) or data.label
end
local function process_default_add_the(data, topic)
local is_default, _, _, add_the = process_default(topic)
if is_default then
topic = get_displaytitle_or_label(data)
if add_the then
topic = "the " .. topic
end
end
return topic, is_default
end
substitute_template_specs = function(data, desc)
desc = convert_spec_to_string(data, desc)
if not desc then
return nil
end
local topdata, lang, label = data.topdata, data.lang, data.label
if desc:find("{{{umbrella_msg}}}") then
local catname = ucfirst(label)
desc = gsub_escaping_replacement(desc, "{{{umbrella_msg}}}",
"This category contains no dictionary entries, only other categories. The subcategories are of two " ..
"sorts:\n\n* Subcategories named like \"{{{thespref}}}aa:" .. catname ..
"\" (with a prefixed language code) are categories of terms in specific languages. " ..
"You may be interested especially in [[:Category:{{{thespref}}}en:" .. catname .. "]], for English terms.\n" ..
"* Subcategories of this one named without the prefixed language code are further categories just like " ..
"this one, but devoted to finer topics."
)
end
if desc:find("{{{topic}}}") then
-- Compute the value for {{{topic}}}. If the user specified `topic`, use it. (If we're an umbrella category,
-- allow a separate value for `umbrella.topic`, falling back to `topic`.) Otherwise, see if the description
-- was specified as 'default' or a variant; if so, parse it to determine whether to add "the" to the label.
-- Otherwise, just use the label directly.
local topic = not lang and topdata.umbrella and topdata.umbrella.topic or topdata.topic
if topic then
topic = process_default_add_the(data, topic)
else
local desc
if not lang then
desc = topdata.umbrella and get_and_cache(data, topdata.umbrella, "description") or
get_and_cache(data, topdata, "umbrella_description")
end
desc = desc or get_and_cache(data, topdata, "description")
local defaulted_desc, is_default = process_default_add_the(data, desc)
if is_default then
topic = defaulted_desc
else
topic = get_displaytitle_or_label(data)
end
end
desc = gsub_escaping_replacement(desc, "{{{topic}}}", topic)
end
desc = desc:gsub("{{{thespref}}}", data.thesaurus_data and "Thesaurus:" or "")
return desc
end
local function process_box(data, def_topright_parts, val, pattern)
if not val then
return
end
local defval = ucfirst(data.label)
if type(val) ~= "table" then
val = {val}
end
for _, v in ipairs(val) do
if v == true then
insert(def_topright_parts, pattern:format(defval))
else
insert(def_topright_parts, pattern:format(v))
end
end
end
local function get_topright(data)
local topdata, lang = data.topdata, data.lang
local def_topright_parts = {}
process_box(data, def_topright_parts, topdata.wp, "{{wikipedia|%s}}")
process_box(data, def_topright_parts, topdata.wpcat, "{{wikipedia|category=%s}}")
process_box(data, def_topright_parts, topdata.commonscat, "{{commonscat|%s}}")
local def_topright
if #def_topright_parts > 0 then
def_topright = concat(def_topright_parts, "\n")
end
if lang then
return substitute_template_specs(data, topdata.topright or def_topright)
else
return topdata.umbrella and substitute_template_specs(data, topdata.umbrella.topright) or
substitute_template_specs(data, def_topright)
end
end
local function remove_lang_params(desc)
desc = desc:gsub("^{{{langname}}} ", "")
desc = desc:gsub("{{{langcode}}}:", "")
desc = desc:gsub("^{{{langcode}}} ", "")
desc = desc:gsub("^{{{langcat}}} ", "")
return desc
end
local function get_additional_msg(data)
local types = split_types(data.topdata.type)
if #types > 1 then
local parts = {"'''NOTE''': This is a mixed category. It may contain terms of any of the following category types:"}
for i, typ in ipairs(types) do
insert(parts, ("* %s {{{topic}}}%s"):format(type_data[typ].desc, i == #types and "." or ";"))
end
insert(parts, "'''WARNING''': Such categories are strongly dispreferred and should be split into separate per-type categories.")
return concat(parts, "\n")
elseif label == "all topics" then
return "'''NOTE''': This is the topmost topic category for {{{langname}}}. It should not directly contain " ..
"any terms, but only lists of topic categories organized by type."
else
return type_data[types[1]].additional
end
end
local function get_labels_categorizing(data)
local m_labels_utilities = require(labels_utilities_module)
return m_labels_utilities.format_labels_categorizing(
m_labels_utilities.find_labels_for_category(data.label, "topic", data.lang), nil, data.lang)
end
-- Return the description along with the text following and preceding the description. The description and additional
-- (i.e. following) text are returned in the form of closures so the work of calculating the text (which can be
-- expensive, especially in the case of the additional text, where get_labels_categorizing() scans the entire set of
-- labels for any that categorize into this category) is not done when not needed, e.g. in higher levels of the
-- breadcrumb chain, where only the breadcrumb and parents (in fact, really just the first parent) are actually needed.
local function get_description_additional_preceding(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local desc, additional, preceding
-- This is kind of hacky, but it works for now.
local function postprocess_thesaurus(txt)
if not txt then
return nil
end
if not data.thesaurus_data then
return txt
end
txt = txt:gsub(" terms([ .,])", " thesaurus entries%1")
return txt
end
if lang then
desc = function()
return postprocess_thesaurus(substitute_template_specs(data,
replace_special_descriptions(data, get_and_cache(data, topdata, "description"))))
end
preceding = topdata.preceding
additional = function()
local additional_parts = {}
if topdata.additional then
insert(additional_parts, topdata.additional)
end
if not data.thesaurus_data then
insert(additional_parts, get_additional_msg(data))
local labels_msg = get_labels_categorizing(data)
if labels_msg then
insert(additional_parts, labels_msg)
end
end
return postprocess_thesaurus(substitute_template_specs(data, concat(additional_parts, "\n\n")))
end
else
if label == "all topics" then
desc = "This is the topmost topic category for all languages."
additional = "It contains no dictionary entries, only other categories. The subcategories are of two " ..
"sorts:\n\n" ..
"* Subcategories listed at the beginning, without a prefixed language code, are grouping " ..
"categories similar to this category, but are devoted to general subject areas. Under them are " ..
"finer-grained subject areas.\n" ..
"* Subcategories named like \"aa:All topics\" (with a prefixed language code) are top-level " ..
"categories like this one, but for specific languages. You may be interested especially in " ..
"[[:Category:en:All topics]], for English terms.\n" ..
"Note that categories under this tree categorize terms semantically rather than grammatically. " ..
"Grammatical categories (such as all French verbs, or all English irregular plural forms) " ..
"have a different naming structure, with the language name spelled out, such as " ..
"[[:Category:French verbs]] or [[:Category:English irregular plurals]]."
return desc, additional
end
-- Assume that if the description field contains a function, the function will return non-nil, so we don't
-- have to call the function at this point (in case it is heavyweight).
local has_umbrella_desc = topdata.umbrella and topdata.umbrella.description or topdata.umbrella_description
desc = function()
local desc = topdata.umbrella and get_and_cache(data, topdata.umbrella, "description") or
get_and_cache(data, topdata, "umbrella_description")
if not desc then
desc = get_and_cache(data, topdata, "description")
if desc then
desc = replace_special_descriptions(data, desc)
desc = remove_lang_params(desc)
desc = desc:gsub("%.$", "")
desc = "This category concerns the topic: " .. desc .. "."
end
end
if not desc then
desc = "Categories concerning " .. label .. " in various specific languages."
end
return postprocess_thesaurus(substitute_template_specs(data, desc))
end
preceding = topdata.umbrella and topdata.umbrella.preceding or not has_umbrella_desc and topdata.preceding
if preceding then
preceding = remove_lang_params(preceding)
end
additional = function()
local additional_parts = {}
local topdata_additional = topdata.umbrella and topdata.umbrella.additional or
not has_umbrella_desc and topdata.additional
if topdata_additional then
insert(additional_parts, remove_lang_params(topdata_additional))
end
insert(additional_parts, "{{{umbrella_msg}}}")
if not data.thesaurus_data then
insert(additional_parts, get_additional_msg(data))
local labels_msg = get_labels_categorizing(data)
if labels_msg then
insert(additional_parts, labels_msg)
end
end
return postprocess_thesaurus(substitute_template_specs(data, concat(additional_parts, "\n\n")))
end
end
preceding = substitute_template_specs(data, preceding)
return desc, additional, preceding
end
local function normalize_sort_key(data, sort)
local lang, label = data.lang, data.label
if not sort then
-- When defaulting sort key to label, strip 'The ' (e.g. in 'The Matrix', 'The Hunger Games')
-- and 'A ' (e.g. in 'A Song of Ice and Fire', 'A Christmas Carol') from label.
local stripped_sort = label:match("^[Tt]he (.*)$")
if stripped_sort then
sort = stripped_sort
end
if not stripped_sort then
stripped_sort = label:match("^[Aa] (.*)$")
if stripped_sort then
sort = stripped_sort
end
end
if not stripped_sort then
sort = label
end
end
sort = substitute_template_specs(data, sort)
if not lang then
sort = " " .. sort
end
return sort
end
local function get_topic_parents(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local parents = topdata.parents
if not lang and label == "ပရောပရာသီုဖအိုတ်ဂမၠိုၚ်" then
return {{ name = "ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်", sort = "topics" }}
end
if not parents or #parents == 0 then
return nil
end
local ret = {}
for _, parent in ipairs(parents) do
parent = mw.clone(parent)
if type(parent) ~= "table" then
parent = {name = parent}
end
parent.sort = normalize_sort_key(data, parent.sort)
if type(parent.name) ~= "string" then
error(("Internal error: parent.name is not a string: parent = %s"):format(dump(parent)))
end
if parent.name:find("^Category:") or parent.nontopic then
-- leave as-is
parent.nontopic = nil
else
parent.name = make_category_name(lang, parent.name)
end
parent.name = substitute_template_specs(data, parent.name)
insert(ret, parent)
end
local function make_list_of_type_parent(typ)
return {
name = make_category_name(lang, ("list of %s categories"):format(typ)),
sort = (not lang and " " or "") .. label,
}
end
if topdata.type ~= "toplevel" then
local types = split_types(topdata.type)
for _, typ in ipairs(types) do
insert(ret, make_list_of_type_parent(typ))
end
if #types > 1 then
insert(ret, make_list_of_type_parent("mixed"))
end
end
-- Add umbrella category.
if lang then
insert(ret, {
name = make_category_name(nil, label),
sort = lang:getCanonicalName(),
})
end
return ret
end
local function get_thesaurus_parents(data)
local topdata, lang, label = data.topdata, data.lang, data.label
local parent_substitutions = data.thesaurus_data.parent_substitutions
local parents = topdata.parents
if not parents or #parents == 0 then
return nil
end
local ret = {}
for _, parent in ipairs(parents) do
-- Process parent categories as follows:
-- 1. skip non-topic cats and meta-categories that start with "List of"
-- 2. map "en:All topics" to "English thesaurus entries" (and same for other languages), but map "All topics" itself to the root "Thesaurus" category
-- 3. check if this parent is to be substituted, if so, substitute it
-- 4. prepend "Thesaurus:" to all other category names
parent = mw.clone(parent)
if type(parent) ~= "table" then
parent = {name = parent}
end
parent.sort = normalize_sort_key(data, parent.sort)
if type(parent.name) ~= "string" then
error(("Internal error: parent.name is not a string: parent = %s"):format(dump(parent)))
end
if parent.name:find("^ကဏ္ဍ:") or parent.nontopic then
-- skip
elseif parent.name == "ပရောပရာသီုဖအိုတ်ဂမၠိုၚ်" or parent_substitutions[parent.name] == "ပရောပရာသီုဖအိုတ်ဂမၠိုၚ်" then
if not lang then
insert(ret, {
name = "Thesaurus",
sort = label,
})
else
insert(ret, {
name = "thesaurus entries",
sort = parent.sort,
lang = lang:getCode(),
is_label = true,
})
end
else
parent.name = "အဘိဓာန်:" .. make_category_name(lang, parent_substitutions[parent.name] or parent.name)
parent.name = substitute_template_specs(data, parent.name)
insert(ret, parent)
end
end
-- Add the non-thesaurus version of this category as a parent, unless it is a thesaurus-only category.
if not topdata.thesaurusonly then
insert(ret, { name = make_category_name(lang, label), sort = " " })
end
-- Add umbrella category.
if lang then
insert(ret, {
name = "အဘိဓာန်:" .. make_category_name(nil, label),
sort = lang:getCanonicalName(),
})
end
return ret
end
local function generate_spec(category, lang, upcase_label, thesaurus_data)
local label_data = require(topic_data_module)
local label
-- Convert label to lowercase if possible
local lowercase_label = mw.getContentLanguage():lcfirst(upcase_label)
-- Check if the label exists
local labels = label_data["LABELS"]
if labels[lowercase_label] then
label = lowercase_label
else
label = upcase_label
end
local topdata = labels[label]
-- Go through handlers
if not topdata then
for _, handler in ipairs(label_data["HANDLERS"]) do
topdata = handler.handler(label)
if topdata then
topdata.module = handler.module
break
end
end
end
if not topdata then
return nil
end
local data = {
category = category,
lang = lang,
label = label,
topdata = topdata,
thesaurus_data = thesaurus_data,
}
local description, additional, preceding = get_description_additional_preceding(data)
local parents
if thesaurus_data then
parents = get_thesaurus_parents(data)
else
parents = get_topic_parents(data)
end
return {
lang = lang and lang:getCode() or nil,
description = description,
additional = additional,
preceding = preceding,
parents = parents,
breadcrumb = get_breadcrumb(data),
displaytitle = format_displaytitle(data, "include lang prefix", "upcase"),
topright = get_topright(data),
module = topdata.module,
can_be_empty = not lang,
hidden = false,
}
end
-- Handler for `Thesaurus:...` categories.
table.insert(raw_handlers, function(data)
local code, upcase_label = data.category:match("^အဘိဓာန်:(%l[%a-]*%a):(.+)$")
local lang
if code then
lang = require(languages_module).getByCode(code)
if not lang then
mw.log(("Category '%s' looks like a language-specific thesaurus category but unable to match language prefix"):
format(data.category))
return nil
end
else
upcase_label = data.category:match("^အဘိဓာန်:(.+)$")
end
if upcase_label then
local thesaurus_data = require(thesaurus_data_module)
-- substituted category names are not allowed
if thesaurus_data.parent_substitutions[lcfirst(upcase_label)] then
error(("Category is not allowed as a Thesaurus category: %s (see the list of parent substitutions at " ..
"[[Module:category tree/topic/thesaurus]])"):format(data.category))
end
return generate_spec(data.category, lang, upcase_label, thesaurus_data)
end
end)
-- Handler for regular topic categories.
table.insert(raw_handlers, function(data)
local code, upcase_label = data.category:match("^(%l[%a-]*%a):(.+)$")
local lang
if code then
lang = require(languages_module).getByCode(code)
if not lang then
mw.log(("Category '%s' looks like a language-specific topic category but unable to match language prefix"):
format(data.category))
return nil
end
else
upcase_label = data.category
end
return generate_spec(data.category, lang, upcase_label)
end)
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["အဘိဓာန်"] = {
description = "Category for entries of the Wiktionary thesaurus, located in a separate namespace.",
additional = [=[
There are '''three ways to browse''' the thesaurus:
* Look under '''[[:Category:Thesaurus entries by language]]''' to get started.
* Use the search box below.
* Browse the thesaurus by topic using the links under "Subcategories" below.
The main project page is [[Wiktionary:Thesaurus]].
{{ws header|<nowiki/>|link=}}]=],
parents = {
"ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
"ကဏ္ဍ:ပရဝ်ဂျေတ်ဝိက်ရှေန်နရဳဂမၠိုၚ်",
},
}
return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}
exn1gy69iv38ecmxljwumyydq9hs4g2
မဝ်ဂျူ:category tree/ဝေါဟာအဓိက
828
1750
157649
155009
2025-07-09T14:08:16Z
咽頭べさ
33
157649
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local ucfirst = require("Module:string utilities").ucfirst
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
local diminutive_augmentative_poses = {
"နာမဝိသေသန",
"ကြိယာဝိသေသန",
"အာမေဍိက်",
"နာမ်",
"ဂၞန်သင်္ချာ",
"မုက်နာမ်",
"နာမ်မကိတ်ညဳ",
"သဗ္ဗနာမ်",
"အဆက်လက္ကရဴ",
"ကြိယာ"
}
labels["ဝေါဟာအဓိက"] = {
description = "ဝေါဟာ[[ဝိက်ရှေန်နရဳ:ဝေါဟာအဓိက|တံသ္ဇိုၚ်]]{{{langname}}}၊ ကဏ္ဍနူကဵုမပါ်ပရံဒကုတ်မဆေၚ်စပ်ကဵုမအရေဝ်ဝေါဟာ။",
umbrella_parents = "ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
parents = {{name = "{{{langcat}}}", raw = true, sort = " "}},
}
labels["abstract verbs"] = {
description = "{{{langname}}} abstract verbs of motion whose motion is multidirectional (as opposed to unidirectional) or indirect, or whose action is repeated or in a series, instead of being a single, completed action. Abstract verbs are always imperfective in aspect, even with prefixes that are normally associated with the perfective aspect.",
additional = "See also [[abstract verb]].",
parents = {"verbs"},
}
labels["action nouns"] = {
description = "{{{langname}}} nouns denoting action of a verb or verbal root that it is derived from.",
parents = {"nouns"},
}
labels["act-related adverbs"] = {
description = "{{{langname}}} adverbs that indicate the motive or other background information for an action.",
parents = {"adverbs"},
}
labels["active verbs"] = {
description = "{{{langname}}} verbs that indicate an activity",
parents = {"verbs"},
}
labels["active-only verbs"] = {
description = "{{{langname}}} verbs that can only be used with the {{w|active voice}}.",
parents = {"verbs"},
}
labels["adjective concords"] = {
description = "{{{langname}}} concords that are prefixed to adjective stems.",
parents = {"concords"},
}
labels["နာမဝိသေသန"] = {
description = "ဝေါဟာ{{{langname}}}မဒုၚ်ကေတ်အၚ်္ဂအဝဲဂုန်နကဵုနာမ်ဂမၠိုၚ်၊ မဒုၚ်ကဵုကေတ်အဓိပ္ပာဲအတေံဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["adverbial accusatives"] = {
description = "Accusative case-forms in {{{langname}}} used as adverbs.",
parents = {"adverbs"},
}
labels["ကြိယာဝိသေသန"] = {
description = "ဝေါဟာ{{{langname}}}မပြုပြေၚ်ပြံၚ်လှာဲလဝ်ပိုဒ်လိက်ဂမၠိုၚ်၊ ပိုတ်ဂမၠိုၚ် ကဵု ဇၟန်လိက်တပ်ပ်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["အဆက်ဖျပ်စုတ်လက္ကရဴ"] = {
description = "Morphemes attached to existing {{{langname}}} words.",
parents = {"morphemes"},
}
labels["agent nouns"] = {
description = "{{{langname}}} nouns that denote an agent that performs the action denoted by the verb from which the noun is derived.",
parents = {"nouns"},
}
labels["ambipositions"] = {
description = "{{{langname}}} adpositions that can occur either before or after their objects.",
parents = {"lemmas"},
}
labels["ambitransitive verbs"] = {
description = "{{{langname}}} verbs that may or may not direct actions, occurrences or states to grammatical objects.",
parents = {"verbs", "transitive verbs", "intransitive verbs"},
}
labels["animal commands"] = {
description = "{{{langname}}} words used to communicate with animals.",
parents = {"interjections"},
}
labels["ပစ္စဲ"] = {
description = "ဝေါဟာဘာသာ{{{langname}}}စၞောန်ထ္ၜးကဵုအတေံ ကဵု နာမ်ချိုတ်ချိုတ်ပၠိုတ်ပၠိုတ်။",
parents = {"ဖျေံလဝ်သန္နိဋ္ဌာန်"},
}
labels["aspect adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Grammatical aspect|grammatical aspect]], describing the flow of time in relation to a statement.",
parents = {"adverbs"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["augmentative " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey big size or big intensity.",
parents = {pos},
}
end
labels["attenuative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event is performed or takes place gently, lightly, partially, perfunctorily or to an otherwise reduced extent.",
parents = {"verbs"},
}
labels["autobenefactive verbs"] = {
description = "{{{langname}}} verbs that indicate that the agent of an action is also its benefactor.",
parents = {"verbs"},
}
labels["automative verbs"] = {
description = "{{{langname}}} verbs that indicate actions directed at or a change of state of the grammatical subject.",
parents = {"verbs"},
}
labels["auxiliary verbs"] = {
description = "{{{langname}}} verbs that provide additional conjugations for other verbs.",
parents = {"verbs"},
}
labels["biaspectual verbs"] = {
description = "{{{langname}}} verbs that can be both imperfective and perfective.",
parents = {"verbs"},
}
labels["causative verbs"] = {
description = "{{{langname}}} verbs that express causing actions or states rather than performing or being them directly. Use this only for separate verbs (as opposed to causative forms that are part of the inflection of verbs).",
parents = {"verbs"},
}
labels["circumfixes"] = {
description = "Affixes attached to both the beginning and the end of {{{langname}}} words, functioning together as single units.",
parents = {"morphemes"},
}
labels["circumpositions"] = {
description = "{{{langname}}} adpositions that appear on both sides of their objects.",
parents = {"lemmas"},
}
labels["နာမ်ပါ်ကၞာတ်"] = {
description = "{{{langname}}} terms that classify nouns according to their meanings.",
parents = {"ဝေါဟာအဓိက"},
}
labels["clitics"] = {
description = "{{{langname}}} morphemes that function as independent words, but are always attached to another word.",
parents = {"morphemes"},
}
for _, pos in ipairs { "နာမ်", "အဆက်လက္ကရဴ" } do
labels["collective " .. pos] = {
description = "{{{langname}}} " .. pos .. " that indicate groups of related things or beings, without the need of grammatical pluralization.",
parents = {pos},
}
end
labels["combining forms"] = {
description = "Forms of {{{langname}}} words that do not occur independently, but are used when joined with other words.",
parents = {"morphemes"},
}
labels["comparable adjectives"] = {
description = "{{{langname}}} adjectives that can be inflected to display different degrees of comparison.",
parents = {"adjectives"},
}
labels["comparable adverbs"] = {
description = "{{{langname}}} adverbs that can be inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["completive verbs"] = {
description = "{{{langname}}} verbs which refer to the completion of an action which has already commenced or which has already been performed upon a subset of the entities which it affects.",
parents = {"verbs"},
}
labels["concords"] = {
description = "{{{langname}}} prefixes attached to words to show agreement with a noun or pronoun.",
parents = {"prefixes"},
}
labels["concrete verbs"] = {
description = "{{{langname}}} concrete verbs refer to a verbal aspect in verbs of motion that is unidirectional (as opposed to multidirectional), a definitely directed motion, or a single, completed action (instead of a repeated action or series of actions). Concrete verbs may be either imperfective or perfective.",
additional = "See also [[concrete verb]].",
parents = {"verbs"},
}
labels["conjunctions"] = {
description = "{{{langname}}} terms that connect words, phrases or clauses together.",
parents = {"lemmas"},
}
labels["conjunctive adverbs"] = {
description = "{{{langname}}} adverbs that connect two independent clauses together.",
parents = {"adverbs"},
}
labels["continuative verbs"] = {
description = "{{{langname}}} verbs that express continuing action.",
parents = {"verbs"},
}
labels["control verbs"] = {
description = "{{{langname}}} verbs that take multiple arguments, one of which is another verb. One of the control verb's arguments is syntactically both an argument of the control verb and an argument of the other verb.",
parents = {"verbs"},
}
labels["cooperative verbs"] = {
description = "{{{langname}}} verbs that indicate cooperation",
parents = {"verbs"},
}
labels["coordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate equal syntactic importance between connected items.",
parents = {"conjunctions"},
}
labels["copulative verbs"] = {
description = "{{{langname}}} verbs that may take adjectives as their complement.",
parents = {"verbs"},
}
for _, pos in ipairs { "နာမ်", "နာမ်မကိတ်ညဳ" } do
labels["countable " .. pos] = {
description = "{{{langname}}} " .. pos .. " that can be quantified directly by numerals.",
parents = {pos},
}
end
labels["countable numerals"] = {
description = "{{{langname}}} numerals that can be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["countable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that can be quantified directly by numerals.",
parents = {"suffixes"},
}
labels["counters"] = {
description = "{{{langname}}} terms that combine with numerals to express quantity of nouns.",
parents = {"lemmas"},
}
labels["cumulative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event gradually yields a certain or significant quantity or effect.",
parents = {"verbs"},
}
labels["degree adverbs"] = {
description = "{{{langname}}} adverbs that express a particular degree to which the word they modify applies.",
parents = {"adverbs"},
}
labels["delimitative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event is performed or takes place briefly or to an otherwise reduced extent.",
parents = {"verbs"},
}
labels["demonstrative adjectives"] = {
description = "{{{langname}}} adjectives that refer to nouns, comparing them to external references.",
parents = {"adjectives", {name = "demonstrative pro-forms", sort = "adjectives"}},
}
labels["demonstrative adverbs"] = {
description = "{{{langname}}} adverbs that refer to other adverbs, comparing them to external references.",
parents = {"adverbs", {name = "demonstrative pro-forms", sort = "adverbs"}},
}
labels["denominal verbs"] = { -- in [[Appendix:Glossary]]; "denominative" more frequent?
description = "{{{langname}}} verbs that derive from nouns.",
parents = { "verbs" },
}
labels["demonstrative determiners"] = {
description = "{{{langname}}} determiners that refer to nouns, comparing them to external references.",
parents = {"determiners", {name = "demonstrative pro-forms", sort = "determiners"}},
}
labels["demonstrative pronouns"] = {
description = "{{{langname}}} pronouns that refer to nouns, comparing them to external references.",
parents = {"pronouns", {name = "demonstrative pro-forms", sort = "pronouns"}},
}
labels["deponent verbs"] = {
description = "{{{langname}}} verbs that can only be used with the {{w|active voice}}, but which conjugate as though they were being used with a difference voice.",
parents = {"active-only verbs", "verbs"},
}
labels["derivational prefixes"] = {
description = "{{{langname}}} prefixes that are used to create new words.",
parents = {"prefixes"},
}
labels["derivational suffixes"] = {
description = "{{{langname}}} suffixes that are used to create new words.",
parents = {"suffixes"},
}
labels["derivative verbs"] = {
description = "{{{langname}}} verbs that are derived from nouns and adjectives.",
parents = {"verbs"},
}
labels["desiderative verbs"] = {
description = "{{{langname}}} verbs with the following morphology: verbal root xxx + [[desiderative]] affix, and the following semantics: to wish to do the action xxx.",
parents = {"verbs"},
}
labels["determinatives"] = {
description = "{{{langname}}} terms that indicate the general class to which the following logogram belongs.",
parents = {"lemmas"},
}
labels["ဖျေံလဝ်သန္နိဋ္ဌာန်"] = {
description = "{{{langname}}} terms that narrow down, within the conversational context, the referent of the following noun.",
parents = {"ဝေါဟာအဓိက"},
}
labels["diminutiva tantum"] = {
description = "{{{langname}}} nouns or noun senses that are mostly or exclusively used in the diminutive form.",
parents = {"nouns"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["diminutive " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey endearment, small size or small intensity.",
parents = {pos},
}
end
labels["discourse particles"] = {
description = "{{{langname}}} particles that manage the flow and structure of discourse.",
parents = {"particles"},
}
labels["distributive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event involves multiple participants or a large quantity of an uncountable mass, usually as the grammatical subject in the case of intransitive verbs and as the grammatical object in the case of transitive verbs.",
parents = {"verbs"},
}
labels["ditransitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states of two grammatical objects simultaneously, one direct and one indirect.",
parents = {"verbs", "transitive verbs"},
}
labels["dualia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the dual form.",
parents = {"nouns"},
}
labels["duration adverbs"] = {
description = "{{{langname}}} adverbs that express duration in time, such as (in English) [[always]], [[all night]] and [[ever since]].",
parents = {"time adverbs"},
}
labels["ergative verbs"] = {
description = "{{{langname}}} [[Appendix:Glossary#ergative|ergative verb]]s: intransitive verbs that become causatives when used transitively.",
parents = {"verbs", "intransitive verbs", "transitive verbs"},
}
labels["excessive verbs"] = {
description = "{{{langname}}} verbs that indicate that an action is performed to an excessive extent.",
parents = {"verbs"},
}
labels["enclitics"] = {
description = "{{{langname}}} clitics that attach to the preceding word.",
parents = {"clitics"},
}
labels["nouns with other-gender equivalents"] = {
description = "{{{langname}}} nouns that refer to gendered concepts (e.g. [[actor]] vs. [[actress]], [[king]] vs. [[queen]]) and have corresponding other-gender equivalent terms.",
parents = {"nouns"},
}
labels["female equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to female beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["neuter equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to neuter beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["female equivalent suffixes"] = {
description = "{{{langname}}} suffixes that refer to female beings with the same characteristics as the base suffix.",
parents = {"noun-forming suffixes"},
}
labels["focus adverbs"] = {
description = "{{{langname}}} adverbs that indicate [[w:Focus (linguistics)|focus]] within the sentence.",
parents = {"adverbs"},
}
labels["frequency adverbs"] = {
description = "{{{langname}}} adverbs that express repetition with a certain frequency or interval, such as (in English) [[monthly]], [[continually]] and [[once in a while]].",
parents = {"time adverbs"},
}
labels["frequentative verbs"] = {
description = "{{{langname}}} verbs that express repeated action.",
parents = {"verbs"},
}
labels["general pronouns"] = {
description = "{{{langname}}} pronouns that refer to all persons, things, abstract ideas and their characteristics.",
parents = {"pronouns"},
}
labels["generational moieties"] = {
description = "{{{langname}}} moieties that alternate every generation.",
parents = {"moieties"},
}
labels["ideophones"] = {
description = "{{{langname}}} terms that evoke an idea, especially a sensation or impression, with a sound.",
parents = {"lemmas"},
}
labels["imperfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as ongoing or continuous, as opposed to completed events.",
parents = {"verbs"},
}
labels["impersonal verbs"] = {
description = "{{{langname}}} verbs that do not indicate actions, occurrences or states of any specific grammatical subject.",
parents = {"verbs"},
}
labels["inchoative verbs"] = {
description = "{{{langname}}} verbs that indicate the beginning of an action or event.",
parents = {"verbs"},
}
labels["indefinite adjectives"] = {
description = "{{{langname}}} adjectives that refer to unspecified adjective meanings.",
parents = {"adjectives", {name = "indefinite pro-forms", sort = "adjectives"}},
}
labels["indefinite adverbs"] = {
description = "{{{langname}}} adverbs that refer to unspecified adverbial meanings.",
parents = {"adverbs", {name = "indefinite pro-forms", sort = "adverbs"}},
}
labels["indefinite determiners"] = {
description = "{{{langname}}} determiners that designate an unidentified noun.",
parents = {"determiners", {name = "indefinite pro-forms", sort = "determiners"}},
}
labels["indefinite pronouns"] = {
description = "{{{langname}}} pronouns that refer to unspecified nouns.",
parents = {"pronouns", {name = "indefinite pro-forms", sort = "pronouns"}},
}
labels["စန်{{{langname}}}ဂမၠိုင်"] = {
description = "Affixes inserted inside {{{langname}}} words.",
parents = {"morphemes"},
}
labels["inflectional prefixes"] = {
description = "{{{langname}}} prefixes that are used as inflectional beginnings in noun, adjective or verb paradigms.",
parents = {"prefixes"},
}
labels["inflectional suffixes"] = {
description = "{{{langname}}} suffixes that are used as inflectional endings in noun, adjective or verb paradigms.",
parents = {"suffixes"},
}
labels["intensive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed vigorously, enthusiastically, forcefully or to an otherwise enlarged extent.",
parents = {"verbs"},
}
labels["interfixes"] = {
description = "Affixes used to join two {{{langname}}} words or morphemes together.",
parents = {"morphemes"},
}
labels["အာမေဍိက်"] = {
description = "ဝေါဟာ{{{langname}}}ဓမံက်ထ္ၜးပရေၚ်သ္ဒးဒုၚ်စသိုၚ်ဂမၠိုၚ်၊ ရမျာၚ်ဂမၠိုၚ်၊ ဥပမာ ညံၚ်ကရေဲကညာၚ်တိုန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["interrogative adjectives"] = {
description = "{{{langname}}} adjectives that indicate questions.",
parents = {"adjectives", {name = "interrogative pro-forms", sort = "adjectives"}},
}
labels["interrogative adverbs"] = {
description = "{{{langname}}} adverbs that indicate questions.",
parents = {"adverbs", {name = "interrogative pro-forms", sort = "adverbs"}},
}
labels["interrogative determiners"] = {
description = "{{{langname}}} determiners that indicate questions.",
parents = {"determiners", {name = "interrogative pro-forms", sort = "determiners"}},
}
labels["interrogative particles"] = {
description = "{{{langname}}} particles that indicate questions.",
parents = {"particles", {name = "interrogative pro-forms", sort = "particles"}},
}
labels["interrogative pronouns"] = {
description = "{{{langname}}} pronouns that indicate questions.",
parents = {"pronouns", {name = "interrogative pro-forms", sort = "pronouns"}},
}
labels["intransitive verbs"] = {
description = "{{{langname}}} verbs that don't require any grammatical objects.",
parents = {"verbs"},
}
labels["iterative verbs"] = {
description = "{{{langname}}} verbs that express the repetition of an event.",
parents = {"verbs"},
}
labels["location adverbs"] = {
description = "{{{langname}}} adverbs that indicate location.",
parents = {"adverbs"},
}
labels["male equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to male beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["manner adverbs"] = {
description = "{{{langname}}} adverbs that indicate the manner, way or style in which an action is performed.",
parents = {"adverbs"},
}
labels["middle verbs"] = {
description = "{{{langname}}} verbs that are used in {{w|middle voice}}.",
parents = {"verbs"},
}
labels["modal adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Linguistic modality|linguistic modality]], indicating the mood or attitude of the speaker with respect to what is being said.",
parents = {"sentence adverbs"},
}
labels["modal particles"] = {
description = "{{{langname}}} particles that reflect the mood or attitude of the speaker, without changing the basic meaning of the sentence.",
parents = {"particles"},
}
labels["modal verbs"] = {
description = "{{{langname}}} verbs that indicate [[grammatical mood]].",
parents = {"auxiliary verbs"},
}
labels["moieties"] = {
description = "{{{langname}}} pairs of abstract categories separating people and the environment.",
parents = {"lemmas"},
}
labels["momentane verbs"] = {
description = "{{{langname}}} verbs that express a sudden and brief action.",
parents = {"verbs"},
}
labels["morphemes"] = {
description = "{{{langname}}} word-elements used to form full words.",
parents = {"lemmas"},
}
labels["multiword terms"] = {
description = "{{{langname}}} lemmas that are a combination of multiple words, including [[WT:CFI#Idiomaticity|idiomatic]] combinations.",
parents = {"lemmas"},
}
labels["negative verbs"] = {
description = "{{{langname}}} verbs that indicate the lack of an action.",
parents = {"verbs"},
}
labels["negative particles"] = {
description = "{{{langname}}} particles that indicate negation.",
parents = {"particles"},
}
labels["negative pronouns"] = {
description = "{{{langname}}} pronouns that refer to negative or non-existent references.",
parents = {"pronouns"},
}
labels["neutral verbs"] = {
description = "{{{langname}}} verbs that indicate either or both an activity or a result of an activity",
parents = {"verbs"},
}
labels["nominalized adjectives"] = {
description = "{{{langname}}} adjectives that are used as nouns.",
parents = {"nouns", "adjectives"},
}
labels["non-constituents"] = {
description = "{{{langname}}} terms that are not grammatical [[constituent#Noun|constituents]], and therefore need to be combined with additional terms to form a complete phrase.",
parents = {"phrases"},
}
labels["noun prefixes"] = {
description = "{{{langname}}} prefixes attached to a noun that display its noun class.",
parents = {"prefixes"},
}
labels["nouns"] = {
description = "{{{langname}}} terms that indicate people, beings, things, places, phenomena, qualities or ideas.",
parents = {"lemmas"},
}
labels["nouns by classifier"] = {
description = "{{{langname}}} nouns organized by the classifier they are used with.",
parents = {{name = "nouns", sort = "classifier"}},
}
labels["ဂၞန်သင်္ချာ"] = {
description = "ဝေါဟာ{{{langname}}}ပွမပ္ညုၚ်ထ္ၜးနာမ်တော်လျိုၚ်နာမ်ဂွံမာန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["object concords"] = {
description = "{{{langname}}} concords used to show the grammatical object.",
parents = {"concords"},
}
labels["object pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical objects.",
parents = {"pronouns"},
}
labels["ကၞာတ်အမှိက်"] = {
description = "{{{langname}}} terms that do not belong to any of the inflected grammatical word classes, often lacking their own grammatical functions and forming other parts of speech or expressing the relationship between clauses.",
parents = {"lemmas"},
}
labels["passive verbs"] = {
description = "{{{langname}}} verbs that are usually used in the {{w|passive voice}}.",
parents = {"verbs"},
}
labels["perfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as completed events, as opposed to ongoing or continuous.",
parents = {"verbs"},
}
labels["personal pronouns"] = {
description = "{{{langname}}} pronouns that are used as substitutes for known nouns.",
parents = {"pronouns"},
}
labels["phrasal verbs"] = {
description = "{{{langname}}} verbs accompanied by particles, such as prepositions and adverbs.",
parents = {"verbs", "phrases"},
}
labels["phrasal prepositions"] = {
description = "{{{langname}}} prepositions formed with combinations of other terms.",
parents = {"prepositions", "phrases"},
}
labels["pluralia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the plural form.",
parents = {"nouns"},
}
labels["point-in-time adverbs"] = {
description = "{{{langname}}} adverbs that reference a specific point in time, e.g. {{m|en|yesterday}}, {{m+|es|anoche||last night}} or {{m+|hu|egykor||at one o'clock}}.",
parents = {"time adverbs"},
}
labels["possessable nouns"] = {
description = "{{{langname}}} nouns can have their possession indicated directly by possessive pronouns.",
parents = {"nouns"},
umbrella = {
description = "Categories with nouns that can have their possession indicated directly by possessive pronouns and, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Possessable nouns by language",
},
}
labels["possessional adjectives"] = {
description = "{{{langname}}} adjectives that indicate that a noun is in possession of something.",
parents = {"adjectives"},
}
labels["possessive adjectives"] = {
description = "{{{langname}}} adjectives that indicate ownership.",
parents = {"adjectives"},
}
labels["possessive concords"] = {
description = "{{{langname}}} concords used to show possession.",
parents = {"concords"},
}
labels["possessive determiners"] = {
description = "{{{langname}}} determiners that indicate ownership.",
parents = {"determiners"},
}
labels["possessive pronouns"] = {
description = "{{{langname}}} pronouns that indicate ownership.",
parents = {"pronouns"},
}
labels["postpositional phrases"] = {
description = "{{{langname}}} phrases headed by a postposition.",
parents = {"phrases", "postpositions"},
}
labels["ကဆံင်"] = {
description = "{{{langname}}} adpositions that are placed after their objects.",
parents = {"ဝေါဟာအဓိက"},
}
labels["predicatives"] = {
description = "{{{langname}}} elements of the predicate that supplement the subject or object of a sentence via the verb.",
parents = {"lemmas"},
}
labels["မုက်နာမ်"] = {
description = "Affixes attached to the beginning of {{{langname}}} words.",
parents = {"morphemes"},
}
labels["prepositional phrases"] = {
description = "{{{langname}}} phrases headed by a preposition.",
parents = {"phrases", "prepositions"},
}
labels["ဝိဘတ်"] = {
description = "{{{langname}}} adpositions that are placed before their objects.",
parents = {"lemmas"},
}
labels["matrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's mother.",
parents = {"moieties"},
}
labels["patrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's father.",
parents = {"moieties"},
}
labels["pejorative suffixes"] = {
description = "{{{langname}}} suffixes that [[belittle]] (lessen in value).",
parents = {"suffixes"},
}
labels["သဗ္ဗနာမ်"] = {
description = "ဝေါဟာ{{{langname}}}နကဵုစပ်ဖျပ် ကဵု စၞးနာမ်ဂမၠိုၚ်။",
parents = {"မုက်နာမ်"},
}
labels["ပေါရာဏာံပေါရာဒါံ"] = {
description = "{{{langname}}} prefixes of various kinds that are attached to verbs.",
parents = {"မုက်နာမ်"},
}
labels["privative verbs"] = {
description = "{{{langname}}} verbs that indicate that the grammatical object is deprived of something or that something is removed from the object.",
parents = {"verbs"},
}
labels["pronominal adverbs"] = {
description = "{{{langname}}} adverbs that are formed by combining a pronoun with a preposition.",
parents = {"adverbs", "prepositions", "pronouns"},
}
labels["pronominal concords"] = {
description = "{{{langname}}} concords that are prefixed to pronominal stems.",
parents = {"concords"},
}
labels["pronouns"] = {
description = "{{{langname}}} terms that refer to and substitute nouns.",
parents = {"lemmas"},
}
labels["နာမ်မကိတ်ညဳ"] = {
description = "{{{langname}}} nouns that indicate individual entities, such as names of persons, places or organizations.",
parents = {"နာမ်"},
}
labels["raising verbs"] = {
description = "{{{langname}}} verbs that, in a matrix or main clause, take an argument from an embedded or subordinate clause; in other words, a raising verb appears with a syntactic argument that is not its semantic argument, but is rather the semantic argument of an embedded predicate.",
parents = {"verbs"},
}
labels["reciprocal pronouns"] = {
description = "{{{langname}}} pronouns that refer back to a plural subject and express an action done in two or more directions.",
parents = {"pronouns", "personal pronouns"},
}
labels["reciprocal verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from multiple subjects to each other.",
parents = {"verbs"},
}
labels["reflexive pronouns"] = {
description = "{{{langname}}} pronouns that refer back to the subject.",
parents = {"pronouns", "personal pronouns"},
}
labels["reflexive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from the grammatical subjects to themselves.",
parents = {"verbs"},
}
labels["relational adjectives"] = {
description = "{{{langname}}} adjectives that stand in place of a noun when modifying another noun.",
parents = {"adjectives"},
}
labels["relational nouns"] = {
description = "{{{langname}}} nouns used to indicate a relation between other two nouns by means of possession.",
parents = {"nouns"},
}
labels["relative adjectives"] = {
description = "{{{langname}}} adjectives used to indicate [[relative clause]]s.",
parents = {"adjectives", {name = "relative pro-forms", sort = "adjectives"}},
}
labels["relative adverbs"] = {
description = "{{{langname}}} adverbs used to indicate [[relative clause]]s.",
parents = {"adverbs", {name = "relative pro-forms", sort = "adverbs"}},
}
labels["relative determiners"] = {
description = "{{{langname}}} determiners used to indicate [[relative clause]]s.",
parents = {"determiners", {name = "relative pro-forms", sort = "determiners"}},
}
labels["relative concords"] = {
description = "{{{langname}}} concords that are prefixed to relative stems.",
parents = {"concords"},
}
labels["relative pronouns"] = {
description = "{{{langname}}} pronouns used to indicate [[relative clause]]s.",
parents = {"pronouns", {name = "relative pro-forms", sort = "pronouns"}},
}
labels["relatives"] = {
description = "{{{langname}}} terms that give attributes to nouns, acting grammatically as relative clauses.",
parents = {"lemmas"},
}
labels["repetitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions or events which are performed or occur again, anew or differently.",
parents = {"verbs"},
}
labels["resultative verbs"] = {
description = "{{{langname}}} verbs that indicate a result of some action",
parents = {"verbs"},
}
labels["reversative verbs"] = {
description = "{{{langname}}} verbs that indicate that the reversal or undoing of an action, event or state.",
parents = {"verbs"},
}
labels["saturative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed to the point of saturation or satisfaction.",
parents = {"verbs"},
}
labels["semelfactive verbs"] = {
description = "{{{langname}}} verbs that are punctual (instantaneous, momentive), perfective (treated as a unitary whole with no explicit internal temporal structure), and telic (having a boundary out of which the activity cannot be said to have taken place or continue).",
parents = {"verbs"},
}
labels["sentence adverbs"] = {
description = "{{{langname}}} adverbs that modify an entire clause or sentence.",
parents = {"adverbs"},
}
labels["sequence adverbs"] = {
description = "{{{langname}}} conjunctive adverbs that express sequence in space or time.",
parents = {"conjunctive adverbs"},
}
labels["simulfixes"] = {
description = "Affixes replacing positions in {{{langname}}} words.",
parents = {"morphemes"},
}
labels["singulative nouns"] = {
description = "{{{langname}}} nouns that indicate a single item of a group of related things or beings.",
parents = {"nouns"},
}
labels["singularia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the singular form.",
parents = {"nouns"},
}
labels["solitary pronouns"] = {
description = "{{{langname}}} pronouns that refer to specific people in particular and sets them apart from anyone else.",
parents = {"pronouns", "personal pronouns"},
}
labels["stative verbs"] = {
description = "{{{langname}}} verbs that define a state with no or insignificant internal dynamics.",
parents = {"verbs"},
}
labels["stems"] = {
description = "Morphemes from which {{{langname}}} words are formed.",
parents = {"morphemes"},
}
labels["subordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate relations of syntactic dependence between connected items.",
parents = {"conjunctions"},
}
labels["subject concords"] = {
description = "{{{langname}}} concords used to show the grammatical subject.",
parents = {"concords"},
}
labels["subject pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical subjects.",
parents = {"pronouns"},
}
labels["အဆက်လက္ကရဴ"] = {
description = "မဆက်တောဲဖျပ်ဆက်ဍံၚ်စုတ်နကဵုမတုဲဒှ်မဆေၚ်စပ်ကဵုဝေါဟာဘာသာ{{{langname}}}ဂမၠိုၚ်။",
parents = {"ဗီုယူနေတ်"},
}
labels["splitting verbs"] = {
description = "{{{langname}}} bisyllabic verbs that obligatorily split around a direct object or pronoun.",
parents = {"verbs"},
}
labels["terminative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event ceases.",
parents = {"verbs"},
}
labels["time adverbs"] = {
description = "{{{langname}}} adverbs that indicate time, expressing either [[duration]], [[frequency]] or a [[point]] in [[time]].",
parents = {"adverbs"},
}
labels["transfixes"] = {
description = "Discontinuous affixes inserted within a word root.",
parents = {"morphemes"},
}
labels["transformative verbs"] = {
description = "{{{langname}}} verbs that indicate a change of state or nature, in the subject for intransitive verbs and in the object for transitive verbs.",
parents = {"verbs"},
}
labels["transitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed to one or more grammatical objects.",
parents = {"verbs"},
}
labels["uncomparable adjectives"] = {
description = "{{{langname}}} adjectives that are not inflected to display different degrees of comparison.",
parents = {"adjectives"},
}
labels["uncomparable adverbs"] = {
description = "{{{langname}}} adverbs that are not inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["uncountable nouns"] = {
description = "{{{langname}}} nouns that indicate qualities, ideas, unbounded mass or other abstract concepts that cannot be quantified directly by numerals.",
parents = {"nouns"},
}
labels["uncountable numerals"] = {
description = "{{{langname}}} numerals that cannot be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["uncountable proper nouns"] = {
description = "{{{langname}}} proper nouns that cannot be quantified directly by numerals.",
parents = {"proper nouns"},
}
labels["uncountable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that cannot be quantified directly by numerals.",
parents = {"suffixes"},
}
labels["unpossessable nouns"] = {
description = "{{{langname}}} nouns that cannot have their possession indicated directly by possessive pronouns.",
parents = {"nouns"},
umbrella = {
description = "Categories with nouns that cannot have their possession indicated directly by possessive pronouns or, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Unpossessable nouns by language",
},
}
labels["verbal nouns"] = {
description = "{{{langname}}} nouns morphologically related to a verb and similar to it in meaning.",
parents = {"nouns"},
}
labels["verbal adjectives"] = {
description = "{{{langname}}} adjectives describing the condition or state resulting from the action of the corresponding verb.",
parents = {"adjectives"},
}
labels["ကြိယာ"] = {
description = "ဝေါဟာ{{{langname}}}ပွမယဵုဒုၚ်မစၞောန်ထ္ၜးအတေံ၊ မက္တဵုဒှ်ပရောဟိုတ် ဝါ ကဆံၚ်ဒတန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["verbs of movement"] = {
description = "{{{langname}}} verbs that indicate physical movement of the grammatical subject across a trajectory, with a starting point and an endpoint.",
parents = {"verbs"},
}
for pos, desc in pairs{
["prepositions"] = "following",
["postpositions"] = "preceding"
} do
for _, case in ipairs{
"ablative",
"accusative",
"dative",
"genitive",
"instrumental",
"locative",
"nominative",
"prepositional",
"vocative",
} do
labels[case .. " " .. pos] = {
breadcrumb = ucfirst(case),
description = ("{{{langname}}} %s that cause the %s noun to be in the %s case."):format(pos, desc, case),
parents = {pos},
}
end
end
-- Add "X-only categories for adjectives and adverbs".
for _, pos in pairs{
"adjectives",
"adverbs",
} do
for _, comp in pairs{
"comparative",
"superlative",
"elative",
"equative",
} do
labels[comp .. "-only " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are only used in their " .. comp .. " forms.",
parents = {pos},
}
end
end
-- Add "POS-forming suffixes".
for _, pos in pairs{
"adjective",
"adverb",
"noun",
"verb",
} do
labels[pos .. "-forming suffixes"] = {
description = "{{{langname}}} suffixes that are used to derive " .. pos .. "s from other words.",
parents = {"derivational suffixes"},
}
end
local labels2 = {}
-- Add "reconstructed" subcategories; add 'umbrella_parents' key if not
-- already present.
for key, data in pairs(labels) do
labels2[key] = data
if not data.umbrella_parents then
data.umbrella_parents = "Lemmas subcategories by language"
end
labels2["reconstructed " .. key] = {
description = "{{{langname}}} " .. key .. " that have been linguistically [[Wiktionary:Reconstructed terms|reconstructed]].",
umbrella_parents = "Lemmas subcategories by language",
parents = {key, {name = "reconstructed terms", sort = key}}
}
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["အဘိဓာန်တၞဟ်ခြာကဏ္ဍနကဵုဗက်အလိုက်အရေဝ်ဘာသာ"] = {
description = "Umbrella categories covering topics related to lemmas.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "ဝေါဟာအဓိက", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for e.g. [[:Category:English phrasal verbs formed with "aback"]].
table.insert(handlers, function(data)
local particle = data.label:match("^phrasal verbs formed with \"(.-)\"$")
if particle then
local tagged_text = require("Module:script utilities").tag_text(particle, data.lang, nil, "term")
local link = require("Module:links").full_link({ term = particle, lang = data.lang }, "term")
return {
description = "{{{langname}}} {{w|phrasal verb}}s formed with the adverb or preposition " .. link .. ".",
displaytitle = '{{{langname}}} phrasal verbs formed with "' .. tagged_text .. '"',
breadcrumb = tagged_text,
parents = {{ name = "phrasal verbs", sort = particle }},
umbrella = false,
}
end
end)
return {LABELS = labels2, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
pufxdn1xjiwwyfracnm2om4zzt1ew78
157695
157649
2025-07-10T05:57:36Z
咽頭べさ
33
157695
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local ucfirst = require("Module:string utilities").ucfirst
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
local diminutive_augmentative_poses = {
"နာမဝိသေသန",
"ကြိယာဝိသေသန",
"အာမေဍိက်",
"နာမ်",
"ဂၞန်သင်္ချာ",
"မုက်နာမ်",
"နာမ်မကိတ်ညဳ",
"သဗ္ဗနာမ်",
"အဆက်လက္ကရဴ",
"ကြိယာ"
}
labels["ဝေါဟာအဓိက"] = {
description = "ဝေါဟာ[[ဝိက်ရှေန်နရဳ:ဝေါဟာအဓိက|တံသ္ဇိုၚ်]]{{{langname}}}၊ ကဏ္ဍနူကဵုမပါ်ပရံဒကုတ်မဆေၚ်စပ်ကဵုမအရေဝ်ဝေါဟာ။",
umbrella_parents = "ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
parents = {{name = "{{{langcat}}}", raw = true, sort = " "}},
}
labels["lemmas"] = labels["ဝေါဟာအဓိက"]
labels["abstract verbs"] = {
description = "{{{langname}}} abstract verbs of motion whose motion is multidirectional (as opposed to unidirectional) or indirect, or whose action is repeated or in a series, instead of being a single, completed action. Abstract verbs are always imperfective in aspect, even with prefixes that are normally associated with the perfective aspect.",
additional = "See also [[abstract verb]].",
parents = {"verbs"},
}
labels["action nouns"] = {
description = "{{{langname}}} nouns denoting action of a verb or verbal root that it is derived from.",
parents = {"nouns"},
}
labels["act-related adverbs"] = {
description = "{{{langname}}} adverbs that indicate the motive or other background information for an action.",
parents = {"adverbs"},
}
labels["active verbs"] = {
description = "{{{langname}}} verbs that indicate an activity",
parents = {"verbs"},
}
labels["active-only verbs"] = {
description = "{{{langname}}} verbs that can only be used with the {{w|active voice}}.",
parents = {"verbs"},
}
labels["adjective concords"] = {
description = "{{{langname}}} concords that are prefixed to adjective stems.",
parents = {"concords"},
}
labels["နာမဝိသေသန"] = {
description = "ဝေါဟာ{{{langname}}}မဒုၚ်ကေတ်အၚ်္ဂအဝဲဂုန်နကဵုနာမ်ဂမၠိုၚ်၊ မဒုၚ်ကဵုကေတ်အဓိပ္ပာဲအတေံဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["adverbial accusatives"] = {
description = "Accusative case-forms in {{{langname}}} used as adverbs.",
parents = {"adverbs"},
}
labels["ကြိယာဝိသေသန"] = {
description = "ဝေါဟာ{{{langname}}}မပြုပြေၚ်ပြံၚ်လှာဲလဝ်ပိုဒ်လိက်ဂမၠိုၚ်၊ ပိုတ်ဂမၠိုၚ် ကဵု ဇၟန်လိက်တပ်ပ်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["အဆက်ဖျပ်စုတ်လက္ကရဴ"] = {
description = "Morphemes attached to existing {{{langname}}} words.",
parents = {"morphemes"},
}
labels["agent nouns"] = {
description = "{{{langname}}} nouns that denote an agent that performs the action denoted by the verb from which the noun is derived.",
parents = {"nouns"},
}
labels["ambipositions"] = {
description = "{{{langname}}} adpositions that can occur either before or after their objects.",
parents = {"lemmas"},
}
labels["ambitransitive verbs"] = {
description = "{{{langname}}} verbs that may or may not direct actions, occurrences or states to grammatical objects.",
parents = {"verbs", "transitive verbs", "intransitive verbs"},
}
labels["animal commands"] = {
description = "{{{langname}}} words used to communicate with animals.",
parents = {"interjections"},
}
labels["ပစ္စဲ"] = {
description = "ဝေါဟာဘာသာ{{{langname}}}စၞောန်ထ္ၜးကဵုအတေံ ကဵု နာမ်ချိုတ်ချိုတ်ပၠိုတ်ပၠိုတ်။",
parents = {"ဖျေံလဝ်သန္နိဋ္ဌာန်"},
}
labels["aspect adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Grammatical aspect|grammatical aspect]], describing the flow of time in relation to a statement.",
parents = {"adverbs"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["augmentative " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey big size or big intensity.",
parents = {pos},
}
end
labels["attenuative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event is performed or takes place gently, lightly, partially, perfunctorily or to an otherwise reduced extent.",
parents = {"verbs"},
}
labels["autobenefactive verbs"] = {
description = "{{{langname}}} verbs that indicate that the agent of an action is also its benefactor.",
parents = {"verbs"},
}
labels["automative verbs"] = {
description = "{{{langname}}} verbs that indicate actions directed at or a change of state of the grammatical subject.",
parents = {"verbs"},
}
labels["auxiliary verbs"] = {
description = "{{{langname}}} verbs that provide additional conjugations for other verbs.",
parents = {"verbs"},
}
labels["biaspectual verbs"] = {
description = "{{{langname}}} verbs that can be both imperfective and perfective.",
parents = {"verbs"},
}
labels["causative verbs"] = {
description = "{{{langname}}} verbs that express causing actions or states rather than performing or being them directly. Use this only for separate verbs (as opposed to causative forms that are part of the inflection of verbs).",
parents = {"verbs"},
}
labels["circumfixes"] = {
description = "Affixes attached to both the beginning and the end of {{{langname}}} words, functioning together as single units.",
parents = {"morphemes"},
}
labels["circumpositions"] = {
description = "{{{langname}}} adpositions that appear on both sides of their objects.",
parents = {"lemmas"},
}
labels["နာမ်ပါ်ကၞာတ်"] = {
description = "{{{langname}}} terms that classify nouns according to their meanings.",
parents = {"ဝေါဟာအဓိက"},
}
labels["clitics"] = {
description = "{{{langname}}} morphemes that function as independent words, but are always attached to another word.",
parents = {"morphemes"},
}
for _, pos in ipairs { "နာမ်", "အဆက်လက္ကရဴ" } do
labels["collective " .. pos] = {
description = "{{{langname}}} " .. pos .. " that indicate groups of related things or beings, without the need of grammatical pluralization.",
parents = {pos},
}
end
labels["combining forms"] = {
description = "Forms of {{{langname}}} words that do not occur independently, but are used when joined with other words.",
parents = {"morphemes"},
}
labels["comparable adjectives"] = {
description = "{{{langname}}} adjectives that can be inflected to display different degrees of comparison.",
parents = {"adjectives"},
}
labels["comparable adverbs"] = {
description = "{{{langname}}} adverbs that can be inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["completive verbs"] = {
description = "{{{langname}}} verbs which refer to the completion of an action which has already commenced or which has already been performed upon a subset of the entities which it affects.",
parents = {"verbs"},
}
labels["concords"] = {
description = "{{{langname}}} prefixes attached to words to show agreement with a noun or pronoun.",
parents = {"prefixes"},
}
labels["concrete verbs"] = {
description = "{{{langname}}} concrete verbs refer to a verbal aspect in verbs of motion that is unidirectional (as opposed to multidirectional), a definitely directed motion, or a single, completed action (instead of a repeated action or series of actions). Concrete verbs may be either imperfective or perfective.",
additional = "See also [[concrete verb]].",
parents = {"verbs"},
}
labels["conjunctions"] = {
description = "{{{langname}}} terms that connect words, phrases or clauses together.",
parents = {"lemmas"},
}
labels["conjunctive adverbs"] = {
description = "{{{langname}}} adverbs that connect two independent clauses together.",
parents = {"adverbs"},
}
labels["continuative verbs"] = {
description = "{{{langname}}} verbs that express continuing action.",
parents = {"verbs"},
}
labels["control verbs"] = {
description = "{{{langname}}} verbs that take multiple arguments, one of which is another verb. One of the control verb's arguments is syntactically both an argument of the control verb and an argument of the other verb.",
parents = {"verbs"},
}
labels["cooperative verbs"] = {
description = "{{{langname}}} verbs that indicate cooperation",
parents = {"verbs"},
}
labels["coordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate equal syntactic importance between connected items.",
parents = {"conjunctions"},
}
labels["copulative verbs"] = {
description = "{{{langname}}} verbs that may take adjectives as their complement.",
parents = {"verbs"},
}
for _, pos in ipairs { "နာမ်", "နာမ်မကိတ်ညဳ" } do
labels["countable " .. pos] = {
description = "{{{langname}}} " .. pos .. " that can be quantified directly by numerals.",
parents = {pos},
}
end
labels["countable numerals"] = {
description = "{{{langname}}} numerals that can be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["countable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that can be quantified directly by numerals.",
parents = {"suffixes"},
}
labels["counters"] = {
description = "{{{langname}}} terms that combine with numerals to express quantity of nouns.",
parents = {"lemmas"},
}
labels["cumulative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event gradually yields a certain or significant quantity or effect.",
parents = {"verbs"},
}
labels["degree adverbs"] = {
description = "{{{langname}}} adverbs that express a particular degree to which the word they modify applies.",
parents = {"adverbs"},
}
labels["delimitative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event is performed or takes place briefly or to an otherwise reduced extent.",
parents = {"verbs"},
}
labels["demonstrative adjectives"] = {
description = "{{{langname}}} adjectives that refer to nouns, comparing them to external references.",
parents = {"adjectives", {name = "demonstrative pro-forms", sort = "adjectives"}},
}
labels["demonstrative adverbs"] = {
description = "{{{langname}}} adverbs that refer to other adverbs, comparing them to external references.",
parents = {"adverbs", {name = "demonstrative pro-forms", sort = "adverbs"}},
}
labels["denominal verbs"] = { -- in [[Appendix:Glossary]]; "denominative" more frequent?
description = "{{{langname}}} verbs that derive from nouns.",
parents = { "verbs" },
}
labels["demonstrative determiners"] = {
description = "{{{langname}}} determiners that refer to nouns, comparing them to external references.",
parents = {"determiners", {name = "demonstrative pro-forms", sort = "determiners"}},
}
labels["demonstrative pronouns"] = {
description = "{{{langname}}} pronouns that refer to nouns, comparing them to external references.",
parents = {"pronouns", {name = "demonstrative pro-forms", sort = "pronouns"}},
}
labels["deponent verbs"] = {
description = "{{{langname}}} verbs that can only be used with the {{w|active voice}}, but which conjugate as though they were being used with a difference voice.",
parents = {"active-only verbs", "verbs"},
}
labels["derivational prefixes"] = {
description = "{{{langname}}} prefixes that are used to create new words.",
parents = {"prefixes"},
}
labels["derivational suffixes"] = {
description = "{{{langname}}} suffixes that are used to create new words.",
parents = {"suffixes"},
}
labels["derivative verbs"] = {
description = "{{{langname}}} verbs that are derived from nouns and adjectives.",
parents = {"verbs"},
}
labels["desiderative verbs"] = {
description = "{{{langname}}} verbs with the following morphology: verbal root xxx + [[desiderative]] affix, and the following semantics: to wish to do the action xxx.",
parents = {"verbs"},
}
labels["determinatives"] = {
description = "{{{langname}}} terms that indicate the general class to which the following logogram belongs.",
parents = {"lemmas"},
}
labels["ဖျေံလဝ်သန္နိဋ္ဌာန်"] = {
description = "{{{langname}}} terms that narrow down, within the conversational context, the referent of the following noun.",
parents = {"ဝေါဟာအဓိက"},
}
labels["diminutiva tantum"] = {
description = "{{{langname}}} nouns or noun senses that are mostly or exclusively used in the diminutive form.",
parents = {"nouns"},
}
for _, pos in ipairs(diminutive_augmentative_poses) do
labels["diminutive " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are derived from a base word to convey endearment, small size or small intensity.",
parents = {pos},
}
end
labels["discourse particles"] = {
description = "{{{langname}}} particles that manage the flow and structure of discourse.",
parents = {"particles"},
}
labels["distributive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action or event involves multiple participants or a large quantity of an uncountable mass, usually as the grammatical subject in the case of intransitive verbs and as the grammatical object in the case of transitive verbs.",
parents = {"verbs"},
}
labels["ditransitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states of two grammatical objects simultaneously, one direct and one indirect.",
parents = {"verbs", "transitive verbs"},
}
labels["dualia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the dual form.",
parents = {"nouns"},
}
labels["duration adverbs"] = {
description = "{{{langname}}} adverbs that express duration in time, such as (in English) [[always]], [[all night]] and [[ever since]].",
parents = {"time adverbs"},
}
labels["ergative verbs"] = {
description = "{{{langname}}} [[Appendix:Glossary#ergative|ergative verb]]s: intransitive verbs that become causatives when used transitively.",
parents = {"verbs", "intransitive verbs", "transitive verbs"},
}
labels["excessive verbs"] = {
description = "{{{langname}}} verbs that indicate that an action is performed to an excessive extent.",
parents = {"verbs"},
}
labels["enclitics"] = {
description = "{{{langname}}} clitics that attach to the preceding word.",
parents = {"clitics"},
}
labels["nouns with other-gender equivalents"] = {
description = "{{{langname}}} nouns that refer to gendered concepts (e.g. [[actor]] vs. [[actress]], [[king]] vs. [[queen]]) and have corresponding other-gender equivalent terms.",
parents = {"nouns"},
}
labels["female equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to female beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["neuter equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to neuter beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["female equivalent suffixes"] = {
description = "{{{langname}}} suffixes that refer to female beings with the same characteristics as the base suffix.",
parents = {"noun-forming suffixes"},
}
labels["focus adverbs"] = {
description = "{{{langname}}} adverbs that indicate [[w:Focus (linguistics)|focus]] within the sentence.",
parents = {"adverbs"},
}
labels["frequency adverbs"] = {
description = "{{{langname}}} adverbs that express repetition with a certain frequency or interval, such as (in English) [[monthly]], [[continually]] and [[once in a while]].",
parents = {"time adverbs"},
}
labels["frequentative verbs"] = {
description = "{{{langname}}} verbs that express repeated action.",
parents = {"verbs"},
}
labels["general pronouns"] = {
description = "{{{langname}}} pronouns that refer to all persons, things, abstract ideas and their characteristics.",
parents = {"pronouns"},
}
labels["generational moieties"] = {
description = "{{{langname}}} moieties that alternate every generation.",
parents = {"moieties"},
}
labels["ideophones"] = {
description = "{{{langname}}} terms that evoke an idea, especially a sensation or impression, with a sound.",
parents = {"lemmas"},
}
labels["imperfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as ongoing or continuous, as opposed to completed events.",
parents = {"verbs"},
}
labels["impersonal verbs"] = {
description = "{{{langname}}} verbs that do not indicate actions, occurrences or states of any specific grammatical subject.",
parents = {"verbs"},
}
labels["inchoative verbs"] = {
description = "{{{langname}}} verbs that indicate the beginning of an action or event.",
parents = {"verbs"},
}
labels["indefinite adjectives"] = {
description = "{{{langname}}} adjectives that refer to unspecified adjective meanings.",
parents = {"adjectives", {name = "indefinite pro-forms", sort = "adjectives"}},
}
labels["indefinite adverbs"] = {
description = "{{{langname}}} adverbs that refer to unspecified adverbial meanings.",
parents = {"adverbs", {name = "indefinite pro-forms", sort = "adverbs"}},
}
labels["indefinite determiners"] = {
description = "{{{langname}}} determiners that designate an unidentified noun.",
parents = {"determiners", {name = "indefinite pro-forms", sort = "determiners"}},
}
labels["indefinite pronouns"] = {
description = "{{{langname}}} pronouns that refer to unspecified nouns.",
parents = {"pronouns", {name = "indefinite pro-forms", sort = "pronouns"}},
}
labels["စန်{{{langname}}}ဂမၠိုင်"] = {
description = "Affixes inserted inside {{{langname}}} words.",
parents = {"morphemes"},
}
labels["inflectional prefixes"] = {
description = "{{{langname}}} prefixes that are used as inflectional beginnings in noun, adjective or verb paradigms.",
parents = {"prefixes"},
}
labels["inflectional suffixes"] = {
description = "{{{langname}}} suffixes that are used as inflectional endings in noun, adjective or verb paradigms.",
parents = {"suffixes"},
}
labels["intensive verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed vigorously, enthusiastically, forcefully or to an otherwise enlarged extent.",
parents = {"verbs"},
}
labels["interfixes"] = {
description = "Affixes used to join two {{{langname}}} words or morphemes together.",
parents = {"morphemes"},
}
labels["အာမေဍိက်"] = {
description = "ဝေါဟာ{{{langname}}}ဓမံက်ထ္ၜးပရေၚ်သ္ဒးဒုၚ်စသိုၚ်ဂမၠိုၚ်၊ ရမျာၚ်ဂမၠိုၚ်၊ ဥပမာ ညံၚ်ကရေဲကညာၚ်တိုန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["interrogative adjectives"] = {
description = "{{{langname}}} adjectives that indicate questions.",
parents = {"adjectives", {name = "interrogative pro-forms", sort = "adjectives"}},
}
labels["interrogative adverbs"] = {
description = "{{{langname}}} adverbs that indicate questions.",
parents = {"adverbs", {name = "interrogative pro-forms", sort = "adverbs"}},
}
labels["interrogative determiners"] = {
description = "{{{langname}}} determiners that indicate questions.",
parents = {"determiners", {name = "interrogative pro-forms", sort = "determiners"}},
}
labels["interrogative particles"] = {
description = "{{{langname}}} particles that indicate questions.",
parents = {"particles", {name = "interrogative pro-forms", sort = "particles"}},
}
labels["interrogative pronouns"] = {
description = "{{{langname}}} pronouns that indicate questions.",
parents = {"pronouns", {name = "interrogative pro-forms", sort = "pronouns"}},
}
labels["intransitive verbs"] = {
description = "{{{langname}}} verbs that don't require any grammatical objects.",
parents = {"verbs"},
}
labels["iterative verbs"] = {
description = "{{{langname}}} verbs that express the repetition of an event.",
parents = {"verbs"},
}
labels["location adverbs"] = {
description = "{{{langname}}} adverbs that indicate location.",
parents = {"adverbs"},
}
labels["male equivalent nouns"] = {
description = "{{{langname}}} nouns that refer to male beings with the same characteristics as the base noun.",
parents = {"nouns with other-gender equivalents"},
}
labels["manner adverbs"] = {
description = "{{{langname}}} adverbs that indicate the manner, way or style in which an action is performed.",
parents = {"adverbs"},
}
labels["middle verbs"] = {
description = "{{{langname}}} verbs that are used in {{w|middle voice}}.",
parents = {"verbs"},
}
labels["modal adverbs"] = {
description = "{{{langname}}} adverbs that express [[w:Linguistic modality|linguistic modality]], indicating the mood or attitude of the speaker with respect to what is being said.",
parents = {"sentence adverbs"},
}
labels["modal particles"] = {
description = "{{{langname}}} particles that reflect the mood or attitude of the speaker, without changing the basic meaning of the sentence.",
parents = {"particles"},
}
labels["modal verbs"] = {
description = "{{{langname}}} verbs that indicate [[grammatical mood]].",
parents = {"auxiliary verbs"},
}
labels["moieties"] = {
description = "{{{langname}}} pairs of abstract categories separating people and the environment.",
parents = {"lemmas"},
}
labels["momentane verbs"] = {
description = "{{{langname}}} verbs that express a sudden and brief action.",
parents = {"verbs"},
}
labels["morphemes"] = {
description = "{{{langname}}} word-elements used to form full words.",
parents = {"lemmas"},
}
labels["multiword terms"] = {
description = "{{{langname}}} lemmas that are a combination of multiple words, including [[WT:CFI#Idiomaticity|idiomatic]] combinations.",
parents = {"lemmas"},
}
labels["negative verbs"] = {
description = "{{{langname}}} verbs that indicate the lack of an action.",
parents = {"verbs"},
}
labels["negative particles"] = {
description = "{{{langname}}} particles that indicate negation.",
parents = {"particles"},
}
labels["negative pronouns"] = {
description = "{{{langname}}} pronouns that refer to negative or non-existent references.",
parents = {"pronouns"},
}
labels["neutral verbs"] = {
description = "{{{langname}}} verbs that indicate either or both an activity or a result of an activity",
parents = {"verbs"},
}
labels["nominalized adjectives"] = {
description = "{{{langname}}} adjectives that are used as nouns.",
parents = {"nouns", "adjectives"},
}
labels["non-constituents"] = {
description = "{{{langname}}} terms that are not grammatical [[constituent#Noun|constituents]], and therefore need to be combined with additional terms to form a complete phrase.",
parents = {"phrases"},
}
labels["noun prefixes"] = {
description = "{{{langname}}} prefixes attached to a noun that display its noun class.",
parents = {"prefixes"},
}
labels["nouns"] = {
description = "{{{langname}}} terms that indicate people, beings, things, places, phenomena, qualities or ideas.",
parents = {"lemmas"},
}
labels["nouns by classifier"] = {
description = "{{{langname}}} nouns organized by the classifier they are used with.",
parents = {{name = "nouns", sort = "classifier"}},
}
labels["ဂၞန်သင်္ချာ"] = {
description = "ဝေါဟာ{{{langname}}}ပွမပ္ညုၚ်ထ္ၜးနာမ်တော်လျိုၚ်နာမ်ဂွံမာန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["object concords"] = {
description = "{{{langname}}} concords used to show the grammatical object.",
parents = {"concords"},
}
labels["object pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical objects.",
parents = {"pronouns"},
}
labels["ကၞာတ်အမှိက်"] = {
description = "{{{langname}}} terms that do not belong to any of the inflected grammatical word classes, often lacking their own grammatical functions and forming other parts of speech or expressing the relationship between clauses.",
parents = {"lemmas"},
}
labels["passive verbs"] = {
description = "{{{langname}}} verbs that are usually used in the {{w|passive voice}}.",
parents = {"verbs"},
}
labels["perfective verbs"] = {
description = "{{{langname}}} verbs that express actions considered as completed events, as opposed to ongoing or continuous.",
parents = {"verbs"},
}
labels["personal pronouns"] = {
description = "{{{langname}}} pronouns that are used as substitutes for known nouns.",
parents = {"pronouns"},
}
labels["phrasal verbs"] = {
description = "{{{langname}}} verbs accompanied by particles, such as prepositions and adverbs.",
parents = {"verbs", "phrases"},
}
labels["phrasal prepositions"] = {
description = "{{{langname}}} prepositions formed with combinations of other terms.",
parents = {"prepositions", "phrases"},
}
labels["pluralia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the plural form.",
parents = {"nouns"},
}
labels["point-in-time adverbs"] = {
description = "{{{langname}}} adverbs that reference a specific point in time, e.g. {{m|en|yesterday}}, {{m+|es|anoche||last night}} or {{m+|hu|egykor||at one o'clock}}.",
parents = {"time adverbs"},
}
labels["possessable nouns"] = {
description = "{{{langname}}} nouns can have their possession indicated directly by possessive pronouns.",
parents = {"nouns"},
umbrella = {
description = "Categories with nouns that can have their possession indicated directly by possessive pronouns and, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Possessable nouns by language",
},
}
labels["possessional adjectives"] = {
description = "{{{langname}}} adjectives that indicate that a noun is in possession of something.",
parents = {"adjectives"},
}
labels["possessive adjectives"] = {
description = "{{{langname}}} adjectives that indicate ownership.",
parents = {"adjectives"},
}
labels["possessive concords"] = {
description = "{{{langname}}} concords used to show possession.",
parents = {"concords"},
}
labels["possessive determiners"] = {
description = "{{{langname}}} determiners that indicate ownership.",
parents = {"determiners"},
}
labels["possessive pronouns"] = {
description = "{{{langname}}} pronouns that indicate ownership.",
parents = {"pronouns"},
}
labels["postpositional phrases"] = {
description = "{{{langname}}} phrases headed by a postposition.",
parents = {"phrases", "postpositions"},
}
labels["ကဆံင်"] = {
description = "{{{langname}}} adpositions that are placed after their objects.",
parents = {"ဝေါဟာအဓိက"},
}
labels["predicatives"] = {
description = "{{{langname}}} elements of the predicate that supplement the subject or object of a sentence via the verb.",
parents = {"lemmas"},
}
labels["မုက်နာမ်"] = {
description = "Affixes attached to the beginning of {{{langname}}} words.",
parents = {"morphemes"},
}
labels["prepositional phrases"] = {
description = "{{{langname}}} phrases headed by a preposition.",
parents = {"phrases", "prepositions"},
}
labels["ဝိဘတ်"] = {
description = "{{{langname}}} adpositions that are placed before their objects.",
parents = {"lemmas"},
}
labels["matrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's mother.",
parents = {"moieties"},
}
labels["patrilineal moieties"] = {
description = "{{{langname}}} moieties inherited from an individual's father.",
parents = {"moieties"},
}
labels["pejorative suffixes"] = {
description = "{{{langname}}} suffixes that [[belittle]] (lessen in value).",
parents = {"suffixes"},
}
labels["သဗ္ဗနာမ်"] = {
description = "ဝေါဟာ{{{langname}}}နကဵုစပ်ဖျပ် ကဵု စၞးနာမ်ဂမၠိုၚ်။",
parents = {"မုက်နာမ်"},
}
labels["ပေါရာဏာံပေါရာဒါံ"] = {
description = "{{{langname}}} prefixes of various kinds that are attached to verbs.",
parents = {"မုက်နာမ်"},
}
labels["privative verbs"] = {
description = "{{{langname}}} verbs that indicate that the grammatical object is deprived of something or that something is removed from the object.",
parents = {"verbs"},
}
labels["pronominal adverbs"] = {
description = "{{{langname}}} adverbs that are formed by combining a pronoun with a preposition.",
parents = {"adverbs", "prepositions", "pronouns"},
}
labels["pronominal concords"] = {
description = "{{{langname}}} concords that are prefixed to pronominal stems.",
parents = {"concords"},
}
labels["pronouns"] = {
description = "{{{langname}}} terms that refer to and substitute nouns.",
parents = {"lemmas"},
}
labels["နာမ်မကိတ်ညဳ"] = {
description = "{{{langname}}} nouns that indicate individual entities, such as names of persons, places or organizations.",
parents = {"နာမ်"},
}
labels["raising verbs"] = {
description = "{{{langname}}} verbs that, in a matrix or main clause, take an argument from an embedded or subordinate clause; in other words, a raising verb appears with a syntactic argument that is not its semantic argument, but is rather the semantic argument of an embedded predicate.",
parents = {"verbs"},
}
labels["reciprocal pronouns"] = {
description = "{{{langname}}} pronouns that refer back to a plural subject and express an action done in two or more directions.",
parents = {"pronouns", "personal pronouns"},
}
labels["reciprocal verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from multiple subjects to each other.",
parents = {"verbs"},
}
labels["reflexive pronouns"] = {
description = "{{{langname}}} pronouns that refer back to the subject.",
parents = {"pronouns", "personal pronouns"},
}
labels["reflexive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed from the grammatical subjects to themselves.",
parents = {"verbs"},
}
labels["relational adjectives"] = {
description = "{{{langname}}} adjectives that stand in place of a noun when modifying another noun.",
parents = {"adjectives"},
}
labels["relational nouns"] = {
description = "{{{langname}}} nouns used to indicate a relation between other two nouns by means of possession.",
parents = {"nouns"},
}
labels["relative adjectives"] = {
description = "{{{langname}}} adjectives used to indicate [[relative clause]]s.",
parents = {"adjectives", {name = "relative pro-forms", sort = "adjectives"}},
}
labels["relative adverbs"] = {
description = "{{{langname}}} adverbs used to indicate [[relative clause]]s.",
parents = {"adverbs", {name = "relative pro-forms", sort = "adverbs"}},
}
labels["relative determiners"] = {
description = "{{{langname}}} determiners used to indicate [[relative clause]]s.",
parents = {"determiners", {name = "relative pro-forms", sort = "determiners"}},
}
labels["relative concords"] = {
description = "{{{langname}}} concords that are prefixed to relative stems.",
parents = {"concords"},
}
labels["relative pronouns"] = {
description = "{{{langname}}} pronouns used to indicate [[relative clause]]s.",
parents = {"pronouns", {name = "relative pro-forms", sort = "pronouns"}},
}
labels["relatives"] = {
description = "{{{langname}}} terms that give attributes to nouns, acting grammatically as relative clauses.",
parents = {"lemmas"},
}
labels["repetitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions or events which are performed or occur again, anew or differently.",
parents = {"verbs"},
}
labels["resultative verbs"] = {
description = "{{{langname}}} verbs that indicate a result of some action",
parents = {"verbs"},
}
labels["reversative verbs"] = {
description = "{{{langname}}} verbs that indicate that the reversal or undoing of an action, event or state.",
parents = {"verbs"},
}
labels["saturative verbs"] = {
description = "{{{langname}}} verbs which indicate that an action is performed to the point of saturation or satisfaction.",
parents = {"verbs"},
}
labels["semelfactive verbs"] = {
description = "{{{langname}}} verbs that are punctual (instantaneous, momentive), perfective (treated as a unitary whole with no explicit internal temporal structure), and telic (having a boundary out of which the activity cannot be said to have taken place or continue).",
parents = {"verbs"},
}
labels["sentence adverbs"] = {
description = "{{{langname}}} adverbs that modify an entire clause or sentence.",
parents = {"adverbs"},
}
labels["sequence adverbs"] = {
description = "{{{langname}}} conjunctive adverbs that express sequence in space or time.",
parents = {"conjunctive adverbs"},
}
labels["simulfixes"] = {
description = "Affixes replacing positions in {{{langname}}} words.",
parents = {"morphemes"},
}
labels["singulative nouns"] = {
description = "{{{langname}}} nouns that indicate a single item of a group of related things or beings.",
parents = {"nouns"},
}
labels["singularia tantum"] = {
description = "{{{langname}}} nouns that are mostly or exclusively used in the singular form.",
parents = {"nouns"},
}
labels["solitary pronouns"] = {
description = "{{{langname}}} pronouns that refer to specific people in particular and sets them apart from anyone else.",
parents = {"pronouns", "personal pronouns"},
}
labels["stative verbs"] = {
description = "{{{langname}}} verbs that define a state with no or insignificant internal dynamics.",
parents = {"verbs"},
}
labels["stems"] = {
description = "Morphemes from which {{{langname}}} words are formed.",
parents = {"morphemes"},
}
labels["subordinating conjunctions"] = {
description = "{{{langname}}} conjunctions that indicate relations of syntactic dependence between connected items.",
parents = {"conjunctions"},
}
labels["subject concords"] = {
description = "{{{langname}}} concords used to show the grammatical subject.",
parents = {"concords"},
}
labels["subject pronouns"] = {
description = "{{{langname}}} pronouns that refer to grammatical subjects.",
parents = {"pronouns"},
}
labels["အဆက်လက္ကရဴ"] = {
description = "မဆက်တောဲဖျပ်ဆက်ဍံၚ်စုတ်နကဵုမတုဲဒှ်မဆေၚ်စပ်ကဵုဝေါဟာဘာသာ{{{langname}}}ဂမၠိုၚ်။",
parents = {"ဗီုယူနေတ်"},
}
labels["splitting verbs"] = {
description = "{{{langname}}} bisyllabic verbs that obligatorily split around a direct object or pronoun.",
parents = {"verbs"},
}
labels["terminative verbs"] = {
description = "{{{langname}}} verbs that indicate that an action or event ceases.",
parents = {"verbs"},
}
labels["time adverbs"] = {
description = "{{{langname}}} adverbs that indicate time, expressing either [[duration]], [[frequency]] or a [[point]] in [[time]].",
parents = {"adverbs"},
}
labels["transfixes"] = {
description = "Discontinuous affixes inserted within a word root.",
parents = {"morphemes"},
}
labels["transformative verbs"] = {
description = "{{{langname}}} verbs that indicate a change of state or nature, in the subject for intransitive verbs and in the object for transitive verbs.",
parents = {"verbs"},
}
labels["transitive verbs"] = {
description = "{{{langname}}} verbs that indicate actions, occurrences or states directed to one or more grammatical objects.",
parents = {"verbs"},
}
labels["uncomparable adjectives"] = {
description = "{{{langname}}} adjectives that are not inflected to display different degrees of comparison.",
parents = {"adjectives"},
}
labels["uncomparable adverbs"] = {
description = "{{{langname}}} adverbs that are not inflected to display different degrees of comparison.",
parents = {"adverbs"},
}
labels["uncountable nouns"] = {
description = "{{{langname}}} nouns that indicate qualities, ideas, unbounded mass or other abstract concepts that cannot be quantified directly by numerals.",
parents = {"nouns"},
}
labels["uncountable numerals"] = {
description = "{{{langname}}} numerals that cannot be quantified directly by other numerals.",
parents = {"numerals"},
}
labels["uncountable proper nouns"] = {
description = "{{{langname}}} proper nouns that cannot be quantified directly by numerals.",
parents = {"proper nouns"},
}
labels["uncountable suffixes"] = {
description = "{{{langname}}} suffixes that can be used to form nouns that cannot be quantified directly by numerals.",
parents = {"suffixes"},
}
labels["unpossessable nouns"] = {
description = "{{{langname}}} nouns that cannot have their possession indicated directly by possessive pronouns.",
parents = {"nouns"},
umbrella = {
description = "Categories with nouns that cannot have their possession indicated directly by possessive pronouns or, in some languages, be transformed into adjectives.",
parents = {"Lemmas subcategories by language"},
breadcrumb = "Unpossessable nouns by language",
},
}
labels["verbal nouns"] = {
description = "{{{langname}}} nouns morphologically related to a verb and similar to it in meaning.",
parents = {"nouns"},
}
labels["verbal adjectives"] = {
description = "{{{langname}}} adjectives describing the condition or state resulting from the action of the corresponding verb.",
parents = {"adjectives"},
}
labels["ကြိယာ"] = {
description = "ဝေါဟာ{{{langname}}}ပွမယဵုဒုၚ်မစၞောန်ထ္ၜးအတေံ၊ မက္တဵုဒှ်ပရောဟိုတ် ဝါ ကဆံၚ်ဒတန်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["verbs of movement"] = {
description = "{{{langname}}} verbs that indicate physical movement of the grammatical subject across a trajectory, with a starting point and an endpoint.",
parents = {"verbs"},
}
for pos, desc in pairs{
["prepositions"] = "following",
["postpositions"] = "preceding"
} do
for _, case in ipairs{
"ablative",
"accusative",
"dative",
"genitive",
"instrumental",
"locative",
"nominative",
"prepositional",
"vocative",
} do
labels[case .. " " .. pos] = {
breadcrumb = ucfirst(case),
description = ("{{{langname}}} %s that cause the %s noun to be in the %s case."):format(pos, desc, case),
parents = {pos},
}
end
end
-- Add "X-only categories for adjectives and adverbs".
for _, pos in pairs{
"adjectives",
"adverbs",
} do
for _, comp in pairs{
"comparative",
"superlative",
"elative",
"equative",
} do
labels[comp .. "-only " .. pos] = {
description = "{{{langname}}} " .. pos .. " that are only used in their " .. comp .. " forms.",
parents = {pos},
}
end
end
-- Add "POS-forming suffixes".
for _, pos in pairs{
"adjective",
"adverb",
"noun",
"verb",
} do
labels[pos .. "-forming suffixes"] = {
description = "{{{langname}}} suffixes that are used to derive " .. pos .. "s from other words.",
parents = {"derivational suffixes"},
}
end
local labels2 = {}
-- Add "reconstructed" subcategories; add 'umbrella_parents' key if not
-- already present.
for key, data in pairs(labels) do
labels2[key] = data
if not data.umbrella_parents then
data.umbrella_parents = "Lemmas subcategories by language"
end
labels2["reconstructed " .. key] = {
description = "{{{langname}}} " .. key .. " that have been linguistically [[Wiktionary:Reconstructed terms|reconstructed]].",
umbrella_parents = "Lemmas subcategories by language",
parents = {key, {name = "reconstructed terms", sort = key}}
}
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["အဘိဓာန်တၞဟ်ခြာကဏ္ဍနကဵုဗက်အလိုက်အရေဝ်ဘာသာ"] = {
description = "Umbrella categories covering topics related to lemmas.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "ဝေါဟာအဓိက", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for e.g. [[:Category:English phrasal verbs formed with "aback"]].
table.insert(handlers, function(data)
local particle = data.label:match("^phrasal verbs formed with \"(.-)\"$")
if particle then
local tagged_text = require("Module:script utilities").tag_text(particle, data.lang, nil, "term")
local link = require("Module:links").full_link({ term = particle, lang = data.lang }, "term")
return {
description = "{{{langname}}} {{w|phrasal verb}}s formed with the adverb or preposition " .. link .. ".",
displaytitle = '{{{langname}}} phrasal verbs formed with "' .. tagged_text .. '"',
breadcrumb = tagged_text,
parents = {{ name = "phrasal verbs", sort = particle }},
umbrella = false,
}
end
end)
return {LABELS = labels2, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
sdnhks8nost6dzjroir49aiaanoeh4h
မဝ်ဂျူ:category tree/miscellaneous
828
1752
157697
157390
2025-07-10T09:29:28Z
咽頭べさ
33
157697
Scribunto
text/plain
local labels = {}
local raw_categories = {}
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
-- Appendices
labels["အဆက်လက္ကရဴဂမၠိုၚ်"] = {
description = "မုက်လိက်မနွံဒၞာဲစရင်စွံလဝ်မဆေင်စပ်ကဵု {{{langdisp}}}။",
parents = {{name = "{{{langcat}}}", raw = true}},
umbrella = {
description = "Categories with pages containing additional information about a given language.",
parents = {"ကဏ္ဍ:အဆက်လက္ကရဴဂမၠိုၚ်"},
breadcrumb = "ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်",
},
}
-- Citations
labels["နိဿဲဂမၠိုၚ်"] = {
description = "Pages documenting instances of actual usage of {{{langname}}} terms.",
parents = {{name = "{{{langcat}}}", raw = true}},
umbrella = {
description = "Categories with pages documenting instances of actual usage of terms in a given language.",
parents = {"ကဏ္ဍ:နိဿဲဂမၠိုၚ်"},
breadcrumb = "နိဿဲဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်",
},
}
labels["ဗီုပြၚ်နိဿဲဟွံဂွံစွံလဝ်"] = {
description = "Pages documenting instances of actual usage of {{{langname}}} terms, but for which the term is not defined yet.",
additional = "Citation pages in {{{langdisp}}} are automatically added here when any of the corresponding entries is a redlink. You can also add citation pages to this category manually when the entry exists but it has not a(n) {{{langname}}} section yet or has not been defined in that specific meaning. Before removing a page from this category, please verify that all citations relate to senses properly defined in the entry.",
parents = {"citations"},
umbrella = {
description = "Categories with pages documenting instances of actual usage of terms in a given language, but for which the term is not defined yet.",
parents = {"အာတ်မိက်", "ကဏ္ဍ:နိဿဲဂမၠိုၚ်"},
breadcrumb = "ဗီုပြင်နိဿဲဟွံဂွံစွံလဝ်ပါ်ပရံဗက်အရေဝ်ဘာသာ",
},
can_be_empty = true,
hidden = true,
}
-- Thesaurus entries
labels["thesaurus entries"] = {
description = "[[WT:WS|Thesaurus]] entries for listing [[Wiktionary:Semantic relations|semantically related terms]] such as [[synonym]]s, [[antonym]]s, [[hyponym]]s, [[hypernym]]s, [[meronym]]s, and [[holonym]]s of {{{langname}}} words.",
parents = {{name = "{{{langcat}}}", raw = true}},
umbrella = {
description = "Categories with [[WT:WS|thesaurus]] entries for listing [[Wiktionary:Semantic relations|semantically related terms]].",
breadcrumb = "By language",
parents = {{name = "Category:Thesaurus", sort = " "}},
},
}
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်"] = {
topright = "{{commonscat|CommonsRoot}}",
description = "This page is the top-level category, under which all categories at Wiktionary should lie.",
additional = "Note that most categories are in [[:Category:All topics]] or under individual [[:Category:All languages|languages]].",
}
raw_categories["က္ဍိုၚ်ကဏ္ဍမေတဂမၠိုၚ်"] = {
description = "This page contains '''umbrella metacategories''', which group umbrella categories under high-level topics.",
additional = "Umbrella categories in turn group language-specific categories devoted to particular low-level topics.",
parents = {"ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်"},
}
return {LABELS = labels, RAW_CATEGORIES = raw_categories}
q3t7m4upd850m668ao15rm588u9uppt
ကဏ္ဍ:နာမ်မန်တြေံဂမၠိုၚ်
14
2231
157677
143126
2025-07-10T05:23:57Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:နာမ်မန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:နာမ်မန်တြေံဂမၠိုၚ်]]
16526
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်တြေံ]]
kfrz1jee49i18pezkjinqsd4uvop8ig
ကဏ္ဍ:ဝေါဟာအဓိကမန်တြေံဂမၠိုၚ်
14
2233
157665
143130
2025-07-09T15:31:22Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဝေါဟာအဓိကမန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဝေါဟာအဓိကမန်တြေံဂမၠိုၚ်]]
16528
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်]][[ကဏ္ဍ:ဘာသာမန်တြေံ]]
ptjef30bridq6swqnd96crd8k3bjjit
ကဏ္ဍ:ကြိယာဝိသေသနမန်ဂမၠိုၚ်
14
2243
157661
133793
2025-07-09T15:29:15Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကြိယာဝိသေသနမန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ကြိယာဝိသေသနမန်ဂမၠိုၚ်]]
6472
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်]]
bsvcnko7m99gh74uhzj7cawhpn6i949
ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်
14
2816
157703
14680
2025-07-10T09:57:26Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]]
14680
wikitext
text/x-wiki
[[ကဏ္ဍ:ဝိက်ရှေန်နရဳ]]
{{sisterlinks|Category:Languages}}
[[File:Languages world map-transparent background.svg|thumb|right|250px|Rough world map of language families]]
{{en-categoryTOC}}
qair8zyw0a6nkl6y57z6nc2xwxo0y0g
157705
157703
2025-07-10T09:58:17Z
咽頭べさ
33
အကြောင်းအရာ "{{auto cat}}" ဖြင့် အစားထိုးခဲ့သည်
157705
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
ထာမ်ပလိက်:mnw-det
10
5176
157624
11251
2025-07-09T12:30:49Z
咽頭べさ
33
157624
wikitext
text/x-wiki
{{head|mnw|ပစ္စဲ|head={{{head|}}}|tr={{{tr|}}}}}
qrggy612r3b4cb4aigiezoj913k5qru
ညးလွပ်:咽頭べさ/Notepad
2
9186
157718
157364
2025-07-10T11:11:38Z
咽頭べさ
33
157718
wikitext
text/x-wiki
[[🝴]] [[🝵]] [[🝶]] [[🝻]] [[🝼]] [[🝽]] [[🝾]] [[🝿]] [[🟙]] [[🛜]] [[🩵]] [[🩶]] [[🩷]] [[🪇]] [[🪈]] [[🪭]] [[🪮]] [[🪯]] [[🪻]] [[🪼]] [[🪽]] [[🪿]] [[🫎]] [[🫏]] [[🫚]] [[🫛]] [[🫨]] [[🫷]] [[🫸]]
[[File:Omx-san̊krān.png|50x50px]]
# {{l|shn|ၶိူဝ်း}}
{{shn-pron|တႆး-လူင်}}
#: {{ux|mnw|ဩ ကွေံဟာ သြ ဗှ်ေသြန်နွံဟာ
|t=bh}}
#: {{ux|ksw|ဃိၣ်သၢဖျၢၣ်တၢ်ဘါတရိၣ်
|t=bh}}
#: {{ux|shn|မႃးတေႉတေႉလႄႈၼႃႈ
|t=bh}}
#: {{ux|my|
လူ ဖြစ် ပြီး လူ စကား နား မ လည် ရင် မ တတ် နိုင် တော့ ဘူး
|t=bh}}
{{alt sp|th|บ้านมอญ นครสวรรค์}}
* {{ur-IPA|grī}}
{{der3|shn
|တေ မိူဝ်း ယဝ့် ႁုး
|
|
}}
{{pi-alt|Latn=yadi tvam maam kashtam karoshi tarhi aham tvaam sadyah eva avaruddhayishyami}}
{{langtrack|mnw|mkh-mmn|omx|mkh-pro|mkh-mnc-pro}}
{{langtrack|mn|en|enm|ang|ine-pro|gem-pro|gmw-pro}}
{{langtrack|th|shn|tai-pro|tai-swe-pro|qfa-bet-pro|aho|ar|ja|}}
{{langtrack|sa|la|hi|ru|ur}}
{{langtrack|so|as|it|hu|pt}}
{{langtrack|zh|vi|km|lo|ko}}
{{langtrack|es|sh|gmw-pro|fr|ine-pro}}
{{langtrack|my|za|wa|ka|mn}}
1klfv56alpy33djwqrw3v1kqspgo906
157719
157718
2025-07-10T11:12:47Z
咽頭べさ
33
157719
wikitext
text/x-wiki
[[🝴]] [[🝵]] [[🝶]] [[🝻]] [[🝼]] [[🝽]] [[🝾]] [[🝿]] [[🟙]] [[🛜]] [[🩵]] [[🩶]] [[🩷]] [[🪇]] [[🪈]] [[🪭]] [[🪮]] [[🪯]] [[🪻]] [[🪼]] [[🪽]] [[🪿]] [[🫎]] [[🫏]] [[🫚]] [[🫛]] [[🫨]] [[🫷]] [[🫸]]
[[File:Omx-san̊krān.png|50x50px]]
# {{l|shn|ၶိူဝ်း}}
{{shn-pron|တႆး-လူင်}}
#: {{ux|mnw|ဩ ကွေံ ဟာ သြ ဗှ်ေ သြန် နွံ ဟာ
|t=bh}}
#: {{ux|ksw|ဃိၣ်သၢဖျၢၣ်တၢ်ဘါတရိၣ်
|t=bh}}
#: {{ux|shn|မႃးတေႉတေႉလႄႈၼႃႈ
|t=bh}}
#: {{ux|my|
လူ ဖြစ် ပြီး လူ စကား နား မ လည် ရင် မ တတ် နိုင် တော့ ဘူး
|t=bh}}
{{alt sp|th|บ้านมอญ นครสวรรค์}}
* {{ur-IPA|grī}}
{{der3|shn
|တေ မိူဝ်း ယဝ့် ႁုး
|
|
}}
{{pi-alt|Latn=yadi tvam maam kashtam karoshi tarhi aham tvaam sadyah eva avaruddhayishyami}}
{{langtrack|mnw|mkh-mmn|omx|mkh-pro|mkh-mnc-pro}}
{{langtrack|mn|en|enm|ang|ine-pro|gem-pro|gmw-pro}}
{{langtrack|th|shn|tai-pro|tai-swe-pro|qfa-bet-pro|aho|ar|ja|}}
{{langtrack|sa|la|hi|ru|ur}}
{{langtrack|so|as|it|hu|pt}}
{{langtrack|zh|vi|km|lo|ko}}
{{langtrack|es|sh|gmw-pro|fr|ine-pro}}
{{langtrack|my|za|wa|ka|mn}}
mla38cu09nt00ouhz7wzo5f2ezwgvpd
ကဏ္ဍ:ပရဝ်ဂျေတ်ဝိက်ရှေန်နရဳဂမၠိုၚ်
14
34577
157710
46833
2025-07-10T10:11:54Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ပရဝ်ဂျေတ်ဝိက်ရှေန်နရဳဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ပရဝ်ဂျေတ်ဝိက်ရှေန်နရဳဂမၠိုၚ်]]
46833
wikitext
text/x-wiki
[[ကဏ္ဍ:ဝိက်ရှေန်နရဳ]]
40ees0dvqo9j5mw84hx20ygq4ulz8oj
မဝ်ဂျူ:category tree/names
828
43681
157699
155143
2025-07-10T09:43:46Z
咽頭べさ
33
157699
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local names_module = "Module:names"
local en_utilities_module = "Module:en-utilities"
local pluralize = require(en_utilities_module).pluralize
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ယၟုဂမၠိုၚ်"] = {
description = "{{{langname}}} terms that are used to refer to specific individuals or groups.",
additional = "Place names, demonyms and other kinds of names can be found in [[:Category:Names]].",
umbrella_parents = {name = "terms by semantic function", is_label = true, sort = " "},
parents = {"terms by semantic function", "နာမ်မကိတ်ညဳ"},
}
------------------------------------------- given names -------------------------------------------
local human_genders = {
["male"] = "to male individuals",
["female"] = "to female individuals",
["unisex"] = "either to male or to female individuals",
}
for gender, props in pairs(require(names_module).given_name_genders) do
if gender ~= "unknown-gender" then
local is_animal = props.type == "animal"
local cat = is_animal and gender .. " names" or gender .. " given names"
local desc = is_animal and " given to " .. pluralize(gender) or " given " .. human_genders[gender]
local function do_cat(cat, desc, breadcrumb, parents)
labels[cat] = {
description = "{{{langname}}} " .. desc .. ".",
breadcrumb = breadcrumb,
parents = parents,
}
end
for _, dimaug in ipairs { "diminutive", "augmentative" } do
do_cat(dimaug .. "s of " .. cat, dimaug .. " names " .. desc, dimaug,
{gender .. " given names", dimaug .. " nouns"})
end
do_cat(cat, "names " .. desc, gender, is_animal and (gender == "animal" and "names" or is_animal and
"animal names") or "given names")
if not is_animal then
do_cat(gender .. " skin names", "skin names " .. desc, gender, {"skin names"})
end
end
end
labels["given names"] = {
description = "{{{langname}}} names given to individuals.",
parents = {"names"},
}
labels["skin names"] = {
description = "{{{langname}}} terms given at birth that are used to refer to individuals from specific marital classes.",
parents = {"proper nouns", "names"},
}
------------------------------------------- surnames -------------------------------------------
labels["common-gender surnames"] = {
description = "{{{langname}}} names shared by both male and female family members, in languages that distinguish male and female surnames.",
breadcrumb = "common-gender",
parents = {"surnames"},
}
labels["female surnames"] = {
description = "{{{langname}}} names shared by female family members.",
breadcrumb = "female",
parents = {"surnames"},
}
labels["male surnames"] = {
description = "{{{langname}}} names shared by male family members.",
breadcrumb = "male",
parents = {"surnames"},
}
labels["surnames"] = {
description = "{{{langname}}} names shared by family members.",
parents = {"names"},
}
for _, nymics in ipairs { "matronymics", "patronymics" } do
local ancestor = nymics == "matronymics" and "mother, grandmother or earlier female ancestor" or
"father, grandfather or earlier male ancestor"
labels["common-gender " .. nymics] = {
description = ("{{{langname}}} names used by both men and women to indicate their %s, in languages that distinguish male and female %s."):
format(ancestor, nymics),
breadcrumb = "common-gender",
parents = {nymics},
}
labels["female " .. nymics] = {
description = ("{{{langname}}} names used by women to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "female",
parents = {nymics},
}
labels["male " .. nymics] = {
description = ("{{{langname}}} names used by men to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "male",
parents = {nymics},
}
labels[nymics] = {
description = ("{{{langname}}} names indicating a person's %s."):format(ancestor),
parents = {"ယၟုဂမၠိုၚ်"},
}
end
labels["nomina gentilia"] = {
description = "{{{langname}}} \"[[family name]]s\" (singular ''[[nomen gentile]]'') in a [[w:Roman naming convention|convential Roman name]].",
parents = {"ယၟုဂမၠိုၚ်"},
}
------------------------------------------- misc -------------------------------------------
labels["exonyms"] = {
description = "{{{langname}}} [[exonym]]s, i.e. terms for toponyms whose name in {{{langname}}} is different from the name in the source language.",
parents = {"ယၟုဂမၠိုၚ်"},
}
labels["renderings of foreign personal names"] = {
description = "{{{langname}}} transliterations, respellings or other renderings of foreign personal names.",
parents = {"ယၟုဂမၠိုၚ်"},
}
-- Add 'umbrella_parents' key if not already present.
for key, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Names subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Names subcategories by language"] = {
description = "Umbrella categories covering topics related to names.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "names", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function source_name_to_source(nametype, source_name)
local special_sources
if nametype:find("given names") then
special_sources = require("Module:table").listToSet {
"surnames", "place names", "coinages", "the Bible", "month names"
}
elseif nametype:find("surnames") then
special_sources = require("Module:table").listToSet {
"given names", "place names", "occupations", "patronymics", "matronymics",
"common nouns", "nicknames", "ethnonyms"
}
else
special_sources = {}
end
if special_sources[source_name] then
return source_name
else
return require("Module:languages").getByCanonicalName(source_name, nil,
"allow etym langs", "allow families")
end
end
local function get_source_text(source)
if type(source) == "table" then
return source:getDisplayForm()
else
return source
end
end
local function get_description(lang, nametype, source)
local origintext, addltext
if source == "surnames" then
origintext = "transferred from surnames"
elseif source == "given names" then
origintext = "transferred from given names"
elseif source == "nicknames" then
origintext = "transferred from nicknames"
elseif source == "place names" then
origintext = "transferred from place names"
addltext = " For place names that are also surnames, see " .. (
lang and "[[:Category:{{{langname}}} " .. nametype .. " from surnames]]" or
"[[:Category:" .. mw.getContentLanguage():ucfirst(nametype) .. " from surnames by language]]"
) .. "."
elseif source == "common nouns" then
origintext = "transferred from common nouns"
elseif source == "month names" then
origintext = "transferred from month names"
elseif source == "coinages" then
origintext = "originating as coinages"
addltext = " These are names of artificial origin, names based on fictional characters, combinations of two words or names or backward spellings. Names of uncertain origin can also be placed here if there is a strong suspicion that they are coinages."
elseif source == "occupations" then
origintext = "originating as occupations"
elseif source == "patronymics" then
origintext = "originating as patronymics"
elseif source == "matronymics" then
origintext = "originating as matronymics"
elseif source == "ethnonyms" then
origintext = "originating as ethnonyms"
elseif source == "the Bible" then
-- Hack esp. for Hawaiian names. We should consider changing them to
-- have the source as Biblical Hebrew and mention the derivation from
-- the Bible some other way.
origintext = "originating from the Bible"
elseif type(source) == "string" then
error("Internal error: Unrecognized string source \"" .. source .. "\", should be special-cased")
else
origintext = "of " .. source:makeCategoryLink() .. " origin"
if lang and source:getCode() == lang:getCode() then
addltext = " These are names derived from common nouns, local mythology, etc."
end
end
local introtext
if lang then
introtext = "{{{langname}}} "
else
introtext = "ကဏ္ဍမနွံကဵု "
end
return introtext .. nametype .. " " .. origintext ..
". (This includes names derived at an older stage of the language.)" .. (addltext or "")
end
-- If one of the following families occurs in any of the ancestral families
-- of a given language, use it instead of the three-letter parent
-- (or immediate parent if no three-letter parent).
local high_level_families = require("Module:table").listToSet {
-- Indo-European
"gem", -- Germanic (for gme, gmq, gmw)
"inc", -- Indic (for e.g. pra = Prakrit)
"ine-ana", -- Anatolian (don't keep going to ine)
"ine-toc", -- Tocharian (don't keep going to ine)
"ira", -- Iranian (for e.g. xme = Median, xsc = Scythian)
"sla", -- Slavic (for zle, zls, zlw)
-- Other
"ath", -- Athabaskan (for e.g. apa = Apachean)
"poz", -- Malayo-Polynesian (for e.g. pqe = Eastern Malayo-Polynesian)
"cau-nwc", -- Northwest Caucasian
"cau-nec", -- Northeast Caucasian
}
local function find_high_level_family(lang)
local family = lang:getFamily()
-- (1) If no family, return nil (e.g. for Pictish).
if not family then
return nil
end
-- (2) See if any ancestor family is in `high_level_families`.
-- if so, return it.
local high_level_family = family
while high_level_family do
local high_level_code = high_level_family:getCode()
if high_level_code == "qfa-not" then
-- "not a family"; its own parent, causing an infinite loop.
-- Break rather than return so we get categories like
-- [[Category:English female given names from sign languages]] and
-- [[Category:English female given names from constructed languages]].
break
end
if high_level_families[high_level_code] then
return high_level_family
end
high_level_family = high_level_family:getFamily()
end
-- (3) If the family is of the form 'FOO-BAR', see if 'FOO' is a family.
-- If so, return it.
local basic_family = family:getCode():match("^(.-)%-.*$")
if basic_family then
basic_family = require("Module:families").getByCode(basic_family)
if basic_family then
return basic_family
end
end
-- (4) Fall back to just the family itself.
return family
end
local function match_gendered_nametype(nametype)
local gender, label = nametype:match("^(f?e?male) (given names)$")
if not gender then
gender, label = nametype:match("^(unisex) (given names)$")
end
if gender then
return gender, label
end
end
local function get_parents(lang, nametype, source)
local parents = {}
if lang then
table.insert(parents, {name = nametype, sort = get_source_text(source)})
if type(source) == "table" then
table.insert(parents, {name = "terms derived from " .. source:getDisplayForm(), sort = " "})
-- If the source is a regular language, put it in a parent category for the high-level language family, e.g. for
-- "Russian female given names from German", put it in a parent category "Russian female given names from Germanic languages"
-- (skipping over West Germanic languages).
--
-- If the source is an etymology language, put it in a parent category for the parent full language, e.g. for
-- "French male given names from Gascon", put it in a parent category "French male given names from Occitan".
--
-- If the source is a family, put it in a parent category for the parent family.
if source:hasType("family") then
local parent_family = source:getFamily()
if parent_family and parent_family:getCode() ~= "qfa-not" then
table.insert(parents, {
name = nametype .. " from " .. parent_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
elseif source:hasType("etymology-only") then
local source_parent = source:getFull()
if source_parent and source_parent:getCode() ~= "und" then
table.insert(parents, {
name = nametype .. " from " .. source_parent:getDisplayForm(),
sort = source:getCanonicalName()
})
end
else
local high_level_family = find_high_level_family(source)
if high_level_family then -- may not exist, e.g. for Pictish
table.insert(parents,
{name = nametype .. " from " .. high_level_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
end
end
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), sort = gender})
end
else
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), is_label = true, sort = " "})
elseif type(source) == "table" then
-- FIXME! This is duplicated in [[Module:category tree/etymology]] in the handler for umbrella categories
-- 'Terms derived from SOURCE'.
local first_umbrella_parent =
source:hasType("family") and {name = source:getCategoryName(), raw = true, sort = " "} or
source:hasType("etymology-only") and {name = "ကဏ္ဍ:" .. nametype, sort = source:getCategoryName() .. "ဂမၠိုၚ်"} or
{name = nametype, raw = true, sort = source:getCategoryName() .. "ဂမၠိုၚ်"}
table.insert(parents, first_umbrella_parent)
end
table.insert(parents, "Names subcategories by language")
end
return parents
end
table.insert(handlers, function(data)
local nametype, source_name = data.label:match("^(.*ယၟုဂမၠိုၚ်) from (.+)$")
if nametype then
local personal_name_type_set = require(names_module).personal_name_type_set
if not personal_name_type_set[nametype] then
return nil
end
local source = source_name_to_source(nametype, source_name)
if not source then
return nil
end
return {
description = get_description(data.lang, nametype, source),
breadcrumb = "from " .. get_source_text(source),
parents = get_parents(data.lang, nametype, source),
umbrella = {
description = get_description(nil, nametype, source),
parents = get_parents(nil, nametype, source),
},
}
end
end)
-- Handler for e.g. 'English renderings of Russian male given names'.
table.insert(handlers, function(data)
local label = data.label:match("^renderings of (.*)$")
if label then
local personal_name_types = require(names_module).personal_name_types
for _, nametype in ipairs(personal_name_types) do
local sourcename = label:match("^(.+) " .. nametype .. "$")
if sourcename then
local source = require("Module:languages").getByCanonicalName(sourcename, nil, "allow etym")
if source then
return {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into {{{langdisp}}}.",
lang = data.lang,
breadcrumb = sourcename .. " " .. nametype,
parents = {
{ name = "renderings of foreign personal names", sort = sourcename },
{ name = nametype, lang = source:getCode(), sort = "{{{langname}}}" },
},
umbrella = {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into various languages.",
parents = {{name = "renderings of foreign personal names", is_label = true, sort = label}},
},
}
end
end
end
end
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
cgvri35wg5gupovn4l1jsl9g2azics0
157700
157699
2025-07-10T09:47:21Z
咽頭べさ
33
157700
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local names_module = "Module:names"
local en_utilities_module = "Module:en-utilities"
local pluralize = require(en_utilities_module).pluralize
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ယၟု"] = {
description = "{{{langname}}} terms that are used to refer to specific individuals or groups.",
additional = "Place names, demonyms and other kinds of names can be found in [[:Category:Names]].",
umbrella_parents = {name = "terms by semantic function", is_label = true, sort = " "},
parents = {"terms by semantic function", "နာမ်မကိတ်ညဳ"},
}
------------------------------------------- given names -------------------------------------------
local human_genders = {
["male"] = "to male individuals",
["female"] = "to female individuals",
["unisex"] = "either to male or to female individuals",
}
for gender, props in pairs(require(names_module).given_name_genders) do
if gender ~= "unknown-gender" then
local is_animal = props.type == "animal"
local cat = is_animal and gender .. " names" or gender .. " given names"
local desc = is_animal and " given to " .. pluralize(gender) or " given " .. human_genders[gender]
local function do_cat(cat, desc, breadcrumb, parents)
labels[cat] = {
description = "{{{langname}}} " .. desc .. ".",
breadcrumb = breadcrumb,
parents = parents,
}
end
for _, dimaug in ipairs { "diminutive", "augmentative" } do
do_cat(dimaug .. "s of " .. cat, dimaug .. " names " .. desc, dimaug,
{gender .. " given names", dimaug .. " nouns"})
end
do_cat(cat, "names " .. desc, gender, is_animal and (gender == "animal" and "names" or is_animal and
"animal names") or "given names")
if not is_animal then
do_cat(gender .. " skin names", "skin names " .. desc, gender, {"skin names"})
end
end
end
labels["given names"] = {
description = "{{{langname}}} names given to individuals.",
parents = {"names"},
}
labels["skin names"] = {
description = "{{{langname}}} terms given at birth that are used to refer to individuals from specific marital classes.",
parents = {"proper nouns", "names"},
}
------------------------------------------- surnames -------------------------------------------
labels["common-gender surnames"] = {
description = "{{{langname}}} names shared by both male and female family members, in languages that distinguish male and female surnames.",
breadcrumb = "common-gender",
parents = {"surnames"},
}
labels["female surnames"] = {
description = "{{{langname}}} names shared by female family members.",
breadcrumb = "female",
parents = {"surnames"},
}
labels["male surnames"] = {
description = "{{{langname}}} names shared by male family members.",
breadcrumb = "male",
parents = {"surnames"},
}
labels["surnames"] = {
description = "{{{langname}}} names shared by family members.",
parents = {"names"},
}
for _, nymics in ipairs { "matronymics", "patronymics" } do
local ancestor = nymics == "matronymics" and "mother, grandmother or earlier female ancestor" or
"father, grandfather or earlier male ancestor"
labels["common-gender " .. nymics] = {
description = ("{{{langname}}} names used by both men and women to indicate their %s, in languages that distinguish male and female %s."):
format(ancestor, nymics),
breadcrumb = "common-gender",
parents = {nymics},
}
labels["female " .. nymics] = {
description = ("{{{langname}}} names used by women to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "female",
parents = {nymics},
}
labels["male " .. nymics] = {
description = ("{{{langname}}} names used by men to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "male",
parents = {nymics},
}
labels[nymics] = {
description = ("{{{langname}}} names indicating a person's %s."):format(ancestor),
parents = {"ယၟုဂမၠိုၚ်"},
}
end
labels["nomina gentilia"] = {
description = "{{{langname}}} \"[[family name]]s\" (singular ''[[nomen gentile]]'') in a [[w:Roman naming convention|convential Roman name]].",
parents = {"ယၟုဂမၠိုၚ်"},
}
------------------------------------------- misc -------------------------------------------
labels["exonyms"] = {
description = "{{{langname}}} [[exonym]]s, i.e. terms for toponyms whose name in {{{langname}}} is different from the name in the source language.",
parents = {"ယၟုဂမၠိုၚ်"},
}
labels["renderings of foreign personal names"] = {
description = "{{{langname}}} transliterations, respellings or other renderings of foreign personal names.",
parents = {"ယၟုဂမၠိုၚ်"},
}
-- Add 'umbrella_parents' key if not already present.
for key, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Names subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Names subcategories by language"] = {
description = "Umbrella categories covering topics related to names.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "names", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function source_name_to_source(nametype, source_name)
local special_sources
if nametype:find("given names") then
special_sources = require("Module:table").listToSet {
"surnames", "place names", "coinages", "the Bible", "month names"
}
elseif nametype:find("surnames") then
special_sources = require("Module:table").listToSet {
"given names", "place names", "occupations", "patronymics", "matronymics",
"common nouns", "nicknames", "ethnonyms"
}
else
special_sources = {}
end
if special_sources[source_name] then
return source_name
else
return require("Module:languages").getByCanonicalName(source_name, nil,
"allow etym langs", "allow families")
end
end
local function get_source_text(source)
if type(source) == "table" then
return source:getDisplayForm()
else
return source
end
end
local function get_description(lang, nametype, source)
local origintext, addltext
if source == "surnames" then
origintext = "transferred from surnames"
elseif source == "given names" then
origintext = "transferred from given names"
elseif source == "nicknames" then
origintext = "transferred from nicknames"
elseif source == "place names" then
origintext = "transferred from place names"
addltext = " For place names that are also surnames, see " .. (
lang and "[[:Category:{{{langname}}} " .. nametype .. " from surnames]]" or
"[[:Category:" .. mw.getContentLanguage():ucfirst(nametype) .. " from surnames by language]]"
) .. "."
elseif source == "common nouns" then
origintext = "transferred from common nouns"
elseif source == "month names" then
origintext = "transferred from month names"
elseif source == "coinages" then
origintext = "originating as coinages"
addltext = " These are names of artificial origin, names based on fictional characters, combinations of two words or names or backward spellings. Names of uncertain origin can also be placed here if there is a strong suspicion that they are coinages."
elseif source == "occupations" then
origintext = "originating as occupations"
elseif source == "patronymics" then
origintext = "originating as patronymics"
elseif source == "matronymics" then
origintext = "originating as matronymics"
elseif source == "ethnonyms" then
origintext = "originating as ethnonyms"
elseif source == "the Bible" then
-- Hack esp. for Hawaiian names. We should consider changing them to
-- have the source as Biblical Hebrew and mention the derivation from
-- the Bible some other way.
origintext = "originating from the Bible"
elseif type(source) == "string" then
error("Internal error: Unrecognized string source \"" .. source .. "\", should be special-cased")
else
origintext = "of " .. source:makeCategoryLink() .. " origin"
if lang and source:getCode() == lang:getCode() then
addltext = " These are names derived from common nouns, local mythology, etc."
end
end
local introtext
if lang then
introtext = "{{{langname}}} "
else
introtext = "ကဏ္ဍမနွံကဵု "
end
return introtext .. nametype .. " " .. origintext ..
". (This includes names derived at an older stage of the language.)" .. (addltext or "")
end
-- If one of the following families occurs in any of the ancestral families
-- of a given language, use it instead of the three-letter parent
-- (or immediate parent if no three-letter parent).
local high_level_families = require("Module:table").listToSet {
-- Indo-European
"gem", -- Germanic (for gme, gmq, gmw)
"inc", -- Indic (for e.g. pra = Prakrit)
"ine-ana", -- Anatolian (don't keep going to ine)
"ine-toc", -- Tocharian (don't keep going to ine)
"ira", -- Iranian (for e.g. xme = Median, xsc = Scythian)
"sla", -- Slavic (for zle, zls, zlw)
-- Other
"ath", -- Athabaskan (for e.g. apa = Apachean)
"poz", -- Malayo-Polynesian (for e.g. pqe = Eastern Malayo-Polynesian)
"cau-nwc", -- Northwest Caucasian
"cau-nec", -- Northeast Caucasian
}
local function find_high_level_family(lang)
local family = lang:getFamily()
-- (1) If no family, return nil (e.g. for Pictish).
if not family then
return nil
end
-- (2) See if any ancestor family is in `high_level_families`.
-- if so, return it.
local high_level_family = family
while high_level_family do
local high_level_code = high_level_family:getCode()
if high_level_code == "qfa-not" then
-- "not a family"; its own parent, causing an infinite loop.
-- Break rather than return so we get categories like
-- [[Category:English female given names from sign languages]] and
-- [[Category:English female given names from constructed languages]].
break
end
if high_level_families[high_level_code] then
return high_level_family
end
high_level_family = high_level_family:getFamily()
end
-- (3) If the family is of the form 'FOO-BAR', see if 'FOO' is a family.
-- If so, return it.
local basic_family = family:getCode():match("^(.-)%-.*$")
if basic_family then
basic_family = require("Module:families").getByCode(basic_family)
if basic_family then
return basic_family
end
end
-- (4) Fall back to just the family itself.
return family
end
local function match_gendered_nametype(nametype)
local gender, label = nametype:match("^(f?e?male) (given names)$")
if not gender then
gender, label = nametype:match("^(unisex) (given names)$")
end
if gender then
return gender, label
end
end
local function get_parents(lang, nametype, source)
local parents = {}
if lang then
table.insert(parents, {name = nametype, sort = get_source_text(source)})
if type(source) == "table" then
table.insert(parents, {name = "terms derived from " .. source:getDisplayForm(), sort = " "})
-- If the source is a regular language, put it in a parent category for the high-level language family, e.g. for
-- "Russian female given names from German", put it in a parent category "Russian female given names from Germanic languages"
-- (skipping over West Germanic languages).
--
-- If the source is an etymology language, put it in a parent category for the parent full language, e.g. for
-- "French male given names from Gascon", put it in a parent category "French male given names from Occitan".
--
-- If the source is a family, put it in a parent category for the parent family.
if source:hasType("family") then
local parent_family = source:getFamily()
if parent_family and parent_family:getCode() ~= "qfa-not" then
table.insert(parents, {
name = nametype .. " from " .. parent_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
elseif source:hasType("etymology-only") then
local source_parent = source:getFull()
if source_parent and source_parent:getCode() ~= "und" then
table.insert(parents, {
name = nametype .. " from " .. source_parent:getDisplayForm(),
sort = source:getCanonicalName()
})
end
else
local high_level_family = find_high_level_family(source)
if high_level_family then -- may not exist, e.g. for Pictish
table.insert(parents,
{name = nametype .. " from " .. high_level_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
end
end
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), sort = gender})
end
else
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), is_label = true, sort = " "})
elseif type(source) == "table" then
-- FIXME! This is duplicated in [[Module:category tree/etymology]] in the handler for umbrella categories
-- 'Terms derived from SOURCE'.
local first_umbrella_parent =
source:hasType("family") and {name = source:getCategoryName(), raw = true, sort = " "} or
source:hasType("etymology-only") and {name = "ကဏ္ဍ:" .. nametype, sort = source:getCategoryName() .. "ဂမၠိုၚ်"} or
{name = nametype, raw = true, sort = source:getCategoryName() .. "ဂမၠိုၚ်"}
table.insert(parents, first_umbrella_parent)
end
table.insert(parents, "Names subcategories by language")
end
return parents
end
table.insert(handlers, function(data)
local nametype, source_name = data.label:match("^(.*ယၟုဂမၠိုၚ်) from (.+)$")
if nametype then
local personal_name_type_set = require(names_module).personal_name_type_set
if not personal_name_type_set[nametype] then
return nil
end
local source = source_name_to_source(nametype, source_name)
if not source then
return nil
end
return {
description = get_description(data.lang, nametype, source),
breadcrumb = "from " .. get_source_text(source),
parents = get_parents(data.lang, nametype, source),
umbrella = {
description = get_description(nil, nametype, source),
parents = get_parents(nil, nametype, source),
},
}
end
end)
-- Handler for e.g. 'English renderings of Russian male given names'.
table.insert(handlers, function(data)
local label = data.label:match("^renderings of (.*)$")
if label then
local personal_name_types = require(names_module).personal_name_types
for _, nametype in ipairs(personal_name_types) do
local sourcename = label:match("^(.+) " .. nametype .. "$")
if sourcename then
local source = require("Module:languages").getByCanonicalName(sourcename, nil, "allow etym")
if source then
return {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into {{{langdisp}}}.",
lang = data.lang,
breadcrumb = sourcename .. " " .. nametype,
parents = {
{ name = "renderings of foreign personal names", sort = sourcename },
{ name = nametype, lang = source:getCode(), sort = "{{{langname}}}" },
},
umbrella = {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into various languages.",
parents = {{name = "renderings of foreign personal names", is_label = true, sort = label}},
},
}
end
end
end
end
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
gsvhgya9e9dd6lp51811r6v9rcb35aa
157713
157700
2025-07-10T10:21:10Z
咽頭べさ
33
157713
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local names_module = "Module:names"
local en_utilities_module = "Module:en-utilities"
local pluralize = require(en_utilities_module).pluralize
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ယၟုဂမၠိုင်"] = {
description = "{{{langname}}} terms that are used to refer to specific individuals or groups.",
additional = "Place names, demonyms and other kinds of names can be found in [[:ကဏ္ဍ:ယၟုဂမၠိုၚ်]].",
umbrella_parents = {name = "terms by semantic function", is_label = true, sort = " "},
parents = {"နာမ်မကိတ်ညဳ{{{langname}}}ဂမၠိုင်"},
}
------------------------------------------- given names -------------------------------------------
local human_genders = {
["male"] = "to male individuals",
["female"] = "to female individuals",
["unisex"] = "either to male or to female individuals",
}
for gender, props in pairs(require(names_module).given_name_genders) do
if gender ~= "unknown-gender" then
local is_animal = props.type == "animal"
local cat = is_animal and gender .. " names" or gender .. " given names"
local desc = is_animal and " given to " .. pluralize(gender) or " given " .. human_genders[gender]
local function do_cat(cat, desc, breadcrumb, parents)
labels[cat] = {
description = "{{{langname}}} " .. desc .. ".",
breadcrumb = breadcrumb,
parents = parents,
}
end
for _, dimaug in ipairs { "diminutive", "augmentative" } do
do_cat(dimaug .. "s of " .. cat, dimaug .. " names " .. desc, dimaug,
{gender .. " given names", dimaug .. " nouns"})
end
do_cat(cat, "names " .. desc, gender, is_animal and (gender == "animal" and "names" or is_animal and
"animal names") or "given names")
if not is_animal then
do_cat(gender .. " skin names", "skin names " .. desc, gender, {"skin names"})
end
end
end
labels["given names"] = {
description = "{{{langname}}} names given to individuals.",
parents = {"names"},
}
labels["skin names"] = {
description = "{{{langname}}} terms given at birth that are used to refer to individuals from specific marital classes.",
parents = {"proper nouns", "names"},
}
------------------------------------------- surnames -------------------------------------------
labels["common-gender surnames"] = {
description = "{{{langname}}} names shared by both male and female family members, in languages that distinguish male and female surnames.",
breadcrumb = "common-gender",
parents = {"surnames"},
}
labels["female surnames"] = {
description = "{{{langname}}} names shared by female family members.",
breadcrumb = "female",
parents = {"surnames"},
}
labels["male surnames"] = {
description = "{{{langname}}} names shared by male family members.",
breadcrumb = "male",
parents = {"surnames"},
}
labels["surnames"] = {
description = "{{{langname}}} names shared by family members.",
parents = {"names"},
}
for _, nymics in ipairs { "matronymics", "patronymics" } do
local ancestor = nymics == "matronymics" and "mother, grandmother or earlier female ancestor" or
"father, grandfather or earlier male ancestor"
labels["common-gender " .. nymics] = {
description = ("{{{langname}}} names used by both men and women to indicate their %s, in languages that distinguish male and female %s."):
format(ancestor, nymics),
breadcrumb = "common-gender",
parents = {nymics},
}
labels["female " .. nymics] = {
description = ("{{{langname}}} names used by women to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "female",
parents = {nymics},
}
labels["male " .. nymics] = {
description = ("{{{langname}}} names used by men to indicate their %s."):
format(ancestor, nymics),
breadcrumb = "male",
parents = {nymics},
}
labels[nymics] = {
description = ("{{{langname}}} names indicating a person's %s."):format(ancestor),
parents = {"names"},
}
end
labels["nomina gentilia"] = {
description = "{{{langname}}} \"[[family name]]s\" (singular ''[[nomen gentile]]'') in a [[w:Roman naming convention|convential Roman name]].",
parents = {"names"},
}
------------------------------------------- misc -------------------------------------------
labels["exonyms"] = {
description = "{{{langname}}} [[exonym]]s, i.e. terms for toponyms whose name in {{{langname}}} is different from the name in the source language.",
parents = {"names"},
}
labels["renderings of foreign personal names"] = {
description = "{{{langname}}} transliterations, respellings or other renderings of foreign personal names.",
parents = {"names"},
}
-- Add 'umbrella_parents' key if not already present.
for key, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Names subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Names subcategories by language"] = {
description = "Umbrella categories covering topics related to names.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "names", is_label = true, sort = " "},
},
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function source_name_to_source(nametype, source_name)
local special_sources
if nametype:find("given names") then
special_sources = require("Module:table").listToSet {
"surnames", "place names", "coinages", "the Bible", "month names"
}
elseif nametype:find("surnames") then
special_sources = require("Module:table").listToSet {
"given names", "place names", "occupations", "patronymics", "matronymics",
"common nouns", "nicknames", "ethnonyms"
}
else
special_sources = {}
end
if special_sources[source_name] then
return source_name
else
return require("Module:languages").getByCanonicalName(source_name, nil,
"allow etym langs", "allow families")
end
end
local function get_source_text(source)
if type(source) == "table" then
return source:getDisplayForm()
else
return source
end
end
local function get_description(lang, nametype, source)
local origintext, addltext
if source == "surnames" then
origintext = "transferred from surnames"
elseif source == "given names" then
origintext = "transferred from given names"
elseif source == "nicknames" then
origintext = "transferred from nicknames"
elseif source == "place names" then
origintext = "transferred from place names"
addltext = " For place names that are also surnames, see " .. (
lang and "[[:Category:{{{langname}}} " .. nametype .. " from surnames]]" or
"[[:Category:" .. mw.getContentLanguage():ucfirst(nametype) .. " from surnames by language]]"
) .. "."
elseif source == "common nouns" then
origintext = "transferred from common nouns"
elseif source == "month names" then
origintext = "transferred from month names"
elseif source == "coinages" then
origintext = "originating as coinages"
addltext = " These are names of artificial origin, names based on fictional characters, combinations of two words or names or backward spellings. Names of uncertain origin can also be placed here if there is a strong suspicion that they are coinages."
elseif source == "occupations" then
origintext = "originating as occupations"
elseif source == "patronymics" then
origintext = "originating as patronymics"
elseif source == "matronymics" then
origintext = "originating as matronymics"
elseif source == "ethnonyms" then
origintext = "originating as ethnonyms"
elseif source == "the Bible" then
-- Hack esp. for Hawaiian names. We should consider changing them to
-- have the source as Biblical Hebrew and mention the derivation from
-- the Bible some other way.
origintext = "originating from the Bible"
elseif type(source) == "string" then
error("Internal error: Unrecognized string source \"" .. source .. "\", should be special-cased")
else
origintext = "of " .. source:makeCategoryLink() .. " origin"
if lang and source:getCode() == lang:getCode() then
addltext = " These are names derived from common nouns, local mythology, etc."
end
end
local introtext
if lang then
introtext = "{{{langname}}} "
else
introtext = "Categories with "
end
return introtext .. nametype .. " " .. origintext ..
". (This includes names derived at an older stage of the language.)" .. (addltext or "")
end
-- If one of the following families occurs in any of the ancestral families
-- of a given language, use it instead of the three-letter parent
-- (or immediate parent if no three-letter parent).
local high_level_families = require("Module:table").listToSet {
-- Indo-European
"gem", -- Germanic (for gme, gmq, gmw)
"inc", -- Indic (for e.g. pra = Prakrit)
"ine-ana", -- Anatolian (don't keep going to ine)
"ine-toc", -- Tocharian (don't keep going to ine)
"ira", -- Iranian (for e.g. xme = Median, xsc = Scythian)
"sla", -- Slavic (for zle, zls, zlw)
-- Other
"ath", -- Athabaskan (for e.g. apa = Apachean)
"poz", -- Malayo-Polynesian (for e.g. pqe = Eastern Malayo-Polynesian)
"cau-nwc", -- Northwest Caucasian
"cau-nec", -- Northeast Caucasian
}
local function find_high_level_family(lang)
local family = lang:getFamily()
-- (1) If no family, return nil (e.g. for Pictish).
if not family then
return nil
end
-- (2) See if any ancestor family is in `high_level_families`.
-- if so, return it.
local high_level_family = family
while high_level_family do
local high_level_code = high_level_family:getCode()
if high_level_code == "qfa-not" then
-- "not a family"; its own parent, causing an infinite loop.
-- Break rather than return so we get categories like
-- [[Category:English female given names from sign languages]] and
-- [[Category:English female given names from constructed languages]].
break
end
if high_level_families[high_level_code] then
return high_level_family
end
high_level_family = high_level_family:getFamily()
end
-- (3) If the family is of the form 'FOO-BAR', see if 'FOO' is a family.
-- If so, return it.
local basic_family = family:getCode():match("^(.-)%-.*$")
if basic_family then
basic_family = require("Module:families").getByCode(basic_family)
if basic_family then
return basic_family
end
end
-- (4) Fall back to just the family itself.
return family
end
local function match_gendered_nametype(nametype)
local gender, label = nametype:match("^(f?e?male) (given names)$")
if not gender then
gender, label = nametype:match("^(unisex) (given names)$")
end
if gender then
return gender, label
end
end
local function get_parents(lang, nametype, source)
local parents = {}
if lang then
table.insert(parents, {name = nametype, sort = get_source_text(source)})
if type(source) == "table" then
table.insert(parents, {name = "terms derived from " .. source:getDisplayForm(), sort = " "})
-- If the source is a regular language, put it in a parent category for the high-level language family, e.g. for
-- "Russian female given names from German", put it in a parent category "Russian female given names from Germanic languages"
-- (skipping over West Germanic languages).
--
-- If the source is an etymology language, put it in a parent category for the parent full language, e.g. for
-- "French male given names from Gascon", put it in a parent category "French male given names from Occitan".
--
-- If the source is a family, put it in a parent category for the parent family.
if source:hasType("family") then
local parent_family = source:getFamily()
if parent_family and parent_family:getCode() ~= "qfa-not" then
table.insert(parents, {
name = nametype .. " from " .. parent_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
elseif source:hasType("etymology-only") then
local source_parent = source:getFull()
if source_parent and source_parent:getCode() ~= "und" then
table.insert(parents, {
name = nametype .. " from " .. source_parent:getDisplayForm(),
sort = source:getCanonicalName()
})
end
else
local high_level_family = find_high_level_family(source)
if high_level_family then -- may not exist, e.g. for Pictish
table.insert(parents,
{name = nametype .. " from " .. high_level_family:getDisplayForm(),
sort = source:getCanonicalName()
})
end
end
end
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), sort = gender})
end
else
local gender, label = match_gendered_nametype(nametype)
if gender then
table.insert(parents, {name = label .. " from " .. get_source_text(source), is_label = true, sort = " "})
elseif type(source) == "table" then
-- FIXME! This is duplicated in [[Module:category tree/etymology]] in the handler for umbrella categories
-- 'Terms derived from SOURCE'.
local first_umbrella_parent =
source:hasType("family") and {name = source:getCategoryName(), raw = true, sort = " "} or
source:hasType("etymology-only") and {name = "Category:" .. source:getCategoryName(), sort = nametype} or
{name = source:getCategoryName(), raw = true, sort = nametype}
table.insert(parents, first_umbrella_parent)
end
table.insert(parents, "Names subcategories by language")
end
return parents
end
table.insert(handlers, function(data)
local nametype, source_name = data.label:match("^(.*names) from (.+)$")
if nametype then
local personal_name_type_set = require(names_module).personal_name_type_set
if not personal_name_type_set[nametype] then
return nil
end
local source = source_name_to_source(nametype, source_name)
if not source then
return nil
end
return {
description = get_description(data.lang, nametype, source),
breadcrumb = "from " .. get_source_text(source),
parents = get_parents(data.lang, nametype, source),
umbrella = {
description = get_description(nil, nametype, source),
parents = get_parents(nil, nametype, source),
},
}
end
end)
-- Handler for e.g. 'English renderings of Russian male given names'.
table.insert(handlers, function(data)
local label = data.label:match("^renderings of (.*)$")
if label then
local personal_name_types = require(names_module).personal_name_types
for _, nametype in ipairs(personal_name_types) do
local sourcename = label:match("^(.+) " .. nametype .. "$")
if sourcename then
local source = require("Module:languages").getByCanonicalName(sourcename, nil, "allow etym")
if source then
return {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into {{{langdisp}}}.",
lang = data.lang,
breadcrumb = sourcename .. " " .. nametype,
parents = {
{ name = "renderings of foreign personal names", sort = sourcename },
{ name = nametype, lang = source:getCode(), sort = "{{{langname}}}" },
},
umbrella = {
description = "Transliterations, respellings or other renderings of " .. source:makeCategoryLink() .. " " .. nametype .. " into various languages.",
parents = {{name = "renderings of foreign personal names", is_label = true, sort = label}},
},
}
end
end
end
end
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers}
bvambtxhguwwls6w22jibzbmsplnh06
မဝ်ဂျူ:category tree/phrases
828
43682
157648
157530
2025-07-09T13:57:45Z
咽頭べさ
33
157648
Scribunto
text/plain
local labels = {}
local raw_categories = {}
labels["ဝါကျ"] = {
description = "{{{langname}}} groups of words elaborated to express ideas, not necessarily [[phrase]]s in the grammatical sense.",
umbrella_parents = "အဘိဓာန်တၞဟ်ခြာကဏ္ဍနကဵုဗက်အလိုက်အရေဝ်ဘာသာ",
parents = {"ဝေါဟာအဓိက"},
}
labels["adverb-adjective phrases"] = {
description = "{{{langname}}} phrases in which an adverb modifies the adjective that heads the phrase.",
umbrella_parents = {name = "phrases", is_label = true, sort = " "},
parents = {"phrases"},
}
labels["alliterative phrases"] = {
description = "{{{langname}}} phrases composed of two or more words that alliterate.",
umbrella_parents = {name = "phrases", is_label = true, sort = " "},
parents = {"phrases"},
}
labels["rhyming phrases"] = {
description = "{{{langname}}} phrases composed of two or more words that rhyme.",
umbrella_parents = {name = "phrases", is_label = true, sort = " "},
parents = {"phrases"},
}
labels["sentences"] = {
description = "{{{langname}}} [[sentence]]s.",
umbrella_parents = "Fundamental",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["phrasebook"] = {
description = "{{{langname}}} non-idiomatic phrases that are used in common situations, and may be useful to language learners or travellers.",
parents = {
"phrases",
{name = "Phrasebooks by language", raw = true, sort = "{{{langname}}}"}
},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
raw_categories["Phrasebooks by language"] = {
description = "Categories with phrasebooks in various specific languages.",
additional = "Phrasebook categories contain non-idiomatic phrases that are used in common situations, and may be useful to language learners or travellers.\n\n" ..
"See [[Wiktionary:Phrasebook]] for more information.\n\n{{{umbrella_msg}}}",
parents = "Fundamental",
}
for _, category in ipairs({
{name = "Basic", topics = {}},
{name = "Communication", topics = {"Communication"}},
{name = "Emergencies", topics = {"Emergency medicine"}},
{name = "Ethnicity", topics = {"Ethnicity"}},
{name = "Family", topics = {"Family"}},
{name = "Farewells", topics = {"Farewells"}},
{name = "Festivities", topics = {}},
{name = "Food and drink", topics = {"Food and drink"}},
{name = "Greetings", topics = {"Greetings"}},
{name = "Health", topics = {"Health"}},
{name = "Love", topics = {"Love"}},
{name = "Money", topics = {"Money"}},
{name = "Needs", topics = {}},
{name = "Religion", topics = {"Religion"}},
{name = "Sex", topics = {"Sex"}},
{name = "Time", topics = {"Time"}},
{name = "Travel", topics = {"Travel"}},
{name = "Weather", topics = {"Weather"}},
}) do
local parents = {
{name = "phrasebook", sort = category.name},
{name = "Phrasebooks by language/" .. category.name, raw = true, sort = "{{{langname}}}"},
}
for _, topic in ipairs(category.topics) do
table.insert(parents, {module = "topic cat", args = {code = "{{{langcode}}}", label = topic}, sort = " "})
end
labels["phrasebook/" .. category.name] = {
description = "{{{langname}}} common non-idiomatic phrases in the category '" .. category.name .. "'.",
breadcrumb = category.name,
parents = parents,
umbrella = false,
}
raw_categories["Phrasebooks by language/" .. category.name] = {
description = "Categories with common non-idiomatic phrases in the category '" .. category.name .. "', in various specific languages.",
additional = "{{{umbrella_msg}}}",
parents = {{name = "Phrasebooks by language", sort = " "}},
breadcrumb = category.name,
}
end
return {LABELS = labels, RAW_CATEGORIES = raw_categories}
83i8i905iggcybvdohsl5ao4sh57dx1
ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်
14
43833
157631
58081
2025-07-09T12:39:44Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]] ဇရေင် [[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
58081
wikitext
text/x-wiki
[[ကဏ္ဍ:ထိင်ဒက်မင်မွဲလဝ်ဝိက်ရှေန်နရဳဂမၠိုင်]]
tfpec825l5g64qziazljuugmt9ojkid
157637
157631
2025-07-09T12:53:43Z
咽頭べさ
33
အကြောင်းအရာ "{{auto cat}}" ဖြင့် အစားထိုးခဲ့သည်
157637
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
ကဏ္ဍ:ဝေါဟာအဓိကဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်
14
43933
157685
58206
2025-07-10T05:30:26Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:အဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဝေါဟာအဓိကဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
58206
wikitext
text/x-wiki
[[Category:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]][[ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]][[Category:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]]
fhrmkslps1mehjnmox8o1ykypfub8it
157687
157685
2025-07-10T05:31:37Z
咽頭べさ
33
အကြောင်းအရာ "{{auto cat}}" ဖြင့် အစားထိုးခဲ့သည်
157687
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
157701
157687
2025-07-10T09:52:24Z
咽頭べさ
33
157701
wikitext
text/x-wiki
[[ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]][[ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]][[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
efvl27imrqnddlaj9zobpotdl2iniaf
ကဏ္ဍ:အဘိဓာန်တၞဟ်ခြာကဏ္ဍနကဵုဗက်အလိုက်အရေဝ်ဘာသာ
14
52137
157702
68269
2025-07-10T09:54:27Z
咽頭べさ
33
157702
wikitext
text/x-wiki
[[ကဏ္ဍ:ဝေါဟာအဓိကဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
ht14pp5bkwwkf2gk8v0hop69fn3522l
ကဏ္ဍ:နာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်
14
53093
157683
69506
2025-07-10T05:28:15Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:နာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:နာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
69506
wikitext
text/x-wiki
[[ကဏ္ဍ:အဘိဓာန်တၞဟ်ခြာကဏ္ဍနကဵုဗက်အလိုက်အရေဝ်ဘာသာ]]
g8z8pnl6rir7mge1c04h4kat1w6xe8h
ကဏ္ဍ:နာမ်မကိတ်ညဳမန်တြေံဂမၠိုၚ်
14
61620
157679
143128
2025-07-10T05:25:40Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:နာမ်မကိတ်ညဳမန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:နာမ်မကိတ်ညဳမန်တြေံဂမၠိုၚ်]]
80666
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်တြေံ]]
kfrz1jee49i18pezkjinqsd4uvop8ig
ကဏ္ဍ:သဗ္ဗနာမ်မန်တြေံဂမၠိုၚ်
14
66682
157675
148967
2025-07-09T17:49:30Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:သဗ္ဗနာမ်မန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:သဗ္ဗနာမ်မန်တြေံဂမၠိုၚ်]]
87141
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်တြေံ]]
kfrz1jee49i18pezkjinqsd4uvop8ig
ကဏ္ဍ:ဗီုပြၚ်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ
14
70923
157629
93400
2025-07-09T12:33:40Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြင်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ]]
93400
wikitext
text/x-wiki
[[Category:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]]
2w6oipmfuuktveqnw4n65talkfqockx
157634
157629
2025-07-09T12:51:14Z
咽頭べさ
33
157634
wikitext
text/x-wiki
[[ကဏ္ဍ:Category:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]]
07x88uy8csanclzheh81um9d1qn7wa2
157635
157634
2025-07-09T12:51:25Z
咽頭べさ
33
157635
wikitext
text/x-wiki
[[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]]
pokvpyrm5jefzs3ra2dzx620t3qafb6
157636
157635
2025-07-09T12:51:51Z
咽頭べさ
33
157636
wikitext
text/x-wiki
[[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
ium36dvic7s05gutv4sw4op1g20fjzy
157650
157636
2025-07-09T14:09:07Z
咽頭べさ
33
အကြောင်းအရာ "{{auto cat}}" ဖြင့် အစားထိုးခဲ့သည်
157650
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
157654
157650
2025-07-09T15:24:49Z
咽頭べさ
33
မကလေၚ်ပလီုထောံ[[Special:Diff/157650|157650]]နူကဵု[[Special:Contributions/咽頭べさ|咽頭べさ]] ([[User talk:咽頭べさ|ဓရီုကျာ]])မပလေဝ်ဒါန်လဝ်
157654
wikitext
text/x-wiki
[[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
ium36dvic7s05gutv4sw4op1g20fjzy
ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်
14
70924
157659
93402
2025-07-09T15:27:53Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
93402
wikitext
text/x-wiki
[[ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]]
rmct367nvhf6lx1fmamb6t1v3cibisr
မဝ်ဂျူ:audio
828
72643
157717
126176
2025-07-10T10:38:32Z
咽頭べさ
33
157717
Scribunto
text/plain
local export = {}
local headword_data_module = "Module:headword/data"
local IPA_module = "Module:IPA"
local labels_module = "Module:labels"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local qualifier_module = "Module:qualifier"
local references_module = "Module:references"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local template_styles_module = "Module:TemplateStyles"
local utilities_module = "Module:utilities"
local audio_styles_css = "audio/styles.css"
local function track(page)
require("Module:debug/track")("audio/" .. page)
return true
end
local function wrap_qualifier_css(text, suffix)
return require(qualifier_module).wrap_qualifier_css(text, suffix)
end
--[==[
Display a box that can be used to play an audio file. `data` is a table containing the following fields:
* `lang` ('''required'''): language object for the audio files;
* `file` ('''required'''): file containing the audio;
* `caption`: Caption to display before the audio box; normally {"Audio"}, and does not usually need to be changed;
* `nocaption`: If specified, don't display the caption;
* `q`: {nil} or a list of left regular qualifier strings, formatted using {format_qualifier()} in [[Module:qualifier]]
and displayed before the audio box and after the caption (and any accent qualifiers);
* `qq`: {nil} or a list of right regular qualifier strings, displayed directly after the audio box (and after any
accent qualifiers);
* `a`: {nil} or a list of left accent qualifier strings, formatted using {format_qualifiers()} in
[[Module:accent qualifier]] and displayed before the audio box and after the caption;
* `aa`: {nil} or a list of right accent qualifier strings, displayed directly after the homophone in question;
* `refs`: {nil} or a list of references or reference specs to add directly after the audio box; the value of a list item
is either a string containing the reference text (typically a call to a citation template such as {{tl|cite-book}}, or
a template wrapping such a call), or an object with fields `text` (the reference text), `name` (the name of the
reference, as in {{cd|<nowiki><ref name="foo">...</ref></nowiki>}} or {{cd|<nowiki><ref name="foo" /></nowiki>}})
and/or `group` (the group of the reference, as in {{cd|<nowiki><ref name="foo" group="bar">...</ref></nowiki>}} or
{{cd|<nowiki><ref name="foo" group="bar"/></nowiki>}}); this uses a parser function to format the reference
appropriately and insert a footnote number that hyperlinks to the actual reference, located in the
{{cd|<nowiki><references /></nowiki>}} section;
* `text`: Text of the audio snippet; if specified, should be an object of the form passed to {full_link()} in
[[Module:links]], including a `lang` field containing the language of the text (usually the same as `data.lang`);
displayed before the audio box, after any regular and accent qualifiers;
* `IPA`: IPA of the audio snippet, or a list of IPA specs; if specified, should be surrounded by slashes or brackets,
and will be processed using {format_IPA_multiple()} in [[Module:IPA]] and displayed before the audio box, after any
regular and accent qualifiers and after the text of the audio snippet, if given;
* `nocat`: If true, suppress categorization;
* `sort`: Sort key for categorization.
]==]
function export.format_audio(data)
local cats = { "ဝေါဟာ" .. data.lang:getFullName() .. "မနွံလေန်ပ္တိတ်ရမျာၚ်ဂမၠိုၚ်" }
local function format_a(a)
if a and a[1] then
return require(labels_module).show_labels {
lang = data.lang,
labels = a,
mode = "accent",
nocat = true,
open = false,
close = false,
no_track_already_seen = true,
}
end
return nil
end
local function format_q(q)
if q and q[1] then
return require(qualifier_module).format_qualifier(q, false, false)
end
return nil
end
local function make_td_if(text)
if text == "" then
return text
end
return "<td>" .. text .. "</td>"
end
-- Generate the full text preceding the audio box.
local pretext_parts = {}
local function ins(text)
table.insert(pretext_parts, text)
end
local formatted_accent_labels, formatted_qualifiers, formatted_text, formatted_ipa
formatted_accent_labels = format_a(data.a)
formatted_qualifiers = format_q(data.q)
if data.text then
formatted_text = require(links_module).full_link(data.text, "term", true)
end
if data.IPA then
local ipa_cats
local ipa = data.IPA
if type(ipa) == "string" then
ipa = {ipa}
end
local ipa_items = {}
for _, ipa_item in ipairs(ipa) do
table.insert(ipa_items, {pron = ipa_item})
end
formatted_ipa, ipa_cats = require(IPA_module).format_IPA_multiple(data.lang, ipa_items, nil, "no count", "raw")
if ipa_cats[1] then
require(table_module).extendList(cats, ipa_cats)
end
end
local has_qual = formatted_accent_labels or formatted_qualifiers
if not data.nocaption then
-- Track uses of caption (3=). Over time as we eliminate most of them, we can use this to find and
-- eliminate the remainder.
if data.caption then
track("caption")
end
ins(data.caption or "ရမျာၚ်")
if has_qual then
ins(" " .. wrap_qualifier_css("(", "brac"))
end
end
if formatted_accent_labels then
ins(formatted_accent_labels)
if formatted_qualifiers then
ins(wrap_qualifier_css(",", "comma") .. " ")
end
end
if formatted_qualifiers then
ins(formatted_qualifiers)
end
if has_qual then
if not data.nocaption then
ins(wrap_qualifier_css(")", "brac"))
end
end
if (formatted_text or formatted_ipa) and (has_qual or not data.nocaption) then
ins(wrap_qualifier_css(";", "semicolon") .. " ")
end
if formatted_text then
ins(formatted_text)
if formatted_ipa then
ins(" ")
end
end
ins(formatted_ipa)
if not data.nocaption then
ins(wrap_qualifier_css(":", "colon"))
end
local pretext = make_td_if(table.concat(pretext_parts))
-- Generate the full text following the audio box.
local posttext_parts = {}
local function ins(text)
table.insert(posttext_parts, text)
end
local formatted_post_accent_labels = format_a(data.aa)
local formatted_post_qualifiers = format_q(data.qq)
local formatted_references = data.refs and require(references_module).format_references(data.refs) or nil
if formatted_references then
ins(formatted_references)
end
if formatted_post_accent_labels or formatted_post_qualifiers then
if formatted_references then
ins(" ")
end
ins(wrap_qualifier_css("(", "brac"))
if formatted_post_accent_labels then
ins(formatted_post_accent_labels)
if formatted_post_qualifiers then
ins(wrap_qualifier_css(",", "comma") .. " ")
end
end
if formatted_post_qualifiers then
ins(formatted_post_qualifiers)
end
ins(wrap_qualifier_css(")", "brac"))
end
if data.bad then
track("bad-audio")
track("bad-audio/" .. data.lang:getCode())
ins(" " .. require(qualifier_module).wrap_css("[bad recording: " .. data.bad .. "]", "bad-audio-note"))
end
local posttext = make_td_if(table.concat(posttext_parts))
local template = [=[
<tr>%s<td class="audiofile">[[File:%s|noicon|175px]]</td><td class="audiometa" style="font-size: 80%%;">([[:File:%s|file]])</td>%s</tr>]=]
local text = template:format(pretext, data.file, data.file, posttext)
text = '<table class="audiotable" style="vertical-align: middle; display: inline-block; list-style: none; line-height: 1em; border-collapse: collapse; margin: 0;">' .. text .. "</table>"
local stylesheet = require(template_styles_module)(audio_styles_css)
local categories =
data.nocat and "" or
cats[1] and require(utilities_module).format_categories(cats, data.lang, data.sort) or ""
return stylesheet .. text .. categories
end
--[==[
FIXME: Old entry point for formatting multiple audios in a single table. Not used anywhere and needs rewriting to the
standard of format_audio().
Meant to be called from a module. `data` is a table containing the following fields:
<pre>
{
lang = LANGUAGE_OBJECT,
audios = {{file = "FILENAME", qualifiers = nil or {"QUALIFIER", "QUALIFIER", ...}}, ...},
caption = nil or "CAPTION"
}
</pre>
Here:
* `lang` is a language object.
* `audios` is the list of audio files to display. FILENAME is the name of the audio file without a namespace.
QUALIFIER is a qualifier string to display after the specific audio file in question, formatted using
{format_qualifier()} in [[Module:qualifier]].
* `caption`, if specified, adds a caption before the audio file.
]==]
function export.format_multiple_audios(data)
local audiocats = { "ဝေါဟာ" .. data.lang:getFullName() .. "မနွံလေန်ပ္တိတ်ရမျာၚ်ဂမၠိုၚ်" }
local rows = { }
local caption = data.caption
for _, audio in ipairs(data.audios) do
local qualifiers = audio.qualifiers
local function repl(key)
if key == "file" then
return audio.file
elseif key == "caption" then
if not caption then return "" end
return "<td rowspan=" .. #data.audios .. ">" .. caption .. ":</td>"
elseif key == "qualifiers" then
if not qualifiers or not qualifiers[1] then return "" end
return "<td>" .. require(qualifier_module).format_qualifier(qualifiers) .. "</td>"
end
end
local template = [=[
<tr>{{{caption}}}
<td class="audiofile">[[File:{{{file}}}|noicon|175px]]</td>
<td class="audiometa" style="font-size: 80%;">([[:File:{{{file}}}|file]])</td>
{{{qualifiers}}}</tr>]=]
local text = (mw.ustring.gsub(template, "{{{([a-z0-9_:]+)}}}", repl))
table.insert(rows, text)
caption = nil
end
local function repl(key)
if key == "rows" then
return table.concat(rows, "\n")
end
end
local template = [=[
<table class="audiotable" style="vertical-align: middle; display: inline-block; list-style: none; line-height: 1em; border-collapse: collapse;">
{{{rows}}}
</table>
]=]
local stylesheet = require(template_styles_module)(audio_styles_css)
local text = mw.ustring.gsub(template, "{{{([a-z0-9_:]+)}}}", repl)
local categories =
data.nocat and "" or
#audiocats > 0 and require(utilities_module).format_categories(audiocats, data.lang, data.sort) or ""
-- remove newlines due to HTML generator bug in MediaWiki(?) - newlines in tables cause list items to not end correctly
text = mw.ustring.gsub(text, "\n", "")
return stylesheet .. text .. categories
end
--[==[
Construct the `text` object passed into {format_audio()}, from raw-ish arguments (essentially, the output of {process()}
in [[Module:parameters]]). On entry, `args` contains the following fields:
* `lang` ('''required'''): Language object.
* `text`: Text. If this isn't defined and neither are any of `gloss`, `tr`, `ts`, `pos`, `lit` or `genders`, the
function returns {nil}.
* `gloss`: Gloss of text.
* `tr`: Manual transliteration of text.
* `ts`: Transcription of text.
* `pos`: Part of speech of text.
* `lit`: Literal meaning of text.
* `genders`: List of gender/number spec(s) of text.
* `sc`: Optional script object of text (rarely needs to be set).
* `pagename`: Pagename; used in place of `text` when `text` is unset but other text-related parameters are set.
If not specified, taken from the actual pagename.
]==]
function export.construct_audio_textobj(args)
local textobj
if args.text or args.gloss or args.tr or args.ts or args.pos or args.lit or args.genders and args.genders[1] then
local text = args.text or args.pagename or mw.loadData("Module:headword/data").pagename
textobj = {
lang = args.lang,
alt = wrap_qualifier_css("“", "quote") .. text .. wrap_qualifier_css("”", "quote"),
gloss = args.gloss,
tr = args.tr,
ts = args.ts,
pos = args.pos,
lit = args.lit,
genders = args.genders,
sc = args.sc,
}
end
return textobj
end
--[==[
Entry point for {{tl|audio}} template.
]==]
function export.show(frame)
local parent_args = frame:getParent().args
local compat = parent_args.lang
local offset = compat and 0 or 1
local params = {
[compat and "lang" or 1] = {required = true, type = "language", default = "en"},
[1 + offset] = {required = true, default = "Example.ogg"},
[2 + offset] = {},
["q"] = {type = "qualifier"},
["qq"] = {type = "qualifier"},
["a"] = {type = "labels"},
["aa"] = {type = "labels"},
["ref"] = {type = "references"},
["IPA"] = {sublist = true},
["text"] = {},
["t"] = {},
["gloss"] = {alias_of = "t"},
["tr"] = {},
["ts"] = {},
["pos"] = {},
["lit"] = {},
["g"] = {sublist = true},
["sc"] = {type = "script"},
["bad"] = {},
["nocat"] = {type = "boolean"},
["sort"] = {},
["pagename"] = {},
}
local args = require(parameters_module).process(parent_args, params)
local lang = args[compat and "lang" or 1]
-- Needed in construct_audio_textobj().
args.lang = lang
local textobj = export.construct_audio_textobj(args)
local caption = args[2 + offset]
local nocaption
if caption == "-" then
caption = nil
nocaption = true
end
if caption then
-- Remove final colon if given, to avoid two colons.
caption = caption:gsub(":$", "")
end
local data = {
lang = lang,
file = args[1 + offset],
caption = caption,
nocaption = nocaption,
q = args.q,
qq = args.qq,
a = args.a,
aa = args.aa,
refs = args.ref,
text = textobj,
IPA = args.IPA,
bad = args.bad,
nocat = args.nocat,
sort = args.sort,
}
return export.format_audio(data)
end
return export
2pmnul15nxp9uiuhbl6i4f9hocn6mbi
ကဏ္ဍ:ပစ္စဲမန်ဂမၠိုၚ်
14
77527
157625
133787
2025-07-09T12:31:39Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ပစ္စဲမန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ပစ္စဲမန်ဂမၠိုၚ်]]
101511
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်]]
bsvcnko7m99gh74uhzj7cawhpn6i949
မဝ်ဂျူ:language tracking
828
78109
157698
135721
2025-07-10T09:32:59Z
咽頭べさ
33
157698
Scribunto
text/plain
local export = {}
local function generate_lemmas(langs)
local output = '<table class="langtrack"><tr class="primary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">" .. mw.site.stats.pagesInCategory("ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်", "pages") .. "</th>"
end
output = output .. '</tr><tr class="secondary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">[[Special:RecentChangesLinked/Category:ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်|ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်]]</th>"
end
output = output .. "</tr></table>"
return output
end
local function generate_nonlemmas(langs)
local output = '<table class="infobox langtrack"><tr class="primary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">" .. mw.site.stats.pagesInCategory("ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်", "pages") .. "</th>"
end
output = output .. '</tr><tr class="secondary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">[[Special:RecentChangesLinked/Category:ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်|ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်]]</th>"
end
output = output .. "</tr></table>"
return output
end
local function generate_both(langs)
local output = '<table class="infobox langtrack"><tr class="primary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">" .. mw.site.stats.pagesInCategory("ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်", "pages") .. "</th>"
end
output = output .. '</tr><tr class="secondary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">[[Special:RecentChangesLinked/Category:ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်|ဝေါဟာအဓိက" .. language .. "ဂမၠိုၚ်]]</th>"
end
output = output .. '</tr><tr class="primary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">" .. mw.site.stats.pagesInCategory("ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်", "pages") .. "</th>"
end
output = output .. '</tr><tr class="secondary">'
for _, language in ipairs(langs) do
output = output .. "<th style=\"padding: 15px\">[[Special:RecentChangesLinked/Category:ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်|ဗီုပြၚ်အပြံၚ်အလှာဲ" .. language .. "ဂမၠိုၚ်]]</th>"
end
output = output .. "</tr></table>"
return output
end
function export.show(frame)
local args = require("Module:parameters").process(
frame:getParent().args,
{
[1] = { list = true },
["type"] = { default = "ဝေါဟာအဓိက" },
})
local langs = {}
local languageData = mw.loadData("Module:languages/code to canonical name")
for _, language in ipairs(args[1]) do
language = languageData[language]
table.insert(langs, (language ~= "") and language or nil)
end
local output
if args.type == "ဝေါဟာအဓိက" then
output = generate_lemmas(langs)
elseif args.type == "ဗီုပြၚ်အပြံၚ်အလှာဲ" then
output = generate_nonlemmas(langs)
elseif args.type == "both" then
output = generate_both(langs)
else
error("Invalid type.")
end
return output .. frame:extensionTag("templatestyles", nil, {src = "Template:language tracking/styles.css"})
end
return export
bex0b5rixnn7cuvy3cqjc4u8gyrmpe9
ကဏ္ဍ:ကၞာတ်အမှိက်မန်ဂမၠိုၚ်
14
79020
157663
133795
2025-07-09T15:29:37Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကၞာတ်အမှိက်မန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ကၞာတ်အမှိက်မန်ဂမၠိုၚ်]]
103571
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်]]
bsvcnko7m99gh74uhzj7cawhpn6i949
ကဏ္ဍ:နာမဝိသေသနမန်တြေံဂမၠိုၚ်
14
79261
157681
143125
2025-07-10T05:26:43Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:နာမဝိသေသနမန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:နာမဝိသေသနမန်တြေံဂမၠိုၚ်]]
143125
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] » [[:ကဏ္ဍ:ဘာသာမန်တြေံ|မန်တြေံ]] » [[:ကဏ္ဍ:ဝေါဟာအဓိကမန်တြေံဂမၠိုင်|ဝေါဟာတံသ္ဇိုၚ်]] » '''နာမဝိသေသနဂမၠိုၚ်'''
:ဝေါဟာမန်တြေံမဒုၚ်ကေတ်အၚ်္ဂအဝဲဂုန်နကဵုနာမ်ဂမၠိုၚ်၊ မဒုၚ်ကဵုကေတ်အဓိပ္ပာဲအတေံဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမန်တြေံ]][[ကဏ္ဍ:နာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်|မ]]
d4a60r4reakafugx0lfef6uobuph1ag
157714
157681
2025-07-10T10:25:49Z
咽頭べさ
33
157714
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမန်တြေံ|မန်တြေံ]] » [[:ကဏ္ဍ:ဝေါဟာအဓိကမန်တြေံဂမၠိုၚ်|ဝေါဟာတံသ္ဇိုၚ်]] » '''နာမဝိသေသနဂမၠိုၚ်'''
:ဝေါဟာမန်တြေံမဒုၚ်ကေတ်အၚ်္ဂအဝဲဂုန်နကဵုနာမ်ဂမၠိုၚ်၊ မဒုၚ်ကဵုကေတ်အဓိပ္ပာဲအတေံဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမန်တြေံ]][[ကဏ္ဍ:နာမဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|မ]]
oso9mqvb1qcr0xgv6lfq570h4qnt48q
ကဏ္ဍ:ဗီုပြၚ်နာမ်မန်ဂမၠိုၚ်
14
108573
157627
134079
2025-07-09T12:32:59Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြင်နာမ်မန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်နာမ်မန်ဂမၠိုၚ်]]
134079
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] » [[:ကဏ္ဍ:ဘာသာမန်|မန်]] » [[:ကဏ္ဍ:ဗီုပြင်အပြံင်အလှာဲမန်ဂမၠိုင်|ဗီုပြၚ်ဝေါဟာတံသ္ဇိုၚ်]] » '''ဗီုပြၚ်နာမ်ဂမၠိုၚ်'''
:နာမ်မန်မပြံၚ်လှာဲနကဵုအဆက်အဆေန်မဆေၚ်စပ်ကဵုမဓမံက်ထ္ၜးသဒ္ဒာဗီုပြၚ်အဓိကတၞဟ်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမန်]][[ကဏ္ဍ:နာမ်မန်ဂမၠိုင်]][[ကဏ္ဍ:ဗီုပြင်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ|မ]]
mcn0jngpgmk9kopqeoq5hcd373ff2ta
157655
157627
2025-07-09T15:26:18Z
咽頭べさ
33
157655
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] » [[:ကဏ္ဍ:ဘာသာမန်|မန်]] » [[:ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်|ဗီုပြၚ်ဝေါဟာတံသ္ဇိုၚ်]] » '''ဗီုပြၚ်နာမ်ဂမၠိုၚ်'''
:နာမ်မန်မပြံၚ်လှာဲနကဵုအဆက်အဆေန်မဆေၚ်စပ်ကဵုမဓမံက်ထ္ၜးသဒ္ဒာဗီုပြၚ်အဓိကတၞဟ်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမန်]][[ကဏ္ဍ:နာမ်မန်ဂမၠိုၚ်]][[ကဏ္ဍ:ဗီုပြင်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ|မ]]
i5jhakcqnudrt2qu28497ozobgwm2kx
157656
157655
2025-07-09T15:26:37Z
咽頭べさ
33
157656
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] » [[:ကဏ္ဍ:ဘာသာမန်|မန်]] » [[:ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်|ဗီုပြၚ်ဝေါဟာတံသ္ဇိုၚ်]] » '''ဗီုပြၚ်နာမ်ဂမၠိုၚ်'''
:နာမ်မန်မပြံၚ်လှာဲနကဵုအဆက်အဆေန်မဆေၚ်စပ်ကဵုမဓမံက်ထ္ၜးသဒ္ဒာဗီုပြၚ်အဓိကတၞဟ်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမန်]][[ကဏ္ဍ:နာမ်မန်ဂမၠိုၚ်]][[ကဏ္ဍ:ဗီုပြၚ်နာမ်ဗက်အလိုက်အရေဝ်ဘာသာ|မ]]
5cwnycy1dx0cxgkaozu65n292yahtlb
ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်
14
108574
157657
134080
2025-07-09T15:27:20Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြင်အပြံင်အလှာဲမန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်]]
134080
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုင်]] » [[:ကဏ္ဍ:ဘာသာမန်|မန်]] » '''ဗီုပြၚ်ဝေါဟာတံသ္ဇိုၚ်ဂမၠိုၚ်'''
:ဗီုပြၚ်အပြံၚ်လှာဲဝေါဟာတံသ္ဇိုၚ်နဲတၞဟ်နကဵုဘာသာမန်၊ ကဏ္ဍနူကဵုမပါ်ပရံဒကုတ်မဆေၚ်စပ်ကဵုမအရေဝ်ဝေါဟာ။
[[ကဏ္ဍ:ဘာသာမန်]][[ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်|မ]]
kygmf1yf4tnmd3alw9i115a96gbfco6
ကဏ္ဍ:ကြိယာဝိသေသနမန်တြေံဂမၠိုၚ်
14
116659
157667
150363
2025-07-09T15:32:12Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကြိယာဝိသေသနမန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ကြိယာဝိသေသနမန်တြေံဂမၠိုၚ်]]
150363
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်တြေံ]]
kfrz1jee49i18pezkjinqsd4uvop8ig
မဝ်ဂျူ:category tree/data/doc
828
119330
157693
154120
2025-07-10T05:52:23Z
咽頭べさ
33
157693
wikitext
text/x-wiki
<div style="float: right; width: 22em; margin: 0 0 1em 0.5em; border: 1px solid darkgray; padding: 0.5em;>
<inputbox>
type=fulltext
prefix=Module:category tree
searchbuttonlabel=Search this module and its submodules
</inputbox>
</div>
This is the documentation page for the [[Module:category tree/data|main data module]] for [[Module:category tree]]. This module does not contain data itself, but rather imports the data from the category tree submodules, and applies some post-processing. For an introduction to the category tree, and details on how to add new categories to the tree, see the documentation for [[Module:category tree]].
* To find which submodule implements a specific category, use the search box on the right.
* To add a new submodule, copy an existing submodule and modify its contents. Then, add its name to the {{lua|subpages}} list at the top of [[Module:category tree/data]].
<includeonly>
[[ကဏ္ဍ:ကဏ္ဍစရၚ်မဝ်ဂျူဂမၠိုၚ်| ]]
</includeonly>
rf166kunvsmj16a956okx7hbob1rcst
ကဏ္ဍ:ကဏ္ဍစရၚ်မဝ်ဂျူဂမၠိုၚ်
14
119332
157691
154122
2025-07-10T05:51:16Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:တၞံမဝ်ဂျူဂၠေံဂၠေံဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:ကဏ္ဍစရၚ်မဝ်ဂျူဂမၠိုၚ်]]
154122
wikitext
text/x-wiki
[[ကဏ္ဍ:ဒေတာမဝ်ဂျူဂမၠိုင်]][[ကဏ္ဍ:ကဏ္ဍမဝ်ဂျူဂမၠိုၚ်]]
2c0fdyh6f30zlh9dq8m6oafhqxm4bh2
ကဏ္ဍ:ကၞာတ်အမှိက်မန်တြေံဂမၠိုၚ်
14
119805
157669
154821
2025-07-09T15:33:49Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကၞာတ်အမှိက်မန်တြေံဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ကၞာတ်အမှိက်မန်တြေံဂမၠိုၚ်]]
154821
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာမန်တြေံ]]
kfrz1jee49i18pezkjinqsd4uvop8ig
မဳဒဳယာဝဳကဳ:Sitenotice
8
120500
157671
155715
2025-07-09T17:42:54Z
咽頭べさ
33
157671
wikitext
text/x-wiki
<div class="plainlinks" style="background:#f5faff; border:1px solid #a7d7f9; margin:1em auto 1em auto; width:100%; padding: 0.5ex;">
* Mon Wiktionary still has weaknesses, so we would like to ask for your support and maintenance. to inquire about the conversation, contact [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] group or Writer [https://web.facebook.com/dr.intobesa Dr.Intobesa]. ဝိက်ရှေန်နရဳမန်မနွံဒၟံၚ်ဇြဟတ်ဍိုန်တုဲ၊ ဟိုတ်ဂှ်ရ ပိုဲမိက်ဂွံအာတ်မိက်အရၚ်သွက်ဗိုၚ်ရီုဗၚ်မၚ်မွဲထိၚ်ဒက်အာကီုရ။ ကေတ်အဆက်စၟဳစၟတ်တၚ်သၟာန်ဂကောံ [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] ဝါ အ္စာလိက် [https://web.facebook.com/dr.intobesa Dr.Intobesa] ညိအဴ။</div>
: Announce: Since this င် [[File:Mon writing system.gif|20x20px]] is an outdated Mon writing system, I would like to request Dr.Intobesa not to continue to use it on Mon Wiktionary for the sake of the modern development of Mon literature. (The difficulties facing the modern development of Mon literature: we continuously taught the Mon language to the AIs for the future Mon literature, but the AIs had a hard time distinguishing the Mon writing system from the Burmese writing system). I am proposing that Mon Wiktionary no longer use this outdated င် Mon writing system as it is known that AIs are learning Wiktionary's data to train the language.
5hr6vffdxfigx8q891uc3k1dz2gfhii
157672
157671
2025-07-09T17:43:22Z
咽頭べさ
33
157672
wikitext
text/x-wiki
<div class="plainlinks" style="background:#f5faff; border:1px solid #a7d7f9; margin:1em auto 1em auto; width:100%; padding: 0.5ex;">
* Mon Wiktionary still has weaknesses, so we would like to ask for your support and maintenance. to inquire about the conversation, contact [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] group or Writer [https://web.facebook.com/dr.intobesa Dr.Intobesa]. ဝိက်ရှေန်နရဳမန်မနွံဒၟံၚ်ဇြဟတ်ဍိုန်တုဲ၊ ဟိုတ်ဂှ်ရ ပိုဲမိက်ဂွံအာတ်မိက်အရၚ်သွက်ဗိုၚ်ရီုဗၚ်မၚ်မွဲထိၚ်ဒက်အာကီုရ။ ကေတ်အဆက်စၟဳစၟတ်တၚ်သၟာန်ဂကောံ [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] ဝါ အ္စာလိက် [https://web.facebook.com/dr.intobesa Dr.Intobesa] ညိအဴ။</div>
: Announce: Since this င် [[File:Mon writing system.gif|70x70px]] is an outdated Mon writing system, I would like to request Dr.Intobesa not to continue to use it on Mon Wiktionary for the sake of the modern development of Mon literature. (The difficulties facing the modern development of Mon literature: we continuously taught the Mon language to the AIs for the future Mon literature, but the AIs had a hard time distinguishing the Mon writing system from the Burmese writing system). I am proposing that Mon Wiktionary no longer use this outdated င် Mon writing system as it is known that AIs are learning Wiktionary's data to train the language.
8nx8yekhgjoq6cl310d5vxuxjl9on1t
157673
157672
2025-07-09T17:44:15Z
咽頭べさ
33
157673
wikitext
text/x-wiki
<div class="plainlinks" style="background:#f5faff; border:1px solid #a7d7f9; margin:1em auto 1em auto; width:100%; padding: 0.5ex;">
* Mon Wiktionary still has weaknesses, so we would like to ask for your support and maintenance. to inquire about the conversation, contact [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] group or Writer [https://web.facebook.com/dr.intobesa Dr.Intobesa]. ဝိက်ရှေန်နရဳမန်မနွံဒၟံၚ်ဇြဟတ်ဍိုန်တုဲ၊ ဟိုတ်ဂှ်ရ ပိုဲမိက်ဂွံအာတ်မိက်အရၚ်သွက်ဗိုၚ်ရီုဗၚ်မၚ်မွဲထိၚ်ဒက်အာကီုရ။ ကေတ်အဆက်စၟဳစၟတ်တၚ်သၟာန်ဂကောံ [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] ဝါ အ္စာလိက် [https://web.facebook.com/dr.intobesa Dr.Intobesa] ညိအဴ။</div>
: Announce: Since this င် [[File:Mon writing system.gif|50x50px]] is an outdated Mon writing system, I would like to request Dr.Intobesa not to continue to use it on Mon Wiktionary for the sake of the modern development of Mon literature. (The difficulties facing the modern development of Mon literature: we continuously taught the Mon language to the AIs for the future Mon literature, but the AIs had a hard time distinguishing the Mon writing system from the Burmese writing system). I am proposing that Mon Wiktionary no longer use this outdated င် Mon writing system as it is known that AIs are learning Wiktionary's data to train the language.
dlz2m0wii8dvxpp7jifgg6z7ccg9hlr
157674
157673
2025-07-09T17:45:02Z
咽頭べさ
33
157674
wikitext
text/x-wiki
<div class="plainlinks" style="background:#f5faff; border:1px solid #a7d7f9; margin:1em auto 1em auto; width:100%; padding: 0.5ex;">
* Mon Wiktionary still has weaknesses, so we would like to ask for your support and maintenance. to inquire about the conversation, contact [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] group or Writer [https://web.facebook.com/dr.intobesa Dr.Intobesa]. ဝိက်ရှေန်နရဳမန်မနွံဒၟံၚ်ဇြဟတ်ဍိုန်တုဲ၊ ဟိုတ်ဂှ်ရ ပိုဲမိက်ဂွံအာတ်မိက်အရၚ်သွက်ဗိုၚ်ရီုဗၚ်မၚ်မွဲထိၚ်ဒက်အာကီုရ။ ကေတ်အဆက်စၟဳစၟတ်တၚ်သၟာန်ဂကောံ [https://web.facebook.com/groups/MonWikipediaGroup Mon Wikipedia Facebook] ဝါ အ္စာလိက် [https://web.facebook.com/dr.intobesa Dr.Intobesa] ညိအဴ။</div>
: Announce: Since this င် is an outdated Mon writing system, I would like to request Dr.Intobesa not to continue to use it on Mon Wiktionary for the sake of the modern development of Mon literature. (The difficulties facing the modern development of Mon literature: we continuously taught the Mon language to the AIs for the future Mon literature, but the AIs had a hard time distinguishing the Mon writing system from the Burmese writing system). I am proposing that Mon Wiktionary no longer use this outdated င် Mon writing system as it is known that AIs are learning Wiktionary's data to train the language.[[File:Mon writing system.gif|50x50px]]
192rzbip4bgaqzo1min2rbaxwe76frg
မဝ်ဂျူ:category tree/wiktionary users
828
121687
157633
157418
2025-07-09T12:50:06Z
咽頭べさ
33
157633
Scribunto
text/plain
local raw_categories = {}
local raw_handlers = {}
local concat = table.concat
local insert = table.insert
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local string_utilities_module = "Module:string utilities"
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["ဝိက်ရှေန်နရဳ"] = {
description = "ကဏ္ဍကဆံၚ်သၠုၚ်သွက်ကပေါတ်ကညောတ်ပရောဟိုတ်ဝိက်ရှေန်နရဳ ကဵု ပရေၚ်ပြုပြေၚ်ဂှ်။",
parents = "ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
}
raw_categories["ဝိက်ရှေန်နရဳစရၚ်အၚ်ဂမၠိုၚ်"] = {
description = "Categories and pages containing statistics about how Wiktionary is used.",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Statistics"},
}
raw_categories["ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်"] = {
description = "Pages listing Wiktionarians according to their user rights and categories listing Wiktionarians according to their linguistic and coding abilities.",
breadcrumb = "ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်",
additional = "For an automatically generated list of all users, see [[Special:ListUsers]].",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Users"},
}
raw_categories["Wikimedians banned by the WMF"] = {
description = "Users who have received a [[m:Global bans|global ban]] imposed by the [[m:Wikimedia Foundation|Wikimedia Foundation]], in accordance with the [[m:WMF Global Ban Policy|WMF Global Ban Policy]].",
breadcrumb = "Banned by the WMF",
parents = "Wiktionary users",
}
raw_categories["User languages"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User languages with invalid code"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities, where the language code is invalid for Wiktionary.",
additional = "Most of these codes are valid ISO 639-3 codes but are invalid in Wiktionary for various reasons, " ..
"typically due to different choices made regarding splitting and merging languages.",
parents = {name = "User languages", sort = " "},
}
raw_categories["User scripts"] = {
description = "Categories listing Wiktionarians according to their abilities to read a given script.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User coders"] = {
description = "Categories listing Wiktionarians according to their coding abilities.",
parents = "Wiktionary users",
}
raw_categories["User families"] = {
description = "Categories listing Wiktionarians according to their knowledge about a given language family.",
parents = "Wiktionary users"
}
raw_categories["Pages with entries"] = {
description = "Pages which contain language entries.",
additional = "The subcategories within this category are used to determine the total number of entries on the English Wiktionary.",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
raw_categories["Redirects connected to a Wikidata item"] = {
description = "Redirect pages which are connected to a [[d:|Wikidata]] item.",
additional = "These are rarely needed, but are occasionally useful following a page merger, where other wikis may still separate the two.",
parents = "Wiktionary statistics",
can_be_empty = true,
hidden = true,
}
raw_categories["Unsupported titles"] = {
description = "Pages with titles that are not supported by the MediaWiki software.",
additional = "For an explanation of the reasons why certain titles are not supported, see [[Appendix:Unsupported titles]].",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
-- Tracked according to [[phab:T347324]].
for ext, data in pairs {
["စရၚ်မုက်လိက်ချဳဒရာၚ်"] = {"DynamicPageList (Wikimedia)", "T287380"},
["EasyTimeline"] = {"EasyTimeline", "T137291"},
["Graph"] = {"Graph", "T334940"},
["Kartographer"] = {"Kartographer"},
["Phonos"] = {"Phonos"},
["Score"] = {"Score"},
["WikiHiero"] = {"WikiHiero", "T344534"},
} do
local link, phab = unpack(data)
raw_categories["မုက်လိက်မရပ်စပ်မဆေၚ်ကဵု" .. ext .. "က္တဵုဒှ်တိုန်"] = {
description = ("Pages which make use of the [[mw:Extension:%s|%s]] extension."):format(link, ext),
additional = phab and ("See [[phab:%s|%s]] on Phabricator for background information on why this extension is tracked."):format(phab, phab) or nil,
breadcrumb = ("Using the %s extension"):format(ext),
parents = "စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်",
can_be_empty = true,
hidden = true,
}
end
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_level_params(data)
local speak_verb = "speak"
if data.typ == "lang" then
local is_sign_language = data.obj and data.obj:getFamilyCode() and data.obj:getFamilyCode():find("^sgn") or data.langfam:find("Sign Language$")
speak_verb = data.args.verb or is_sign_language and "communicate in" or "speak"
end
return {
["-"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM!.",
script = "These users read !SCRIPT!.",
coder = "These users know how to code in !LANGFAM!.",
family = "These users know !LANGFAM!.",
},
["1"] = {
cssclass = "babel-1",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''basic''' level.",
script = "These users can read !SCRIPT! at a '''basic''' level.",
coder = "These users know the '''basics''' of how to write !LANGFAM! code and make minor tweaks.",
family = "These users know the '''basics''' of contributing to !LANGFAM!.",
},
["2"] = {
cssclass = "babel-2",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''intermediate''' level.",
script = "These users can read !SCRIPT! at an '''intermediate''' level.",
coder = "These users have a '''fair command''' of !LANGFAM!, and can understand some scripts written by others.",
family = "These users are '''fairly familiar''' with !LANGFAM!.",
},
["3"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''advanced''' level.",
script = "These users can read !SCRIPT! at an '''advanced''' level.",
coder = "These users can write '''more complex''' !LANGFAM! code, and can understand and modify most scripts written by others.",
family = "These users '''regularly''' contribute to !LANGFAM!.",
},
["4"] = {
cssclass = "babel-4",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''near-native''' level.",
script = "These users can read !SCRIPT! at a '''near native''' level.",
coder = "These users can write and understand '''very complex''' !LANGFAM! code.",
},
["5"] = {
cssclass = "babel-5",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''professional''' level.",
script = "These users can read !SCRIPT! at a '''professional''' level.",
coder = "These users can write and understand !LANGFAM! code at a '''professional''' level.",
},
["N"] = {
cssclass = "babel-N",
lang = "These users are '''native''' speakers of !LANGFAM!.",
script = "These users' '''native''' script is !SCRIPT!.",
},
}
end
local coder_links = {
Asm = "w:Assembly language",
Bash = "w:Bash (Unix shell)",
C = "w:C (programming language)",
["C++"] = "w:C++",
["C Sharp"] = {link = "w:C Sharp (programming language)", lang = "C#"},
CSS = "w:CSS",
Go = "w:Go (programming language)",
Haskell = "w:Haskell",
HTML = "w:HTML",
Java = "w:Java (programming language)",
JavaScript = "w:JavaScript",
Julia = "w:Julia (programming language)",
Kotlin = "w:Kotlin (programming language)",
Lisp = "w:Lisp (programming language)",
Lua = "Wiktionary:Scripting",
Perl = "w:Perl",
PHP = "w:PHP",
Python = "w:Python (programming language)",
regex = {link = "w:Regular expression", name = "regular expressions"},
Ruby = "w:Ruby (programming language)",
Rust = "w:Rust (programming language)",
Scala = "w:Scala (programming language)",
Scheme = "w:Scheme (programming language)",
SQL = "w:SQL",
template = {link = "Wiktionary:Templates", name = "wiki templates"},
Typescript = "w:Typescript",
VBScript = "w:VBScript",
}
local custom_script_links = {
IPA = "w:International Phonetic Alphabet",
UPA = "w:Uralic Phonetic Alphabet",
}
-- Generic implementation of competency handler for (natural) languages, scripts, families and "coders" (= programming languages).
local function competency_handler(data)
local category = data.category
local langtext = data.langtext
local typ = data.typ
local args = data.args
local code = data.code
local langfam = data.langfam
local langfamcat = data.langfamcat
local script = data.script
local scriptcat = data.scriptcat
local level = data.level
local parents = data.parents
local addl_parents = data.addl_parents
local topright = data.topright
local data_addl = data.additional
local inactive = data.inactive
local parts = {}
local function ins(txt)
insert(parts, txt)
end
local level_params = get_level_params(data)
local params = level_params[level or "-"]
if not params then
error(("Internal error: No params for for code '%s', level %s"):format(code, level or "-"))
end
local function insert_text()
if langtext then
ins(langtext)
ins("<hr />")
end
if not params[typ] then
error(("No English text for code '%s', type '%s', level %s"):format(code, typ, level or "-"))
end
local pattern, repl
if typ == "script" then
pattern = "!SCRIPT!"
repl = ("'''" .. scriptcat .. "'''"):format(script)
else
pattern = "!LANGFAM!"
repl = ("'''" .. langfamcat .. "'''"):format(langfam)
if script then
repl = repl .. (" written in '''" .. scriptcat .. "'''"):format(script)
end
end
ins(params[typ]:gsub(pattern, repl))
end
local additional = {}
if level then
insert(additional, ("To be included on this list, add {{tl|Babel|%s}} to your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]]."):format(level == "N" and code or ("%s-%s"):format(code, level)))
else
insert(additional, "To be included on this list, use {{tl|Babel}} on your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]].")
end
if inactive then
insert(additional, "'''NOTE:''' Users in this category have not been active on the English Wiktionary for at " ..
"least two years and have been moved into the 'inactive' state due to " ..
"[[Wiktionary:Votes/pl-2017-04/Removing inactive editors from user-proficiency categories]].")
parents = {{name = category, sort = " "}}
end
if addl_parents then
for _, addl_parent in ipairs(addl_parents) do
insert(parents, addl_parent)
end
end
if data_addl then
insert(additional, data_addl)
end
local babel_templatestyles = require("Module:TemplateStyles")("Template:Babel/style.css")
if level then
ins(('<div class="babel-box %s">'):format(params.cssclass))
ins('<table class="babel-content" style="width:238px"><tr>')
ins('<td class="babel-code" style="font-size:14pt">')
ins(("'''%s-%s'''</td>"):format(code, level))
ins('<td class="babel-text">')
insert_text()
ins('</td></tr></table></div><br clear="left">')
return {
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or "Level " .. level,
parents = parents,
}, not not args
else
ins(('<div class="babel-box %s">\n'):format(params.cssclass))
ins('{| class="babel-content" style="width:260px;"\n')
ins('| class="babel-code" style="font-size:14pt;" | ')
ins(("'''%s'''\n"):format(code))
ins('| class="babel-text" style="text-align:center;" | ')
insert_text()
ins('\n|}</div><br clear="left">')
return {
topright = topright,
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or lang,
parents = parents,
}, not not args
end
end
-- Guts of implementation of competency handlers for natural languages (full or etymology-only), possibly with a
-- script attached (e.g. [[Category:User ko-Kore]]).
local function handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
local lang = require("Module:languages").getByCode(code, nil, "allow etym")
local langname = args.langname
local sc, scriptname
if sccode then
sc = require("Module:scripts").getByCode(sccode)
scriptname = args.scriptname
end
local code_with_script = code .. (sccode and "-" .. sccode or "")
if not lang or sccode and not sc then
-- If unrecognized language and called from inside, we're handling the parents and breadcrumb for a
-- higher-level category, so at least return something.
if not level and data.called_from_inside then
return {
-- FIXME, scrape langname= category?
breadcrumb = {name = code_with_script, nocap = true},
parents = {name = lang and "User languages with invalid script code" or
"User languages with invalid code", sort = code_with_script}
}, true
end
if not langname then
-- Check if the code matches a Wikimedia language (e.g. "ku" for Kurdish). If it does, treat
-- its canonical name as though it had been given as langname=.
local wm_lang = require("Module:wikimedia languages").getByCode(code)
if not wm_lang then
mw.log(("Skipping category '%s' because lang code '%s' is unrecognized and langname= not given"):
format(data.category, code))
return
end
langname = wm_lang:getCanonicalName()
end
if sccode and not sc and not scriptname then
mw.log(("Skipping category '%s' because script code '%s' is unrecognized and scriptname= not given"):
format(data.category, sccode))
return
end
end
if not langname then
if not lang then
error("Internal error: Something went wrong, undefined lang= should have been caught above")
end
langname = lang:getCanonicalName()
end
if not scriptname and sccode then
if not sc then
error("Internal error: Something went wrong, undefined sc= should have been caught above")
end
-- Use `getCategoryName` not `getCanonicalName` to display 'Foo script' than just 'Foo', as so many scripts
-- are the same as language names, and otherwise we get nonsensical output like "These users are native speakers
-- of Korean written in Korean".
scriptname = sc:getCategoryName()
end
-- Insert text, appropriately script-tagged, unless already script-tagged (we check for '<span'), in which case we
-- insert it directly. Also handle <<...>> and <<<...>>> in text and convert to bolded link to parent category.
local function wrap(txt)
if not txt then
return
end
if sccode then
-- Substitute <<<...>>> (where ... is supposed to be the native rendering of the script) with a link to the
-- top-level 'User SCRIPT' category (e.g. [[:Category:User Kore]] if we're in a sublevel category, or to the
-- top-level script category (e.g. [[:Category:Korean script]]) if we're in a top-level 'User CODE-SCRIPT'
-- category.
txt = txt:gsub("<<<(.-)>>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(sccode, inside)
elseif sc then
return ("'''[[:Category:%s|%s]]'''"):format(sc:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
end
-- Substitute <<...>> (where ... is supposed to be the native rendering of the language) with a link to the
-- top-level 'User CODE' category (e.g. [[:Category:User fr]] or [[:Category:User fr-CA]]) if we're in a
-- sublevel category, or to the top-level language category (e.g. [[:Category:French language]] or
-- [[:Category:Canadian English]]) if we're in a top-level 'User CODE' category.
txt = txt:gsub("<<(.-)>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(code, inside)
elseif lang then
return ("'''[[:Category:%s|%s]]'''"):format(lang:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
if txt:find("<span") or not lang then
return txt
else
return require("Module:script utilities").tag_text(txt, lang, sc)
end
end
local function get_request_cats()
if args.text or code == "en" or code:find("^en%-") then
return
end
local num_pages = mw.site.stats.pagesInCategory(data.category, "pages")
local count_cat, count_sort
if num_pages == 0 then
count_cat = "Requests for translations in user-competency categories with 0 users"
count_sort = "*" .. code_with_script
elseif num_pages == 1 then
count_cat = "Requests for translations in user-competency categories with 1 user"
count_sort = "*" .. code_with_script
else
local lowernum, uppernum
lowernum = 2
while true do
uppernum = lowernum * 2 - 1
if num_pages <= uppernum then
break
end
lowernum = lowernum * 2
end
count_cat = ("Requests for translations in user-competency categories with %s-%s users"):format(
lowernum, uppernum)
count_sort = "*" .. ("%0" .. #(tostring(uppernum)) .. "d"):format(num_pages)
end
local addl_parents = {}
insert(addl_parents, {
name = "Requests for translations in user-competency categories by language",
sort = code_with_script,
})
insert(addl_parents, {
name = count_cat,
sort = count_sort,
})
return addl_parents
end
local invalid_lang_warning
if not lang then
invalid_lang_warning = "'''WARNING''': The specified language code is invalid on Wiktionary. Please migrate " ..
"all competency ratings to the closest valid code."
end
local parents
if level then
parents = {("User %s"):format(code_with_script), sort = level}
elseif sccode then
parents = {}
insert(parents, {name = ("User %s"):format(code), sort = sccode})
insert(parents, {name = ("User %s"):format(sccode), sort = code})
elseif lang then
parents = {}
if lang:hasType("etymology-only") then
local full_code = lang:getFullCode()
local sort_key = code:gsub(("^%s%%-"):format(require(string_utilities_module).pattern_escape(full_code)),
"")
insert(parents, {name = ("User %s"):format(full_code), sort = sort_key})
else
insert(parents, {name = "User languages", sort = code})
end
insert(parents, {name = lang:getCategoryName(), sort = "user"})
else
parents = {"User languages with invalid code", sort = code}
end
local addl_parents = get_request_cats()
local topright
if args.commonscat then
local commonscat = require("Module:yesno")(args.commonscat, "+")
if commonscat == "+" or commonscat == true then
commonscat = data.category
end
if commonscat then
topright = ("{{commonscat|%s}}"):format(commonscat)
end
end
local langcat
if level then
langcat = ("[[:Category:User %s|%%s]]"):format(code)
elseif lang then
langcat = ("[[:Category:%s|%%s]]"):format(lang:getCategoryName())
else
langcat = "[[%s]]"
end
local scriptcat
if sccode then
if level then
scriptcat = ("[[:Category:User %s|%%s]]"):format(sccode)
elseif sc then
scriptcat = ("[[:Category:%s|%%s]]"):format(sc:getCategoryName())
else
scriptcat = "[[%s]]"
end
end
return competency_handler {
category = category,
inactive = inactive,
langtext = wrap(args.text),
typ = "lang",
args = args,
obj = lang,
code = code_with_script,
langfam = langname,
langfamcat = langcat,
script = scriptname,
scriptcat = scriptcat,
level = level,
parents = parents,
addl_parents = addl_parents,
topright = topright,
additional = invalid_lang_warning,
}
end
-- Hander for categories named [[Category:User LANG-SCRIPT]] or [[Category:User LANG-SCRIPT-#]] where # is a
-- competency level (0 through 5 or N), e.g. [[Category:zh-Hans]] or [[Category:yue-Hant-N]]. It's a bit tricky because
-- of the multitude of language formats, e.g. ko-KP is a language code (etym variety) but ko-Kore is a combination
-- lang + script code. We depend on the fact that all script codes are currently of the form Xxxx or Xxxxx, and check
-- for that first. We also need to run prior to the lang-only handler (next handler) so it doesn't try to interpret
-- the script code as an etym variant code.
--
-- Note that there are current categories named things like 'zh-Hant-TW' and 'zh-Hant-HK-3', which we don't support.
-- They should be renamed to some supported code, e.g. 'cmn-TW-Hant' and 'yue-HK-Hant-3'.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, sccode, level = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, sccode, level =
category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
scriptname = true,
scname = {alias_of = "scriptname"},
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
end)
-- Hander for categories named [[Category:User LANG]] e.g. [[Category:User en]], [[Category:User en-US]],
-- [[Category:User ine-pro]] or [[Category:User LANG-#]] where # is a competency level (0 through 5 or N) e.g.
-- [[Category:User en-N]] or [[Category:User ndl-nl-1]].
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, nil, level, args)
end)
-- Handler for scripts.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local sc = require("Module:scripts").getByCode(code)
if not sc then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User scripts", sort = code},
{name = sc:getCategoryName(), sort = "user"},
}
end
local scriptcat
-- Better to display 'Foo script' than just 'Foo', as so many scripts are the same as language names.
if level then
scriptcat = ("[[:Category:User %s|%s]]"):format(code, sc:getCategoryName())
else
scriptcat = ("[[:Category:%s|%s]]"):format(sc:getCategoryName(), sc:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
obj = sc,
code = code,
script = sc:getCanonicalName(),
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for "custom" scripts (e.g. IPA).
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z-]+)$")
end
if not code or not custom_script_links[code] then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {"User scripts", sort = code}
end
local scriptdata = custom_script_links[code]
if type(scriptdata) == "string" then
scriptdata = {link = scriptdata}
end
local scriptcat = ("[[%s|%%s]]"):format(scriptdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
code = code,
script = scriptdata.script or code,
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for programming languages.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z+-]+) coder%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z+-]+) coder$")
end
if not code or not coder_links[code] then
return
end
local parents
if level then
parents = {("User %s coder"):format(code), sort = level}
else
parents = {"User coders", sort = code}
end
local langdata = coder_links[code]
if type(langdata) == "string" then
langdata = {link = langdata}
end
local langcat = ("[[%s|%%s]]"):format(langdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "coder",
code = code,
langfam = langdata.lang or code,
langfamcat = langcat,
level = level,
parents = parents,
}
end)
-- Handler for language families.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local fam = require("Module:families").getByCode(code)
if not fam then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User families", sort = code},
{name = fam:getCategoryName(), sort = "user"},
}
end
local famcat
if level then
famcat = ("[[:Category:User %s|%s]]"):format(code, fam:getCategoryName())
else
famcat = ("[[:Category:%s|%s]]"):format(fam:getCategoryName(), fam:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "family",
obj = fam,
code = code,
langfam = fam:getCanonicalName(),
langfamcat = famcat,
level = level,
parents = parents,
}
end)
insert(raw_handlers, function(data)
local n, suffix = data.category:match("^Pages with (%d+) entr(.+)$")
-- Only match if there are no leading zeroes and the suffix is correct.
if not (n and not n:match("^0%d") and suffix == (n == "1" and "y" or "ies")) then
return
end
return {
breadcrumb = ("%d entr%s"):format(n, suffix),
description = ("Pages which contain %s language entr%s."):format(n, suffix),
additional = "This category, and others like it, are used to determine the total number of entries on the English Wiktionary",
hidden = true,
can_be_empty = true,
parents = {
{name = "Pages with entries", sort = require("Module:category tree").numeral_sortkey(n)},
n == "0" and "Wiktionary maintenance" or nil, -- "Pages with 0 entries" only contains pages with something wrong.
},
}
end)
return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}
jes70d772x2jo3wdzipu22acxvzfylm
157639
157633
2025-07-09T13:00:57Z
咽頭べさ
33
157639
Scribunto
text/plain
local raw_categories = {}
local raw_handlers = {}
local concat = table.concat
local insert = table.insert
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local string_utilities_module = "Module:string utilities"
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["ဝိက်ရှေန်နရဳ"] = {
description = "ကဏ္ဍကဆံၚ်သၠုၚ်သွက်ကပေါတ်ကညောတ်ပရောဟိုတ်ဝိက်ရှေန်နရဳ ကဵု ပရေၚ်ပြုပြေၚ်ဂှ်။",
parents = "ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
}
raw_categories["စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်"] = {
description = "Categories and pages containing statistics about how Wiktionary is used.",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Statistics"},
}
raw_categories["ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်"] = {
description = "Pages listing Wiktionarians according to their user rights and categories listing Wiktionarians according to their linguistic and coding abilities.",
breadcrumb = "ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်",
additional = "For an automatically generated list of all users, see [[Special:ListUsers]].",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Users"},
}
raw_categories["Wikimedians banned by the WMF"] = {
description = "Users who have received a [[m:Global bans|global ban]] imposed by the [[m:Wikimedia Foundation|Wikimedia Foundation]], in accordance with the [[m:WMF Global Ban Policy|WMF Global Ban Policy]].",
breadcrumb = "Banned by the WMF",
parents = "Wiktionary users",
}
raw_categories["User languages"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User languages with invalid code"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities, where the language code is invalid for Wiktionary.",
additional = "Most of these codes are valid ISO 639-3 codes but are invalid in Wiktionary for various reasons, " ..
"typically due to different choices made regarding splitting and merging languages.",
parents = {name = "User languages", sort = " "},
}
raw_categories["User scripts"] = {
description = "Categories listing Wiktionarians according to their abilities to read a given script.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User coders"] = {
description = "Categories listing Wiktionarians according to their coding abilities.",
parents = "Wiktionary users",
}
raw_categories["User families"] = {
description = "Categories listing Wiktionarians according to their knowledge about a given language family.",
parents = "Wiktionary users"
}
raw_categories["Pages with entries"] = {
description = "Pages which contain language entries.",
additional = "The subcategories within this category are used to determine the total number of entries on the English Wiktionary.",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
raw_categories["Redirects connected to a Wikidata item"] = {
description = "Redirect pages which are connected to a [[d:|Wikidata]] item.",
additional = "These are rarely needed, but are occasionally useful following a page merger, where other wikis may still separate the two.",
parents = "Wiktionary statistics",
can_be_empty = true,
hidden = true,
}
raw_categories["Unsupported titles"] = {
description = "Pages with titles that are not supported by the MediaWiki software.",
additional = "For an explanation of the reasons why certain titles are not supported, see [[Appendix:Unsupported titles]].",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
-- Tracked according to [[phab:T347324]].
for ext, data in pairs {
["စရၚ်မုက်လိက်ချဳဒရာၚ်"] = {"DynamicPageList (Wikimedia)", "T287380"},
["EasyTimeline"] = {"EasyTimeline", "T137291"},
["Graph"] = {"Graph", "T334940"},
["Kartographer"] = {"Kartographer"},
["Phonos"] = {"Phonos"},
["Score"] = {"Score"},
["WikiHiero"] = {"WikiHiero", "T344534"},
} do
local link, phab = unpack(data)
raw_categories["မုက်လိက်မရပ်စပ်မဆေၚ်ကဵု" .. ext .. "က္တဵုဒှ်တိုန်"] = {
description = ("Pages which make use of the [[mw:Extension:%s|%s]] extension."):format(link, ext),
additional = phab and ("See [[phab:%s|%s]] on Phabricator for background information on why this extension is tracked."):format(phab, phab) or nil,
breadcrumb = ("Using the %s extension"):format(ext),
parents = "စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်",
can_be_empty = true,
hidden = true,
}
end
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_level_params(data)
local speak_verb = "speak"
if data.typ == "lang" then
local is_sign_language = data.obj and data.obj:getFamilyCode() and data.obj:getFamilyCode():find("^sgn") or data.langfam:find("Sign Language$")
speak_verb = data.args.verb or is_sign_language and "communicate in" or "speak"
end
return {
["-"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM!.",
script = "These users read !SCRIPT!.",
coder = "These users know how to code in !LANGFAM!.",
family = "These users know !LANGFAM!.",
},
["1"] = {
cssclass = "babel-1",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''basic''' level.",
script = "These users can read !SCRIPT! at a '''basic''' level.",
coder = "These users know the '''basics''' of how to write !LANGFAM! code and make minor tweaks.",
family = "These users know the '''basics''' of contributing to !LANGFAM!.",
},
["2"] = {
cssclass = "babel-2",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''intermediate''' level.",
script = "These users can read !SCRIPT! at an '''intermediate''' level.",
coder = "These users have a '''fair command''' of !LANGFAM!, and can understand some scripts written by others.",
family = "These users are '''fairly familiar''' with !LANGFAM!.",
},
["3"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''advanced''' level.",
script = "These users can read !SCRIPT! at an '''advanced''' level.",
coder = "These users can write '''more complex''' !LANGFAM! code, and can understand and modify most scripts written by others.",
family = "These users '''regularly''' contribute to !LANGFAM!.",
},
["4"] = {
cssclass = "babel-4",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''near-native''' level.",
script = "These users can read !SCRIPT! at a '''near native''' level.",
coder = "These users can write and understand '''very complex''' !LANGFAM! code.",
},
["5"] = {
cssclass = "babel-5",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''professional''' level.",
script = "These users can read !SCRIPT! at a '''professional''' level.",
coder = "These users can write and understand !LANGFAM! code at a '''professional''' level.",
},
["N"] = {
cssclass = "babel-N",
lang = "These users are '''native''' speakers of !LANGFAM!.",
script = "These users' '''native''' script is !SCRIPT!.",
},
}
end
local coder_links = {
Asm = "w:Assembly language",
Bash = "w:Bash (Unix shell)",
C = "w:C (programming language)",
["C++"] = "w:C++",
["C Sharp"] = {link = "w:C Sharp (programming language)", lang = "C#"},
CSS = "w:CSS",
Go = "w:Go (programming language)",
Haskell = "w:Haskell",
HTML = "w:HTML",
Java = "w:Java (programming language)",
JavaScript = "w:JavaScript",
Julia = "w:Julia (programming language)",
Kotlin = "w:Kotlin (programming language)",
Lisp = "w:Lisp (programming language)",
Lua = "Wiktionary:Scripting",
Perl = "w:Perl",
PHP = "w:PHP",
Python = "w:Python (programming language)",
regex = {link = "w:Regular expression", name = "regular expressions"},
Ruby = "w:Ruby (programming language)",
Rust = "w:Rust (programming language)",
Scala = "w:Scala (programming language)",
Scheme = "w:Scheme (programming language)",
SQL = "w:SQL",
template = {link = "Wiktionary:Templates", name = "wiki templates"},
Typescript = "w:Typescript",
VBScript = "w:VBScript",
}
local custom_script_links = {
IPA = "w:International Phonetic Alphabet",
UPA = "w:Uralic Phonetic Alphabet",
}
-- Generic implementation of competency handler for (natural) languages, scripts, families and "coders" (= programming languages).
local function competency_handler(data)
local category = data.category
local langtext = data.langtext
local typ = data.typ
local args = data.args
local code = data.code
local langfam = data.langfam
local langfamcat = data.langfamcat
local script = data.script
local scriptcat = data.scriptcat
local level = data.level
local parents = data.parents
local addl_parents = data.addl_parents
local topright = data.topright
local data_addl = data.additional
local inactive = data.inactive
local parts = {}
local function ins(txt)
insert(parts, txt)
end
local level_params = get_level_params(data)
local params = level_params[level or "-"]
if not params then
error(("Internal error: No params for for code '%s', level %s"):format(code, level or "-"))
end
local function insert_text()
if langtext then
ins(langtext)
ins("<hr />")
end
if not params[typ] then
error(("No English text for code '%s', type '%s', level %s"):format(code, typ, level or "-"))
end
local pattern, repl
if typ == "script" then
pattern = "!SCRIPT!"
repl = ("'''" .. scriptcat .. "'''"):format(script)
else
pattern = "!LANGFAM!"
repl = ("'''" .. langfamcat .. "'''"):format(langfam)
if script then
repl = repl .. (" written in '''" .. scriptcat .. "'''"):format(script)
end
end
ins(params[typ]:gsub(pattern, repl))
end
local additional = {}
if level then
insert(additional, ("To be included on this list, add {{tl|Babel|%s}} to your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]]."):format(level == "N" and code or ("%s-%s"):format(code, level)))
else
insert(additional, "To be included on this list, use {{tl|Babel}} on your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]].")
end
if inactive then
insert(additional, "'''NOTE:''' Users in this category have not been active on the English Wiktionary for at " ..
"least two years and have been moved into the 'inactive' state due to " ..
"[[Wiktionary:Votes/pl-2017-04/Removing inactive editors from user-proficiency categories]].")
parents = {{name = category, sort = " "}}
end
if addl_parents then
for _, addl_parent in ipairs(addl_parents) do
insert(parents, addl_parent)
end
end
if data_addl then
insert(additional, data_addl)
end
local babel_templatestyles = require("Module:TemplateStyles")("Template:Babel/style.css")
if level then
ins(('<div class="babel-box %s">'):format(params.cssclass))
ins('<table class="babel-content" style="width:238px"><tr>')
ins('<td class="babel-code" style="font-size:14pt">')
ins(("'''%s-%s'''</td>"):format(code, level))
ins('<td class="babel-text">')
insert_text()
ins('</td></tr></table></div><br clear="left">')
return {
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or "Level " .. level,
parents = parents,
}, not not args
else
ins(('<div class="babel-box %s">\n'):format(params.cssclass))
ins('{| class="babel-content" style="width:260px;"\n')
ins('| class="babel-code" style="font-size:14pt;" | ')
ins(("'''%s'''\n"):format(code))
ins('| class="babel-text" style="text-align:center;" | ')
insert_text()
ins('\n|}</div><br clear="left">')
return {
topright = topright,
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or lang,
parents = parents,
}, not not args
end
end
-- Guts of implementation of competency handlers for natural languages (full or etymology-only), possibly with a
-- script attached (e.g. [[Category:User ko-Kore]]).
local function handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
local lang = require("Module:languages").getByCode(code, nil, "allow etym")
local langname = args.langname
local sc, scriptname
if sccode then
sc = require("Module:scripts").getByCode(sccode)
scriptname = args.scriptname
end
local code_with_script = code .. (sccode and "-" .. sccode or "")
if not lang or sccode and not sc then
-- If unrecognized language and called from inside, we're handling the parents and breadcrumb for a
-- higher-level category, so at least return something.
if not level and data.called_from_inside then
return {
-- FIXME, scrape langname= category?
breadcrumb = {name = code_with_script, nocap = true},
parents = {name = lang and "User languages with invalid script code" or
"User languages with invalid code", sort = code_with_script}
}, true
end
if not langname then
-- Check if the code matches a Wikimedia language (e.g. "ku" for Kurdish). If it does, treat
-- its canonical name as though it had been given as langname=.
local wm_lang = require("Module:wikimedia languages").getByCode(code)
if not wm_lang then
mw.log(("Skipping category '%s' because lang code '%s' is unrecognized and langname= not given"):
format(data.category, code))
return
end
langname = wm_lang:getCanonicalName()
end
if sccode and not sc and not scriptname then
mw.log(("Skipping category '%s' because script code '%s' is unrecognized and scriptname= not given"):
format(data.category, sccode))
return
end
end
if not langname then
if not lang then
error("Internal error: Something went wrong, undefined lang= should have been caught above")
end
langname = lang:getCanonicalName()
end
if not scriptname and sccode then
if not sc then
error("Internal error: Something went wrong, undefined sc= should have been caught above")
end
-- Use `getCategoryName` not `getCanonicalName` to display 'Foo script' than just 'Foo', as so many scripts
-- are the same as language names, and otherwise we get nonsensical output like "These users are native speakers
-- of Korean written in Korean".
scriptname = sc:getCategoryName()
end
-- Insert text, appropriately script-tagged, unless already script-tagged (we check for '<span'), in which case we
-- insert it directly. Also handle <<...>> and <<<...>>> in text and convert to bolded link to parent category.
local function wrap(txt)
if not txt then
return
end
if sccode then
-- Substitute <<<...>>> (where ... is supposed to be the native rendering of the script) with a link to the
-- top-level 'User SCRIPT' category (e.g. [[:Category:User Kore]] if we're in a sublevel category, or to the
-- top-level script category (e.g. [[:Category:Korean script]]) if we're in a top-level 'User CODE-SCRIPT'
-- category.
txt = txt:gsub("<<<(.-)>>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(sccode, inside)
elseif sc then
return ("'''[[:Category:%s|%s]]'''"):format(sc:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
end
-- Substitute <<...>> (where ... is supposed to be the native rendering of the language) with a link to the
-- top-level 'User CODE' category (e.g. [[:Category:User fr]] or [[:Category:User fr-CA]]) if we're in a
-- sublevel category, or to the top-level language category (e.g. [[:Category:French language]] or
-- [[:Category:Canadian English]]) if we're in a top-level 'User CODE' category.
txt = txt:gsub("<<(.-)>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(code, inside)
elseif lang then
return ("'''[[:Category:%s|%s]]'''"):format(lang:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
if txt:find("<span") or not lang then
return txt
else
return require("Module:script utilities").tag_text(txt, lang, sc)
end
end
local function get_request_cats()
if args.text or code == "en" or code:find("^en%-") then
return
end
local num_pages = mw.site.stats.pagesInCategory(data.category, "pages")
local count_cat, count_sort
if num_pages == 0 then
count_cat = "Requests for translations in user-competency categories with 0 users"
count_sort = "*" .. code_with_script
elseif num_pages == 1 then
count_cat = "Requests for translations in user-competency categories with 1 user"
count_sort = "*" .. code_with_script
else
local lowernum, uppernum
lowernum = 2
while true do
uppernum = lowernum * 2 - 1
if num_pages <= uppernum then
break
end
lowernum = lowernum * 2
end
count_cat = ("Requests for translations in user-competency categories with %s-%s users"):format(
lowernum, uppernum)
count_sort = "*" .. ("%0" .. #(tostring(uppernum)) .. "d"):format(num_pages)
end
local addl_parents = {}
insert(addl_parents, {
name = "Requests for translations in user-competency categories by language",
sort = code_with_script,
})
insert(addl_parents, {
name = count_cat,
sort = count_sort,
})
return addl_parents
end
local invalid_lang_warning
if not lang then
invalid_lang_warning = "'''WARNING''': The specified language code is invalid on Wiktionary. Please migrate " ..
"all competency ratings to the closest valid code."
end
local parents
if level then
parents = {("User %s"):format(code_with_script), sort = level}
elseif sccode then
parents = {}
insert(parents, {name = ("User %s"):format(code), sort = sccode})
insert(parents, {name = ("User %s"):format(sccode), sort = code})
elseif lang then
parents = {}
if lang:hasType("etymology-only") then
local full_code = lang:getFullCode()
local sort_key = code:gsub(("^%s%%-"):format(require(string_utilities_module).pattern_escape(full_code)),
"")
insert(parents, {name = ("User %s"):format(full_code), sort = sort_key})
else
insert(parents, {name = "User languages", sort = code})
end
insert(parents, {name = lang:getCategoryName(), sort = "user"})
else
parents = {"User languages with invalid code", sort = code}
end
local addl_parents = get_request_cats()
local topright
if args.commonscat then
local commonscat = require("Module:yesno")(args.commonscat, "+")
if commonscat == "+" or commonscat == true then
commonscat = data.category
end
if commonscat then
topright = ("{{commonscat|%s}}"):format(commonscat)
end
end
local langcat
if level then
langcat = ("[[:Category:User %s|%%s]]"):format(code)
elseif lang then
langcat = ("[[:Category:%s|%%s]]"):format(lang:getCategoryName())
else
langcat = "[[%s]]"
end
local scriptcat
if sccode then
if level then
scriptcat = ("[[:Category:User %s|%%s]]"):format(sccode)
elseif sc then
scriptcat = ("[[:Category:%s|%%s]]"):format(sc:getCategoryName())
else
scriptcat = "[[%s]]"
end
end
return competency_handler {
category = category,
inactive = inactive,
langtext = wrap(args.text),
typ = "lang",
args = args,
obj = lang,
code = code_with_script,
langfam = langname,
langfamcat = langcat,
script = scriptname,
scriptcat = scriptcat,
level = level,
parents = parents,
addl_parents = addl_parents,
topright = topright,
additional = invalid_lang_warning,
}
end
-- Hander for categories named [[Category:User LANG-SCRIPT]] or [[Category:User LANG-SCRIPT-#]] where # is a
-- competency level (0 through 5 or N), e.g. [[Category:zh-Hans]] or [[Category:yue-Hant-N]]. It's a bit tricky because
-- of the multitude of language formats, e.g. ko-KP is a language code (etym variety) but ko-Kore is a combination
-- lang + script code. We depend on the fact that all script codes are currently of the form Xxxx or Xxxxx, and check
-- for that first. We also need to run prior to the lang-only handler (next handler) so it doesn't try to interpret
-- the script code as an etym variant code.
--
-- Note that there are current categories named things like 'zh-Hant-TW' and 'zh-Hant-HK-3', which we don't support.
-- They should be renamed to some supported code, e.g. 'cmn-TW-Hant' and 'yue-HK-Hant-3'.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, sccode, level = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, sccode, level =
category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
scriptname = true,
scname = {alias_of = "scriptname"},
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
end)
-- Hander for categories named [[Category:User LANG]] e.g. [[Category:User en]], [[Category:User en-US]],
-- [[Category:User ine-pro]] or [[Category:User LANG-#]] where # is a competency level (0 through 5 or N) e.g.
-- [[Category:User en-N]] or [[Category:User ndl-nl-1]].
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, nil, level, args)
end)
-- Handler for scripts.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local sc = require("Module:scripts").getByCode(code)
if not sc then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User scripts", sort = code},
{name = sc:getCategoryName(), sort = "user"},
}
end
local scriptcat
-- Better to display 'Foo script' than just 'Foo', as so many scripts are the same as language names.
if level then
scriptcat = ("[[:Category:User %s|%s]]"):format(code, sc:getCategoryName())
else
scriptcat = ("[[:Category:%s|%s]]"):format(sc:getCategoryName(), sc:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
obj = sc,
code = code,
script = sc:getCanonicalName(),
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for "custom" scripts (e.g. IPA).
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z-]+)$")
end
if not code or not custom_script_links[code] then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {"User scripts", sort = code}
end
local scriptdata = custom_script_links[code]
if type(scriptdata) == "string" then
scriptdata = {link = scriptdata}
end
local scriptcat = ("[[%s|%%s]]"):format(scriptdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
code = code,
script = scriptdata.script or code,
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for programming languages.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z+-]+) coder%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z+-]+) coder$")
end
if not code or not coder_links[code] then
return
end
local parents
if level then
parents = {("User %s coder"):format(code), sort = level}
else
parents = {"User coders", sort = code}
end
local langdata = coder_links[code]
if type(langdata) == "string" then
langdata = {link = langdata}
end
local langcat = ("[[%s|%%s]]"):format(langdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "coder",
code = code,
langfam = langdata.lang or code,
langfamcat = langcat,
level = level,
parents = parents,
}
end)
-- Handler for language families.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local fam = require("Module:families").getByCode(code)
if not fam then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User families", sort = code},
{name = fam:getCategoryName(), sort = "user"},
}
end
local famcat
if level then
famcat = ("[[:Category:User %s|%s]]"):format(code, fam:getCategoryName())
else
famcat = ("[[:Category:%s|%s]]"):format(fam:getCategoryName(), fam:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "family",
obj = fam,
code = code,
langfam = fam:getCanonicalName(),
langfamcat = famcat,
level = level,
parents = parents,
}
end)
insert(raw_handlers, function(data)
local n, suffix = data.category:match("^Pages with (%d+) entr(.+)$")
-- Only match if there are no leading zeroes and the suffix is correct.
if not (n and not n:match("^0%d") and suffix == (n == "1" and "y" or "ies")) then
return
end
return {
breadcrumb = ("%d entr%s"):format(n, suffix),
description = ("Pages which contain %s language entr%s."):format(n, suffix),
additional = "This category, and others like it, are used to determine the total number of entries on the English Wiktionary",
hidden = true,
can_be_empty = true,
parents = {
{name = "Pages with entries", sort = require("Module:category tree").numeral_sortkey(n)},
n == "0" and "Wiktionary maintenance" or nil, -- "Pages with 0 entries" only contains pages with something wrong.
},
}
end)
return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}
ffnwh1f8qvr1i32jddlhu17fz1iyabq
157644
157639
2025-07-09T13:37:12Z
咽頭べさ
33
157644
Scribunto
text/plain
local raw_categories = {}
local raw_handlers = {}
local concat = table.concat
local insert = table.insert
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local string_utilities_module = "Module:string utilities"
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["ဝိက်ရှေန်နရဳ"] = {
description = "ကဏ္ဍကဆံၚ်သၠုၚ်သွက်ကပေါတ်ကညောတ်ပရောဟိုတ်ဝိက်ရှေန်နရဳ ကဵု ပရေၚ်ပြုပြေၚ်ဂှ်။",
parents = "ဒၞာဲလုပ်အဝေါင်ကဵုပၟိက်",
}
raw_categories["စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်"] = {
description = "Categories and pages containing statistics about how Wiktionary is used.",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Statistics"},
}
raw_categories["ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်"] = {
description = "Pages listing Wiktionarians according to their user rights and categories listing Wiktionarians according to their linguistic and coding abilities.",
breadcrumb = "ညးသုၚ်စောဲဝိက်ရှေန်နရဳဂမၠိုင်",
additional = "For an automatically generated list of all users, see [[Special:ListUsers]].",
parents = {"ဝိက်ရှေန်နရဳ", sort = "Users"},
}
raw_categories["Wikimedians banned by the WMF"] = {
description = "Users who have received a [[m:Global bans|global ban]] imposed by the [[m:Wikimedia Foundation|Wikimedia Foundation]], in accordance with the [[m:WMF Global Ban Policy|WMF Global Ban Policy]].",
breadcrumb = "Banned by the WMF",
parents = "Wiktionary users",
}
raw_categories["User languages"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User languages with invalid code"] = {
description = "Categories listing Wiktionarians according to their linguistic abilities, where the language code is invalid for Wiktionary.",
additional = "Most of these codes are valid ISO 639-3 codes but are invalid in Wiktionary for various reasons, " ..
"typically due to different choices made regarding splitting and merging languages.",
parents = {name = "User languages", sort = " "},
}
raw_categories["User scripts"] = {
description = "Categories listing Wiktionarians according to their abilities to read a given script.",
parents = {
"Wiktionary users",
"Category:Wiktionary multilingual issues",
},
}
raw_categories["User coders"] = {
description = "Categories listing Wiktionarians according to their coding abilities.",
parents = "Wiktionary users",
}
raw_categories["User families"] = {
description = "Categories listing Wiktionarians according to their knowledge about a given language family.",
parents = "Wiktionary users"
}
raw_categories["Pages with entries"] = {
description = "Pages which contain language entries.",
additional = "The subcategories within this category are used to determine the total number of entries on the English Wiktionary.",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
raw_categories["Redirects connected to a Wikidata item"] = {
description = "Redirect pages which are connected to a [[d:|Wikidata]] item.",
additional = "These are rarely needed, but are occasionally useful following a page merger, where other wikis may still separate the two.",
parents = "Wiktionary statistics",
can_be_empty = true,
hidden = true,
}
raw_categories["Unsupported titles"] = {
description = "Pages with titles that are not supported by the MediaWiki software.",
additional = "For an explanation of the reasons why certain titles are not supported, see [[Appendix:Unsupported titles]].",
parents = "Wiktionary",
can_be_empty = true,
hidden = true,
}
-- Tracked according to [[phab:T347324]].
for ext, data in pairs {
["စရၚ်မုက်လိက်ချဳဒရာၚ်"] = {"DynamicPageList (Wikimedia)", "T287380"},
["EasyTimeline"] = {"EasyTimeline", "T137291"},
["Graph"] = {"Graph", "T334940"},
["Kartographer"] = {"Kartographer"},
["Phonos"] = {"Phonos"},
["Score"] = {"Score"},
["WikiHiero"] = {"WikiHiero", "T344534"},
} do
local link, phab = unpack(data)
raw_categories["မုက်လိက်မရပ်စပ်မဆေၚ်ကဵု" .. ext .. "က္တဵုဒှ်တိုန်"] = {
description = ("မုက်လိက်မရပ်စပ်ကၠောန်သ္ပလဝ်ဆေၚ်စပ်ကဵု[[mw:Extension:%s|%s]]က္တဵုဒှ်တိုန်။"):format(link, ext),
additional = phab and ("See [[phab:%s|%s]] on Phabricator for background information on why this extension is tracked."):format(phab, phab) or nil,
breadcrumb = ("မရပ်စပ်ဆေၚ်စပ်ကဵု%sက္တဵုဒှ်တိုန်"):format(ext),
parents = "စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်",
can_be_empty = true,
hidden = true,
}
end
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_level_params(data)
local speak_verb = "speak"
if data.typ == "lang" then
local is_sign_language = data.obj and data.obj:getFamilyCode() and data.obj:getFamilyCode():find("^sgn") or data.langfam:find("Sign Language$")
speak_verb = data.args.verb or is_sign_language and "communicate in" or "speak"
end
return {
["-"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM!.",
script = "These users read !SCRIPT!.",
coder = "These users know how to code in !LANGFAM!.",
family = "These users know !LANGFAM!.",
},
["1"] = {
cssclass = "babel-1",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''basic''' level.",
script = "These users can read !SCRIPT! at a '''basic''' level.",
coder = "These users know the '''basics''' of how to write !LANGFAM! code and make minor tweaks.",
family = "These users know the '''basics''' of contributing to !LANGFAM!.",
},
["2"] = {
cssclass = "babel-2",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''intermediate''' level.",
script = "These users can read !SCRIPT! at an '''intermediate''' level.",
coder = "These users have a '''fair command''' of !LANGFAM!, and can understand some scripts written by others.",
family = "These users are '''fairly familiar''' with !LANGFAM!.",
},
["3"] = {
cssclass = "babel-3",
lang = "These users " .. speak_verb .. " !LANGFAM! at an '''advanced''' level.",
script = "These users can read !SCRIPT! at an '''advanced''' level.",
coder = "These users can write '''more complex''' !LANGFAM! code, and can understand and modify most scripts written by others.",
family = "These users '''regularly''' contribute to !LANGFAM!.",
},
["4"] = {
cssclass = "babel-4",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''near-native''' level.",
script = "These users can read !SCRIPT! at a '''near native''' level.",
coder = "These users can write and understand '''very complex''' !LANGFAM! code.",
},
["5"] = {
cssclass = "babel-5",
lang = "These users " .. speak_verb .. " !LANGFAM! at a '''professional''' level.",
script = "These users can read !SCRIPT! at a '''professional''' level.",
coder = "These users can write and understand !LANGFAM! code at a '''professional''' level.",
},
["N"] = {
cssclass = "babel-N",
lang = "These users are '''native''' speakers of !LANGFAM!.",
script = "These users' '''native''' script is !SCRIPT!.",
},
}
end
local coder_links = {
Asm = "w:Assembly language",
Bash = "w:Bash (Unix shell)",
C = "w:C (programming language)",
["C++"] = "w:C++",
["C Sharp"] = {link = "w:C Sharp (programming language)", lang = "C#"},
CSS = "w:CSS",
Go = "w:Go (programming language)",
Haskell = "w:Haskell",
HTML = "w:HTML",
Java = "w:Java (programming language)",
JavaScript = "w:JavaScript",
Julia = "w:Julia (programming language)",
Kotlin = "w:Kotlin (programming language)",
Lisp = "w:Lisp (programming language)",
Lua = "Wiktionary:Scripting",
Perl = "w:Perl",
PHP = "w:PHP",
Python = "w:Python (programming language)",
regex = {link = "w:Regular expression", name = "regular expressions"},
Ruby = "w:Ruby (programming language)",
Rust = "w:Rust (programming language)",
Scala = "w:Scala (programming language)",
Scheme = "w:Scheme (programming language)",
SQL = "w:SQL",
template = {link = "Wiktionary:Templates", name = "wiki templates"},
Typescript = "w:Typescript",
VBScript = "w:VBScript",
}
local custom_script_links = {
IPA = "w:International Phonetic Alphabet",
UPA = "w:Uralic Phonetic Alphabet",
}
-- Generic implementation of competency handler for (natural) languages, scripts, families and "coders" (= programming languages).
local function competency_handler(data)
local category = data.category
local langtext = data.langtext
local typ = data.typ
local args = data.args
local code = data.code
local langfam = data.langfam
local langfamcat = data.langfamcat
local script = data.script
local scriptcat = data.scriptcat
local level = data.level
local parents = data.parents
local addl_parents = data.addl_parents
local topright = data.topright
local data_addl = data.additional
local inactive = data.inactive
local parts = {}
local function ins(txt)
insert(parts, txt)
end
local level_params = get_level_params(data)
local params = level_params[level or "-"]
if not params then
error(("Internal error: No params for for code '%s', level %s"):format(code, level or "-"))
end
local function insert_text()
if langtext then
ins(langtext)
ins("<hr />")
end
if not params[typ] then
error(("No English text for code '%s', type '%s', level %s"):format(code, typ, level or "-"))
end
local pattern, repl
if typ == "script" then
pattern = "!SCRIPT!"
repl = ("'''" .. scriptcat .. "'''"):format(script)
else
pattern = "!LANGFAM!"
repl = ("'''" .. langfamcat .. "'''"):format(langfam)
if script then
repl = repl .. (" written in '''" .. scriptcat .. "'''"):format(script)
end
end
ins(params[typ]:gsub(pattern, repl))
end
local additional = {}
if level then
insert(additional, ("To be included on this list, add {{tl|Babel|%s}} to your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]]."):format(level == "N" and code or ("%s-%s"):format(code, level)))
else
insert(additional, "To be included on this list, use {{tl|Babel}} on your user page. Complete instructions are " ..
"available at [[Wiktionary:Babel]].")
end
if inactive then
insert(additional, "'''NOTE:''' Users in this category have not been active on the English Wiktionary for at " ..
"least two years and have been moved into the 'inactive' state due to " ..
"[[Wiktionary:Votes/pl-2017-04/Removing inactive editors from user-proficiency categories]].")
parents = {{name = category, sort = " "}}
end
if addl_parents then
for _, addl_parent in ipairs(addl_parents) do
insert(parents, addl_parent)
end
end
if data_addl then
insert(additional, data_addl)
end
local babel_templatestyles = require("Module:TemplateStyles")("Template:Babel/style.css")
if level then
ins(('<div class="babel-box %s">'):format(params.cssclass))
ins('<table class="babel-content" style="width:238px"><tr>')
ins('<td class="babel-code" style="font-size:14pt">')
ins(("'''%s-%s'''</td>"):format(code, level))
ins('<td class="babel-text">')
insert_text()
ins('</td></tr></table></div><br clear="left">')
return {
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or "Level " .. level,
parents = parents,
}, not not args
else
ins(('<div class="babel-box %s">\n'):format(params.cssclass))
ins('{| class="babel-content" style="width:260px;"\n')
ins('| class="babel-code" style="font-size:14pt;" | ')
ins(("'''%s'''\n"):format(code))
ins('| class="babel-text" style="text-align:center;" | ')
insert_text()
ins('\n|}</div><br clear="left">')
return {
topright = topright,
description = concat(parts) .. babel_templatestyles,
additional = concat(additional, "\n\n"),
breadcrumb = inactive and "Inactive" or lang,
parents = parents,
}, not not args
end
end
-- Guts of implementation of competency handlers for natural languages (full or etymology-only), possibly with a
-- script attached (e.g. [[Category:User ko-Kore]]).
local function handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
local lang = require("Module:languages").getByCode(code, nil, "allow etym")
local langname = args.langname
local sc, scriptname
if sccode then
sc = require("Module:scripts").getByCode(sccode)
scriptname = args.scriptname
end
local code_with_script = code .. (sccode and "-" .. sccode or "")
if not lang or sccode and not sc then
-- If unrecognized language and called from inside, we're handling the parents and breadcrumb for a
-- higher-level category, so at least return something.
if not level and data.called_from_inside then
return {
-- FIXME, scrape langname= category?
breadcrumb = {name = code_with_script, nocap = true},
parents = {name = lang and "User languages with invalid script code" or
"User languages with invalid code", sort = code_with_script}
}, true
end
if not langname then
-- Check if the code matches a Wikimedia language (e.g. "ku" for Kurdish). If it does, treat
-- its canonical name as though it had been given as langname=.
local wm_lang = require("Module:wikimedia languages").getByCode(code)
if not wm_lang then
mw.log(("Skipping category '%s' because lang code '%s' is unrecognized and langname= not given"):
format(data.category, code))
return
end
langname = wm_lang:getCanonicalName()
end
if sccode and not sc and not scriptname then
mw.log(("Skipping category '%s' because script code '%s' is unrecognized and scriptname= not given"):
format(data.category, sccode))
return
end
end
if not langname then
if not lang then
error("Internal error: Something went wrong, undefined lang= should have been caught above")
end
langname = lang:getCanonicalName()
end
if not scriptname and sccode then
if not sc then
error("Internal error: Something went wrong, undefined sc= should have been caught above")
end
-- Use `getCategoryName` not `getCanonicalName` to display 'Foo script' than just 'Foo', as so many scripts
-- are the same as language names, and otherwise we get nonsensical output like "These users are native speakers
-- of Korean written in Korean".
scriptname = sc:getCategoryName()
end
-- Insert text, appropriately script-tagged, unless already script-tagged (we check for '<span'), in which case we
-- insert it directly. Also handle <<...>> and <<<...>>> in text and convert to bolded link to parent category.
local function wrap(txt)
if not txt then
return
end
if sccode then
-- Substitute <<<...>>> (where ... is supposed to be the native rendering of the script) with a link to the
-- top-level 'User SCRIPT' category (e.g. [[:Category:User Kore]] if we're in a sublevel category, or to the
-- top-level script category (e.g. [[:Category:Korean script]]) if we're in a top-level 'User CODE-SCRIPT'
-- category.
txt = txt:gsub("<<<(.-)>>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(sccode, inside)
elseif sc then
return ("'''[[:Category:%s|%s]]'''"):format(sc:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
end
-- Substitute <<...>> (where ... is supposed to be the native rendering of the language) with a link to the
-- top-level 'User CODE' category (e.g. [[:Category:User fr]] or [[:Category:User fr-CA]]) if we're in a
-- sublevel category, or to the top-level language category (e.g. [[:Category:French language]] or
-- [[:Category:Canadian English]]) if we're in a top-level 'User CODE' category.
txt = txt:gsub("<<(.-)>>", function(inside)
if level then
return ("'''[[:Category:User %s|%s]]'''"):format(code, inside)
elseif lang then
return ("'''[[:Category:%s|%s]]'''"):format(lang:getCategoryName(), inside)
else
return ("'''%s'''"):format(inside)
end
end)
if txt:find("<span") or not lang then
return txt
else
return require("Module:script utilities").tag_text(txt, lang, sc)
end
end
local function get_request_cats()
if args.text or code == "en" or code:find("^en%-") then
return
end
local num_pages = mw.site.stats.pagesInCategory(data.category, "pages")
local count_cat, count_sort
if num_pages == 0 then
count_cat = "Requests for translations in user-competency categories with 0 users"
count_sort = "*" .. code_with_script
elseif num_pages == 1 then
count_cat = "Requests for translations in user-competency categories with 1 user"
count_sort = "*" .. code_with_script
else
local lowernum, uppernum
lowernum = 2
while true do
uppernum = lowernum * 2 - 1
if num_pages <= uppernum then
break
end
lowernum = lowernum * 2
end
count_cat = ("Requests for translations in user-competency categories with %s-%s users"):format(
lowernum, uppernum)
count_sort = "*" .. ("%0" .. #(tostring(uppernum)) .. "d"):format(num_pages)
end
local addl_parents = {}
insert(addl_parents, {
name = "Requests for translations in user-competency categories by language",
sort = code_with_script,
})
insert(addl_parents, {
name = count_cat,
sort = count_sort,
})
return addl_parents
end
local invalid_lang_warning
if not lang then
invalid_lang_warning = "'''WARNING''': The specified language code is invalid on Wiktionary. Please migrate " ..
"all competency ratings to the closest valid code."
end
local parents
if level then
parents = {("User %s"):format(code_with_script), sort = level}
elseif sccode then
parents = {}
insert(parents, {name = ("User %s"):format(code), sort = sccode})
insert(parents, {name = ("User %s"):format(sccode), sort = code})
elseif lang then
parents = {}
if lang:hasType("etymology-only") then
local full_code = lang:getFullCode()
local sort_key = code:gsub(("^%s%%-"):format(require(string_utilities_module).pattern_escape(full_code)),
"")
insert(parents, {name = ("User %s"):format(full_code), sort = sort_key})
else
insert(parents, {name = "User languages", sort = code})
end
insert(parents, {name = lang:getCategoryName(), sort = "user"})
else
parents = {"User languages with invalid code", sort = code}
end
local addl_parents = get_request_cats()
local topright
if args.commonscat then
local commonscat = require("Module:yesno")(args.commonscat, "+")
if commonscat == "+" or commonscat == true then
commonscat = data.category
end
if commonscat then
topright = ("{{commonscat|%s}}"):format(commonscat)
end
end
local langcat
if level then
langcat = ("[[:Category:User %s|%%s]]"):format(code)
elseif lang then
langcat = ("[[:Category:%s|%%s]]"):format(lang:getCategoryName())
else
langcat = "[[%s]]"
end
local scriptcat
if sccode then
if level then
scriptcat = ("[[:Category:User %s|%%s]]"):format(sccode)
elseif sc then
scriptcat = ("[[:Category:%s|%%s]]"):format(sc:getCategoryName())
else
scriptcat = "[[%s]]"
end
end
return competency_handler {
category = category,
inactive = inactive,
langtext = wrap(args.text),
typ = "lang",
args = args,
obj = lang,
code = code_with_script,
langfam = langname,
langfamcat = langcat,
script = scriptname,
scriptcat = scriptcat,
level = level,
parents = parents,
addl_parents = addl_parents,
topright = topright,
additional = invalid_lang_warning,
}
end
-- Hander for categories named [[Category:User LANG-SCRIPT]] or [[Category:User LANG-SCRIPT-#]] where # is a
-- competency level (0 through 5 or N), e.g. [[Category:zh-Hans]] or [[Category:yue-Hant-N]]. It's a bit tricky because
-- of the multitude of language formats, e.g. ko-KP is a language code (etym variety) but ko-Kore is a combination
-- lang + script code. We depend on the fact that all script codes are currently of the form Xxxx or Xxxxx, and check
-- for that first. We also need to run prior to the lang-only handler (next handler) so it doesn't try to interpret
-- the script code as an etym variant code.
--
-- Note that there are current categories named things like 'zh-Hant-TW' and 'zh-Hant-HK-3', which we don't support.
-- They should be renamed to some supported code, e.g. 'cmn-TW-Hant' and 'yue-HK-Hant-3'.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, sccode, level = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, sccode, level =
category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, sccode = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
scriptname = true,
scname = {alias_of = "scriptname"},
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, sccode, level, args)
end)
-- Hander for categories named [[Category:User LANG]] e.g. [[Category:User en]], [[Category:User en-US]],
-- [[Category:User ine-pro]] or [[Category:User LANG-#]] where # is a competency level (0 through 5 or N) e.g.
-- [[Category:User en-N]] or [[Category:User ndl-nl-1]].
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local args = require("Module:parameters").process(data.args, {
text = true,
verb = true,
langname = true,
commonscat = true,
})
return handle_user_lang_maybe_script(data, category, inactive, code, nil, level, args)
end)
-- Handler for scripts.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code = category:match("^User ([A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[A-Z][a-z][a-z][a-z][a-z]?)$")
end
if not code then
return
end
local sc = require("Module:scripts").getByCode(code)
if not sc then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User scripts", sort = code},
{name = sc:getCategoryName(), sort = "user"},
}
end
local scriptcat
-- Better to display 'Foo script' than just 'Foo', as so many scripts are the same as language names.
if level then
scriptcat = ("[[:Category:User %s|%s]]"):format(code, sc:getCategoryName())
else
scriptcat = ("[[:Category:%s|%s]]"):format(sc:getCategoryName(), sc:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
obj = sc,
code = code,
script = sc:getCanonicalName(),
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for "custom" scripts (e.g. IPA).
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z-]+)$")
end
if not code or not custom_script_links[code] then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {"User scripts", sort = code}
end
local scriptdata = custom_script_links[code]
if type(scriptdata) == "string" then
scriptdata = {link = scriptdata}
end
local scriptcat = ("[[%s|%%s]]"):format(scriptdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "script",
code = code,
script = scriptdata.script or code,
scriptcat = scriptcat,
level = level,
parents = parents,
}
end)
-- Handler for programming languages.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level
if not code then
code, level = category:match("^User ([A-Za-z+-]+) coder%-([0-5N])$")
end
if not code then
code = category:match("^User ([A-Za-z+-]+) coder$")
end
if not code or not coder_links[code] then
return
end
local parents
if level then
parents = {("User %s coder"):format(code), sort = level}
else
parents = {"User coders", sort = code}
end
local langdata = coder_links[code]
if type(langdata) == "string" then
langdata = {link = langdata}
end
local langcat = ("[[%s|%%s]]"):format(langdata.link)
return competency_handler {
category = category,
inactive = inactive,
typ = "coder",
code = code,
langfam = langdata.lang or code,
langfamcat = langcat,
level = level,
parents = parents,
}
end)
-- Handler for language families.
insert(raw_handlers, function(data)
local category, inactive = data.category:match("^(.*) (%(inactive%))$")
category = category or data.category
local code, level = category:match("^User ([a-z][a-z][a-z]?)%-([0-5N])$")
if not code then
code, level = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)%-([0-5N])$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?)$")
end
if not code then
code = category:match("^User ([a-z][a-z][a-z]?%-[a-zA-Z-]+)$")
end
if not code then
return
end
local fam = require("Module:families").getByCode(code)
if not fam then
return
end
local parents
if level then
parents = {("User %s"):format(code), sort = level}
else
parents = {
{name = "User families", sort = code},
{name = fam:getCategoryName(), sort = "user"},
}
end
local famcat
if level then
famcat = ("[[:Category:User %s|%s]]"):format(code, fam:getCategoryName())
else
famcat = ("[[:Category:%s|%s]]"):format(fam:getCategoryName(), fam:getCategoryName())
end
return competency_handler {
category = category,
inactive = inactive,
typ = "family",
obj = fam,
code = code,
langfam = fam:getCanonicalName(),
langfamcat = famcat,
level = level,
parents = parents,
}
end)
insert(raw_handlers, function(data)
local n, suffix = data.category:match("^Pages with (%d+) entr(.+)$")
-- Only match if there are no leading zeroes and the suffix is correct.
if not (n and not n:match("^0%d") and suffix == (n == "1" and "y" or "ies")) then
return
end
return {
breadcrumb = ("%d entr%s"):format(n, suffix),
description = ("Pages which contain %s language entr%s."):format(n, suffix),
additional = "This category, and others like it, are used to determine the total number of entries on the English Wiktionary",
hidden = true,
can_be_empty = true,
parents = {
{name = "Pages with entries", sort = require("Module:category tree").numeral_sortkey(n)},
n == "0" and "Wiktionary maintenance" or nil, -- "Pages with 0 entries" only contains pages with something wrong.
},
}
end)
return {RAW_CATEGORIES = raw_categories, RAW_HANDLERS = raw_handlers}
4of3zhcqjl6k91grkqsokknt0c3n0bt
ကဏ္ဍ:ဗီုပြင်နာမ်မန်ဂမၠိုင်
14
121858
157628
2025-07-09T12:32:59Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြင်နာမ်မန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်နာမ်မန်ဂမၠိုၚ်]]
157628
wikitext
text/x-wiki
#REDIRECT [[:ကဏ္ဍ:ဗီုပြၚ်နာမ်မန်ဂမၠိုၚ်]]
e53k0d1iu1emuawc7aqlhzcgr11hz16
ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်
14
121860
157632
2025-07-09T12:39:44Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေင်ကဵုစရင်မုက်လိက်ချဳဒရာက္တဵုတိုန်]] ဇရေင် [[ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
157632
wikitext
text/x-wiki
#REDIRECT [[:ကဏ္ဍ:မုက်လိက်မရပ်စပ်မဆေၚ်ကဵုစရၚ်မုက်လိက်ချဳဒရာၚ်က္တဵုဒှ်တိုန်]]
97q74dadadhpswpctzslhwo7ab59jyx
ကဏ္ဍ:စရၚ်အၚ်ဝိက်ရှေန်နရဳဂမၠိုၚ်
14
121861
157645
2025-07-09T13:38:23Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကဵု "{{auto cat}}"
157645
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
ကဏ္ဍ:ဗီုပြင်အပြံင်အလှာဲမန်ဂမၠိုင်
14
121862
157658
2025-07-09T15:27:20Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြင်အပြံင်အလှာဲမန်ဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်]]
157658
wikitext
text/x-wiki
#REDIRECT [[:ကဏ္ဍ:ဗီုပြၚ်အပြံၚ်အလှာဲမန်ဂမၠိုၚ်]]
4xzabpns9d2nn0tyme5zdt1hzvu0y5e
ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်
14
121863
157660
2025-07-09T15:27:53Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုင်]] ဇရေင် [[ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
157660
wikitext
text/x-wiki
#REDIRECT [[:ကဏ္ဍ:ဗီုပြၚ်ဟွံမွဲကဵုပ္ဍဲအဘိဓာန်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်]]
kt93wwf4ex0rkq01nlffvjnq39vfhx8
မဝ်ဂျူ:category tree/poscatboiler/data/terms by semantic function
828
121877
157707
2025-07-10T10:01:42Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[မဝ်ဂျူ:category tree/poscatboiler/data/terms by semantic function]] ဇရေင် [[မဝ်ဂျူ:category tree/semantic classes]]
157707
Scribunto
text/plain
return require [[မဝ်ဂျူ:category tree/semantic classes]]
lo013e3nzie1zir7m5lxl94s0u4qgj5
မဝ်ဂျူ:category tree/speech acts
828
121878
157709
2025-07-10T10:06:03Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကဵု "local labels = {} local raw_categories = {} ----------------------------------------------------------------------------- -- -- -- LABELS -- -- -- -----------------------------------------------------------..."
157709
Scribunto
text/plain
local labels = {}
local raw_categories = {}
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["speech acts"] = {
description = "{{{langname}}} terms that serves a performative function, in addition to conveying information.",
umbrella_parents = "Terms by semantic function subcategories by language",
parents = {"terms by semantic function"},
}
labels["dismissals"] = {
description = "{{{langname}}} expressions intended to [[dismiss]] the listener.",
parents = {"farewells", "imperative sentences"},
}
labels["expressions of gratitude"] = {
description = "{{{langname}}} expressions intended to express the [[gratitude]] or [[thank]]s of the speaker to the listener.",
parents = {"speech acts"},
}
labels["farewells"] = {
description = "{{{langname}}} expressions intended to mark the end of the speaker's interaction with the listener.",
parents = {"speech acts"},
}
labels["greetings"] = {
description = "{{{langname}}} expressions intended to mark the start of the speaker's interaction with the listener.",
parents = {"speech acts"},
}
labels["mnemonics"] = {
description = "{{{langname}}} terms used for remembering something more easily.",
parents = {"speech acts"},
}
labels["oaths"] = {
description = "{{{langname}}} expressions which appeal to a deity or entity as a form of intensifier.",
parents = {"speech acts", "intensifiers"},
}
labels["responses to sneezing"] = {
description = "{{{langname}}} expressions said in response to a [[sneeze]].",
parents = {"speech acts"},
}
labels["toasts"] = {
description = "{{{langname}}} expressions said as part of a [[toast]].",
parents = {"speech acts"},
}
for label, data in pairs(labels) do
if not data.umbrella_parents then
data.umbrella_parents = "Speech acts subcategories by language"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["Speech acts subcategories by language"] = {
description = "Umbrella categories covering topics related to speech acts, such as greetings or farewells.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"Umbrella metacategories",
{name = "speech acts", is_label = true, sort = " "},
},
}
return {LABELS = labels, RAW_CATEGORIES = raw_categories}
cmv9beiak1prmzgc5jf7btdah9dakx7