ဝိက်ရှေန်နရဳ
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.47.0-wmf.3
case-sensitive
မဳဒဳယာ
တၟေင်
ဓရီုကျာ
ညးလွပ်
ညးလွပ် ဓရီုကျာ
ဝိက်ရှေန်နရဳ
ဝိက်ရှေန်နရဳ ဓရီုကျာ
ဝှာင်
ဝှာင် ဓရီုကျာ
မဳဒဳယာဝဳကဳ
မဳဒဳယာဝဳကဳ ဓရီုကျာ
ထာမ်ပလိက်
ထာမ်ပလိက် ဓရီုကျာ
ရီု
ရီု ဓရီုကျာ
ကဏ္ဍ
ကဏ္ဍ ဓရီုကျာ
အဆက်လက္ကရဴ
အဆက်လက္ကရဴ ဓရီုကျာ
ကာရန်
ကာရန် ဓရီုကျာ
အဘိဓာန်
အဘိဓာန် ဓရီုကျာ
ဗီုပြၚ်သိုၚ်တၟိ
ဗီုပြၚ်သိုၚ်တၟိ ဓရီုကျာ
TimedText
TimedText talk
မဝ်ဂျူ
မဝ်ဂျူ ဓရီုကျာ
Event
Event talk
မဝ်ဂျူ:ug-translit
828
1070
395271
51697
2026-05-20T19:30:10Z
咽頭べさ
33
395271
Scribunto
text/plain
local export = {}
local data = {}
data["ug-Arab"] = {
-- consonants
["م"] = "m", ["ن"] = "n", ["د"] = "d", ["ت"] = "t",
["ب"] = "b", ["پ"] = "p", ["ف"] = "f", ["ق"] = "q",
["ك"] = "k", ["ڭ"] = "ng", ["گ"] = "g", ["غ"] = "gh",
["ھ"] = "h", ["خ"] = "x", ["چ"] = "ch",
["ج"] = "j", ["ژ"] = "zh", ["ز"] = "z", ["س"] = "s",
["ش"] = "sh", ["ر"] = "r", ["ل"] = "l", ["ئ"] = "'",
["ي"] = "y", ["ۋ"] = "w",
-- vowels
["ا"] = "a", ["ە"] = "e", ["ې"] = "ë", ["ى"] = "i",
["و"] = "o", ["ۆ"] = "ö", ["ۇ"] = "u", ["ۈ"] = "ü",
-- punctuation
["؟"]="?",
["،"]=",",
["؛"]=";",
["ـ"]="-"
}
data["Arab"] = data["ug-Arab"]
data["Cyrl"] = {
["А"] = "A", ["Б"] = "B", ["В"] = "W", ["Г"] = "G", ["Ғ"] = "Gh", ["Д"] = "D", ["Е"] = "Ë", ["Ә"] = "E", ["Ж"] = "Zh", ["Җ"] = "J",
["З"] = "Z", ["И"] = "I", ["Й"] = "Y", ["К"] = "K", ["Қ"] = "Q", ["Л"] = "L", ["М"] = "M", ["Н"] = "N", ["Ң"] = "Ng", ["О"] = "O",
["Ө"] = "Ö", ["П"] = "P", ["Р"] = "R", ["С"] = "S", ["Т"] = "T", ["У"] = "U", ["Ү"] = "Ü", ["Ф"] = "F", ["Х"] = "X", ["Һ"] = "H",
["Ч"] = "Ch", ["Ш"] = "Sh", ["Ю"] = "Yu", ["Я"] = "Ya",
["Э"] = "É",
["а"] = "a", ["б"] = "b", ["в"] = "w", ["г"] = "g", ["ғ"] = "gh", ["д"] = "d", ["е"] = "ë", ["ә"] = "e", ["ж"] = "zh", ["җ"] = "j",
["з"] = "z", ["и"] = "i", ["й"] = "y", ["к"] = "k", ["қ"] = "q", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["ң"] = "ng", ["о"] = "o",
["ө"] = "ö", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ү"] = "ü", ["ф"] = "f", ["х"] = "x", ["һ"] = "h",
["ч"] = "ch", ["ш"] = "sh", ["ю"] = "yu", ["я"] = "ya",
["э"] = "é",
}
function export.tr(text, lang, sc)
if not sc then
sc = require("Module:languages").getByCode(lang):findBestScript(text):getCode()
end
if sc ~= "ug-Arab" and sc ~= "Arab" and sc ~= "Cyrl" then
return nil
end
-- remove initial hamza
text = mw.ustring.gsub(text, "^\216\166(.)", "%1")
text = mw.ustring.gsub(text, "%s\216\166(.)", " %1")
-- add apostrophe in some cases
text = mw.ustring.gsub(text, "([اەوۇۆۈېىаәоуөүеиАӘОУӨҮЕИ])([ڭң])([اەوۇۆۈېىаәоуөүеи])", "%1'%2%3") -- V'ngV
text = mw.ustring.gsub(text, "([نн])([گغгғ])", "%1'%2") -- n'g, n'gh
text = mw.ustring.gsub(text, "([ڭزسңзс])([ھһ])", "%1'%2") -- ng'h, z'h, s'h
text = mw.ustring.gsub(text, '.', data[sc])
return text
end
return export
d5ax0ds9jr6zxr8izw2hw40kx3x0upt
မဝ်ဂျူ:category tree/lang
828
1748
395212
379574
2026-05-20T14:05:18Z
咽頭べさ
33
395212
Scribunto
text/plain
-- This module contains a list of languages with lang-specific modules.
local langs_with_modules = {
["acm"] = true,
["acw"] = true,
["acy"] = true,
["aeb"] = true,
["afb"] = true,
["aii"] = true,
["ajp"] = true,
["akk"] = true,
["akl"] = true,
["ang"] = true,
["apc"] = true,
["apd"] = true,
["ar"] = true,
["arn"] = true,
["ars"] = true,
["ary"] = true,
["arz"] = true,
["ayl"] = true,
["az"] = true,
["bbl"] = true,
["be"] = true,
["bcl"] = true,
["bg"] = true,
["bku"] = true,
["ca"] = true,
["cbk"] = true,
["ce"] = true,
["ceb"] = true,
["cpi"] = true,
["cs"] = true,
["csb"] = true,
["cu"] = true,
["cy"] = true,
["de"] = true,
["egy"] = true,
["el"] = true,
["en"] = true,
["enm"] = true,
["eo"] = true,
["es"] = true,
["et"] = true,
["eu"] = true,
["fa"] = true,
["fax"] = true,
["fi"] = true,
["fr"] = true,
["fro"] = true,
["fy"] = true,
["gl"] = true,
["gmh"] = true,
["goh"] = true,
["got"] = true,
["grk-pro"] = true,
["gmq-osw"] = true,
["gmw-pro"] = true,
["gu"] = true,
["gug"] = true,
["he"] = true,
["hi"] = true,
["hil"] = true,
["hnn"] = true,
["hrx"] = true,
["hsb"] = true,
["hu"] = true,
["id"] = true,
["ilo"] = true,
["inc-apa"] = true,
["inc-ash"] = true,
["ine-bsl-pro"] = true,
["ine-pro"] = true,
["ira-pro"] = true,
["is"] = true,
["it"] = true,
["ja"] = true,
["jbo"] = true,
["jv"] = true,
["ket"] = true,
["klj"] = true,
["kn"] = true,
["kne"] = true,
["ko"] = true,
["krj"] = true,
["ky"] = true,
["la"] = true,
["lo"] = true,
["mdh"] = true,
["mhr"] = true,
["mk"] = true,
["moh"] = true,
["mr"] = true,
["mrw"] = true,
["ms"] = true,
["mt"] = true,
["mul"] = true,
["mvi"] = true,
["mwl"] = true,
["nan-hbl"] = true,
["nb"] = true,
["ne"] = true,
["nl"] = true,
["nn"] = true,
["non"] = true,
["ny"] = true,
["odt"] = true,
["orv"] = true,
["osx"] = true,
["pag"] = true,
["pam"] = true,
["phl"] = true,
["pi"] = true,
["pl"] = true,
["pra"] = true,
["pt"] = true,
["ro"] = true,
["roa-opt"] = true,
["rsk"] = true,
["ru"] = true,
["rue"] = true,
["sa"] = true,
["sc"] = true,
["sd"] = true,
["sei"] = true,
["sga"] = true,
["sh"] = true,
["shn"] = true,
["shu"] = true,
["sk"] = true,
["skr"] = true,
["sw"] = true,
["syc"] = true,
["szl"] = true,
["te"] = true,
["tg"] = true,
["th"] = true,
["tl"] = true,
["tpw"] = true,
["tsg"] = true,
["uk"] = true,
["ulw"] = true,
["ur"] = true,
["vec"] = true,
["vep"] = true,
["vi"] = true,
["war"] = true,
["yrl"] = true,
["zhx"] = true,
["zle-ono"] = true,
["zle-ort"] = true,
["zlw-ocs"] = true,
}
return langs_with_modules
mzoxgt494umbm0vdse25cln2salqsc1
မဝ်ဂျူ:category tree/ဝေါဟာအဓိက
828
1750
395215
272701
2026-05-20T14:23:58Z
咽頭べさ
33
395215
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 [[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ]]; "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}}} [[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#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}}} 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["သဗ္ဗနာမ်"] = {
description = "ဝေါဟာ{{{langname}}}နကဵုစပ်ဖျပ် ကဵု စၞးနာမ်ဂမၠိုၚ်။",
parents = {"ဝေါဟာအဓိက"},
}
labels["prenouns"] = labels["သဗ္ဗနာမ်"]
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"] = labels["ကြိယာ"]
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[pos .. case] = {
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{
"နာမဝိသေသန",
"ကြိယာဝိသေသန",
"နာမ်",
"ကြိယာ",
} do
labels[pos .. comp .. "အဆက်လက္ကရဴ"] = {
description = "{{{langname}}} " .. pos .. " that are only used in their " .. comp .. " forms.",
parents = {pos},
}
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}
q5iq4kz0lj3dgsuql2sse7zvweu2nev
395216
395215
2026-05-20T14:25:10Z
咽頭べさ
33
ကလေင်ပလီု မူတၟိ[[Special:Diff/395215|395215]]နကု[[Special:Contributions/咽頭べさ|咽頭べさ]] ([[User talk:咽頭べさ|ဓရီုကျာ]])
395216
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 [[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ]]; "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}}} [[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#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}
tlqlbgmh8w162avu55tnzujbjuf2ymk
ညးလွပ်:咽頭べさ/Notepad
2
9186
395204
395039
2026-05-20T12:48:11Z
咽頭べさ
33
395204
wikitext
text/x-wiki
[[🝴]] [[🝵]] [[🝶]] [[🝻]] [[🝼]] [[🝽]] [[🝾]] [[🝿]] [[🟙]] [[🛜]] [[🩵]] [[🩶]] [[🩷]] [[🪇]] [[🪈]] [[🪭]] [[🪮]] [[🪯]] [[🪻]] [[🪼]] [[🪽]] [[🪿]] [[🫎]] [[🫏]] [[🫚]] [[🫛]] [[🫨]] [[🫷]] [[🫸]]
[[File:Omx-san̊krān.png|50x50px]]
# {{l|shn|ၶိူဝ်း}}
{{shn-pron|ၽူၼ်-တူၵ်း}}
* {{kjp-IPA|လီ}}
#: {{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|Mymr=ယဒိ လောကသန္တိံ ဣစ္ဆေယျ၊ ဗုဒ္ဓမဂ္ဂံ ဝိနာ အညော မဂ္ဂေါ နတ္ထိ။}}
{{sa-alt|Deva=किं मया एतस्य विषये रोदनस्य आवश्यकता अस्ति}}
{{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}}
qf22eyatpc5cy8yc4j2nfjdvopk90xa
မဝ်ဂျူ:ar-nominals
828
9594
395248
291533
2026-05-20T18:48:02Z
咽頭べさ
33
395248
Scribunto
text/plain
-- Author: Benwing, based on early version by CodeCat.
--[[
FIXME: Nouns/adjectives to create to exemplify complex declensions:
-- riḍan (رِضًا or رِضًى)
--]]
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local ar_utilities = require("Module:ar-utilities")
local lang = require("Module:languages").getByCode("ar")
local u = require("Module:string/char")
local rfind = mw.ustring.find
local rsubn = mw.ustring.gsub
local rmatch = mw.ustring.match
local rsplit = mw.text.split
-- This is used in place of a transliteration when no manual
-- translit is specified and we're unable to automatically generate
-- one (typically because some vowel diacritics are missing).
local BOGUS_CHAR = u(0xFFFD)
-- hamza variants
local HAMZA = u(0x0621) -- hamza on the line (stand-alone hamza) = ء
local HAMZA_ON_ALIF = u(0x0623)
local HAMZA_ON_W = u(0x0624)
local HAMZA_UNDER_ALIF = u(0x0625)
local HAMZA_ON_Y = u(0x0626)
local HAMZA_ANY = "[" .. HAMZA .. HAMZA_ON_ALIF .. HAMZA_UNDER_ALIF .. HAMZA_ON_W .. HAMZA_ON_Y .. "]"
local HAMZA_PH = u(0xFFF0) -- hamza placeholder
-- various letters
local ALIF = u(0x0627) -- ʾalif = ا
local AMAQ = u(0x0649) -- ʾalif maqṣūra = ى
local AMAD = u(0x0622) -- ʾalif madda = آ
local TAM = u(0x0629) -- tāʾ marbūṭa = ة
local T = u(0x062A) -- tāʾ = ت
local HYPHEN = u(0x0640)
local N = u(0x0646) -- nūn = ن
local W = u(0x0648) -- wāw = و
local Y = u(0x064A) -- yā = ي
-- diacritics
local A = u(0x064E) -- fatḥa
local AN = u(0x064B) -- fatḥatān (fatḥa tanwīn)
local U = u(0x064F) -- ḍamma
local UN = u(0x064C) -- ḍammatān (ḍamma tanwīn)
local I = u(0x0650) -- kasra
local IN = u(0x064D) -- kasratān (kasra tanwīn)
local SK = u(0x0652) -- sukūn = no vowel
local SH = u(0x0651) -- šadda = gemination of consonants
local DAGGER_ALIF = u(0x0670)
local DIACRITIC_ANY_BUT_SH = "[" .. A .. I .. U .. AN .. IN .. UN .. SK .. DAGGER_ALIF .. "]"
-- common combinations
local NA = N .. A
local NI = N .. I
local AH = A .. TAM
local AT = A .. T
local AA = A .. ALIF
local AAMAQ = A .. AMAQ
local AAH = AA .. TAM
local AAT = AA .. T
local II = I .. Y
local IIN = II .. N
local IINA = II .. NA
local IY = II
local UU = U .. W
local UUN = UU .. N
local UUNA = UU .. NA
local AY = A .. Y
local AW = A .. W
local AYSK = AY .. SK
local AWSK = AW .. SK
local AAN = AA .. N
local AANI = AA .. NI
local AYN = AYSK .. N
local AYNI = AYSK .. NI
local AWN = AWSK .. N
local AWNA = AWSK .. NA
local AYNA = AYSK .. NA
local AYAAT = AY .. AAT
local UNU = "[" .. UN .. U .. "]"
-- optional diacritics/letters
local AOPT = A .. "?"
local AOPTA = A .. "?" .. ALIF
local IOPT = I .. "?"
local UOPT = U .. "?"
local UNOPT = UN .. "?"
local UNUOPT = UNU .. "?"
local SKOPT = SK .. "?"
-- lists of consonants
-- exclude tāʾ marbūṭa because we don't want it treated as a consonant
-- in patterns like أَفْعَل
local consonants_needing_vowels_no_tam = "بتثجحخدذرزسشصضطظعغفقكلمنهپچڤگڨڧأإؤئء"
-- consonants on the right side; includes alif madda
local rconsonants_no_tam = consonants_needing_vowels_no_tam .. "ويآ"
-- consonants on the left side; does not include alif madda
local lconsonants_no_tam = consonants_needing_vowels_no_tam .. "وي"
local CONS = "[" .. lconsonants_no_tam .. "]"
local CONSPAR = "([" .. lconsonants_no_tam .. "])"
local LRM = u(0x200E) --left-to-right mark
-- First syllable or so of elative/color-defect adjective
local ELCD_START = "^" .. HAMZA_ON_ALIF .. AOPT .. CONSPAR
local export = {}
--------------------
-- Utility functions
--------------------
function ine(x) -- If Not Empty
if x == nil then
return nil
elseif rfind(x, '^".*"$') then
local ret = rmatch(x, '^"(.*)"$')
return ret
elseif rfind(x, "^'.*'$") then
local ret = rmatch(x, "^'(.*)'$")
return ret
elseif x == "" then
return nil
else
return x
end
end
-- Compare two items, recursively comparing arrays.
-- FIXME, doesn't work for tables that aren't arrays.
function equals(x, y)
if type(x) == "table" and type(y) == "table" then
if #x ~= #y then
return false
end
for key, value in ipairs(x) do
if not equals(value, y[key]) then
return false
end
end
return true
end
return x == y
end
-- true if array contains item
function contains(tab, item)
for _, value in pairs(tab) do
if equals(value, item) then
return true
end
end
return false
end
-- append to array if element not already present
function insert_if_not(tab, item)
if not contains(tab, item) then
table.insert(tab, item)
end
end
-- version of rsubn() that discards all but the first return value
function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsub() that asserts that a match occurred
function assert_rsub(term, foo, bar)
local retval, numsub = rsubn(term, foo, bar)
assert(numsub > 0)
return retval
end
function make_link(arabic)
--return m_links.full_link(nil, arabic, lang, nil, "term", nil, {tr = "-"}, false)
return m_links.full_link({lang = lang, alt = arabic}, "term")
end
function track(page)
require("Module:debug").track("ar-nominals/" .. page)
return true
end
-------------------------------------
-- Functions for building inflections
-------------------------------------
-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}
local max_mods = 9 -- maximum number of modifiers
local mod_list = {"mod"} -- list of "mod", "mod2", "mod3", ...
for i=2,max_mods do
table.insert(mod_list, "mod" .. i)
end
-- Create and return the 'data' structure that will hold all of the
-- generated declensional forms, as well as other ancillary information
-- such as the possible numbers, genders and cases the the actual numbers
-- and states to store (in 'data.numbers' and 'data.states' respectively).
function init_data()
-- FORMS contains a table of forms for each inflectional category,
-- e.g. "nom_sg_ind" for nouns or "nom_m_sg_ind" for adjectives. The value
-- of an entry is an array of alternatives (e.g. different plurals), where
-- each alternative is either a string of the form "ARABIC" or
-- "ARABIC/TRANSLIT", or an array of such strings (this is used for
-- alternative spellings involving different hamza seats,
-- e.g. مُبْتَدَؤُون or مُبْتَدَأُون). Alternative hamza spellings are separated
-- in display by an "inner separator" (/), while alternatives on
-- the level of different plurals are separated by an "outer separator" (;).
return {forms = {}, title = nil, categories = {},
allgenders = {"m", "f"},
allstates = {"ind", "def", "con"},
allnumbers = {"sg", "du", "pl"},
states = {}, -- initialized later
numbers = {}, -- initialized later
engnumbers = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal"},
engnumberscap = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal (3-10)"},
allcases = {"nom", "acc", "gen", "inf"},
allcases_with_lemma = {"nom", "acc", "gen", "inf", "lemma"},
-- index into endings array indicating correct ending for given
-- combination of state and case
statecases = {
ind = {nom = 1, acc = 2, gen = 3, inf = 10, lemma = 13},
def = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
-- used for a definite adjective modifying a construct-state noun
defcon = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
con = {nom = 7, acc = 8, gen = 9, inf = 12, lemma = 15},
},
}
end
-- Initialize and return ARGS, ORIGARGS and DATA (see init_data()).
-- ARGS is a table of user-supplied arguments, massaged from the original
-- arguments by converting empty-string arguments to nil and appending
-- translit arguments to their base arguments with a separating slash.
-- ORIGARGS is the original table of arguments.
function init(origargs)
-- Massage arguments by converting empty arguments to nil, and
-- "" or '' arguments to empty.
local args = {}
for k, v in pairs(origargs) do
args[k] = ine(v)
end
-- Further massage arguments by appending translit arguments to the
-- corresponding base arguments, with a slash separator, as is expected
-- in the rest of the code.
--
-- FIXME: We should consider separating translit and base arguments by the
-- separators ; , | (used in overrides; see handle_lemma_and_overrides())
-- and matching up individual parts, to allow separate translit arguments
-- to be specified for overrides. But maybe not; the point of allowing
-- separate translit arguments is for compatibility with headword
-- templates such as "ar-noun" and "ar-adj", and those templates don't
-- handle override arguments.
local function dotr(arg, argtr)
if not args[arg] then
error("Argument '" .. argtr .."' specified but not corresponding base argument '" .. arg .. "'")
end
args[arg] = args[arg] .. "/" .. args[argtr]
end
-- By convention, corresponding to arg 1 is tr; corresponding to
-- head2, head3, ... is tr2, tr3, ...; corresponding to
-- modhead2, modhead3, ... is modtr2, modtr3, ...; corresponding to
-- modNhead2, modNhead3, ... is modNtr2, modNtr3, ..; corresponding to
-- all other arguments FOO, FOO2, ... is FOOtr, FOO2tr, ...
for k, v in pairs(args) do
if k == "tr" then
dotr(1, "tr")
elseif rfind(k, "tr[0-9]+$") then
dotr(assert_rsub(k, "tr([0-9]+)$", "head%1"), k)
elseif rfind(k, "tr$") then
dotr(assert_rsub(k, "tr$", ""), k)
end
end
-- Construct data.
local data = init_data()
return args, origargs, data
end
-- Parse the user-specified state spec and other related arguments. The
-- user can specify, using idafaN=, how modifiers are related to previous
-- words. The user can also manually specify which states are to appear;
-- whether to omit the definite article in the definite state; and
-- how/whether to restrict modifiers to a particular state, case or number.
-- Normally the modN_* parameters and basestate= do not need to be set
-- directly; instead, use idafaN=. It may be necessary to explicitly
-- specify state= in the presence of proper nouns or definite-only
-- adjectival expressions. NOTE: At the time this function is called,
-- data.numbers has not yet been initialized.
function parse_state_etc_spec(data, args)
local function check(arg, dataval, allvalues)
if args[arg] then
if not contains(allvalues, args[arg]) then
error("For " .. arg .. "=, value '" .. args[arg] .. "' should be one of " ..
table.concat(allvalues, ", "))
end
data[dataval] = args[arg]
end
end
local function check_boolean(arg, dataval)
check(arg, dataval, {"yes", "no"})
if data[dataval] == "yes" then
data[dataval] = true
elseif data[dataval] == "no" then
data[dataval] = false
end
end
-- Make sure no holes in mod values
for i=1,(#mod_list)-1 do
if args[mod_list[i+1]] and not args[mod_list[i]] then
error("Hole in modifier arguments -- " .. mod_list[i+1] ..
" present but not " .. mod_list[i])
end
end
-- FIXME! Remove this once we're sure there are no instances of mod2
-- that haven't been converted to modhead2.
if args["mod2"] then
track("mod2")
end
-- Set default value; may be overridden e.g. by arg["state"] or
-- by idafaN=.
data.states = data.allstates
-- List of pairs of idafaN/modN parameters
local idafa_mod_list = {{"idafa", "mod"}}
for i=2,max_mods do
table.insert(idafa_mod_list, {"idafa" .. i, "mod" .. i})
end
-- True if the value of an |idafa= param is a valid adjectival modifier
-- value.
local function valid_adjectival_idafaval(idafaval)
return idafaval == "adj" or idafaval == "adj-base" or
idafaval == "adj-mod" or rfind(idafaval, "^adj%-mod[0-9]+$")
end
-- Extract the referent (base or modifier) of an adjectival |idafa= param.
-- Assumes the value is valid.
local function adjectival_idafaval_referent(idafaval)
if idafaval == "adj" then
return "base"
end
return assert_rsub(idafaval, "^adj%-", "")
end
-- Convert a base/mod spec to an index: 0=base, 1=mod, 2=mod2, etc.
local function basemod_to_index(basemod)
if basemod == "base" then return 0 end
if basemod == "mod" then return 1 end
return tonumber(assert_rsub(basemod, "^mod", ""))
end
-- Recognize idafa spec and handle it.
-- We do the following:
-- (1) Check that if idafaN= is given, then modN= is also given.
-- (2) Check that adjectival modifiers aren't followed by idafa modifiers.
-- (3) Check that adjectival modifiers are modifying the base or an
-- ʾidāfa modifier, not another adjectival modifier.
-- (4) Support idafa values "adj-base", "adj-mod", "adj-mod2", "adj"
-- (="adj-base") etc. and check that we're referring to an earlier
-- word.
-- (5) For ʾidāfa modifiers, set basestate=con, set modN_case=gen,
-- set modN_idafa=true, and set modN_number to the number specified
-- in the parameter value (e.g. 'sg' or 'def-pl'); and if the
-- parameter value specifies a state (e.g. 'def' or 'ind-du'),
-- set modN_state= to this value, and if this is the last ʾidāfa
-- modifier, also set state= to this value; if this is not the last
-- ʾidāfa modifier, set modN_state=con and disallow a state to be
-- specified in the parameter value.
-- (6) For adjectival modifiers of the base, do nothing.
-- (7) For adjectival modifiers of ʾidāfa modifiers, set modN_case=gen;
-- set modN_idafa=false; and set modN_number=, modN_numgen= and
-- modN_state= to match the values of the idafa modifier.
-- error checking and find last ʾidāfa modifier
local last_is_idafa = true
local last_idafa_mod = "base"
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
if not args[mod] then
error("'" .. idafaparam .. "' parameter without corresponding '"
.. mod .. "' parameter")
end
if not valid_adjectival_idafaval(idafaval) then
-- We're a construct (ʾidāfa) modifier
if not last_is_idafa then
error("ʾidāfa modifier " .. paramval .. " follows adjectival modifier")
end
last_idafa_mod = mod
else
last_is_idafa = false
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
if basemod_to_index(adjref) >= basemod_to_index(mod) then
error(paramval .. " can only refer to an earlier element")
end
local idafaref = assert_rsub(adjref, "^mod", "idafa")
if not args[idafaref] then
error(paramval .. " cannot refer to a missing modifier")
elseif valid_adjectival_idafaval(args[idafaref]) then
error(paramval .. " cannot refer to an adjectival modifier")
end
end
end
end
end
-- Now go through and set all the modN_ data values appropriately.
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
local bad_idafa = true
if idafaval == "yes" then
idafaval = "sg"
end
if idafaval == "ind-def" or contains(data.allstates, idafaval) then
idafaval = idafaval .. "-sg"
end
if not idafaval then
bad_idafa = false
elseif valid_adjectival_idafaval(idafaval) then
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = data[adjref .. "_state"]
-- if agreement is with ind-def, make it def
if data[mod .. "_state"] == "ind-def" then
data[mod .. "_state"] = "def"
end
data[mod .. "_number"] = data[adjref .. "_number"]
data[mod .. "_numgen"] = data[adjref .. "_numgen"]
data[mod .. "_idafa"] = false
end
bad_idafa = false
elseif contains(data.allnumbers, idafaval) then
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_number"] = idafaval
data[mod .. "_idafa"] = true
if mod ~= last_idafa_mod then
data[mod .. "_state"] = "con"
end
bad_idafa = false
elseif rfind(idafaval, "%-") then
local state_num = rsplit(idafaval, "%-")
-- Support ind-def as a possible value. We set modstate to
-- ind-def, which will signal definite agreement with adjectival
-- modifiers; then later on we change the value to ind.
if #state_num == 3 and state_num[1] == "ind" and state_num[2] == "def" then
state_num[1] = "ind-def"
state_num[2] = state_num[3]
table.remove(state_num)
end
if #state_num == 2 then
local state = state_num[1]
local num = state_num[2]
if (state == "ind-def" or contains(data.allstates, state))
and contains(data.allnumbers, num) then
if mod == last_idafa_mod then
if state == "ind-def" then
data.states = {"def"}
else
data.states = {state}
end
else
error(paramval .. " cannot specify a state because it is not the last ʾidāfa modifier")
end
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = state
data[mod .. "_number"] = num
data[mod .. "_idafa"] = true
bad_idafa = false
end
end
end
if bad_idafa then
error(paramval .. " should be one of yes, def, sg, def-sg, adj, adj-base, adj-mod, adj-mod2 or similar")
end
end
end
if args["state"] == "ind-def" then
data.states = {"def"}
data.basestate = "ind"
elseif args["state"] then
data.states = rsplit(args["state"], ",")
for _, state in ipairs(data.states) do
if not contains(data.allstates, state) then
error("For state=, value '" .. state .. "' should be one of " ..
table.concat(data.allstates, ", "))
end
end
end
-- Now process explicit settings, so that they can override the
-- settings based on idafaN=.
check("basestate", "basestate", data.allstates)
check_boolean("noirreg", "noirreg")
check_boolean("omitarticle", "omitarticle")
data.prefix = args.prefix
for _, mod in ipairs(mod_list) do
check(mod .. "state", mod .. "_state", data.allstates)
check(mod .. "case", mod .. "_case", data.allcases)
check(mod .. "number", mod .. "_number", data.allnumgens)
check(mod .. "numgen", mod .. "_numgen", data.allnumgens)
check_boolean(mod .. "idafa", mod .. "_idafa")
check_boolean(mod .. "omitarticle", mod .. "_omitarticle")
data[mod .. "_prefix"] = args[mod .. "prefix"]
end
-- Make sure modN_numgen is initialized, to modN_number if necessary.
-- This simplifies logic in certain places, e.g. call_inflections().
-- Also convert ind-def to ind.
for _, mod in ipairs(mod_list) do
data[mod .. "_numgen"] = data[mod .. "_numgen"] or data[mod .. "_number"]
if data[mod .. "_state"] == "ind-def" then
data[mod.. "_state"] = "ind"
end
end
end
-- Parse the user-specified number spec. The user can manually specify which
-- numbers are to appear. Return true if |number= was specified.
function parse_number_spec(data, args)
if args["number"] then
data.numbers = rsplit(args["number"], ",")
for _, num in ipairs(data.numbers) do
if not contains(data.allnumbers, num) then
error("For number=, value '" .. num .. "' should be one of " ..
table.concat(data.allnumbers, ", "))
end
end
return true
else
data.numbers = data.allnumbers
return false
end
end
-- Determine which numbers will appear using the logic for nouns.
-- See comment just below.
function determine_noun_numbers(data, args, pls)
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, duals and plurals
-- appear; else, only singular (on the assumption that the word is a proper
-- noun or abstract noun that exists only in the singular); however,
-- singular won't appear if "-" given for singular, and similarly for dual.
if not parse_number_spec(data, args) then
data.numbers = {}
local sgarg1 = args[1]
local duarg1 = args["d"]
if sgarg1 ~= "-" then
table.insert(data.numbers, "sg")
end
if #pls["base"] > 0 then
-- Dual appears if either: explicit dual stem (not -) is given, or
-- default dual is used and explicit singular stem (not -) is given.
if (duarg1 and duarg1 ~= "-") or (not duarg1 and sgarg1 ~= "-") then
table.insert(data.numbers, "du")
end
table.insert(data.numbers, "pl")
elseif duarg1 and duarg1 ~= "-" then
-- If explicit dual but no plural given, include it. Useful for
-- dual tantum words.
table.insert(data.numbers, "du")
end
end
end
-- For stem STEM, convert to stem-and-type format and insert stem and type
-- into RESULTS, checking to make sure it's not already there. SGS is the
-- list of singular items to base derived forms off of (masculine or feminine
-- as appropriate), an array of length-two arrays of {COMBINED_STEM, TYPE} as
-- returned by stem_and_type(); ISFEM is true if this is feminine gender;
-- NUM is "sg", "du" or "pl". POS is the part of speech, generally "noun" or
-- "adjective".
function insert_stems(stem, results, sgs, isfem, num, pos)
if stem == "-" then
return
end
for _, sg in ipairs(sgs) do
local combined_stem, ty = export.stem_and_type(stem,
sg[1], sg[2], isfem, num, pos)
insert_if_not(results, {combined_stem, ty})
end
end
-- Handle manually specified overrides of individual forms. Separate
-- outer-level alternants with ; or , or the Arabic equivalents; separate
-- inner-level alternants with | (we can't use / because it's already in
-- use separating Arabic from translit).
--
-- Also determine lemma and allow it to be overridden.
-- Also allow POS (part of speech) to be overridden.
function handle_lemma_and_overrides(data, args)
local function handle_override(arg)
if args[arg] then
local ovval = {}
local alts1 = rsplit(args[arg], "[;,؛،]")
for _, alt1 in ipairs(alts1) do
local alts2 = rsplit(alt1, "|")
table.insert(ovval, alts2)
end
data.forms[arg] = ovval
end
end
local function do_overrides(mod)
for _, numgen in ipairs(data.allnumgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases) do
local arg = mod .. case .. "_" .. numgen .. "_" .. state
handle_override(arg)
if args[arg] and not data.noirreg then
insert_cat(data, mod, numgen,
"Arabic NOUNs with irregular SINGULAR",
"SINGULAR of irregular NOUN")
end
end
end
end
end
do_overrides("")
for _, mod in ipairs(mod_list) do
do_overrides(mod .. "_")
end
local function get_lemma(mod)
for _, numgen in ipairs(data.numgens()) do
for _, state in ipairs(data.states) do
local arg = mod .. "lemma_" .. numgen .. "_" .. state
if data.forms[arg] and #data.forms[arg] > 0 then
return data.forms[arg]
end
end
end
return nil
end
data.forms["lemma"] = get_lemma("")
for _, mod in ipairs(mod_list) do
data.forms[mod .. "_lemma"] = get_lemma(mod .. "_")
end
handle_override("lemma")
for _, mod in ipairs(mod_list) do
handle_override(mod .. "_lemma")
end
end
-- Return the part of speech based on the part of speech contained in
-- data.pos and MOD (either "", "mod_", "mod2_", etc., same as in
-- do_gender_number_1()). If we're a modifier, don't use data.pos but
-- instead choose based on whether modifier is adjectival or nominal
-- (ʾiḍāfa).
function get_pos(data, mod)
local ismod = mod ~= ""
if not ismod then
return data.pos
elseif data[mod .. "idafa"] then
return "noun"
else
return "adjective"
end
end
-- Find the stems associated with a particular gender/number combination.
-- ARGS is the set of all arguments. ARGPREFS is an array of argument prefixes
-- (e.g. "f" for the actual arguments "f", "f2", ..., for the feminine
-- singular; we allow more than one to handle "cpl"). SGS is a
-- "stem-type list" (see do_gender_number()), and is the list of stems to
-- base derived forms off of (masculine or feminine as appropriate), an array
-- of length-two arrays of {COMBINED_STEM, TYPE} as returned by
-- stem_and_type(). DEFAULT, ISFEM and NUM are as in do_gender_number().
-- MOD is either "", "mod_", "mod2_", etc. depending if we're working on a
-- base or modifier argument (in the latter case, basically if the argument
-- begins with "mod").
function do_gender_number_1(data, args, argprefs, sgs, default, isfem, num, mod)
local results = {}
local function handle_stem(stem)
insert_stems(stem, results, sgs, isfem, num, get_pos(data, mod))
end
-- If no arguments specified, use the default instead.
need_default = true
for _, argpref in ipairs(argprefs) do
if args[argpref] then
need_default = false
break
end
end
if need_default then
if not default then
return results
end
handle_stem(default)
return results
end
-- For explicitly specified arguments, make sure there's at least one
-- stem to generate off of; otherwise specifying e.g. 'sing=- pauc=فُلَان'
-- won't override paucal.
if #sgs == 0 then
sgs = {{"", ""}}
end
for _, argpref in ipairs(argprefs) do
if args[argpref] then
handle_stem(args[argpref])
end
local i = 2
while args[argpref .. i] do
handle_stem(args[argpref .. i])
i = i + 1
end
end
return results
end
-- For a given gender/number combination, parse and return the full set
-- of stems for both base and modifier. The return value is a
-- "stem specification", i.e. table with a "base" key for the base, a
-- "mod" key for the first modifier (see below), a "mod2" key for the
-- second modifier, etc. listing all stems for both the base and modifier(s).
-- The value of each key is a "stem-type list", i.e. an array of stem-type
-- pairs, where each element is a size-two array of {COMBINED_STEM, STEM_TYPE}.
-- COMBINED_STEM is a stem with attached transliteration in the form
-- STEM/TRANSLIT (where the transliteration is either manually specified in
-- the stem argument, e.g. 'pl=لُورْدَات/lordāt', or auto-transliterated from
-- the Arabic, with BOGUS_CHAR substituting for the transliteration if
-- auto-translit fails). STEM_TYPE is the declension of the stem, either
-- manually specified, e.g. 'بَبَّغَاء:di' for manually-specified diptote, or
-- auto-detected (see stem_and_type() and detect_type()).
--
-- DATA and ARGS are as in init(). ARGPREFS is an array of the prefixes for
-- the argument(s) specifying the stem (and optional translit and declension
-- type). For a given ARGPREF, we check ARGPREF, ARGPREF2, ARGPREF3, ... in
-- turn for the base, and modARGPREF, modARGPREF2, modARGPREF3, ... in turn
-- for the first modifier, and mod2ARGPREF, mod2ARGPREF2, mod2ARGPREF3, ...
-- for the second modifier, etc. SGS is a stem specification (see above),
-- giving the stems that are used to base derived forms off of (e.g. if a stem
-- type "smp" appears in place of a stem, the sound masculine plural of the
-- stems in SGS will be derived). DEFAULT is a single stem (i.e. a string) that
-- is used when no stems were explicitly given by the user (typically either
-- "f", "m", "d" or "p"), or nil for no default. ISFEM is true if we're
-- accumulating stems for a feminine number/gender category, and NUM is the
-- number (expected to be "sg", "du" or "pl") of the number/gender category
-- we're accumulating stems for.
--
-- About bases and modifiers: Note that e.g. in the noun phrase يَوْم الاِثْنَيْن
-- the head noun يَوْم is the base and the noun الاِثْنَيْن is the modifier.
-- In a noun phrase like البَحْر الأَبْيَض المُتَوَسِّط, there are two modifiers.
-- Note that modifiers come in two varieties, adjectival modifiers and
-- construct (ʾidāfa) modifiers. The first above noun phrase is an example
-- of a noun phrase with a construct modifier, where the base is fixed in
-- the construct state and the modifier is fixed in number and case
-- (which is always genitive) and possibly in state. The second above noun
-- phrase is an example of a noun phrase with two adjectival modifiers.
-- A construct modifier is generally a noun, whereas an adjectival modifier
-- is an adjective that usually agrees in state, number and case with the
-- base noun. (Note that in the case of multiple modifiers, it is possible
-- for e.g. the second modifier to be an adjectival modifier that agrees
-- with the first, construct, modifier, in which case its case will be fixed
-- to genitive, its number will be fixed to the same number as the first
-- modifier and its state will vary or not depending on whether the first
-- modifier's state varies. It is not possible in general to distinguish
-- adjectival and construct modifiers by looking at the values of
-- modN_state, modN_case or modN_number, since e.g. a third modifier could
-- have all of them specified and be either kind. Thus we have modN_idafa,
-- which is true for a construct modifier, false otherwise.)
function do_gender_number(data, args, argprefs, sgs, default, isfem, num)
local results = do_gender_number_1(data, args, argprefs, sgs["base"],
default, isfem, num, "")
basemodtable = {base=results}
for _, mod in ipairs(mod_list) do
local modn_argprefs = {}
for _, argpref in ipairs(argprefs) do
table.insert(modn_argprefs, mod .. argpref)
end
local modn_results = do_gender_number_1(data, args, modn_argprefs,
sgs[mod] or {}, default, isfem, num, mod .. "_")
basemodtable[mod] = modn_results
end
return basemodtable
end
-- Generate inflections for the given combined stem and type, for MOD
-- (either "" if we're working on the base or "mod_", "mod2_", etc. if we're
-- working on a modifier) and NUMGEN (number or number-gender combination,
-- of the sort that forms part of the keys in DATA.FORMS).
function call_inflection(combined_stem, ty, data, mod, numgen)
if ty == "-" then
return
end
if not inflections[ty] then
error("Unknown inflection type '" .. ty .. "'")
end
local ar, tr = split_arabic_tr(combined_stem)
inflections[ty](ar, tr, data, mod, numgen)
end
-- Generate inflections for the stems of a given number/gender combination
-- and for either the base or the modifier. STEMTYPES is a stem-type list
-- (see do_gender_number()), listing all the stems and corresponding
-- declension types. MOD is either "", "mod_", "mod2_", etc. depending on
-- whether we're working on the base or a modifier. NUMGEN is the number or
-- number-gender combination we're working on, of the sort that forms part
-- of the keys in DATA.FORMS, e.g. "sg" or "m_sg".
function call_inflections(stemtypes, data, mod, numgen)
local mod_with_modnumgen = mod ~= "" and data[mod .. "numgen"]
-- If modN_numgen= is given, do nothing if NUMGEN isn't the same
if mod_with_modnumgen and data[mod .. "numgen"] ~= numgen then
return
end
-- always call inflection() if mod_with_modnumgen since it may affect
-- other numbers (cf. يَوْم الاِثْنَيْن)
if mod_with_modnumgen or contains(data.numbers, rsub(numgen, "^.*_", "")) then
for _, stemtype in ipairs(stemtypes) do
call_inflection(stemtype[1], stemtype[2], data, mod, numgen)
end
end
end
-- Generate the entire set of inflections for a noun or adjective.
-- Also handle any manually-specified part of speech and any manual
-- inflection overrides. The value of INFLECTIONS is an array of stem
-- specifications, one per number, where each element is a size-two
-- array of a stem specification (containing the set of stems and
-- corresponding declension types for the base and any modifiers;
-- see do_gender_number()) and a NUMGEN string, i.e. a string identifying
-- the number or number/gender in question (e.g. "sg", "du", "pl",
-- "m_sg", "f_pl", etc.).
function do_inflections_and_overrides(data, args, inflections)
-- do this before generating inflections so POS change is reflected in
-- categories
if args["pos"] then
data.pos = args["pos"]
end
for _, inflection in ipairs(inflections) do
call_inflections(inflection[1]["base"] or {}, data, "", inflection[2])
for _, mod in ipairs(mod_list) do
call_inflections(inflection[1][mod] or {}, data,
mod .. "_", inflection[2])
end
end
handle_lemma_and_overrides(data, args)
end
-- Helper function for get_heads(). Parses the stems for either the
-- base or the modifier (see do_gender_number()). ARG1 is the argument
-- for the first stem and ARGN is the prefix of the arguments for the
-- remaining stems. For example, for the singular base, ARG1=1 and
-- ARGN="head"; for the first singular modifier, ARG1="mod" and
-- ARGN="modhead"; for the plural base, ARG1=ARGN="pl". The arguments
-- other than the first are numbered 2, 3, ..., which is appended to
-- ARGN. MOD is either "", "mod_", "mod2_", etc. depending if we're
-- working on a base or modifier argument. The returned value is an
-- array of stems, where each element is a size-two array of
-- {COMBINED_STEM, STEM_TYPE}. See do_gender_number().
function get_heads_1(data, args, arg1, argn, mod)
if not args[arg1] then
return {}
end
local heads
if args[arg1] == "-" then
heads = {{"", "-"}}
else
heads = {}
insert_stems(args[arg1], heads, {{args[arg1], ""}}, false, "sg",
get_pos(data, mod))
end
local i = 2
while args[argn .. i] do
local arg = args[argn .. i]
insert_stems(arg, heads, {{arg, ""}}, false, "sg",
get_pos(data, mod))
i = i + 1
end
return heads
end
-- Very similar to do_gender_number(), and returns the same type of
-- structure, but works specifically for the stems of the head (the
-- most basic gender/number combiation, e.g. singular for nouns,
-- masculine singular for adjectives and gendered nouns, collective
-- for collective nouns, etc.), including both base and modifier.
-- See do_gender_number(). Note that the actual return value is
-- two items, the first of which is the same type of structure
-- returned by do_gender_number() and the second of which is a boolean
-- indicating whether we were called from within a template documentation
-- page (in which case no user-specified arguments exist and we
-- substitute sample ones). The reason for this boolean is to indicate
-- whether sample arguments need to be substituted for other numbers
-- as well.
function get_heads(data, args, headtype)
if not args[1] and mw.title.getCurrentTitle().nsText == "Template" then
return {base={{"{{{1}}}", "tri"}}}, true
end
if not args[1] then error("Parameter 1 (" .. headtype .. " stem) may not be empty.") end
local base = get_heads_1(data, args, 1, "head", "")
basemodtable = {base=base}
for _, mod in ipairs(mod_list) do
local modn = get_heads_1(data, args, mod, mod .. "head", mod .. "_")
basemodtable[mod] = modn
end
return basemodtable, false
end
-- The main entry point for noun tables.
function export.show_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "noun"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local sgs, is_template = get_heads(data, args, "singular")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, sgs, nil, false, "pl")
-- always do dual so cases like يَوْم الاِثْنَيْن work -- a singular with
-- a dual modifier, where data.number refers only the singular
-- but we need to go ahead and compute the dual so it parses the
-- "modd" modifier dual argument. When the modifier dual argument
-- is parsed, it will store the resulting dual declension for اِثْنَيْن
-- in the modifier slot for all numbers, including specifically
-- the singular.
local dus = do_gender_number(data, args, {"d"}, sgs, "d", false, "du")
parse_state_etc_spec(data, args)
determine_noun_numbers(data, args, pls)
do_inflections_and_overrides(data, args,
{{sgs, "sg"}, {dus, "du"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
function any_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return true
end
end
end
end
return false
end
function all_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if not rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return false
end
end
end
end
return true
end
-- The main entry point for collective noun tables.
function export.show_coll_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "noun"
data.allnumbers = {"coll", "sing", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local colls, is_template = get_heads(data, args, "collective")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
parse_state_etc_spec(data, args)
-- If collective noun is already feminine in form, don't try to
-- form a feminine singulative
local collfem = any_feminine(data, colls)
local sings = do_gender_number(data, args, {"sing"}, colls,
not already_feminine and "f" or nil, true, "sg")
local singfem = all_feminine(data, sings)
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear,
-- and if singulative given, dual and paucal appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "coll")
end
if #sings["base"] > 0 then
table.insert(data.numbers, "sing")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the collective, singulative, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{colls, "coll"}, {sings, "sing"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The main entry point for singulative noun tables.
function export.show_sing_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.allnumbers = {"sing", "coll", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
parse_state_etc_spec(data, args)
local sings, is_template = get_heads(data, args, "singulative")
-- If all singulative nouns feminine in form, form a masculine collective
local singfem = all_feminine(data, sings)
local colls = do_gender_number(data, args, {"coll"}, sings,
singfem and "m" or nil, false, "sg")
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear;
-- if singulative given or derivable, it and dual and paucal will appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "sing")
end
if #colls["base"] > 0 then
table.insert(data.numbers, "coll")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the singulative, collective, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{sings, "sing"}, {colls, "coll"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The implementation of the main entry point for adjective and
-- gendered noun tables.
function show_gendered(frame, isadj, pos)
local args, origargs, data = init(frame:getParent().args)
data.pos = pos
data.numgens = function()
local numgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.numbers) do
table.insert(numgens, gender .. "_" .. number)
end
end
return numgens
end
data.allnumgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.allnumbers) do
table.insert(data.allnumgens, gender .. "_" .. number)
end
end
parse_state_etc_spec(data, args)
local msgs = get_heads(data, args, 'masculine singular')
-- Always do all of these so cases like يَوْم الاِثْنَيْن work.
-- See comment in show_noun().
local fsgs = do_gender_number(data, args, {"f"}, msgs, "f", true, "sg")
local mdus = do_gender_number(data, args, {"d"}, msgs, "d", false, "du")
local fdus = do_gender_number(data, args, {"fd"}, fsgs, "d", true, "du")
local mpls = do_gender_number(data, args, {"pl", "cpl"}, msgs,
isadj and "p" or nil, false, "pl")
local fpls = do_gender_number(data, args, {"fpl", "cpl"}, fsgs, "fp",
true, "pl")
if isadj then
parse_number_spec(data, args)
else
determine_noun_numbers(data, args, mpls)
end
-- Generate the singular, dual and plural forms
do_inflections_and_overrides(data, args,
{{msgs, "m_sg"}, {fsgs, "f_sg"}, {mdus, "m_du"}, {fdus, "f_du"},
{mpls, "m_pl"}, {fpls, "f_pl"}})
-- Make the table
if isadj then
return make_adj_table(data)
else
return make_gendered_noun_table(data)
end
end
-- The main entry point for gendered noun tables.
function export.show_gendered_noun(frame)
return show_gendered(frame, false, "noun")
end
-- The main entry point for numeral tables. Same as using show_gendered_noun()
-- with pos=numeral.
function export.show_numeral(frame)
return show_gendered(frame, false, "numeral")
end
-- The main entry point for adjective tables.
function export.show_adj(frame)
return show_gendered(frame, true, "adjective")
end
-- Inflection functions
function do_translit(term)
return (lang:transliterate(term)) or track("cant-translit") and BOGUS_CHAR
end
function split_arabic_tr(term)
if term == "" then
return "", ""
elseif not rfind(term, "/") then
return term, do_translit(term)
else
splitvals = rsplit(term, "/")
if #splitvals ~= 2 then
error("Must have at most one slash in a combined Arabic/translit expr: '" .. term .. "'")
end
return splitvals[1], splitvals[2]
end
end
function reorder_shadda(word)
-- shadda+short-vowel (including tanwīn vowels, i.e. -an -in -un) gets
-- replaced with short-vowel+shadda during NFC normalisation, which
-- MediaWiki does for all Unicode strings; however, it makes the
-- detection process inconvenient, so undo it.
word = rsub(word, "(" .. DIACRITIC_ANY_BUT_SH .. ")" .. SH, SH .. "%1")
return word
end
-- Combine PREFIX, AR/TR, and ENDING in that order. PREFIX and ENDING
-- can be of the form ARABIC/TRANSLIT. The Arabic and translit parts are
-- separated out and grouped together, resulting in a string of the
-- form ARABIC/TRANSLIT (TRANSLIT will always be present, computed
-- automatically if not present in the source). The return value is actually a
-- list of ARABIC/TRANSLIT strings because hamza resolution is applied to
-- ARABIC, which may produce multiple outcomes (all of which will have the
-- same TRANSLIT).
function combine_with_ending(prefix, ar, tr, ending)
local prefixar, prefixtr = split_arabic_tr(prefix)
local endingar, endingtr = split_arabic_tr(ending)
-- When calling hamza_seat(), leave out prefixes, which we expect to be
-- clitics like وَ. (In case the prefix is a separate word, it won't matter
-- whether we include it in the text passed to hamza_seat().)
allar = hamza_seat(ar .. endingar)
-- Convert ...īān to ...iyān in case of stems ending in -ī or -ū
-- (e.g. kubrī "bridge").
if rfind(endingtr, "^[aeiouāēīōū]") then
if rfind(tr, "ī$") then
tr = rsub(tr, "ī$", "iy")
elseif rfind(tr, "ū$") then
tr = rsub(tr, "ū$", "uw")
end
end
tr = prefixtr .. tr .. endingtr
allartr = {}
for _, arval in ipairs(allar) do
table.insert(allartr, prefixar .. arval .. "/" .. tr)
end
return allartr
end
-- Combine PREFIX, STEM/TR and ENDING in that order and insert into the
-- list of items in DATA[KEY], initializing it if empty and making sure
-- not to insert duplicates. ENDING can be a list of endings, will be
-- distributed over the remaining parts. PREFIX and/or ENDING can be
-- of the form ARABIC/TRANSLIT (the stem is already split into Arabic STEM
-- and Latin TR). Note that what's inserted into DATA[KEY] is actually a
-- list of ARABIC/TRANSLIT strings; if more than one is present in the list,
-- they represent hamza variants, i.e. different ways of writing a hamza
-- sound, such as مُبْتَدَؤُون vs. مُبْتَدَأُون (see init_data()).
function add_inflection(data, key, prefix, stem, tr, ending)
if data.forms[key] == nil then
data.forms[key] = {}
end
if type(ending) ~= "table" then
ending = {ending}
end
for _, endingval in ipairs(ending) do
insert_if_not(data.forms[key],
combine_with_ending(prefix, stem, tr, endingval))
end
end
-- Form inflections from combination of STEM, with transliteration TR,
-- and ENDINGS (and definite article where necessary, plus any specified
-- prefixes) and store in DATA, for the number or gender/number
-- determined by MOD ("", "mod_", "mod2_", etc.; see call_inflection()) and
-- NUMGEN ("sg", "du", "pl", or "m_sg", "f_pl", etc. for adjectives). ENDINGS
-- is an array of 15 values, each of which is a string or array of
-- alternatives. The order of ENDINGS is indefinite nom, acc, gen; definite
-- nom, acc, gen; construct-state nom, acc, gen; informal indefinite, definite,
-- construct; lemma indefinite, definite, construct. (Normally the lemma is
-- based off of the indefinite, but if the inflection has been restricted to
-- particular states, it comes from one of those states, in the order
-- indefinite, definite, construct.) See also add_inflection() for more info
-- on exactly what is inserted into DATA.
function add_inflections(stem, tr, data, mod, numgen, endings)
stem = canon_hamza(stem)
assert(#endings == 15)
local ismod = mod ~= ""
-- If working on modifier and modN_numgen= is given, it better agree with
-- NUMGEN; the case where it doesn't agree should have been caught in
-- call_inflections().
if ismod and data[mod .. "numgen"] then
assert(data[mod .. "numgen"] == numgen)
end
-- Return a list of combined of ar/tr forms, with the ending tacked on.
-- There may be more than one form because of alternative hamza seats that
-- may be supplied, e.g. مُبْتَدَؤُون or مُبْتَدَأُون (mubtadaʾūn "(grammatical) subjects").
local defstem, deftr
if stem == "?" or data[mod .. "omitarticle"] then
defstem = stem
deftr = tr
else
-- apply sun-letter assimilation and hamzat al-wasl elision
defstem = rsub("الْ" .. stem, "^الْ([سشصتثطدذضزژظنرل])", "ال%1ّ")
defstem = rsub(defstem, "^الْ([اٱ])([ًٌٍَُِ])", "ال%2%1")
deftr = rsub("al-" .. tr, "^al%-([sšṣtṯṭdḏḍzžẓnrḷ])", "a%1-%1")
end
-- For a given MOD spec, is the previous word (base or modifier) a noun?
-- We assume the base is always a noun in this case, and otherwise
-- look at the value of modN_idafa.
local function prev_mod_is_noun(mod)
if mod == "mod_" then
return true
end
if mod == "mod2_" then
return data["mod_idafa"]
end
modnum = assert_rsub(mod, "^mod([0-9]+)_$", "%1")
modnum = modnum - 1
return data["mod" .. modnum .. "_idafa"]
end
local numgens = ismod and data[mod .. "numgen"] and data.numgens() or {numgen}
-- "defcon" means definite adjective modifying construct state noun. We
-- add a ... before the adjective (and after the construct-state noun) to
-- indicate that a nominal modifier would go between noun and adjective.
local stems = {ind = stem, def = defstem, con = stem,
defcon = "... " .. defstem}
local trs = {ind = tr, def = deftr, con = tr, defcon = "... " .. deftr}
for _, ng in ipairs(numgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases_with_lemma) do
-- We are generating the inflections for STATE, but sometimes
-- we want to use the inflected form of a different state, e.g.
-- if modN_state= or basestate= is set to some particular state.
-- If we're dealing with an adjectival modifier, then in
-- place of "con" we use "defcon" if immediately after a noun
-- (see comment above), else "def".
local thestate = ismod and data[mod .. "state"] or
ismod and not data[mod .. "idafa"] and state == "con" and
(prev_mod_is_noun(mod) and "defcon" or "def") or
not ismod and data.basestate or
state
local is_lemmainf = case == "lemma" or case == "inf"
-- Don't substitute value of modcase for lemma/informal "cases"
local thecase = is_lemmainf and case or
ismod and data[mod .. "case"] or case
add_inflection(data, mod .. case .. "_" .. ng .. "_" .. state,
data[mod .. "prefix"] or "",
stems[thestate], trs[thestate],
endings[data.statecases[thestate][thecase]])
end
end
end
end
-- Insert into a category and a type variable (e.g. m_sg_type) for the
-- declension type of a particular declension (e.g. masculine singular for
-- adjectives). MOD and NUMGEN are as in call_inflection(). CATVALUE is the
-- category and ENGVALUE is the English description of the declension type.
-- In these values, NOUN is replaced with either "noun" or "adjective",
-- SINGULAR is replaced with the English equivalent of the number in NUMGEN
-- (e.g. "singular", "dual" or "plural") while BROKSING is the same but uses
-- "broken plural" in place of "plural" and "broken paucal" in place of
-- "paucal".
function insert_cat(data, mod, numgen, catvalue, engvalue)
local singpl = data.engnumbers[rsub(numgen, "^.*_", "")]
assert(singpl ~= nil)
local broksingpl = rsub(singpl, "plural", "broken plural")
broksingpl = rsub(broksingpl, "paucal", "broken paucal")
if rfind(broksingpl, "broken plural") and (rfind(catvalue, "BROKSING") or
rfind(engvalue, "BROKSING")) then
table.insert(data.categories, "Arabic " .. data.pos .. "s with broken plural")
end
if rfind(catvalue, "irregular") or rfind(engvalue, "irregular") then
table.insert(data.categories, "Arabic irregular " .. data.pos .. "s")
end
catvalue = rsub(catvalue, "NOUN", data.pos)
catvalue = rsub(catvalue, "SINGULAR", singpl)
catvalue = rsub(catvalue, "BROKSING", broksingpl)
engvalue = rsub(engvalue, "NOUN", data.pos)
engvalue = rsub(engvalue, "SINGULAR", singpl)
engvalue = rsub(engvalue, "BROKSING", broksingpl)
-- add links to specialised grammatical terms
engvalue = rsub(engvalue, "triptote", "[[triptote]]")
engvalue = rsub(engvalue, "diptote", "[[diptote]]")
engvalue = rsub(engvalue, "broken plural", "BBB")
engvalue = rsub(engvalue, "sound plural", "SSS")
engvalue = rsub(engvalue, "broken", "[[broken plural|broken]]")
engvalue = rsub(engvalue, "sound", "[[sound plural|sound]]")
engvalue = rsub(engvalue, "BBB", "[[broken plural]]")
engvalue = rsub(engvalue, "SSS", "[[sound plural]]")
if mod == "" and catvalue ~= "" then
insert_if_not(data.categories, catvalue)
end
if engvalue ~= "" then
local key = mod .. numgen .. "_type"
if data.forms[key] == nil then
data.forms[key] = {}
end
insert_if_not(data.forms[key], engvalue)
end
if contains(data.states, "def") and not contains(data.states, "ind") then
insert_if_not(data.categories, "Arabic definite " .. data.pos .. "s")
end
end
-- Return true if we're handling modifier inflections and the modifier's
-- case is limited to an oblique case (gen or acc; typically genitive,
-- in an ʾidāfa construction). This is used when returning lemma
-- inflections -- the modifier part of the lemma should agree in case
-- with modifier's case if it's restricted in case.
function mod_oblique(mod, data)
return mod ~= "" and data[mod .. "case"] and (
data[mod .. "case"] == "acc" or data[mod .. "case"] == "gen")
end
-- Similar to mod_oblique but specifically when the modifier case is
-- limited to the accusative (which is rare or nonexistent in practice).
function mod_acc(mod, data)
return mod ~= "" and data[mod .. "case"] and data[mod .. "case"] == "acc"
end
-- Handle triptote and diptote inflections
function triptote_diptote(stem, tr, data, mod, numgen, is_dip, lc)
-- Remove any case ending
if rfind(stem, "[" .. UN .. U .. "]$") then
stem = rsub(stem, "[" .. UN .. U .. "]$", "")
tr = rsub(tr, "un?$", "")
end
-- special-case for صلوة pronounced ṣalāh; check translit
local is_aah = rfind(stem, TAM .. "$") and rfind(tr, "āh$")
if rfind(stem, TAM .. "$") then
if rfind(tr, "h$") then
tr = rsub(tr, "h$", "t")
elseif not rfind(tr, "t$") then
tr = tr .. "t"
end
end
add_inflections(stem, tr, data, mod, numgen,
{is_dip and U or UN,
is_dip and A or AN .. ((rfind(stem, "[" .. HAMZA_ON_ALIF .. TAM .. "]$")
or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. HAMZA .. "$")
) and "" or ALIF),
is_dip and A or IN,
U, A, I,
lc and UU or U,
lc and AA or A,
lc and II or I,
{}, {}, {}, -- omit informal inflections
{}, {}, {}, -- omit lemma inflections
})
-- add category and informal and lemma inflections
local tote = lc and "long construct" or is_dip and "diptote" or "triptote"
local singpl_tote = "BROKSING " .. tote
local cat_prefix = "Arabic NOUNs with " .. tote .. " BROKSING"
-- since we're checking translit for -āh we probably don't need to
-- check stem too
if is_aah or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"/t", "/t", "/t", -- informal pron. is -āt
"/h", "/h", "/t", -- lemma uses -āh
})
insert_cat(data, mod, numgen, cat_prefix .. " in -āh",
singpl_tote .. " in " .. make_link(HYPHEN .. AAH))
elseif rfind(stem, TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "/t",
"", "", "/t",
})
insert_cat(data, mod, numgen, cat_prefix .. " in -a",
singpl_tote .. " in " .. make_link(HYPHEN .. AH))
elseif lc then
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", UU,
"", "", UU,
})
insert_cat(data, mod, numgen, cat_prefix,
singpl_tote)
else
-- also special-case the nisba ending, which has an informal
-- pronunciation.
if rfind(stem, IY .. SH .. "$") then
local infstem = rsub(stem, SH .. "$", "")
local inftr = rsub(tr, "iyy$", "ī")
-- add informal and lemma inflections separately
add_inflections(infstem, inftr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
{}, {}, {},
})
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
})
else
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
"", "", "",
})
end
insert_cat(data, mod, numgen, "Arabic NOUNs with basic " .. tote .. " BROKSING",
"basic " .. singpl_tote)
end
end
-- Regular triptote
inflections["tri"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false)
end
-- Regular diptote
inflections["di"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, true)
end
-- Elative and color/defect adjective: usually same as diptote,
-- might be invariable
function elative_color_defect(stem, tr, data, mod, numgen)
if rfind(stem, "[" .. ALIF .. AMAQ .. "]$") then
invariable(stem, tr, data, mod, numgen)
else
triptote_diptote(stem, tr, data, mod, numgen, true)
end
end
-- Elative: usually same as diptote, might be invariable
inflections["el"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Color/defect adjective: Same as elative
inflections["cd"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Triptote with lengthened ending in the construct state
inflections["lc"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false, true)
end
function in_defective(stem, tr, data, mod, numgen, tri)
if not rfind(stem, IN .. "$") then
error("'in' declension stem should end in -in: '" .. stem .. "'")
end
stem = rsub(stem, IN .. "$", "")
tr = rsub(tr, "in$", "")
local acc_ind_ending = tri and IY .. AN .. ALIF or IY .. A
add_inflections(stem, tr, data, mod, numgen,
{IN, acc_ind_ending, IN,
II, IY .. A, II,
II, IY .. A, II,
II, II, II,
-- FIXME: What should happen with the lemma when modifier case
-- is limited to the accusative and modifier state is e.g. definite?
-- Should the lemma end in -iya or -ī? In practice this will rarely
-- if ever happen.
mod_acc(mod, data) and acc_ind_ending or IN, II, II,
})
local tote = tri and "triptote" or "diptote"
insert_cat(data, mod, numgen, "Arabic NOUNs with " .. tote .. " BROKSING in -in",
"BROKSING " .. tote .. " in " .. make_link(HYPHEN .. IN))
end
function detect_in_type(stem, ispl)
if ispl and rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IN .. "$") then -- layālin
return "diin"
else -- other -in words
return "triin"
end
end
-- Defective in -in
inflections["in"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen,
detect_in_type(stem, rfind(numgen, "pl")) == "triin")
end
-- Defective in -in, force "triptote" variant
inflections["triin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, true)
end
-- Defective in -in, force "diptote" variant
inflections["diin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, false)
end
-- Defective in -an (comes in two variants, depending on spelling with tall alif or alif maqṣūra)
inflections["an"] = function(stem, tr, data, mod, numgen)
local tall_alif
if rfind(stem, AN .. ALIF .. "$") then
tall_alif = true
stem = rsub(stem, AN .. ALIF .. "$", "")
elseif rfind(stem, AN .. AMAQ .. "$") then
tall_alif = false
stem = rsub(stem, AN .. AMAQ .. "$", "")
else
error("Invalid stem for 'an' declension type: " .. stem)
end
tr = rsub(tr, "an$", "")
if tall_alif then
add_inflections(stem, tr, data, mod, numgen,
{AN .. ALIF, AN .. ALIF, AN .. ALIF,
AA, AA, AA,
AA, AA, AA,
AA, AA, AA,
AN .. ALIF, AA, AA,
})
else
add_inflections(stem, tr, data, mod, numgen,
{AN .. AMAQ, AN .. AMAQ, AN .. AMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AN .. AMAQ, AAMAQ, AAMAQ,
})
end
-- FIXME: Should we distinguish between tall alif and alif maqṣūra?
insert_cat(data, mod, numgen, "Arabic NOUNs with BROKSING in -an",
"BROKSING in " .. make_link(HYPHEN .. AN .. (tall_alif and ALIF or AMAQ)))
end
function invariable(stem, tr, data, mod, numgen)
add_inflections(stem, tr, data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
insert_cat(data, mod, numgen, "Arabic NOUNs with invariable BROKSING",
"BROKSING invariable")
end
-- Invariable in -ā (non-loanword type)
inflections["inv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Invariable in -ā (loanword type, behaving in the dual as if ending in -a, I think!)
inflections["lwinv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Duals
inflections["d"] = function(stem, tr, data, mod, numgen)
if rfind(stem, ALIF .. NI .. "?$") then
stem = rsub(stem, AOPTA .. NI .. "?$", "")
elseif rfind(stem, AMAD .. NI .. "?$") then
stem = rsub(stem, AMAD .. NI .. "?$", HAMZA_PH)
else
error("Dual stem should end in -ān(i): '" .. stem .. "'")
end
tr = rsub(tr, "āni?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AANI, AYNI, AYNI,
AANI, AYNI, AYNI,
AA, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AAN, mo and AYN or AAN, mo and AYSK or AA,
})
insert_cat(data, mod, numgen, "", "dual in " .. make_link(HYPHEN .. AANI))
end
-- Sound masculine plural
inflections["smp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, UUNA .. "?$") then
error("Sound masculine plural stem should end in -ūn(a): '" .. stem .. "'")
end
stem = rsub(stem, UUNA .. "?$", "")
tr = rsub(tr, "ūna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{UUNA, IINA, IINA,
UUNA, IINA, IINA,
UU, II, II,
IIN, IIN, II,
mo and IIN or UUN, mo and IIN or UUN, mo and II or UU,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
insert_cat(data, mod, numgen, "Arabic NOUNs with sound masculine SINGULAR",
"sound masculine SINGULAR")
end
-- Sound feminine plural
inflections["sfp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, "[" .. ALIF .. AMAD .. "]" .. T .. UN .. "?$") then
error("Sound feminine plural stem should end in -āt(un): '" .. stem .. "'")
end
stem = rsub(stem, UN .. "$", "")
tr = rsub(tr, "un$", "")
add_inflections(stem, tr, data, mod, numgen,
{UN, IN, IN,
U, I, I,
U, I, I,
"", "", "",
"", "", "",
})
-- use SINGULAR because this might be used with the paucal
-- instead of plural
insert_cat(data, mod, numgen, "Arabic NOUNs with sound feminine SINGULAR",
"sound feminine SINGULAR")
end
-- Plural of defective in -an
inflections["awnp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, AWNA .. "?$") then
error("'awnp' plural stem should end in -awn(a): '" .. stem .. "'")
end
stem = rsub(stem, AWNA .. "?$", "")
tr = rsub(tr, "awna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AWNA, AYNA, AYNA,
AWNA, AYNA, AYNA,
AWSK, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AWN, mo and AYN or AWN, mo and AYSK or AWSK,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
insert_cat(data, mod, numgen, "Arabic NOUNs with sound SINGULAR in -awna",
"sound SINGULAR in " .. make_link(HYPHEN .. AWNA))
end
-- Unknown
inflections["?"] = function(stem, tr, data, mod, numgen)
add_inflections("?", "?", data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
insert_cat(data, mod, numgen, "Arabic NOUNs with unknown SINGULAR",
"SINGULAR unknown")
end
-- Detect declension of noun or adjective stem or lemma. We allow triptotes,
-- diptotes and sound plurals to either come with ʾiʿrāb or not. We detect
-- some cases where vowels are missing, when it seems fairly unambiguous to
-- do so. ISFEM is true if we are dealing with a feminine stem (not
-- currently used and needs to be rethought). NUM is "sg", "du", or "pl",
-- depending on the number of the stem.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
--
-- Some unexpectedly diptote nouns/adjectives:
--
-- jiʿrān in ʾabū jiʿrān "dung beetle"
-- distributive numbers: ṯunāʾ "two at a time", ṯulāṯ/maṯlaṯ "three at a time",
-- rubāʿ "four at a time" (not a regular diptote pattern, cf. triptote
-- junāḥ "misdemeanor, sin", nujār "origin, root", nuḥām "flamingo")
-- jahannam (f.) "hell"
-- many names: jilliq/jillaq "Damascus", judda/jidda "Jedda", jibrīl (and
-- variants) "Gabriel", makka "Mecca", etc.
-- jibriyāʾ "pride"
-- kibriyāʾ "glory, pride"
-- babbaḡāʾ "parrot"
-- ʿayāyāʾ "incapable, tired"
-- suwaidāʾ "black bile, melancholy"
-- Note also: ʾajhar "day-blind" (color-defect) and ʾajhar "louder" (elative)
function export.detect_type(stem, isfem, num, pos)
local function dotrack(word)
track(word)
track(word .. "/" .. pos)
return true
end
-- Not strictly necessary because the caller (stem_and_type) already
-- reorders, but won't hurt, and may be necessary if this function is
-- called from an external caller.
stem = reorder_shadda(stem)
local origstem = stem
-- So that we don't get tripped up by alif madda, we replace alif madda
-- with the sequence hamza + fatḥa + alif before the regexps below.
stem = rsub(stem, AMAD, HAMZA .. AA)
if num == "du" then
if rfind(stem, ALIF .. NI .. "?$") then
return "d"
else
error("Malformed stem for dual, should end in the nominative dual ending -ān(i): '" .. origstem .. "'")
end
end
if rfind(stem, IN .. "$") then -- -in words
return detect_in_type(stem, num == "pl")
elseif rfind(stem, AN .. "[" .. ALIF .. AMAQ .. "]$") then
return "an"
elseif rfind(stem, AN .. "$") then
error("Malformed stem, fatḥatan should be over second-to-last letter: " .. origstem)
elseif num == "pl" and rfind(stem, AW .. SKOPT .. N .. AOPT .. "$") then
return "awnp"
elseif num == "pl" and rfind(stem, ALIF .. T .. UNOPT .. "$") and
-- Avoid getting tripped up by plurals like ʾawqāt "times",
-- ʾaḥwāt "fishes", ʾabyāt "verses", ʾazyāt "oils", ʾaṣwāt "voices",
-- ʾamwāt "dead (pl.)".
not rfind(stem, HAMZA_ON_ALIF .. A .. CONS .. SK .. CONS .. AAT .. UNOPT .. "$") then
return "sfp"
elseif num == "pl" and rfind(stem, W .. N .. AOPT .. "$") and
-- Avoid getting tripped up by plurals like ʿuyūn "eyes",
-- qurūn "horns" (note we check for U between first two consonants
-- so we correctly ignore cases like sinūn "hours" (from sana),
-- riʾūn "lungs" (from riʾa) and banūn "sons" (from ibn).
not rfind(stem, "^" .. CONS .. U .. CONS .. UUN .. AOPT .. "$") then
return "smp"
elseif rfind(stem, UN .. "$") then -- explicitly specified triptotes (we catch sound feminine plurals above)
return "tri"
elseif rfind(stem, U .. "$") then -- explicitly specified diptotes
return "di"
elseif -- num == "pl" and
( -- various diptote plural patterns; these are diptote even in the singular (e.g. yanāyir "January", falāfil "falafel", tuʾabāʾ "yawn, fatigue"
-- currently we sometimes end up with such plural patterns in the "singular" in a singular
-- ʾidāfa construction with plural modifier. (FIXME: These should be fixed to the correct number.)
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IOPT .. Y .. "?" .. CONS .. "$") and dotrack("fawaakih") or -- fawākih, daqāʾiq, makātib, mafātīḥ
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. SH .. "$")
and not rfind(stem, "^" .. T) and dotrack("mawaadd") or -- mawādd, maqāmm, ḍawāll; exclude t- so we don't catch form-VI verbal nouns like taḍādd (HACK!!!)
rfind(stem, "^" .. CONS .. U .. CONS .. AOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("wuzaraa") or -- wuzarāʾ "ministers", juhalāʾ "ignorant (pl.)"
rfind(stem, ELCD_START .. SKOPT .. CONS .. IOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("asdiqaa") or -- ʾaṣdiqāʾ
rfind(stem, ELCD_START .. IOPT .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("aqillaa") -- ʾaqillāʾ, ʾajillāʾ "important (pl.)", ʾaḥibbāʾ "lovers"
) then
return "di"
elseif num == "sg" and ( -- diptote singular patterns (nouns/adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("qamraa") or -- qamrāʾ "moon-white, moonlight"; baydāʾ "desert"; ṣaḥrāʾ "desert-like, desert"; tayhāʾ "trackless, desolate region"; not pl. to avoid catching e.g. ʾabnāʾ "sons", ʾaḥmāʾ "fathers-in-law", ʾamlāʾ "steppes, deserts" (pl. of malan), ʾanbāʾ "reports" (pl. of nabaʾ)
rfind(stem, ELCD_START .. SK .. CONS .. A .. CONS .. "$") and dotrack("abyad") or -- ʾabyaḍ "white", ʾakbar "greater"; FIXME nouns like ʾaʿzab "bachelor", ʾaḥmad "Ahmed" but not ʾarnab "rabbit", ʾanjar "anchor", ʾabjad "abjad", ʾarbaʿ "four", ʾandar "threshing floor" (cf. diptote ʾandar "rarer")
rfind(stem, ELCD_START .. A .. CONS .. SH .. "$") and dotrack("alaff") or -- ʾalaff "plump", ʾaḥabb "more desirable"
-- do the following on the origstem so we can check specifically for alif madda
rfind(origstem, "^" .. AMAD .. CONS .. A .. CONS .. "$") and dotrack("aalam") -- ʾālam "more painful", ʾāḵar "other"
) then
return "di"
elseif num == "sg" and pos == "adjective" and ( -- diptote singular patterns (adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. "$") and dotrack("kaslaan") or -- kaslān "lazy", ʿaṭšān "thirsty", jawʿān "hungry", ḡaḍbān "angry", tayhān "wandering, perplexed"; but not nouns like qaṭrān "tar", šayṭān "devil", mawtān "plague", maydān "square"
-- rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. "$") and dotrack("laffaa") -- excluded because of too many false positives e.g. ḵawwān "disloyal", not to mention nouns like jannān "gardener"; only diptote example I can find is ʿayyān "incapable, weary" (diptote per Lane but not Wehr)
rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("laffaa") -- laffāʾ "plump (fem.)"; but not nouns like jarrāʾ "runner", ḥaddāʾ "camel driver", lawwāʾ "wryneck"
) then
return "di"
elseif rfind(stem, AMAQ .. "$") then -- kaslā, ḏikrā (spelled with alif maqṣūra)
return "inv"
elseif rfind(stem, "[" .. ALIF .. SK .. "]" .. Y .. AOPTA .. "$") then -- dunyā, hadāyā (spelled with tall alif after yāʾ)
return "inv"
elseif rfind(stem, ALIF .. "$") then -- kāmērā, lībiyā (spelled with tall alif; we catch dunyā and hadāyā above)
return "lwinv"
elseif rfind(stem, II .. "$") then -- cases like كُوبْرِي kubrī "bridge" and صَوَانِي ṣawānī pl. of ṣīniyya; modern words that would probably end with -in
dotrack("ii")
return "inv"
elseif rfind(stem, UU .. "$") then -- FIXME: Does this occur? Check the tracking
dotrack("uu")
return "inv"
else
return "tri"
end
end
-- Replace hamza (of any sort) at the end of a word, possibly followed by
-- a nominative case ending or -in or -an, with HAMZA_PH, and replace alif
-- madda at the end of a word with HAMZA_PH plus fatḥa + alif. To undo these
-- changes, use hamza_seat().
function canon_hamza(word)
word = rsub(word, AMAD .. "$", HAMZA_PH .. AA)
word = rsub(word, HAMZA_ANY .. "([" .. UN .. U .. IN .. "]?)$", HAMZA_PH .. "%1")
word = rsub(word, HAMZA_ANY .. "(" .. AN .. "[" .. ALIF .. AMAQ .. "])$", HAMZA_PH .. "%1")
return word
end
-- Supply the appropriate hamza seat(s) for a placeholder hamza.
function hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
return ar_utilities.process_hamza(word)
end
return {word}
end
--[[
-- Supply the appropriate hamza seat for a placeholder hamza in a combined
-- Arabic/translation expression.
function split_and_hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
local ar, tr = split_arabic_tr(word)
-- FIXME: Do something with all values returned
ar = ar_utilities.process_hamza(ar)[1]
return ar .. "/" .. tr
end
return word
end
--]]
-- Return stem and type of an argument given the singular stem and whether
-- this is a plural argument. WORD may be of the form ARABIC, ARABIC/TR,
-- ARABIC:TYPE, ARABIC/TR:TYPE, or TYPE, for Arabic stem ARABIC with
-- transliteration TR and of type (i.e. declension) TYPE. If the type
-- is omitted, it is auto-detected using detect_type(). If the transliteration
-- is omitted, it is auto-transliterated from the Arabic. If only the type
-- is present, it is a sound plural type ("sf", "sm" or "awn"),
-- in which case the stem and translit are generated from the singular by
-- regular rules. SG may be of the form ARABIC/TR or ARABIC. ISFEM is true
-- if WORD is a feminine stem. NUM is either "sg", "du" or "pl" according to
-- the number of the stem. The return value will be in the ARABIC/TR format.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
function export.stem_and_type(word, sg, sgtype, isfem, num, pos)
local rettype = nil
if rfind(word, ":") then
local split = rsplit(word, ":")
if #split > 2 then
error("More than one colon found in argument: '" .. word .. "'")
end
word, rettype = split[1], split[2]
end
local ar, tr = split_arabic_tr(word)
-- Need to reorder shaddas here so that shadda at the end of a stem
-- followed by ʾiʿrāb or a plural ending or whatever can get processed
-- correctly. This processing happens in various places so make sure
-- we return the reordered Arabic in all circumstances.
ar = reorder_shadda(ar)
local artr = ar .. "/" .. tr
-- Now return split-out ARABIC/TR and TYPE, with shaddas reordered in
-- the Arabic.
if rettype then
return artr, rettype
end
-- Likewise, do shadda reordering for the singular.
local sgar, sgtr = split_arabic_tr(sg)
sgar = reorder_shadda(sgar)
-- Apply a substitution to the singular Arabic and translit. If a
-- substitution could be made, return the combined ARABIC/TR with
-- substitutions made; else, return nil. The Arabic has ARFROM
-- replaced with ARTO, while the translit has TRFROM replaced with
-- TRTO, and if that doesn't match, replace TRFROM2 with TRTO2.
local function sub(arfrom, arto, trfrom, trto, trfrom2, trto2, trfrom3, trto3)
if rfind(sgar, arfrom) then
local arret = rsub(sgar, arfrom, arto)
local trret = sgtr
if rfind(sgtr, trfrom) then
trret = rsub(sgtr, trfrom, trto)
elseif trfrom2 and rfind(sgtr, trfrom2) then
trret = rsub(sgtr, trfrom2, trto2)
elseif trfrom3 and rfind(sgtr, trfrom3) then
trret = rsub(sgtr, trfrom3, trto3)
elseif not rfind(sgtr, BOGUS_CHAR) then
error("Transliteration '" .. sgtr .."' does not have same ending as Arabic '" .. sgar .. "'")
end
return arret .. "/" .. trret
else
return nil
end
end
if (num ~= "sg" or not isfem) and (word == "elf" or word == "cdf" or word == "intf" or word == "rf" or word == "f") then
error("Inference of form for inflection type '" .. word .. "' only allowed in singular feminine")
end
if num ~= "du" and word == "d" then
error("Inference of form for inflection type '" .. word .. "' only allowed in dual")
end
if num ~= "pl" and (word == "sfp" or word == "smp" or word == "awnp" or word == "cdp" or word == "sp" or word == "fp" or word == "p") then
error("Inference of form for inflection type '" .. word .. "' only allowed in plural")
end
local function is_intensive_adj(ar)
return rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SK .. AMAD .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. UOPT .. "$")
end
local function is_feminine_cd_adj(ar)
return pos == "adjective" and
(rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. UOPT .. "$") or -- ʾḥamrāʾ/ʿamyāʾ/bayḍāʾ
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. UOPT .. "$") -- laffāʾ
)
end
local function is_elcd_adj(ar)
return rfind(ar, ELCD_START .. SK .. CONS .. A .. CONS .. UOPT .. "$") or -- ʾabyaḍ "white", ʾakbar "greater"
rfind(ar, ELCD_START .. A .. CONS .. SH .. UOPT .. "$") or -- ʾalaff "plump", ʾaqall "fewer"
rfind(ar, ELCD_START .. SK .. CONS .. AAMAQ .. "$") or -- ʾaʿmā "blind", ʾadnā "lower"
rfind(ar, "^" .. AMAD .. CONS .. A .. CONS .. UOPT .. "$") -- ʾālam "more painful", ʾāḵar "other"
end
if word == "?" or
(rfind(word, "^[a-z][a-z]*$") and sgtype == "?") then
--if 'word' is a type, actual value inferred from sg; if sgtype is ?,
--propagate it to all derived types
return "", "?"
end
if word == "intf" then
if not is_intensive_adj(sgar) then
error("Singular stem not in CACCān form: " .. sgar)
end
local ret = (
sub(AMAD .. N .. UOPT .. "$", AMAD, "nu?$", "") or -- ends in -ʾān
sub(AOPTA .. N .. UOPT .. "$", AMAQ, "nu?$", "") -- ends in -ān
)
return ret, "inv"
end
if word == "elf" then
local ret = (
sub(ELCD_START .. SK .. "[" .. Y .. W .. "]" .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2" .. AMAQ, "ʔa(.)[yw]a(.)u?", "%1ū%2ā") or -- ʾajyad
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3" .. AMAQ, "ʔa(.)(.)a(.)u?", "%1u%2%3ā") or -- ʾakbar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH .. AMAQ, "ʔa(.)a(.)%2u?", "%1u%2%2ā") or -- ʾaqall
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. SK .. Y .. ALIF, "ʔa(.)(.)ā", "%1u%2yā") or -- ʾadnā
sub("^" .. AMAD .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
HAMZA_ON_ALIF .. U .. "%1" .. SK .. "%2" .. AMAQ, "ʔā(.)a(.)u?", "ʔu%1%2ā") -- ʾālam "more painful", ʾāḵar "other"
)
if not ret then
error("Singular stem not an elative adjective: " .. sgar)
end
return ret, "inv"
end
if word == "cdf" then
local ret = (
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. A .. "%2" .. SK .. "%3" .. AA .. HAMZA, "ʔa(.)(.)a(.)u?", "%1a%2%3āʔ") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. A .. "%2" .. SH .. AA .. HAMZA, "ʔa(.)a(.)%2u?", "%1a%2%2āʔ") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. A .. "%2" .. SK .. Y .. AA .. HAMZA, "ʔa(.)(.)ā", "%1a%2yāʔ") -- ʾaʿmā
)
if not ret then
error("Singular stem not a color/defect adjective: " .. sgar)
end
return ret, "cd" -- so plural will be correct
end
-- Regular feminine -- add ة, possibly with stem modifications
if word == "rf" then
sgar = canon_hamza(sgar)
if rfind(sgar, TAM .. UNUOPT .. "$") then
--Don't do this or we have problems when forming singulative from
--collective with a construct modifier that's feminine
--error("Singular stem is already feminine: " .. sgar)
return sgar .. "/" .. sgtr, "tri"
end
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AAH, "an$", "āh") or -- ends in -an
sub(IN .. "$", IY .. AH, "in$", "iya") or -- ends in -in
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AAH, "ā$", "āh") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AH, "un?$", "a", "$", "a") or -- anything else + -u(n)
sub("$", AH, "$", "a") -- anything else
)
return ret, "tri"
end
if word == "f" then
if sgtype == "cd" then
return export.stem_and_type("cdf", sg, sgtype, true, "sg", pos)
elseif sgtype == "el" then
return export.stem_and_type("elf", sg, sgtype, true, "sg", pos)
elseif sgtype =="di" and is_intensive_adj(sgar) then
return export.stem_and_type("intf", sg, sgtype, true, "sg", pos)
elseif sgtype == "di" and is_elcd_adj(sgar) then
-- If form is elative or color-defect, we don't know which of
-- the two it is, and each has a special feminine which isn't
-- the regular "just add ة", so shunt to unknown. This will
-- ensure that ?'s appear in place of the inflection -- also
-- for dual and plural.
return export.stem_and_type("?", sg, sgtype, true, "sg", pos)
else
return export.stem_and_type("rf", sg, sgtype, true, "sg", pos)
end
end
if word == "rm" then
sgar = canon_hamza(sgar)
--Don't do this or we have problems when forming collective from
--singulative with a construct modifier that's not feminine,
--e.g. شَجَرَة التُفَّاح
--if not rfind(sgar, TAM .. UNUOPT .. "$") then
-- error("Singular stem is not feminine: " .. sgar)
--end
local ret = (
sub(AAH .. UNUOPT .. "$", AN .. AMAQ, "ātun?$", "an", "ā[ht]$", "an") or -- in -āh
sub(IY .. AH .. UNUOPT .. "$", IN, "iyatun?$", "in", "iya$", "in") or -- ends in -iya
sub(AOPT .. TAM .. UNUOPT .. "$", "", "atun?$", "", "a$", "") or --ends in -a
sub("$", "", "$", "") -- do nothing
)
return ret, "tri"
end
if word == "m" then
-- FIXME: handle cd (color-defect)
-- FIXME: handle el (elative)
-- FIXME: handle int (intensive)
return export.stem_and_type("rm", sg, sgtype, false, "sg", pos)
end
-- The plural used for feminine adjectives. If the singular type is
-- color/defect or it looks like a feminine color/defect adjective,
-- use color/defect plural. Otherwise shunt to sound feminine plural.
if word == "fp" then
if sgtype == "cd" or is_feminine_cd_adj(sgar) then
return export.stem_and_type("cdp", sg, sgtype, true, "pl", pos)
else
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
end
end
if word == "sp" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
elseif isfem then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif sgtype == "an" then
return export.stem_and_type("awnp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
end
end
-- Conservative plural, as used for masculine plural adjectives.
-- If singular type is color-defect, shunt to color-defect plural; else
-- shunt to unknown, so ? appears in place of the inflections.
if word == "p" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
else
return export.stem_and_type("?", sg, sgtype, isfem, "pl", pos)
end
end
-- Special plural used for paucal plurals of singulatives. If ends in -ة
-- (most common), use strong feminine plural; if ends with -iyy (next
-- most common), use strong masculine plural; ends default to "p"
-- (conservative plural).
if word == "paucp" then
if rfind(sgar, TAM .. UNUOPT .. "$") then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif rfind(sgar, IY .. SH .. UNUOPT .. "$") then
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("p", sg, sgtype, isfem, "pl", pos)
end
end
if word == "d" then
sgar = canon_hamza(sgar)
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "an$", "ayān") or -- ends in -an
sub(IN .. "$", IY .. AAN, "in$", "iyān") or -- ends in -in
sgtype == "lwinv" and sub(AOPTA .. "$", AT .. AAN, "[āa]$", "atān") or -- lwinv, ends in alif; allow translit with short -a
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "ā$", "ayān") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
--
-- NOTE: Collapsing the "h$" and "$" cases into "h?$" doesn't work
-- in the case of words ending in -āh, which end up having the
-- translit end in -tāntān.
sub(TAM .. UNU .. "$", T .. AAN, "[ht]un?$", "tān", "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa + -u(n)
sub(TAM .. "$", T .. AAN, "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa
-- Same here as above
sub(UNU .. "$", AAN, "un?$", "ān", "$", "ān") or -- anything else + -u(n)
sub("$", AAN, "$", "ān") -- anything else
)
return ret, "d"
end
-- Strong feminine plural in -āt, possibly with stem modifications
if word == "sfp" then
sgar = canon_hamza(sgar)
sgar = rsub(sgar, AMAD .. "(" .. TAM .. UNUOPT .. ")$", HAMZA_PH .. AA .. "%1")
sgar = rsub(sgar, HAMZA_ANY .. "(" .. AOPT .. TAM .. UNUOPT .. ")$", HAMZA_PH .. "%1")
local ret = (
sub(AOPTA .. TAM .. UNUOPT .. "$", AYAAT, "ā[ht]$", "ayāt", "ātun?$", "ayāt") or -- ends in -āh
sub(AOPT .. TAM .. UNUOPT .. "$", AAT, "a$", "āt", "atun?$", "āt") or -- ends in -a
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "an$", "ayāt") or -- ends in -an
sub(IN .. "$", IY .. AAT, "in$", "iyāt") or -- ends in -in
sgtype == "inv" and (
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "ā$", "ayāt") -- ends in alif or alif maqṣūra
) or
sgtype == "lwinv" and (
sub(AOPTA .. "$", AAT, "[āa]$", "āt") -- loanword ending in tall alif; allow translit with short -a
) or
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AAT, "un?$", "āt", "$", "āt") or -- anything else + -u(n)
sub("$", AAT, "$", "āt") -- anything else
)
return ret, "sfp"
end
if word == "smp" then
sgar = canon_hamza(sgar)
local ret = (
sub(IN .. "$", UUN, "in$", "ūn") or -- ends in -in
-- See comments above for why we have two cases, one for UNU and
-- one for non-UNU
sub(UNU .. "$", UUN, "un?$", "ūn", "$", "ūn") or -- anything else + -u(n)
sub("$", UUN, "$", "ūn") -- anything else
)
return ret, "smp"
end
-- Color/defect plural; singular must be masculine or feminine
-- color/defect adjective
if word == "cdp" then
local ret = (
sub(ELCD_START .. SK .. W .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2", "ʔa(.)wa(.)u?", "%1ū%2") or -- ʾaswad
sub(ELCD_START .. SK .. Y .. A .. CONSPAR .. UOPT .. "$",
"%1" .. II .. "%2", "ʔa(.)ya(.)u?", "%1ī%2") or -- ʾabyaḍ
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3", "ʔa(.)(.)a(.)u?", "%1u%2%3") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH, "ʔa(.)a(.)%2u?", "%1u%2%2") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. Y, "ʔa(.)(.)ā", "%1u%2y") or -- ʾaʿmā
sub("^" .. CONSPAR .. A .. W .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. UU .. "%2", "(.)aw(.)āʔu?", "%1ū%2") or -- sawdāʾ
sub("^" .. CONSPAR .. A .. Y .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. II .. "%2", "(.)ay(.)āʔu?", "%1ī%2") or -- bayḍāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SK .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SK .. "%3", "(.)a(.)(.)āʔu?", "%1u%2%3") or -- ʾḥamrāʾ/ʿamyāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SH .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SH, "(.)a(.)%2āʔu?", "%1u%2%2") -- laffāʾ
)
if not ret then
error("For 'cdp', singular must be masculine or feminine color/defect adjective: " .. sgar)
end
return ret, "tri"
end
if word == "awnp" then
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AWSK .. N, "an$", "awn") -- ends in -an
)
if not ret then
error("For 'awnp', singular must end in -an: " .. sgar)
end
return ret, "awnp"
end
return artr, export.detect_type(ar, isfem, num, pos)
end
-- need LRM here so multiple Arabic plurals end up agreeing in order with
-- the transliteration
local outersep = LRM .. "; "
local innersep = LRM .. "/"
-- Subfunction of show_form(), used to implement recursively generating
-- all combinations of elements from FORM and from each of the items in
-- LIST_OF_MODS, both of which are either arrays of strings or arrays of
-- arrays of strings, where the strings are in the form ARABIC/TRANSLIT,
-- as described in show_form(). TRAILING_ARTRMODS is an array of ARTRMOD
-- items, each of which is a two-element array of ARMOD (Arabic) and TRMOD
-- (transliteration), accumulating all of the suffixes generated so far
-- in the recursion process. Each time we recur we take the last MOD item
-- off of LIST_OF_MODS, separate each element in MOD into its Arabic and
-- Latin parts and to each Arabic/Latin pair we add all elements in
-- TRAILING_ARTRMODS, passing the newly generated list of ARTRMOD items
-- down the next recursion level with the shorter LIST_OF_MODS. We end up
-- returning a string to insert into the Wiki-markup table.
function show_form_1(form, list_of_mods, trailing_artrmods, use_parens)
if #list_of_mods == 0 then
local arabicvals = {}
local latinvals = {}
local parenvals = {}
-- Accumulate separately the Arabic and transliteration into
-- ARABICVALS and LATINVALS, then concatenate each down below.
-- However, if USE_PARENS, we put each transliteration directly
-- after the corresponding Arabic, in parens, and put the results
-- in PARENVALS, which get concatenated below. (This is used in the
-- title of the declension table.)
for _, artrmod in ipairs(trailing_artrmods) do
assert(#artrmod == 2)
local armod = artrmod[1]
local trmod = artrmod[2]
for _, subform in ipairs(form) do
local ar_span, tr_span
local ar_subspan, tr_subspan
local ar_subspans = {}
local tr_subspans = {}
if type(subform) ~= "table" then
subform = {subform}
end
for _, subsubform in ipairs(subform) do
local arabic, translit = split_arabic_tr(subsubform)
if arabic == "-" then
ar_subspan = "—"
tr_subspan = "—"
elseif arabic == "?" then
ar_subspan = "?"
tr_subspan = "?"
else
tr_subspan = (rfind(translit, BOGUS_CHAR) or rfind(trmod, BOGUS_CHAR)) and "?" or
require("Module:script utilities").tag_translit(translit .. trmod, lang, "default", 'style="color: var(--wikt-palette-grey-8,#888);"')
-- implement elision of al- after vowel
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a([sšṣtṯṭdḏḍzžẓnrḷl]%-)", "%1%2")
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a(llāh)", "%1%2")
ar_subspan = m_links.full_link({lang = lang, term = arabic .. armod, tr = "-"})
end
insert_if_not(ar_subspans, ar_subspan)
insert_if_not(tr_subspans, tr_subspan)
end
ar_span = table.concat(ar_subspans, innersep)
tr_span = table.concat(tr_subspans, innersep)
if use_parens then
table.insert(parenvals, ar_span .. " (" .. tr_span .. ")")
else
table.insert(arabicvals, ar_span)
table.insert(latinvals, tr_span)
end
end
end
if use_parens then
return table.concat(parenvals, outersep)
else
local arabic_span = table.concat(arabicvals, outersep)
local latin_span = table.concat(latinvals, outersep)
if arabic_span == "?" then
return "?"
else
return arabic_span .. "<br />" .. latin_span
end
end
else
local last_mods = table.remove(list_of_mods)
local artrmods = {}
for _, mod in ipairs(last_mods) do
if type(mod) ~= "table" then
mod = {mod}
end
for _, submod in ipairs(mod) do
local armod, trmod = split_arabic_tr(submod)
-- If the value is -, we need to create a blank entry
-- rather than skipping it; if we have no entries at any
-- level, then there will be no overall entries at all
-- because the inside of the loop at the next level will
-- never be executed.
if armod == "-" then
armod = ""
trmod = ""
end
if armod ~= "" then armod = ' ' .. armod end
if trmod ~= "" then trmod = ' ' .. trmod end
for _, trailing_artrmod in ipairs(trailing_artrmods) do
local trailing_armod = trailing_artrmod[1]
local trailing_trmod = trailing_artrmod[2]
armod = armod .. trailing_armod
trmod = trmod .. trailing_trmod
artrmod = {armod, trmod}
table.insert(artrmods, artrmod)
end
end
end
return show_form_1(form, list_of_mods, artrmods, use_parens)
end
end
-- Generate a string to substitute into a particular form in a Wiki-markup
-- table. FORM is the set of inflected forms corresponding to the base,
-- either an array of strings (referring e.g. to different possible plurals)
-- or an array of arrays of strings (the first level referring e.g. to
-- different possible plurals and the inner level referring typically to
-- hamza-spelling variants). LIST_OF_MODS is an array of MODS elements, one
-- per modifier. Each MODS element is the set of inflected forms corresponding
-- to the modifier and is of the same form as FORM, i.e. an array of strings
-- or an array of arrays of strings. Each string is typically of the form
-- "ARABIC/TRANSLIT", i.e. an Arabic string and a Latin string separated
-- by a slash. We loop over all possible combinations of elements from
-- each array; this requires recursion.
function show_form(form, list_of_mods, use_parens)
if not form then
return "—"
elseif type(form) ~= "table" then
error("a non-table value was given in the list of inflected forms.")
end
if #form == 0 then
return "—"
end
-- We need to start the recursion with the third parameter containing
-- one blank element rather than no elements, otherwise no elements
-- will be propagated to the next recursion level.
return show_form_1(form, list_of_mods, {{"", ""}}, use_parens)
end
-- Create a Wiki-markup table using the values in DATA and the template in
-- WIKICODE.
function make_table(data, wikicode)
-- Function used as replace arg of call to rsub(). Replace the
-- specified param with its (HTML) value. The param references appear
-- as {{{PARAM}}} in the wikicode.
local function repl(param)
if param == "pos" then
return data.pos
elseif param == "info" then
return data.title and " (" .. data.title .. ")" or ""
elseif rfind(param, "type$") then
return table.concat(data.forms[param] or {"—"}, outersep .. "<br>")
else
local list_of_mods = {}
for _, mod in ipairs(mod_list) do
local mods = data.forms[mod .. "_" .. param]
if not mods or #mods == 0 then
-- We need one blank element rather than no element,
-- otherwise no elements will be propagated from one
-- recursion level to the next.
mods = {""}
end
table.insert(list_of_mods, mods)
end
return show_form(data.forms[param], list_of_mods, param == "lemma")
end
end
-- For states not in the list of those to be displayed, clear out the
-- corresponding inflections so they appear as a dash.
for _, state in ipairs(data.allstates) do
if not contains(data.states, state) then
for _, numgen in ipairs(data.numgens()) do
for _, case in ipairs(data.allcases) do
data.forms[case .. "_" .. numgen .. "_" .. state] = {}
end
end
end
end
return rsub(wikicode, "{{{([a-z_]+)}}}", repl) .. m_utilities.format_categories(data.categories, lang)
end
-- Generate part of the noun table for a given number spec NUM (e.g. sg)
function generate_noun_num(num)
return [=[! indefinite
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_]=] .. num .. [=[_ind}}}
| {{{inf_]=] .. num .. [=[_def}}}
| {{{inf_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_]=] .. num .. [=[_ind}}}
| {{{nom_]=] .. num .. [=[_def}}}
| {{{nom_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_]=] .. num .. [=[_ind}}}
| {{{acc_]=] .. num .. [=[_def}}}
| {{{acc_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_]=] .. num .. [=[_ind}}}
| {{{gen_]=] .. num .. [=[_def}}}
| {{{gen_]=] .. num .. [=[_con}}}
]=]
end
-- Make the noun table
function make_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" | dual
]=] .. generate_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" style="font-style:normal" colspan=3 | {{{]=] .. num .. [=[_type}}}
|-
]=] .. generate_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the gendered-noun table for a given numgen spec
-- NUM (e.g. m_sg)
function generate_gendered_noun_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_m_]=] .. num .. [=[_con}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_m_]=] .. num .. [=[_con}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_m_]=] .. num .. [=[_con}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_m_]=] .. num .. [=[_con}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_con}}}
]=]
end
-- Make the gendered noun table
function make_gendered_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'declension',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
]=] .. generate_gendered_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=3 | {{{m_]=] .. num .. [=[_type}}}
! class="outer" style="font-style:normal" colspan=3 | {{{f_]=] .. num .. [=[_type}}}
]=] .. generate_gendered_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the adjective table for a given numgen spec NUM (e.g. m_sg)
function generate_adj_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
]=]
end
-- Make the adjective table
function make_adj_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
if contains(data.numbers, "sg") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဨကဝုစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_sg_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_sg_type}}}
]=] .. generate_adj_num("sg")
end
if contains(data.numbers, "du") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
]=] .. generate_adj_num("du")
end
if contains(data.numbers, "pl") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဗဟုဝစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_pl_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_pl_type}}}
]=] .. generate_adj_num("pl")
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
return export
-- For Vim, so we get 4-space tabs
-- vim: set ts=4 sw=4 noet:
f19n6htbg025exrqs73bbz85qjzy1ys
395265
395248
2026-05-20T19:18:33Z
咽頭べさ
33
395265
Scribunto
text/plain
-- Author: Benwing, based on early version by CodeCat.
--[[
FIXME: Nouns/adjectives to create to exemplify complex declensions:
-- riḍan (رِضًا or رِضًى)
--]]
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local ar_utilities = require("Module:ar-utilities")
local lang = require("Module:languages").getByCode("ar")
local u = require("Module:string/char")
local rfind = mw.ustring.find
local rsubn = mw.ustring.gsub
local rmatch = mw.ustring.match
local rsplit = mw.text.split
-- This is used in place of a transliteration when no manual
-- translit is specified and we're unable to automatically generate
-- one (typically because some vowel diacritics are missing).
local BOGUS_CHAR = u(0xFFFD)
-- hamza variants
local HAMZA = u(0x0621) -- hamza on the line (stand-alone hamza) = ء
local HAMZA_ON_ALIF = u(0x0623)
local HAMZA_ON_W = u(0x0624)
local HAMZA_UNDER_ALIF = u(0x0625)
local HAMZA_ON_Y = u(0x0626)
local HAMZA_ANY = "[" .. HAMZA .. HAMZA_ON_ALIF .. HAMZA_UNDER_ALIF .. HAMZA_ON_W .. HAMZA_ON_Y .. "]"
local HAMZA_PH = u(0xFFF0) -- hamza placeholder
-- various letters
local ALIF = u(0x0627) -- ʾalif = ا
local AMAQ = u(0x0649) -- ʾalif maqṣūra = ى
local AMAD = u(0x0622) -- ʾalif madda = آ
local TAM = u(0x0629) -- tāʾ marbūṭa = ة
local T = u(0x062A) -- tāʾ = ت
local HYPHEN = u(0x0640)
local N = u(0x0646) -- nūn = ن
local W = u(0x0648) -- wāw = و
local Y = u(0x064A) -- yā = ي
-- diacritics
local A = u(0x064E) -- fatḥa
local AN = u(0x064B) -- fatḥatān (fatḥa tanwīn)
local U = u(0x064F) -- ḍamma
local UN = u(0x064C) -- ḍammatān (ḍamma tanwīn)
local I = u(0x0650) -- kasra
local IN = u(0x064D) -- kasratān (kasra tanwīn)
local SK = u(0x0652) -- sukūn = no vowel
local SH = u(0x0651) -- šadda = gemination of consonants
local DAGGER_ALIF = u(0x0670)
local DIACRITIC_ANY_BUT_SH = "[" .. A .. I .. U .. AN .. IN .. UN .. SK .. DAGGER_ALIF .. "]"
-- common combinations
local NA = N .. A
local NI = N .. I
local AH = A .. TAM
local AT = A .. T
local AA = A .. ALIF
local AAMAQ = A .. AMAQ
local AAH = AA .. TAM
local AAT = AA .. T
local II = I .. Y
local IIN = II .. N
local IINA = II .. NA
local IY = II
local UU = U .. W
local UUN = UU .. N
local UUNA = UU .. NA
local AY = A .. Y
local AW = A .. W
local AYSK = AY .. SK
local AWSK = AW .. SK
local AAN = AA .. N
local AANI = AA .. NI
local AYN = AYSK .. N
local AYNI = AYSK .. NI
local AWN = AWSK .. N
local AWNA = AWSK .. NA
local AYNA = AYSK .. NA
local AYAAT = AY .. AAT
local UNU = "[" .. UN .. U .. "]"
-- optional diacritics/letters
local AOPT = A .. "?"
local AOPTA = A .. "?" .. ALIF
local IOPT = I .. "?"
local UOPT = U .. "?"
local UNOPT = UN .. "?"
local UNUOPT = UNU .. "?"
local SKOPT = SK .. "?"
-- lists of consonants
-- exclude tāʾ marbūṭa because we don't want it treated as a consonant
-- in patterns like أَفْعَل
local consonants_needing_vowels_no_tam = "بتثجحخدذرزسشصضطظعغفقكلمنهپچڤگڨڧأإؤئء"
-- consonants on the right side; includes alif madda
local rconsonants_no_tam = consonants_needing_vowels_no_tam .. "ويآ"
-- consonants on the left side; does not include alif madda
local lconsonants_no_tam = consonants_needing_vowels_no_tam .. "وي"
local CONS = "[" .. lconsonants_no_tam .. "]"
local CONSPAR = "([" .. lconsonants_no_tam .. "])"
local LRM = u(0x200E) --left-to-right mark
-- First syllable or so of elative/color-defect adjective
local ELCD_START = "^" .. HAMZA_ON_ALIF .. AOPT .. CONSPAR
local export = {}
--------------------
-- Utility functions
--------------------
function ine(x) -- If Not Empty
if x == nil then
return nil
elseif rfind(x, '^".*"$') then
local ret = rmatch(x, '^"(.*)"$')
return ret
elseif rfind(x, "^'.*'$") then
local ret = rmatch(x, "^'(.*)'$")
return ret
elseif x == "" then
return nil
else
return x
end
end
-- Compare two items, recursively comparing arrays.
-- FIXME, doesn't work for tables that aren't arrays.
function equals(x, y)
if type(x) == "table" and type(y) == "table" then
if #x ~= #y then
return false
end
for key, value in ipairs(x) do
if not equals(value, y[key]) then
return false
end
end
return true
end
return x == y
end
-- true if array contains item
function contains(tab, item)
for _, value in pairs(tab) do
if equals(value, item) then
return true
end
end
return false
end
-- append to array if element not already present
function insert_if_not(tab, item)
if not contains(tab, item) then
table.insert(tab, item)
end
end
-- version of rsubn() that discards all but the first return value
function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsub() that asserts that a match occurred
function assert_rsub(term, foo, bar)
local retval, numsub = rsubn(term, foo, bar)
assert(numsub > 0)
return retval
end
function make_link(arabic)
--return m_links.full_link(nil, arabic, lang, nil, "term", nil, {tr = "-"}, false)
return m_links.full_link({lang = lang, alt = arabic}, "term")
end
function track(page)
require("Module:debug").track("ar-nominals/" .. page)
return true
end
-------------------------------------
-- Functions for building inflections
-------------------------------------
-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}
local max_mods = 9 -- maximum number of modifiers
local mod_list = {"mod"} -- list of "mod", "mod2", "mod3", ...
for i=2,max_mods do
table.insert(mod_list, "mod" .. i)
end
-- Create and return the 'data' structure that will hold all of the
-- generated declensional forms, as well as other ancillary information
-- such as the possible numbers, genders and cases the the actual numbers
-- and states to store (in 'data.numbers' and 'data.states' respectively).
function init_data()
-- FORMS contains a table of forms for each inflectional category,
-- e.g. "nom_sg_ind" for nouns or "nom_m_sg_ind" for adjectives. The value
-- of an entry is an array of alternatives (e.g. different plurals), where
-- each alternative is either a string of the form "ARABIC" or
-- "ARABIC/TRANSLIT", or an array of such strings (this is used for
-- alternative spellings involving different hamza seats,
-- e.g. مُبْتَدَؤُون or مُبْتَدَأُون). Alternative hamza spellings are separated
-- in display by an "inner separator" (/), while alternatives on
-- the level of different plurals are separated by an "outer separator" (;).
return {forms = {}, title = nil, categories = {},
allgenders = {"m", "f"},
allstates = {"ind", "def", "con"},
allnumbers = {"sg", "du", "pl"},
states = {}, -- initialized later
numbers = {}, -- initialized later
engnumbers = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal"},
engnumberscap = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal (3-10)"},
allcases = {"nom", "acc", "gen", "inf"},
allcases_with_lemma = {"nom", "acc", "gen", "inf", "lemma"},
-- index into endings array indicating correct ending for given
-- combination of state and case
statecases = {
ind = {nom = 1, acc = 2, gen = 3, inf = 10, lemma = 13},
def = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
-- used for a definite adjective modifying a construct-state noun
defcon = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
con = {nom = 7, acc = 8, gen = 9, inf = 12, lemma = 15},
},
}
end
-- Initialize and return ARGS, ORIGARGS and DATA (see init_data()).
-- ARGS is a table of user-supplied arguments, massaged from the original
-- arguments by converting empty-string arguments to nil and appending
-- translit arguments to their base arguments with a separating slash.
-- ORIGARGS is the original table of arguments.
function init(origargs)
-- Massage arguments by converting empty arguments to nil, and
-- "" or '' arguments to empty.
local args = {}
for k, v in pairs(origargs) do
args[k] = ine(v)
end
-- Further massage arguments by appending translit arguments to the
-- corresponding base arguments, with a slash separator, as is expected
-- in the rest of the code.
--
-- FIXME: We should consider separating translit and base arguments by the
-- separators ; , | (used in overrides; see handle_lemma_and_overrides())
-- and matching up individual parts, to allow separate translit arguments
-- to be specified for overrides. But maybe not; the point of allowing
-- separate translit arguments is for compatibility with headword
-- templates such as "ar-noun" and "ar-adj", and those templates don't
-- handle override arguments.
local function dotr(arg, argtr)
if not args[arg] then
error("Argument '" .. argtr .."' specified but not corresponding base argument '" .. arg .. "'")
end
args[arg] = args[arg] .. "/" .. args[argtr]
end
-- By convention, corresponding to arg 1 is tr; corresponding to
-- head2, head3, ... is tr2, tr3, ...; corresponding to
-- modhead2, modhead3, ... is modtr2, modtr3, ...; corresponding to
-- modNhead2, modNhead3, ... is modNtr2, modNtr3, ..; corresponding to
-- all other arguments FOO, FOO2, ... is FOOtr, FOO2tr, ...
for k, v in pairs(args) do
if k == "tr" then
dotr(1, "tr")
elseif rfind(k, "tr[0-9]+$") then
dotr(assert_rsub(k, "tr([0-9]+)$", "head%1"), k)
elseif rfind(k, "tr$") then
dotr(assert_rsub(k, "tr$", ""), k)
end
end
-- Construct data.
local data = init_data()
return args, origargs, data
end
-- Parse the user-specified state spec and other related arguments. The
-- user can specify, using idafaN=, how modifiers are related to previous
-- words. The user can also manually specify which states are to appear;
-- whether to omit the definite article in the definite state; and
-- how/whether to restrict modifiers to a particular state, case or number.
-- Normally the modN_* parameters and basestate= do not need to be set
-- directly; instead, use idafaN=. It may be necessary to explicitly
-- specify state= in the presence of proper nouns or definite-only
-- adjectival expressions. NOTE: At the time this function is called,
-- data.numbers has not yet been initialized.
function parse_state_etc_spec(data, args)
local function check(arg, dataval, allvalues)
if args[arg] then
if not contains(allvalues, args[arg]) then
error("For " .. arg .. "=, value '" .. args[arg] .. "' should be one of " ..
table.concat(allvalues, ", "))
end
data[dataval] = args[arg]
end
end
local function check_boolean(arg, dataval)
check(arg, dataval, {"yes", "no"})
if data[dataval] == "yes" then
data[dataval] = true
elseif data[dataval] == "no" then
data[dataval] = false
end
end
-- Make sure no holes in mod values
for i=1,(#mod_list)-1 do
if args[mod_list[i+1]] and not args[mod_list[i]] then
error("Hole in modifier arguments -- " .. mod_list[i+1] ..
" present but not " .. mod_list[i])
end
end
-- FIXME! Remove this once we're sure there are no instances of mod2
-- that haven't been converted to modhead2.
if args["mod2"] then
track("mod2")
end
-- Set default value; may be overridden e.g. by arg["state"] or
-- by idafaN=.
data.states = data.allstates
-- List of pairs of idafaN/modN parameters
local idafa_mod_list = {{"idafa", "mod"}}
for i=2,max_mods do
table.insert(idafa_mod_list, {"idafa" .. i, "mod" .. i})
end
-- True if the value of an |idafa= param is a valid adjectival modifier
-- value.
local function valid_adjectival_idafaval(idafaval)
return idafaval == "adj" or idafaval == "adj-base" or
idafaval == "adj-mod" or rfind(idafaval, "^adj%-mod[0-9]+$")
end
-- Extract the referent (base or modifier) of an adjectival |idafa= param.
-- Assumes the value is valid.
local function adjectival_idafaval_referent(idafaval)
if idafaval == "adj" then
return "base"
end
return assert_rsub(idafaval, "^adj%-", "")
end
-- Convert a base/mod spec to an index: 0=base, 1=mod, 2=mod2, etc.
local function basemod_to_index(basemod)
if basemod == "base" then return 0 end
if basemod == "mod" then return 1 end
return tonumber(assert_rsub(basemod, "^mod", ""))
end
-- Recognize idafa spec and handle it.
-- We do the following:
-- (1) Check that if idafaN= is given, then modN= is also given.
-- (2) Check that adjectival modifiers aren't followed by idafa modifiers.
-- (3) Check that adjectival modifiers are modifying the base or an
-- ʾidāfa modifier, not another adjectival modifier.
-- (4) Support idafa values "adj-base", "adj-mod", "adj-mod2", "adj"
-- (="adj-base") etc. and check that we're referring to an earlier
-- word.
-- (5) For ʾidāfa modifiers, set basestate=con, set modN_case=gen,
-- set modN_idafa=true, and set modN_number to the number specified
-- in the parameter value (e.g. 'sg' or 'def-pl'); and if the
-- parameter value specifies a state (e.g. 'def' or 'ind-du'),
-- set modN_state= to this value, and if this is the last ʾidāfa
-- modifier, also set state= to this value; if this is not the last
-- ʾidāfa modifier, set modN_state=con and disallow a state to be
-- specified in the parameter value.
-- (6) For adjectival modifiers of the base, do nothing.
-- (7) For adjectival modifiers of ʾidāfa modifiers, set modN_case=gen;
-- set modN_idafa=false; and set modN_number=, modN_numgen= and
-- modN_state= to match the values of the idafa modifier.
-- error checking and find last ʾidāfa modifier
local last_is_idafa = true
local last_idafa_mod = "base"
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
if not args[mod] then
error("'" .. idafaparam .. "' parameter without corresponding '"
.. mod .. "' parameter")
end
if not valid_adjectival_idafaval(idafaval) then
-- We're a construct (ʾidāfa) modifier
if not last_is_idafa then
error("ʾidāfa modifier " .. paramval .. " follows adjectival modifier")
end
last_idafa_mod = mod
else
last_is_idafa = false
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
if basemod_to_index(adjref) >= basemod_to_index(mod) then
error(paramval .. " can only refer to an earlier element")
end
local idafaref = assert_rsub(adjref, "^mod", "idafa")
if not args[idafaref] then
error(paramval .. " cannot refer to a missing modifier")
elseif valid_adjectival_idafaval(args[idafaref]) then
error(paramval .. " cannot refer to an adjectival modifier")
end
end
end
end
end
-- Now go through and set all the modN_ data values appropriately.
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
local bad_idafa = true
if idafaval == "yes" then
idafaval = "sg"
end
if idafaval == "ind-def" or contains(data.allstates, idafaval) then
idafaval = idafaval .. "-sg"
end
if not idafaval then
bad_idafa = false
elseif valid_adjectival_idafaval(idafaval) then
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = data[adjref .. "_state"]
-- if agreement is with ind-def, make it def
if data[mod .. "_state"] == "ind-def" then
data[mod .. "_state"] = "def"
end
data[mod .. "_number"] = data[adjref .. "_number"]
data[mod .. "_numgen"] = data[adjref .. "_numgen"]
data[mod .. "_idafa"] = false
end
bad_idafa = false
elseif contains(data.allnumbers, idafaval) then
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_number"] = idafaval
data[mod .. "_idafa"] = true
if mod ~= last_idafa_mod then
data[mod .. "_state"] = "con"
end
bad_idafa = false
elseif rfind(idafaval, "%-") then
local state_num = rsplit(idafaval, "%-")
-- Support ind-def as a possible value. We set modstate to
-- ind-def, which will signal definite agreement with adjectival
-- modifiers; then later on we change the value to ind.
if #state_num == 3 and state_num[1] == "ind" and state_num[2] == "def" then
state_num[1] = "ind-def"
state_num[2] = state_num[3]
table.remove(state_num)
end
if #state_num == 2 then
local state = state_num[1]
local num = state_num[2]
if (state == "ind-def" or contains(data.allstates, state))
and contains(data.allnumbers, num) then
if mod == last_idafa_mod then
if state == "ind-def" then
data.states = {"def"}
else
data.states = {state}
end
else
error(paramval .. " cannot specify a state because it is not the last ʾidāfa modifier")
end
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = state
data[mod .. "_number"] = num
data[mod .. "_idafa"] = true
bad_idafa = false
end
end
end
if bad_idafa then
error(paramval .. " should be one of yes, def, sg, def-sg, adj, adj-base, adj-mod, adj-mod2 or similar")
end
end
end
if args["state"] == "ind-def" then
data.states = {"def"}
data.basestate = "ind"
elseif args["state"] then
data.states = rsplit(args["state"], ",")
for _, state in ipairs(data.states) do
if not contains(data.allstates, state) then
error("For state=, value '" .. state .. "' should be one of " ..
table.concat(data.allstates, ", "))
end
end
end
-- Now process explicit settings, so that they can override the
-- settings based on idafaN=.
check("basestate", "basestate", data.allstates)
check_boolean("noirreg", "noirreg")
check_boolean("omitarticle", "omitarticle")
data.prefix = args.prefix
for _, mod in ipairs(mod_list) do
check(mod .. "state", mod .. "_state", data.allstates)
check(mod .. "case", mod .. "_case", data.allcases)
check(mod .. "number", mod .. "_number", data.allnumgens)
check(mod .. "numgen", mod .. "_numgen", data.allnumgens)
check_boolean(mod .. "idafa", mod .. "_idafa")
check_boolean(mod .. "omitarticle", mod .. "_omitarticle")
data[mod .. "_prefix"] = args[mod .. "prefix"]
end
-- Make sure modN_numgen is initialized, to modN_number if necessary.
-- This simplifies logic in certain places, e.g. call_inflections().
-- Also convert ind-def to ind.
for _, mod in ipairs(mod_list) do
data[mod .. "_numgen"] = data[mod .. "_numgen"] or data[mod .. "_number"]
if data[mod .. "_state"] == "ind-def" then
data[mod.. "_state"] = "ind"
end
end
end
-- Parse the user-specified number spec. The user can manually specify which
-- numbers are to appear. Return true if |number= was specified.
function parse_number_spec(data, args)
if args["number"] then
data.numbers = rsplit(args["number"], ",")
for _, num in ipairs(data.numbers) do
if not contains(data.allnumbers, num) then
error("For number=, value '" .. num .. "' should be one of " ..
table.concat(data.allnumbers, ", "))
end
end
return true
else
data.numbers = data.allnumbers
return false
end
end
-- Determine which numbers will appear using the logic for nouns.
-- See comment just below.
function determine_noun_numbers(data, args, pls)
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, duals and plurals
-- appear; else, only singular (on the assumption that the word is a proper
-- noun or abstract noun that exists only in the singular); however,
-- singular won't appear if "-" given for singular, and similarly for dual.
if not parse_number_spec(data, args) then
data.numbers = {}
local sgarg1 = args[1]
local duarg1 = args["d"]
if sgarg1 ~= "-" then
table.insert(data.numbers, "sg")
end
if #pls["base"] > 0 then
-- Dual appears if either: explicit dual stem (not -) is given, or
-- default dual is used and explicit singular stem (not -) is given.
if (duarg1 and duarg1 ~= "-") or (not duarg1 and sgarg1 ~= "-") then
table.insert(data.numbers, "du")
end
table.insert(data.numbers, "pl")
elseif duarg1 and duarg1 ~= "-" then
-- If explicit dual but no plural given, include it. Useful for
-- dual tantum words.
table.insert(data.numbers, "du")
end
end
end
-- For stem STEM, convert to stem-and-type format and insert stem and type
-- into RESULTS, checking to make sure it's not already there. SGS is the
-- list of singular items to base derived forms off of (masculine or feminine
-- as appropriate), an array of length-two arrays of {COMBINED_STEM, TYPE} as
-- returned by stem_and_type(); ISFEM is true if this is feminine gender;
-- NUM is "sg", "du" or "pl". POS is the part of speech, generally "noun" or
-- "adjective".
function insert_stems(stem, results, sgs, isfem, num, pos)
if stem == "-" then
return
end
for _, sg in ipairs(sgs) do
local combined_stem, ty = export.stem_and_type(stem,
sg[1], sg[2], isfem, num, pos)
insert_if_not(results, {combined_stem, ty})
end
end
-- Handle manually specified overrides of individual forms. Separate
-- outer-level alternants with ; or , or the Arabic equivalents; separate
-- inner-level alternants with | (we can't use / because it's already in
-- use separating Arabic from translit).
--
-- Also determine lemma and allow it to be overridden.
-- Also allow POS (part of speech) to be overridden.
function handle_lemma_and_overrides(data, args)
local function handle_override(arg)
if args[arg] then
local ovval = {}
local alts1 = rsplit(args[arg], "[;,؛،]")
for _, alt1 in ipairs(alts1) do
local alts2 = rsplit(alt1, "|")
table.insert(ovval, alts2)
end
data.forms[arg] = ovval
end
end
local function do_overrides(mod)
for _, numgen in ipairs(data.allnumgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases) do
local arg = mod .. case .. "_" .. numgen .. "_" .. state
handle_override(arg)
if args[arg] and not data.noirreg then
insert_cat(data, mod, numgen,
"Arabic NOUNs with irregular SINGULAR",
"SINGULAR of irregular NOUN")
end
end
end
end
end
do_overrides("")
for _, mod in ipairs(mod_list) do
do_overrides(mod .. "_")
end
local function get_lemma(mod)
for _, numgen in ipairs(data.numgens()) do
for _, state in ipairs(data.states) do
local arg = mod .. "lemma_" .. numgen .. "_" .. state
if data.forms[arg] and #data.forms[arg] > 0 then
return data.forms[arg]
end
end
end
return nil
end
data.forms["lemma"] = get_lemma("")
for _, mod in ipairs(mod_list) do
data.forms[mod .. "_lemma"] = get_lemma(mod .. "_")
end
handle_override("lemma")
for _, mod in ipairs(mod_list) do
handle_override(mod .. "_lemma")
end
end
-- Return the part of speech based on the part of speech contained in
-- data.pos and MOD (either "", "mod_", "mod2_", etc., same as in
-- do_gender_number_1()). If we're a modifier, don't use data.pos but
-- instead choose based on whether modifier is adjectival or nominal
-- (ʾiḍāfa).
function get_pos(data, mod)
local ismod = mod ~= ""
if not ismod then
return data.pos
elseif data[mod .. "idafa"] then
return "noun"
else
return "adjective"
end
end
-- Find the stems associated with a particular gender/number combination.
-- ARGS is the set of all arguments. ARGPREFS is an array of argument prefixes
-- (e.g. "f" for the actual arguments "f", "f2", ..., for the feminine
-- singular; we allow more than one to handle "cpl"). SGS is a
-- "stem-type list" (see do_gender_number()), and is the list of stems to
-- base derived forms off of (masculine or feminine as appropriate), an array
-- of length-two arrays of {COMBINED_STEM, TYPE} as returned by
-- stem_and_type(). DEFAULT, ISFEM and NUM are as in do_gender_number().
-- MOD is either "", "mod_", "mod2_", etc. depending if we're working on a
-- base or modifier argument (in the latter case, basically if the argument
-- begins with "mod").
function do_gender_number_1(data, args, argprefs, sgs, default, isfem, num, mod)
local results = {}
local function handle_stem(stem)
insert_stems(stem, results, sgs, isfem, num, get_pos(data, mod))
end
-- If no arguments specified, use the default instead.
need_default = true
for _, argpref in ipairs(argprefs) do
if args[argpref] then
need_default = false
break
end
end
if need_default then
if not default then
return results
end
handle_stem(default)
return results
end
-- For explicitly specified arguments, make sure there's at least one
-- stem to generate off of; otherwise specifying e.g. 'sing=- pauc=فُلَان'
-- won't override paucal.
if #sgs == 0 then
sgs = {{"", ""}}
end
for _, argpref in ipairs(argprefs) do
if args[argpref] then
handle_stem(args[argpref])
end
local i = 2
while args[argpref .. i] do
handle_stem(args[argpref .. i])
i = i + 1
end
end
return results
end
-- For a given gender/number combination, parse and return the full set
-- of stems for both base and modifier. The return value is a
-- "stem specification", i.e. table with a "base" key for the base, a
-- "mod" key for the first modifier (see below), a "mod2" key for the
-- second modifier, etc. listing all stems for both the base and modifier(s).
-- The value of each key is a "stem-type list", i.e. an array of stem-type
-- pairs, where each element is a size-two array of {COMBINED_STEM, STEM_TYPE}.
-- COMBINED_STEM is a stem with attached transliteration in the form
-- STEM/TRANSLIT (where the transliteration is either manually specified in
-- the stem argument, e.g. 'pl=لُورْدَات/lordāt', or auto-transliterated from
-- the Arabic, with BOGUS_CHAR substituting for the transliteration if
-- auto-translit fails). STEM_TYPE is the declension of the stem, either
-- manually specified, e.g. 'بَبَّغَاء:di' for manually-specified diptote, or
-- auto-detected (see stem_and_type() and detect_type()).
--
-- DATA and ARGS are as in init(). ARGPREFS is an array of the prefixes for
-- the argument(s) specifying the stem (and optional translit and declension
-- type). For a given ARGPREF, we check ARGPREF, ARGPREF2, ARGPREF3, ... in
-- turn for the base, and modARGPREF, modARGPREF2, modARGPREF3, ... in turn
-- for the first modifier, and mod2ARGPREF, mod2ARGPREF2, mod2ARGPREF3, ...
-- for the second modifier, etc. SGS is a stem specification (see above),
-- giving the stems that are used to base derived forms off of (e.g. if a stem
-- type "smp" appears in place of a stem, the sound masculine plural of the
-- stems in SGS will be derived). DEFAULT is a single stem (i.e. a string) that
-- is used when no stems were explicitly given by the user (typically either
-- "f", "m", "d" or "p"), or nil for no default. ISFEM is true if we're
-- accumulating stems for a feminine number/gender category, and NUM is the
-- number (expected to be "sg", "du" or "pl") of the number/gender category
-- we're accumulating stems for.
--
-- About bases and modifiers: Note that e.g. in the noun phrase يَوْم الاِثْنَيْن
-- the head noun يَوْم is the base and the noun الاِثْنَيْن is the modifier.
-- In a noun phrase like البَحْر الأَبْيَض المُتَوَسِّط, there are two modifiers.
-- Note that modifiers come in two varieties, adjectival modifiers and
-- construct (ʾidāfa) modifiers. The first above noun phrase is an example
-- of a noun phrase with a construct modifier, where the base is fixed in
-- the construct state and the modifier is fixed in number and case
-- (which is always genitive) and possibly in state. The second above noun
-- phrase is an example of a noun phrase with two adjectival modifiers.
-- A construct modifier is generally a noun, whereas an adjectival modifier
-- is an adjective that usually agrees in state, number and case with the
-- base noun. (Note that in the case of multiple modifiers, it is possible
-- for e.g. the second modifier to be an adjectival modifier that agrees
-- with the first, construct, modifier, in which case its case will be fixed
-- to genitive, its number will be fixed to the same number as the first
-- modifier and its state will vary or not depending on whether the first
-- modifier's state varies. It is not possible in general to distinguish
-- adjectival and construct modifiers by looking at the values of
-- modN_state, modN_case or modN_number, since e.g. a third modifier could
-- have all of them specified and be either kind. Thus we have modN_idafa,
-- which is true for a construct modifier, false otherwise.)
function do_gender_number(data, args, argprefs, sgs, default, isfem, num)
local results = do_gender_number_1(data, args, argprefs, sgs["base"],
default, isfem, num, "")
basemodtable = {base=results}
for _, mod in ipairs(mod_list) do
local modn_argprefs = {}
for _, argpref in ipairs(argprefs) do
table.insert(modn_argprefs, mod .. argpref)
end
local modn_results = do_gender_number_1(data, args, modn_argprefs,
sgs[mod] or {}, default, isfem, num, mod .. "_")
basemodtable[mod] = modn_results
end
return basemodtable
end
-- Generate inflections for the given combined stem and type, for MOD
-- (either "" if we're working on the base or "mod_", "mod2_", etc. if we're
-- working on a modifier) and NUMGEN (number or number-gender combination,
-- of the sort that forms part of the keys in DATA.FORMS).
function call_inflection(combined_stem, ty, data, mod, numgen)
if ty == "-" then
return
end
if not inflections[ty] then
error("Unknown inflection type '" .. ty .. "'")
end
local ar, tr = split_arabic_tr(combined_stem)
inflections[ty](ar, tr, data, mod, numgen)
end
-- Generate inflections for the stems of a given number/gender combination
-- and for either the base or the modifier. STEMTYPES is a stem-type list
-- (see do_gender_number()), listing all the stems and corresponding
-- declension types. MOD is either "", "mod_", "mod2_", etc. depending on
-- whether we're working on the base or a modifier. NUMGEN is the number or
-- number-gender combination we're working on, of the sort that forms part
-- of the keys in DATA.FORMS, e.g. "sg" or "m_sg".
function call_inflections(stemtypes, data, mod, numgen)
local mod_with_modnumgen = mod ~= "" and data[mod .. "numgen"]
-- If modN_numgen= is given, do nothing if NUMGEN isn't the same
if mod_with_modnumgen and data[mod .. "numgen"] ~= numgen then
return
end
-- always call inflection() if mod_with_modnumgen since it may affect
-- other numbers (cf. يَوْم الاِثْنَيْن)
if mod_with_modnumgen or contains(data.numbers, rsub(numgen, "^.*_", "")) then
for _, stemtype in ipairs(stemtypes) do
call_inflection(stemtype[1], stemtype[2], data, mod, numgen)
end
end
end
-- Generate the entire set of inflections for a noun or adjective.
-- Also handle any manually-specified part of speech and any manual
-- inflection overrides. The value of INFLECTIONS is an array of stem
-- specifications, one per number, where each element is a size-two
-- array of a stem specification (containing the set of stems and
-- corresponding declension types for the base and any modifiers;
-- see do_gender_number()) and a NUMGEN string, i.e. a string identifying
-- the number or number/gender in question (e.g. "sg", "du", "pl",
-- "m_sg", "f_pl", etc.).
function do_inflections_and_overrides(data, args, inflections)
-- do this before generating inflections so POS change is reflected in
-- categories
if args["pos"] then
data.pos = args["pos"]
end
for _, inflection in ipairs(inflections) do
call_inflections(inflection[1]["base"] or {}, data, "", inflection[2])
for _, mod in ipairs(mod_list) do
call_inflections(inflection[1][mod] or {}, data,
mod .. "_", inflection[2])
end
end
handle_lemma_and_overrides(data, args)
end
-- Helper function for get_heads(). Parses the stems for either the
-- base or the modifier (see do_gender_number()). ARG1 is the argument
-- for the first stem and ARGN is the prefix of the arguments for the
-- remaining stems. For example, for the singular base, ARG1=1 and
-- ARGN="head"; for the first singular modifier, ARG1="mod" and
-- ARGN="modhead"; for the plural base, ARG1=ARGN="pl". The arguments
-- other than the first are numbered 2, 3, ..., which is appended to
-- ARGN. MOD is either "", "mod_", "mod2_", etc. depending if we're
-- working on a base or modifier argument. The returned value is an
-- array of stems, where each element is a size-two array of
-- {COMBINED_STEM, STEM_TYPE}. See do_gender_number().
function get_heads_1(data, args, arg1, argn, mod)
if not args[arg1] then
return {}
end
local heads
if args[arg1] == "-" then
heads = {{"", "-"}}
else
heads = {}
insert_stems(args[arg1], heads, {{args[arg1], ""}}, false, "sg",
get_pos(data, mod))
end
local i = 2
while args[argn .. i] do
local arg = args[argn .. i]
insert_stems(arg, heads, {{arg, ""}}, false, "sg",
get_pos(data, mod))
i = i + 1
end
return heads
end
-- Very similar to do_gender_number(), and returns the same type of
-- structure, but works specifically for the stems of the head (the
-- most basic gender/number combiation, e.g. singular for nouns,
-- masculine singular for adjectives and gendered nouns, collective
-- for collective nouns, etc.), including both base and modifier.
-- See do_gender_number(). Note that the actual return value is
-- two items, the first of which is the same type of structure
-- returned by do_gender_number() and the second of which is a boolean
-- indicating whether we were called from within a template documentation
-- page (in which case no user-specified arguments exist and we
-- substitute sample ones). The reason for this boolean is to indicate
-- whether sample arguments need to be substituted for other numbers
-- as well.
function get_heads(data, args, headtype)
if not args[1] and mw.title.getCurrentTitle().nsText == "ထာမ်ပလိက်" then
return {base={{"{{{1}}}", "tri"}}}, true
end
if not args[1] then error("Parameter 1 (" .. headtype .. " stem) may not be empty.") end
local base = get_heads_1(data, args, 1, "head", "")
basemodtable = {base=base}
for _, mod in ipairs(mod_list) do
local modn = get_heads_1(data, args, mod, mod .. "head", mod .. "_")
basemodtable[mod] = modn
end
return basemodtable, false
end
-- The main entry point for noun tables.
function export.show_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local sgs, is_template = get_heads(data, args, "ကိုန်ဨကဝုစ်")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, sgs, nil, false, "pl")
-- always do dual so cases like يَوْم الاِثْنَيْن work -- a singular with
-- a dual modifier, where data.number refers only the singular
-- but we need to go ahead and compute the dual so it parses the
-- "modd" modifier dual argument. When the modifier dual argument
-- is parsed, it will store the resulting dual declension for اِثْنَيْن
-- in the modifier slot for all numbers, including specifically
-- the singular.
local dus = do_gender_number(data, args, {"d"}, sgs, "d", false, "du")
parse_state_etc_spec(data, args)
determine_noun_numbers(data, args, pls)
do_inflections_and_overrides(data, args,
{{sgs, "sg"}, {dus, "du"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
function any_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return true
end
end
end
end
return false
end
function all_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if not rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return false
end
end
end
end
return true
end
-- The main entry point for collective noun tables.
function export.show_coll_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.allnumbers = {"coll", "sing", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local colls, is_template = get_heads(data, args, "collective")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
parse_state_etc_spec(data, args)
-- If collective noun is already feminine in form, don't try to
-- form a feminine singulative
local collfem = any_feminine(data, colls)
local sings = do_gender_number(data, args, {"sing"}, colls,
not already_feminine and "f" or nil, true, "sg")
local singfem = all_feminine(data, sings)
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear,
-- and if singulative given, dual and paucal appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "coll")
end
if #sings["base"] > 0 then
table.insert(data.numbers, "sing")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the collective, singulative, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{colls, "coll"}, {sings, "sing"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The main entry point for singulative noun tables.
function export.show_sing_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.allnumbers = {"sing", "coll", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
parse_state_etc_spec(data, args)
local sings, is_template = get_heads(data, args, "singulative")
-- If all singulative nouns feminine in form, form a masculine collective
local singfem = all_feminine(data, sings)
local colls = do_gender_number(data, args, {"coll"}, sings,
singfem and "m" or nil, false, "sg")
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear;
-- if singulative given or derivable, it and dual and paucal will appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "sing")
end
if #colls["base"] > 0 then
table.insert(data.numbers, "coll")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the singulative, collective, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{sings, "sing"}, {colls, "coll"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The implementation of the main entry point for adjective and
-- gendered noun tables.
function show_gendered(frame, isadj, pos)
local args, origargs, data = init(frame:getParent().args)
data.pos = pos
data.numgens = function()
local numgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.numbers) do
table.insert(numgens, gender .. "_" .. number)
end
end
return numgens
end
data.allnumgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.allnumbers) do
table.insert(data.allnumgens, gender .. "_" .. number)
end
end
parse_state_etc_spec(data, args)
local msgs = get_heads(data, args, 'masculine singular')
-- Always do all of these so cases like يَوْم الاِثْنَيْن work.
-- See comment in show_noun().
local fsgs = do_gender_number(data, args, {"f"}, msgs, "f", true, "sg")
local mdus = do_gender_number(data, args, {"d"}, msgs, "d", false, "du")
local fdus = do_gender_number(data, args, {"fd"}, fsgs, "d", true, "du")
local mpls = do_gender_number(data, args, {"pl", "cpl"}, msgs,
isadj and "p" or nil, false, "pl")
local fpls = do_gender_number(data, args, {"fpl", "cpl"}, fsgs, "fp",
true, "pl")
if isadj then
parse_number_spec(data, args)
else
determine_noun_numbers(data, args, mpls)
end
-- Generate the singular, dual and plural forms
do_inflections_and_overrides(data, args,
{{msgs, "m_sg"}, {fsgs, "f_sg"}, {mdus, "m_du"}, {fdus, "f_du"},
{mpls, "m_pl"}, {fpls, "f_pl"}})
-- Make the table
if isadj then
return make_adj_table(data)
else
return make_gendered_noun_table(data)
end
end
-- The main entry point for gendered noun tables.
function export.show_gendered_noun(frame)
return show_gendered(frame, false, "နာမ်")
end
-- The main entry point for numeral tables. Same as using show_gendered_noun()
-- with pos=numeral.
function export.show_numeral(frame)
return show_gendered(frame, false, "ဂၞန်သၚ်္ချာ")
end
-- The main entry point for adjective tables.
function export.show_adj(frame)
return show_gendered(frame, true, "နာမဝိသေသန")
end
-- Inflection functions
function do_translit(term)
return (lang:transliterate(term)) or track("cant-translit") and BOGUS_CHAR
end
function split_arabic_tr(term)
if term == "" then
return "", ""
elseif not rfind(term, "/") then
return term, do_translit(term)
else
splitvals = rsplit(term, "/")
if #splitvals ~= 2 then
error("Must have at most one slash in a combined Arabic/translit expr: '" .. term .. "'")
end
return splitvals[1], splitvals[2]
end
end
function reorder_shadda(word)
-- shadda+short-vowel (including tanwīn vowels, i.e. -an -in -un) gets
-- replaced with short-vowel+shadda during NFC normalisation, which
-- MediaWiki does for all Unicode strings; however, it makes the
-- detection process inconvenient, so undo it.
word = rsub(word, "(" .. DIACRITIC_ANY_BUT_SH .. ")" .. SH, SH .. "%1")
return word
end
-- Combine PREFIX, AR/TR, and ENDING in that order. PREFIX and ENDING
-- can be of the form ARABIC/TRANSLIT. The Arabic and translit parts are
-- separated out and grouped together, resulting in a string of the
-- form ARABIC/TRANSLIT (TRANSLIT will always be present, computed
-- automatically if not present in the source). The return value is actually a
-- list of ARABIC/TRANSLIT strings because hamza resolution is applied to
-- ARABIC, which may produce multiple outcomes (all of which will have the
-- same TRANSLIT).
function combine_with_ending(prefix, ar, tr, ending)
local prefixar, prefixtr = split_arabic_tr(prefix)
local endingar, endingtr = split_arabic_tr(ending)
-- When calling hamza_seat(), leave out prefixes, which we expect to be
-- clitics like وَ. (In case the prefix is a separate word, it won't matter
-- whether we include it in the text passed to hamza_seat().)
allar = hamza_seat(ar .. endingar)
-- Convert ...īān to ...iyān in case of stems ending in -ī or -ū
-- (e.g. kubrī "bridge").
if rfind(endingtr, "^[aeiouāēīōū]") then
if rfind(tr, "ī$") then
tr = rsub(tr, "ī$", "iy")
elseif rfind(tr, "ū$") then
tr = rsub(tr, "ū$", "uw")
end
end
tr = prefixtr .. tr .. endingtr
allartr = {}
for _, arval in ipairs(allar) do
table.insert(allartr, prefixar .. arval .. "/" .. tr)
end
return allartr
end
-- Combine PREFIX, STEM/TR and ENDING in that order and insert into the
-- list of items in DATA[KEY], initializing it if empty and making sure
-- not to insert duplicates. ENDING can be a list of endings, will be
-- distributed over the remaining parts. PREFIX and/or ENDING can be
-- of the form ARABIC/TRANSLIT (the stem is already split into Arabic STEM
-- and Latin TR). Note that what's inserted into DATA[KEY] is actually a
-- list of ARABIC/TRANSLIT strings; if more than one is present in the list,
-- they represent hamza variants, i.e. different ways of writing a hamza
-- sound, such as مُبْتَدَؤُون vs. مُبْتَدَأُون (see init_data()).
function add_inflection(data, key, prefix, stem, tr, ending)
if data.forms[key] == nil then
data.forms[key] = {}
end
if type(ending) ~= "table" then
ending = {ending}
end
for _, endingval in ipairs(ending) do
insert_if_not(data.forms[key],
combine_with_ending(prefix, stem, tr, endingval))
end
end
-- Form inflections from combination of STEM, with transliteration TR,
-- and ENDINGS (and definite article where necessary, plus any specified
-- prefixes) and store in DATA, for the number or gender/number
-- determined by MOD ("", "mod_", "mod2_", etc.; see call_inflection()) and
-- NUMGEN ("sg", "du", "pl", or "m_sg", "f_pl", etc. for adjectives). ENDINGS
-- is an array of 15 values, each of which is a string or array of
-- alternatives. The order of ENDINGS is indefinite nom, acc, gen; definite
-- nom, acc, gen; construct-state nom, acc, gen; informal indefinite, definite,
-- construct; lemma indefinite, definite, construct. (Normally the lemma is
-- based off of the indefinite, but if the inflection has been restricted to
-- particular states, it comes from one of those states, in the order
-- indefinite, definite, construct.) See also add_inflection() for more info
-- on exactly what is inserted into DATA.
function add_inflections(stem, tr, data, mod, numgen, endings)
stem = canon_hamza(stem)
assert(#endings == 15)
local ismod = mod ~= ""
-- If working on modifier and modN_numgen= is given, it better agree with
-- NUMGEN; the case where it doesn't agree should have been caught in
-- call_inflections().
if ismod and data[mod .. "numgen"] then
assert(data[mod .. "numgen"] == numgen)
end
-- Return a list of combined of ar/tr forms, with the ending tacked on.
-- There may be more than one form because of alternative hamza seats that
-- may be supplied, e.g. مُبْتَدَؤُون or مُبْتَدَأُون (mubtadaʾūn "(grammatical) subjects").
local defstem, deftr
if stem == "?" or data[mod .. "omitarticle"] then
defstem = stem
deftr = tr
else
-- apply sun-letter assimilation and hamzat al-wasl elision
defstem = rsub("الْ" .. stem, "^الْ([سشصتثطدذضزژظنرل])", "ال%1ّ")
defstem = rsub(defstem, "^الْ([اٱ])([ًٌٍَُِ])", "ال%2%1")
deftr = rsub("al-" .. tr, "^al%-([sšṣtṯṭdḏḍzžẓnrḷ])", "a%1-%1")
end
-- For a given MOD spec, is the previous word (base or modifier) a noun?
-- We assume the base is always a noun in this case, and otherwise
-- look at the value of modN_idafa.
local function prev_mod_is_noun(mod)
if mod == "mod_" then
return true
end
if mod == "mod2_" then
return data["mod_idafa"]
end
modnum = assert_rsub(mod, "^mod([0-9]+)_$", "%1")
modnum = modnum - 1
return data["mod" .. modnum .. "_idafa"]
end
local numgens = ismod and data[mod .. "numgen"] and data.numgens() or {numgen}
-- "defcon" means definite adjective modifying construct state noun. We
-- add a ... before the adjective (and after the construct-state noun) to
-- indicate that a nominal modifier would go between noun and adjective.
local stems = {ind = stem, def = defstem, con = stem,
defcon = "... " .. defstem}
local trs = {ind = tr, def = deftr, con = tr, defcon = "... " .. deftr}
for _, ng in ipairs(numgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases_with_lemma) do
-- We are generating the inflections for STATE, but sometimes
-- we want to use the inflected form of a different state, e.g.
-- if modN_state= or basestate= is set to some particular state.
-- If we're dealing with an adjectival modifier, then in
-- place of "con" we use "defcon" if immediately after a noun
-- (see comment above), else "def".
local thestate = ismod and data[mod .. "state"] or
ismod and not data[mod .. "idafa"] and state == "con" and
(prev_mod_is_noun(mod) and "defcon" or "def") or
not ismod and data.basestate or
state
local is_lemmainf = case == "lemma" or case == "inf"
-- Don't substitute value of modcase for lemma/informal "cases"
local thecase = is_lemmainf and case or
ismod and data[mod .. "case"] or case
add_inflection(data, mod .. case .. "_" .. ng .. "_" .. state,
data[mod .. "prefix"] or "",
stems[thestate], trs[thestate],
endings[data.statecases[thestate][thecase]])
end
end
end
end
-- Insert into a category and a type variable (e.g. m_sg_type) for the
-- declension type of a particular declension (e.g. masculine singular for
-- adjectives). MOD and NUMGEN are as in call_inflection(). CATVALUE is the
-- category and ENGVALUE is the English description of the declension type.
-- In these values, NOUN is replaced with either "noun" or "adjective",
-- SINGULAR is replaced with the English equivalent of the number in NUMGEN
-- (e.g. "singular", "dual" or "plural") while BROKSING is the same but uses
-- "broken plural" in place of "plural" and "broken paucal" in place of
-- "paucal".
function insert_cat(data, mod, numgen, catvalue, engvalue)
local singpl = data.engnumbers[rsub(numgen, "^.*_", "")]
assert(singpl ~= nil)
local broksingpl = rsub(singpl, "plural", "broken plural")
broksingpl = rsub(broksingpl, "paucal", "broken paucal")
if rfind(broksingpl, "broken plural") and (rfind(catvalue, "BROKSING") or
rfind(engvalue, "BROKSING")) then
-- table.insert(data.categories, "Arabic " .. data.pos .. "s with broken plural")
end
if rfind(catvalue, "irregular") or rfind(engvalue, "irregular") then
-- table.insert(data.categories, "Arabic irregular " .. data.pos .. "s")
end
catvalue = rsub(catvalue, "NOUN", data.pos)
catvalue = rsub(catvalue, "SINGULAR", singpl)
catvalue = rsub(catvalue, "BROKSING", broksingpl)
engvalue = rsub(engvalue, "NOUN", data.pos)
engvalue = rsub(engvalue, "SINGULAR", singpl)
engvalue = rsub(engvalue, "BROKSING", broksingpl)
-- add links to specialised grammatical terms
engvalue = rsub(engvalue, "triptote", "[[triptote]]")
engvalue = rsub(engvalue, "diptote", "[[diptote]]")
engvalue = rsub(engvalue, "broken plural", "BBB")
engvalue = rsub(engvalue, "sound plural", "SSS")
engvalue = rsub(engvalue, "broken", "[[broken plural|broken]]")
engvalue = rsub(engvalue, "sound", "[[sound plural|sound]]")
engvalue = rsub(engvalue, "BBB", "[[broken plural]]")
engvalue = rsub(engvalue, "SSS", "[[sound plural]]")
if mod == "" and catvalue ~= "" then
insert_if_not(data.categories, catvalue)
end
if engvalue ~= "" then
local key = mod .. numgen .. "_type"
if data.forms[key] == nil then
data.forms[key] = {}
end
insert_if_not(data.forms[key], engvalue)
end
if contains(data.states, "def") and not contains(data.states, "ind") then
-- insert_if_not(data.categories, "Arabic definite " .. data.pos .. "s")
end
end
-- Return true if we're handling modifier inflections and the modifier's
-- case is limited to an oblique case (gen or acc; typically genitive,
-- in an ʾidāfa construction). This is used when returning lemma
-- inflections -- the modifier part of the lemma should agree in case
-- with modifier's case if it's restricted in case.
function mod_oblique(mod, data)
return mod ~= "" and data[mod .. "case"] and (
data[mod .. "case"] == "acc" or data[mod .. "case"] == "gen")
end
-- Similar to mod_oblique but specifically when the modifier case is
-- limited to the accusative (which is rare or nonexistent in practice).
function mod_acc(mod, data)
return mod ~= "" and data[mod .. "case"] and data[mod .. "case"] == "acc"
end
-- Handle triptote and diptote inflections
function triptote_diptote(stem, tr, data, mod, numgen, is_dip, lc)
-- Remove any case ending
if rfind(stem, "[" .. UN .. U .. "]$") then
stem = rsub(stem, "[" .. UN .. U .. "]$", "")
tr = rsub(tr, "un?$", "")
end
-- special-case for صلوة pronounced ṣalāh; check translit
local is_aah = rfind(stem, TAM .. "$") and rfind(tr, "āh$")
if rfind(stem, TAM .. "$") then
if rfind(tr, "h$") then
tr = rsub(tr, "h$", "t")
elseif not rfind(tr, "t$") then
tr = tr .. "t"
end
end
add_inflections(stem, tr, data, mod, numgen,
{is_dip and U or UN,
is_dip and A or AN .. ((rfind(stem, "[" .. HAMZA_ON_ALIF .. TAM .. "]$")
or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. HAMZA .. "$")
) and "" or ALIF),
is_dip and A or IN,
U, A, I,
lc and UU or U,
lc and AA or A,
lc and II or I,
{}, {}, {}, -- omit informal inflections
{}, {}, {}, -- omit lemma inflections
})
-- add category and informal and lemma inflections
local tote = lc and "long construct" or is_dip and "diptote" or "triptote"
local singpl_tote = "BROKSING " .. tote
local cat_prefix = "Arabic NOUNs with " .. tote .. " BROKSING"
-- since we're checking translit for -āh we probably don't need to
-- check stem too
if is_aah or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"/t", "/t", "/t", -- informal pron. is -āt
"/h", "/h", "/t", -- lemma uses -āh
})
insert_cat(data, mod, numgen, cat_prefix .. " in -āh",
singpl_tote .. " in " .. make_link(HYPHEN .. AAH))
elseif rfind(stem, TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "/t",
"", "", "/t",
})
insert_cat(data, mod, numgen, cat_prefix .. " in -a",
singpl_tote .. " in " .. make_link(HYPHEN .. AH))
elseif lc then
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", UU,
"", "", UU,
})
insert_cat(data, mod, numgen, cat_prefix,
singpl_tote)
else
-- also special-case the nisba ending, which has an informal
-- pronunciation.
if rfind(stem, IY .. SH .. "$") then
local infstem = rsub(stem, SH .. "$", "")
local inftr = rsub(tr, "iyy$", "ī")
-- add informal and lemma inflections separately
add_inflections(infstem, inftr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
{}, {}, {},
})
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
})
else
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
"", "", "",
})
end
insert_cat(data, mod, numgen, "Arabic NOUNs with basic " .. tote .. " BROKSING",
"basic " .. singpl_tote)
end
end
-- Regular triptote
inflections["tri"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false)
end
-- Regular diptote
inflections["di"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, true)
end
-- Elative and color/defect adjective: usually same as diptote,
-- might be invariable
function elative_color_defect(stem, tr, data, mod, numgen)
if rfind(stem, "[" .. ALIF .. AMAQ .. "]$") then
invariable(stem, tr, data, mod, numgen)
else
triptote_diptote(stem, tr, data, mod, numgen, true)
end
end
-- Elative: usually same as diptote, might be invariable
inflections["el"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Color/defect adjective: Same as elative
inflections["cd"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Triptote with lengthened ending in the construct state
inflections["lc"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false, true)
end
function in_defective(stem, tr, data, mod, numgen, tri)
if not rfind(stem, IN .. "$") then
error("'in' declension stem should end in -in: '" .. stem .. "'")
end
stem = rsub(stem, IN .. "$", "")
tr = rsub(tr, "in$", "")
local acc_ind_ending = tri and IY .. AN .. ALIF or IY .. A
add_inflections(stem, tr, data, mod, numgen,
{IN, acc_ind_ending, IN,
II, IY .. A, II,
II, IY .. A, II,
II, II, II,
-- FIXME: What should happen with the lemma when modifier case
-- is limited to the accusative and modifier state is e.g. definite?
-- Should the lemma end in -iya or -ī? In practice this will rarely
-- if ever happen.
mod_acc(mod, data) and acc_ind_ending or IN, II, II,
})
local tote = tri and "triptote" or "diptote"
insert_cat(data, mod, numgen, "Arabic NOUNs with " .. tote .. " BROKSING in -in",
"BROKSING " .. tote .. " in " .. make_link(HYPHEN .. IN))
end
function detect_in_type(stem, ispl)
if ispl and rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IN .. "$") then -- layālin
return "diin"
else -- other -in words
return "triin"
end
end
-- Defective in -in
inflections["in"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen,
detect_in_type(stem, rfind(numgen, "pl")) == "triin")
end
-- Defective in -in, force "triptote" variant
inflections["triin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, true)
end
-- Defective in -in, force "diptote" variant
inflections["diin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, false)
end
-- Defective in -an (comes in two variants, depending on spelling with tall alif or alif maqṣūra)
inflections["an"] = function(stem, tr, data, mod, numgen)
local tall_alif
if rfind(stem, AN .. ALIF .. "$") then
tall_alif = true
stem = rsub(stem, AN .. ALIF .. "$", "")
elseif rfind(stem, AN .. AMAQ .. "$") then
tall_alif = false
stem = rsub(stem, AN .. AMAQ .. "$", "")
else
error("Invalid stem for 'an' declension type: " .. stem)
end
tr = rsub(tr, "an$", "")
if tall_alif then
add_inflections(stem, tr, data, mod, numgen,
{AN .. ALIF, AN .. ALIF, AN .. ALIF,
AA, AA, AA,
AA, AA, AA,
AA, AA, AA,
AN .. ALIF, AA, AA,
})
else
add_inflections(stem, tr, data, mod, numgen,
{AN .. AMAQ, AN .. AMAQ, AN .. AMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AN .. AMAQ, AAMAQ, AAMAQ,
})
end
-- FIXME: Should we distinguish between tall alif and alif maqṣūra?
insert_cat(data, mod, numgen, "Arabic NOUNs with BROKSING in -an",
"BROKSING in " .. make_link(HYPHEN .. AN .. (tall_alif and ALIF or AMAQ)))
end
function invariable(stem, tr, data, mod, numgen)
add_inflections(stem, tr, data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
insert_cat(data, mod, numgen, "Arabic NOUNs with invariable BROKSING",
"BROKSING invariable")
end
-- Invariable in -ā (non-loanword type)
inflections["inv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Invariable in -ā (loanword type, behaving in the dual as if ending in -a, I think!)
inflections["lwinv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Duals
inflections["d"] = function(stem, tr, data, mod, numgen)
if rfind(stem, ALIF .. NI .. "?$") then
stem = rsub(stem, AOPTA .. NI .. "?$", "")
elseif rfind(stem, AMAD .. NI .. "?$") then
stem = rsub(stem, AMAD .. NI .. "?$", HAMZA_PH)
else
error("Dual stem should end in -ān(i): '" .. stem .. "'")
end
tr = rsub(tr, "āni?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AANI, AYNI, AYNI,
AANI, AYNI, AYNI,
AA, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AAN, mo and AYN or AAN, mo and AYSK or AA,
})
-- insert_cat(data, mod, numgen, "", "dual in " .. make_link(HYPHEN .. AANI))
end
-- Sound masculine plural
inflections["smp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, UUNA .. "?$") then
error("Sound masculine plural stem should end in -ūn(a): '" .. stem .. "'")
end
stem = rsub(stem, UUNA .. "?$", "")
tr = rsub(tr, "ūna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{UUNA, IINA, IINA,
UUNA, IINA, IINA,
UU, II, II,
IIN, IIN, II,
mo and IIN or UUN, mo and IIN or UUN, mo and II or UU,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
-- insert_cat(data, mod, numgen, "Arabic NOUNs with sound masculine SINGULAR",
-- "sound masculine SINGULAR")
end
-- Sound feminine plural
inflections["sfp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, "[" .. ALIF .. AMAD .. "]" .. T .. UN .. "?$") then
error("Sound feminine plural stem should end in -āt(un): '" .. stem .. "'")
end
stem = rsub(stem, UN .. "$", "")
tr = rsub(tr, "un$", "")
add_inflections(stem, tr, data, mod, numgen,
{UN, IN, IN,
U, I, I,
U, I, I,
"", "", "",
"", "", "",
})
-- use SINGULAR because this might be used with the paucal
-- instead of plural
-- insert_cat(data, mod, numgen, "Arabic NOUNs with sound feminine SINGULAR",
-- "sound feminine SINGULAR")
end
-- Plural of defective in -an
inflections["awnp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, AWNA .. "?$") then
error("'awnp' plural stem should end in -awn(a): '" .. stem .. "'")
end
stem = rsub(stem, AWNA .. "?$", "")
tr = rsub(tr, "awna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AWNA, AYNA, AYNA,
AWNA, AYNA, AYNA,
AWSK, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AWN, mo and AYN or AWN, mo and AYSK or AWSK,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
--insert_cat(data, mod, numgen, "Arabic NOUNs with sound SINGULAR in -awna",
-- "sound SINGULAR in " .. make_link(HYPHEN .. AWNA))
end
-- Unknown
inflections["?"] = function(stem, tr, data, mod, numgen)
add_inflections("?", "?", data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
-- insert_cat(data, mod, numgen, "Arabic NOUNs with unknown SINGULAR",
-- "SINGULAR unknown")
end
-- Detect declension of noun or adjective stem or lemma. We allow triptotes,
-- diptotes and sound plurals to either come with ʾiʿrāb or not. We detect
-- some cases where vowels are missing, when it seems fairly unambiguous to
-- do so. ISFEM is true if we are dealing with a feminine stem (not
-- currently used and needs to be rethought). NUM is "sg", "du", or "pl",
-- depending on the number of the stem.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
--
-- Some unexpectedly diptote nouns/adjectives:
--
-- jiʿrān in ʾabū jiʿrān "dung beetle"
-- distributive numbers: ṯunāʾ "two at a time", ṯulāṯ/maṯlaṯ "three at a time",
-- rubāʿ "four at a time" (not a regular diptote pattern, cf. triptote
-- junāḥ "misdemeanor, sin", nujār "origin, root", nuḥām "flamingo")
-- jahannam (f.) "hell"
-- many names: jilliq/jillaq "Damascus", judda/jidda "Jedda", jibrīl (and
-- variants) "Gabriel", makka "Mecca", etc.
-- jibriyāʾ "pride"
-- kibriyāʾ "glory, pride"
-- babbaḡāʾ "parrot"
-- ʿayāyāʾ "incapable, tired"
-- suwaidāʾ "black bile, melancholy"
-- Note also: ʾajhar "day-blind" (color-defect) and ʾajhar "louder" (elative)
function export.detect_type(stem, isfem, num, pos)
local function dotrack(word)
track(word)
track(word .. "/" .. pos)
return true
end
-- Not strictly necessary because the caller (stem_and_type) already
-- reorders, but won't hurt, and may be necessary if this function is
-- called from an external caller.
stem = reorder_shadda(stem)
local origstem = stem
-- So that we don't get tripped up by alif madda, we replace alif madda
-- with the sequence hamza + fatḥa + alif before the regexps below.
stem = rsub(stem, AMAD, HAMZA .. AA)
if num == "du" then
if rfind(stem, ALIF .. NI .. "?$") then
return "d"
else
error("Malformed stem for dual, should end in the nominative dual ending -ān(i): '" .. origstem .. "'")
end
end
if rfind(stem, IN .. "$") then -- -in words
return detect_in_type(stem, num == "pl")
elseif rfind(stem, AN .. "[" .. ALIF .. AMAQ .. "]$") then
return "an"
elseif rfind(stem, AN .. "$") then
error("Malformed stem, fatḥatan should be over second-to-last letter: " .. origstem)
elseif num == "pl" and rfind(stem, AW .. SKOPT .. N .. AOPT .. "$") then
return "awnp"
elseif num == "pl" and rfind(stem, ALIF .. T .. UNOPT .. "$") and
-- Avoid getting tripped up by plurals like ʾawqāt "times",
-- ʾaḥwāt "fishes", ʾabyāt "verses", ʾazyāt "oils", ʾaṣwāt "voices",
-- ʾamwāt "dead (pl.)".
not rfind(stem, HAMZA_ON_ALIF .. A .. CONS .. SK .. CONS .. AAT .. UNOPT .. "$") then
return "sfp"
elseif num == "pl" and rfind(stem, W .. N .. AOPT .. "$") and
-- Avoid getting tripped up by plurals like ʿuyūn "eyes",
-- qurūn "horns" (note we check for U between first two consonants
-- so we correctly ignore cases like sinūn "hours" (from sana),
-- riʾūn "lungs" (from riʾa) and banūn "sons" (from ibn).
not rfind(stem, "^" .. CONS .. U .. CONS .. UUN .. AOPT .. "$") then
return "smp"
elseif rfind(stem, UN .. "$") then -- explicitly specified triptotes (we catch sound feminine plurals above)
return "tri"
elseif rfind(stem, U .. "$") then -- explicitly specified diptotes
return "di"
elseif -- num == "pl" and
( -- various diptote plural patterns; these are diptote even in the singular (e.g. yanāyir "January", falāfil "falafel", tuʾabāʾ "yawn, fatigue"
-- currently we sometimes end up with such plural patterns in the "singular" in a singular
-- ʾidāfa construction with plural modifier. (FIXME: These should be fixed to the correct number.)
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IOPT .. Y .. "?" .. CONS .. "$") and dotrack("fawaakih") or -- fawākih, daqāʾiq, makātib, mafātīḥ
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. SH .. "$")
and not rfind(stem, "^" .. T) and dotrack("mawaadd") or -- mawādd, maqāmm, ḍawāll; exclude t- so we don't catch form-VI verbal nouns like taḍādd (HACK!!!)
rfind(stem, "^" .. CONS .. U .. CONS .. AOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("wuzaraa") or -- wuzarāʾ "ministers", juhalāʾ "ignorant (pl.)"
rfind(stem, ELCD_START .. SKOPT .. CONS .. IOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("asdiqaa") or -- ʾaṣdiqāʾ
rfind(stem, ELCD_START .. IOPT .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("aqillaa") -- ʾaqillāʾ, ʾajillāʾ "important (pl.)", ʾaḥibbāʾ "lovers"
) then
return "di"
elseif num == "sg" and ( -- diptote singular patterns (nouns/adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("qamraa") or -- qamrāʾ "moon-white, moonlight"; baydāʾ "desert"; ṣaḥrāʾ "desert-like, desert"; tayhāʾ "trackless, desolate region"; not pl. to avoid catching e.g. ʾabnāʾ "sons", ʾaḥmāʾ "fathers-in-law", ʾamlāʾ "steppes, deserts" (pl. of malan), ʾanbāʾ "reports" (pl. of nabaʾ)
rfind(stem, ELCD_START .. SK .. CONS .. A .. CONS .. "$") and dotrack("abyad") or -- ʾabyaḍ "white", ʾakbar "greater"; FIXME nouns like ʾaʿzab "bachelor", ʾaḥmad "Ahmed" but not ʾarnab "rabbit", ʾanjar "anchor", ʾabjad "abjad", ʾarbaʿ "four", ʾandar "threshing floor" (cf. diptote ʾandar "rarer")
rfind(stem, ELCD_START .. A .. CONS .. SH .. "$") and dotrack("alaff") or -- ʾalaff "plump", ʾaḥabb "more desirable"
-- do the following on the origstem so we can check specifically for alif madda
rfind(origstem, "^" .. AMAD .. CONS .. A .. CONS .. "$") and dotrack("aalam") -- ʾālam "more painful", ʾāḵar "other"
) then
return "di"
elseif num == "sg" and pos == "adjective" and ( -- diptote singular patterns (adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. "$") and dotrack("kaslaan") or -- kaslān "lazy", ʿaṭšān "thirsty", jawʿān "hungry", ḡaḍbān "angry", tayhān "wandering, perplexed"; but not nouns like qaṭrān "tar", šayṭān "devil", mawtān "plague", maydān "square"
-- rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. "$") and dotrack("laffaa") -- excluded because of too many false positives e.g. ḵawwān "disloyal", not to mention nouns like jannān "gardener"; only diptote example I can find is ʿayyān "incapable, weary" (diptote per Lane but not Wehr)
rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("laffaa") -- laffāʾ "plump (fem.)"; but not nouns like jarrāʾ "runner", ḥaddāʾ "camel driver", lawwāʾ "wryneck"
) then
return "di"
elseif rfind(stem, AMAQ .. "$") then -- kaslā, ḏikrā (spelled with alif maqṣūra)
return "inv"
elseif rfind(stem, "[" .. ALIF .. SK .. "]" .. Y .. AOPTA .. "$") then -- dunyā, hadāyā (spelled with tall alif after yāʾ)
return "inv"
elseif rfind(stem, ALIF .. "$") then -- kāmērā, lībiyā (spelled with tall alif; we catch dunyā and hadāyā above)
return "lwinv"
elseif rfind(stem, II .. "$") then -- cases like كُوبْرِي kubrī "bridge" and صَوَانِي ṣawānī pl. of ṣīniyya; modern words that would probably end with -in
dotrack("ii")
return "inv"
elseif rfind(stem, UU .. "$") then -- FIXME: Does this occur? Check the tracking
dotrack("uu")
return "inv"
else
return "tri"
end
end
-- Replace hamza (of any sort) at the end of a word, possibly followed by
-- a nominative case ending or -in or -an, with HAMZA_PH, and replace alif
-- madda at the end of a word with HAMZA_PH plus fatḥa + alif. To undo these
-- changes, use hamza_seat().
function canon_hamza(word)
word = rsub(word, AMAD .. "$", HAMZA_PH .. AA)
word = rsub(word, HAMZA_ANY .. "([" .. UN .. U .. IN .. "]?)$", HAMZA_PH .. "%1")
word = rsub(word, HAMZA_ANY .. "(" .. AN .. "[" .. ALIF .. AMAQ .. "])$", HAMZA_PH .. "%1")
return word
end
-- Supply the appropriate hamza seat(s) for a placeholder hamza.
function hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
return ar_utilities.process_hamza(word)
end
return {word}
end
--[[
-- Supply the appropriate hamza seat for a placeholder hamza in a combined
-- Arabic/translation expression.
function split_and_hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
local ar, tr = split_arabic_tr(word)
-- FIXME: Do something with all values returned
ar = ar_utilities.process_hamza(ar)[1]
return ar .. "/" .. tr
end
return word
end
--]]
-- Return stem and type of an argument given the singular stem and whether
-- this is a plural argument. WORD may be of the form ARABIC, ARABIC/TR,
-- ARABIC:TYPE, ARABIC/TR:TYPE, or TYPE, for Arabic stem ARABIC with
-- transliteration TR and of type (i.e. declension) TYPE. If the type
-- is omitted, it is auto-detected using detect_type(). If the transliteration
-- is omitted, it is auto-transliterated from the Arabic. If only the type
-- is present, it is a sound plural type ("sf", "sm" or "awn"),
-- in which case the stem and translit are generated from the singular by
-- regular rules. SG may be of the form ARABIC/TR or ARABIC. ISFEM is true
-- if WORD is a feminine stem. NUM is either "sg", "du" or "pl" according to
-- the number of the stem. The return value will be in the ARABIC/TR format.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
function export.stem_and_type(word, sg, sgtype, isfem, num, pos)
local rettype = nil
if rfind(word, ":") then
local split = rsplit(word, ":")
if #split > 2 then
error("More than one colon found in argument: '" .. word .. "'")
end
word, rettype = split[1], split[2]
end
local ar, tr = split_arabic_tr(word)
-- Need to reorder shaddas here so that shadda at the end of a stem
-- followed by ʾiʿrāb or a plural ending or whatever can get processed
-- correctly. This processing happens in various places so make sure
-- we return the reordered Arabic in all circumstances.
ar = reorder_shadda(ar)
local artr = ar .. "/" .. tr
-- Now return split-out ARABIC/TR and TYPE, with shaddas reordered in
-- the Arabic.
if rettype then
return artr, rettype
end
-- Likewise, do shadda reordering for the singular.
local sgar, sgtr = split_arabic_tr(sg)
sgar = reorder_shadda(sgar)
-- Apply a substitution to the singular Arabic and translit. If a
-- substitution could be made, return the combined ARABIC/TR with
-- substitutions made; else, return nil. The Arabic has ARFROM
-- replaced with ARTO, while the translit has TRFROM replaced with
-- TRTO, and if that doesn't match, replace TRFROM2 with TRTO2.
local function sub(arfrom, arto, trfrom, trto, trfrom2, trto2, trfrom3, trto3)
if rfind(sgar, arfrom) then
local arret = rsub(sgar, arfrom, arto)
local trret = sgtr
if rfind(sgtr, trfrom) then
trret = rsub(sgtr, trfrom, trto)
elseif trfrom2 and rfind(sgtr, trfrom2) then
trret = rsub(sgtr, trfrom2, trto2)
elseif trfrom3 and rfind(sgtr, trfrom3) then
trret = rsub(sgtr, trfrom3, trto3)
elseif not rfind(sgtr, BOGUS_CHAR) then
error("Transliteration '" .. sgtr .."' does not have same ending as Arabic '" .. sgar .. "'")
end
return arret .. "/" .. trret
else
return nil
end
end
if (num ~= "sg" or not isfem) and (word == "elf" or word == "cdf" or word == "intf" or word == "rf" or word == "f") then
error("Inference of form for inflection type '" .. word .. "' only allowed in singular feminine")
end
if num ~= "du" and word == "d" then
error("Inference of form for inflection type '" .. word .. "' only allowed in dual")
end
if num ~= "pl" and (word == "sfp" or word == "smp" or word == "awnp" or word == "cdp" or word == "sp" or word == "fp" or word == "p") then
error("Inference of form for inflection type '" .. word .. "' only allowed in plural")
end
local function is_intensive_adj(ar)
return rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SK .. AMAD .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. UOPT .. "$")
end
local function is_feminine_cd_adj(ar)
return pos == "adjective" and
(rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. UOPT .. "$") or -- ʾḥamrāʾ/ʿamyāʾ/bayḍāʾ
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. UOPT .. "$") -- laffāʾ
)
end
local function is_elcd_adj(ar)
return rfind(ar, ELCD_START .. SK .. CONS .. A .. CONS .. UOPT .. "$") or -- ʾabyaḍ "white", ʾakbar "greater"
rfind(ar, ELCD_START .. A .. CONS .. SH .. UOPT .. "$") or -- ʾalaff "plump", ʾaqall "fewer"
rfind(ar, ELCD_START .. SK .. CONS .. AAMAQ .. "$") or -- ʾaʿmā "blind", ʾadnā "lower"
rfind(ar, "^" .. AMAD .. CONS .. A .. CONS .. UOPT .. "$") -- ʾālam "more painful", ʾāḵar "other"
end
if word == "?" or
(rfind(word, "^[a-z][a-z]*$") and sgtype == "?") then
--if 'word' is a type, actual value inferred from sg; if sgtype is ?,
--propagate it to all derived types
return "", "?"
end
if word == "intf" then
if not is_intensive_adj(sgar) then
error("Singular stem not in CACCān form: " .. sgar)
end
local ret = (
sub(AMAD .. N .. UOPT .. "$", AMAD, "nu?$", "") or -- ends in -ʾān
sub(AOPTA .. N .. UOPT .. "$", AMAQ, "nu?$", "") -- ends in -ān
)
return ret, "inv"
end
if word == "elf" then
local ret = (
sub(ELCD_START .. SK .. "[" .. Y .. W .. "]" .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2" .. AMAQ, "ʔa(.)[yw]a(.)u?", "%1ū%2ā") or -- ʾajyad
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3" .. AMAQ, "ʔa(.)(.)a(.)u?", "%1u%2%3ā") or -- ʾakbar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH .. AMAQ, "ʔa(.)a(.)%2u?", "%1u%2%2ā") or -- ʾaqall
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. SK .. Y .. ALIF, "ʔa(.)(.)ā", "%1u%2yā") or -- ʾadnā
sub("^" .. AMAD .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
HAMZA_ON_ALIF .. U .. "%1" .. SK .. "%2" .. AMAQ, "ʔā(.)a(.)u?", "ʔu%1%2ā") -- ʾālam "more painful", ʾāḵar "other"
)
if not ret then
error("Singular stem not an elative adjective: " .. sgar)
end
return ret, "inv"
end
if word == "cdf" then
local ret = (
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. A .. "%2" .. SK .. "%3" .. AA .. HAMZA, "ʔa(.)(.)a(.)u?", "%1a%2%3āʔ") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. A .. "%2" .. SH .. AA .. HAMZA, "ʔa(.)a(.)%2u?", "%1a%2%2āʔ") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. A .. "%2" .. SK .. Y .. AA .. HAMZA, "ʔa(.)(.)ā", "%1a%2yāʔ") -- ʾaʿmā
)
if not ret then
error("Singular stem not a color/defect adjective: " .. sgar)
end
return ret, "cd" -- so plural will be correct
end
-- Regular feminine -- add ة, possibly with stem modifications
if word == "rf" then
sgar = canon_hamza(sgar)
if rfind(sgar, TAM .. UNUOPT .. "$") then
--Don't do this or we have problems when forming singulative from
--collective with a construct modifier that's feminine
--error("Singular stem is already feminine: " .. sgar)
return sgar .. "/" .. sgtr, "tri"
end
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AAH, "an$", "āh") or -- ends in -an
sub(IN .. "$", IY .. AH, "in$", "iya") or -- ends in -in
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AAH, "ā$", "āh") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AH, "un?$", "a", "$", "a") or -- anything else + -u(n)
sub("$", AH, "$", "a") -- anything else
)
return ret, "tri"
end
if word == "f" then
if sgtype == "cd" then
return export.stem_and_type("cdf", sg, sgtype, true, "sg", pos)
elseif sgtype == "el" then
return export.stem_and_type("elf", sg, sgtype, true, "sg", pos)
elseif sgtype =="di" and is_intensive_adj(sgar) then
return export.stem_and_type("intf", sg, sgtype, true, "sg", pos)
elseif sgtype == "di" and is_elcd_adj(sgar) then
-- If form is elative or color-defect, we don't know which of
-- the two it is, and each has a special feminine which isn't
-- the regular "just add ة", so shunt to unknown. This will
-- ensure that ?'s appear in place of the inflection -- also
-- for dual and plural.
return export.stem_and_type("?", sg, sgtype, true, "sg", pos)
else
return export.stem_and_type("rf", sg, sgtype, true, "sg", pos)
end
end
if word == "rm" then
sgar = canon_hamza(sgar)
--Don't do this or we have problems when forming collective from
--singulative with a construct modifier that's not feminine,
--e.g. شَجَرَة التُفَّاح
--if not rfind(sgar, TAM .. UNUOPT .. "$") then
-- error("Singular stem is not feminine: " .. sgar)
--end
local ret = (
sub(AAH .. UNUOPT .. "$", AN .. AMAQ, "ātun?$", "an", "ā[ht]$", "an") or -- in -āh
sub(IY .. AH .. UNUOPT .. "$", IN, "iyatun?$", "in", "iya$", "in") or -- ends in -iya
sub(AOPT .. TAM .. UNUOPT .. "$", "", "atun?$", "", "a$", "") or --ends in -a
sub("$", "", "$", "") -- do nothing
)
return ret, "tri"
end
if word == "m" then
-- FIXME: handle cd (color-defect)
-- FIXME: handle el (elative)
-- FIXME: handle int (intensive)
return export.stem_and_type("rm", sg, sgtype, false, "sg", pos)
end
-- The plural used for feminine adjectives. If the singular type is
-- color/defect or it looks like a feminine color/defect adjective,
-- use color/defect plural. Otherwise shunt to sound feminine plural.
if word == "fp" then
if sgtype == "cd" or is_feminine_cd_adj(sgar) then
return export.stem_and_type("cdp", sg, sgtype, true, "pl", pos)
else
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
end
end
if word == "sp" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
elseif isfem then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif sgtype == "an" then
return export.stem_and_type("awnp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
end
end
-- Conservative plural, as used for masculine plural adjectives.
-- If singular type is color-defect, shunt to color-defect plural; else
-- shunt to unknown, so ? appears in place of the inflections.
if word == "p" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
else
return export.stem_and_type("?", sg, sgtype, isfem, "pl", pos)
end
end
-- Special plural used for paucal plurals of singulatives. If ends in -ة
-- (most common), use strong feminine plural; if ends with -iyy (next
-- most common), use strong masculine plural; ends default to "p"
-- (conservative plural).
if word == "paucp" then
if rfind(sgar, TAM .. UNUOPT .. "$") then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif rfind(sgar, IY .. SH .. UNUOPT .. "$") then
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("p", sg, sgtype, isfem, "pl", pos)
end
end
if word == "d" then
sgar = canon_hamza(sgar)
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "an$", "ayān") or -- ends in -an
sub(IN .. "$", IY .. AAN, "in$", "iyān") or -- ends in -in
sgtype == "lwinv" and sub(AOPTA .. "$", AT .. AAN, "[āa]$", "atān") or -- lwinv, ends in alif; allow translit with short -a
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "ā$", "ayān") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
--
-- NOTE: Collapsing the "h$" and "$" cases into "h?$" doesn't work
-- in the case of words ending in -āh, which end up having the
-- translit end in -tāntān.
sub(TAM .. UNU .. "$", T .. AAN, "[ht]un?$", "tān", "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa + -u(n)
sub(TAM .. "$", T .. AAN, "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa
-- Same here as above
sub(UNU .. "$", AAN, "un?$", "ān", "$", "ān") or -- anything else + -u(n)
sub("$", AAN, "$", "ān") -- anything else
)
return ret, "d"
end
-- Strong feminine plural in -āt, possibly with stem modifications
if word == "sfp" then
sgar = canon_hamza(sgar)
sgar = rsub(sgar, AMAD .. "(" .. TAM .. UNUOPT .. ")$", HAMZA_PH .. AA .. "%1")
sgar = rsub(sgar, HAMZA_ANY .. "(" .. AOPT .. TAM .. UNUOPT .. ")$", HAMZA_PH .. "%1")
local ret = (
sub(AOPTA .. TAM .. UNUOPT .. "$", AYAAT, "ā[ht]$", "ayāt", "ātun?$", "ayāt") or -- ends in -āh
sub(AOPT .. TAM .. UNUOPT .. "$", AAT, "a$", "āt", "atun?$", "āt") or -- ends in -a
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "an$", "ayāt") or -- ends in -an
sub(IN .. "$", IY .. AAT, "in$", "iyāt") or -- ends in -in
sgtype == "inv" and (
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "ā$", "ayāt") -- ends in alif or alif maqṣūra
) or
sgtype == "lwinv" and (
sub(AOPTA .. "$", AAT, "[āa]$", "āt") -- loanword ending in tall alif; allow translit with short -a
) or
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AAT, "un?$", "āt", "$", "āt") or -- anything else + -u(n)
sub("$", AAT, "$", "āt") -- anything else
)
return ret, "sfp"
end
if word == "smp" then
sgar = canon_hamza(sgar)
local ret = (
sub(IN .. "$", UUN, "in$", "ūn") or -- ends in -in
-- See comments above for why we have two cases, one for UNU and
-- one for non-UNU
sub(UNU .. "$", UUN, "un?$", "ūn", "$", "ūn") or -- anything else + -u(n)
sub("$", UUN, "$", "ūn") -- anything else
)
return ret, "smp"
end
-- Color/defect plural; singular must be masculine or feminine
-- color/defect adjective
if word == "cdp" then
local ret = (
sub(ELCD_START .. SK .. W .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2", "ʔa(.)wa(.)u?", "%1ū%2") or -- ʾaswad
sub(ELCD_START .. SK .. Y .. A .. CONSPAR .. UOPT .. "$",
"%1" .. II .. "%2", "ʔa(.)ya(.)u?", "%1ī%2") or -- ʾabyaḍ
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3", "ʔa(.)(.)a(.)u?", "%1u%2%3") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH, "ʔa(.)a(.)%2u?", "%1u%2%2") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. Y, "ʔa(.)(.)ā", "%1u%2y") or -- ʾaʿmā
sub("^" .. CONSPAR .. A .. W .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. UU .. "%2", "(.)aw(.)āʔu?", "%1ū%2") or -- sawdāʾ
sub("^" .. CONSPAR .. A .. Y .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. II .. "%2", "(.)ay(.)āʔu?", "%1ī%2") or -- bayḍāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SK .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SK .. "%3", "(.)a(.)(.)āʔu?", "%1u%2%3") or -- ʾḥamrāʾ/ʿamyāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SH .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SH, "(.)a(.)%2āʔu?", "%1u%2%2") -- laffāʾ
)
if not ret then
error("For 'cdp', singular must be masculine or feminine color/defect adjective: " .. sgar)
end
return ret, "tri"
end
if word == "awnp" then
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AWSK .. N, "an$", "awn") -- ends in -an
)
if not ret then
error("For 'awnp', singular must end in -an: " .. sgar)
end
return ret, "awnp"
end
return artr, export.detect_type(ar, isfem, num, pos)
end
-- need LRM here so multiple Arabic plurals end up agreeing in order with
-- the transliteration
local outersep = LRM .. "; "
local innersep = LRM .. "/"
-- Subfunction of show_form(), used to implement recursively generating
-- all combinations of elements from FORM and from each of the items in
-- LIST_OF_MODS, both of which are either arrays of strings or arrays of
-- arrays of strings, where the strings are in the form ARABIC/TRANSLIT,
-- as described in show_form(). TRAILING_ARTRMODS is an array of ARTRMOD
-- items, each of which is a two-element array of ARMOD (Arabic) and TRMOD
-- (transliteration), accumulating all of the suffixes generated so far
-- in the recursion process. Each time we recur we take the last MOD item
-- off of LIST_OF_MODS, separate each element in MOD into its Arabic and
-- Latin parts and to each Arabic/Latin pair we add all elements in
-- TRAILING_ARTRMODS, passing the newly generated list of ARTRMOD items
-- down the next recursion level with the shorter LIST_OF_MODS. We end up
-- returning a string to insert into the Wiki-markup table.
function show_form_1(form, list_of_mods, trailing_artrmods, use_parens)
if #list_of_mods == 0 then
local arabicvals = {}
local latinvals = {}
local parenvals = {}
-- Accumulate separately the Arabic and transliteration into
-- ARABICVALS and LATINVALS, then concatenate each down below.
-- However, if USE_PARENS, we put each transliteration directly
-- after the corresponding Arabic, in parens, and put the results
-- in PARENVALS, which get concatenated below. (This is used in the
-- title of the declension table.)
for _, artrmod in ipairs(trailing_artrmods) do
assert(#artrmod == 2)
local armod = artrmod[1]
local trmod = artrmod[2]
for _, subform in ipairs(form) do
local ar_span, tr_span
local ar_subspan, tr_subspan
local ar_subspans = {}
local tr_subspans = {}
if type(subform) ~= "table" then
subform = {subform}
end
for _, subsubform in ipairs(subform) do
local arabic, translit = split_arabic_tr(subsubform)
if arabic == "-" then
ar_subspan = "—"
tr_subspan = "—"
elseif arabic == "?" then
ar_subspan = "?"
tr_subspan = "?"
else
tr_subspan = (rfind(translit, BOGUS_CHAR) or rfind(trmod, BOGUS_CHAR)) and "?" or
require("Module:script utilities").tag_translit(translit .. trmod, lang, "default", 'style="color: var(--wikt-palette-grey-8,#888);"')
-- implement elision of al- after vowel
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a([sšṣtṯṭdḏḍzžẓnrḷl]%-)", "%1%2")
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a(llāh)", "%1%2")
ar_subspan = m_links.full_link({lang = lang, term = arabic .. armod, tr = "-"})
end
insert_if_not(ar_subspans, ar_subspan)
insert_if_not(tr_subspans, tr_subspan)
end
ar_span = table.concat(ar_subspans, innersep)
tr_span = table.concat(tr_subspans, innersep)
if use_parens then
table.insert(parenvals, ar_span .. " (" .. tr_span .. ")")
else
table.insert(arabicvals, ar_span)
table.insert(latinvals, tr_span)
end
end
end
if use_parens then
return table.concat(parenvals, outersep)
else
local arabic_span = table.concat(arabicvals, outersep)
local latin_span = table.concat(latinvals, outersep)
if arabic_span == "?" then
return "?"
else
return arabic_span .. "<br />" .. latin_span
end
end
else
local last_mods = table.remove(list_of_mods)
local artrmods = {}
for _, mod in ipairs(last_mods) do
if type(mod) ~= "table" then
mod = {mod}
end
for _, submod in ipairs(mod) do
local armod, trmod = split_arabic_tr(submod)
-- If the value is -, we need to create a blank entry
-- rather than skipping it; if we have no entries at any
-- level, then there will be no overall entries at all
-- because the inside of the loop at the next level will
-- never be executed.
if armod == "-" then
armod = ""
trmod = ""
end
if armod ~= "" then armod = ' ' .. armod end
if trmod ~= "" then trmod = ' ' .. trmod end
for _, trailing_artrmod in ipairs(trailing_artrmods) do
local trailing_armod = trailing_artrmod[1]
local trailing_trmod = trailing_artrmod[2]
armod = armod .. trailing_armod
trmod = trmod .. trailing_trmod
artrmod = {armod, trmod}
table.insert(artrmods, artrmod)
end
end
end
return show_form_1(form, list_of_mods, artrmods, use_parens)
end
end
-- Generate a string to substitute into a particular form in a Wiki-markup
-- table. FORM is the set of inflected forms corresponding to the base,
-- either an array of strings (referring e.g. to different possible plurals)
-- or an array of arrays of strings (the first level referring e.g. to
-- different possible plurals and the inner level referring typically to
-- hamza-spelling variants). LIST_OF_MODS is an array of MODS elements, one
-- per modifier. Each MODS element is the set of inflected forms corresponding
-- to the modifier and is of the same form as FORM, i.e. an array of strings
-- or an array of arrays of strings. Each string is typically of the form
-- "ARABIC/TRANSLIT", i.e. an Arabic string and a Latin string separated
-- by a slash. We loop over all possible combinations of elements from
-- each array; this requires recursion.
function show_form(form, list_of_mods, use_parens)
if not form then
return "—"
elseif type(form) ~= "table" then
error("a non-table value was given in the list of inflected forms.")
end
if #form == 0 then
return "—"
end
-- We need to start the recursion with the third parameter containing
-- one blank element rather than no elements, otherwise no elements
-- will be propagated to the next recursion level.
return show_form_1(form, list_of_mods, {{"", ""}}, use_parens)
end
-- Create a Wiki-markup table using the values in DATA and the template in
-- WIKICODE.
function make_table(data, wikicode)
-- Function used as replace arg of call to rsub(). Replace the
-- specified param with its (HTML) value. The param references appear
-- as {{{PARAM}}} in the wikicode.
local function repl(param)
if param == "pos" then
return data.pos
elseif param == "info" then
return data.title and " (" .. data.title .. ")" or ""
elseif rfind(param, "type$") then
return table.concat(data.forms[param] or {"—"}, outersep .. "<br>")
else
local list_of_mods = {}
for _, mod in ipairs(mod_list) do
local mods = data.forms[mod .. "_" .. param]
if not mods or #mods == 0 then
-- We need one blank element rather than no element,
-- otherwise no elements will be propagated from one
-- recursion level to the next.
mods = {""}
end
table.insert(list_of_mods, mods)
end
return show_form(data.forms[param], list_of_mods, param == "lemma")
end
end
-- For states not in the list of those to be displayed, clear out the
-- corresponding inflections so they appear as a dash.
for _, state in ipairs(data.allstates) do
if not contains(data.states, state) then
for _, numgen in ipairs(data.numgens()) do
for _, case in ipairs(data.allcases) do
data.forms[case .. "_" .. numgen .. "_" .. state] = {}
end
end
end
end
return rsub(wikicode, "{{{([a-z_]+)}}}", repl) .. m_utilities.format_categories(data.categories, lang)
end
-- Generate part of the noun table for a given number spec NUM (e.g. sg)
function generate_noun_num(num)
return [=[! indefinite
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_]=] .. num .. [=[_ind}}}
| {{{inf_]=] .. num .. [=[_def}}}
| {{{inf_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_]=] .. num .. [=[_ind}}}
| {{{nom_]=] .. num .. [=[_def}}}
| {{{nom_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_]=] .. num .. [=[_ind}}}
| {{{acc_]=] .. num .. [=[_def}}}
| {{{acc_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_]=] .. num .. [=[_ind}}}
| {{{gen_]=] .. num .. [=[_def}}}
| {{{gen_]=] .. num .. [=[_con}}}
]=]
end
-- Make the noun table
function make_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" | dual
]=] .. generate_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" style="font-style:normal" colspan=3 | {{{]=] .. num .. [=[_type}}}
|-
]=] .. generate_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the gendered-noun table for a given numgen spec
-- NUM (e.g. m_sg)
function generate_gendered_noun_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_m_]=] .. num .. [=[_con}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_m_]=] .. num .. [=[_con}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_m_]=] .. num .. [=[_con}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_m_]=] .. num .. [=[_con}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_con}}}
]=]
end
-- Make the gendered noun table
function make_gendered_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'declension',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
]=] .. generate_gendered_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=3 | {{{m_]=] .. num .. [=[_type}}}
! class="outer" style="font-style:normal" colspan=3 | {{{f_]=] .. num .. [=[_type}}}
]=] .. generate_gendered_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the adjective table for a given numgen spec NUM (e.g. m_sg)
function generate_adj_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
]=]
end
-- Make the adjective table
function make_adj_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
if contains(data.numbers, "sg") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဨကဝုစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_sg_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_sg_type}}}
]=] .. generate_adj_num("sg")
end
if contains(data.numbers, "du") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
]=] .. generate_adj_num("du")
end
if contains(data.numbers, "pl") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဗဟုဝစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_pl_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_pl_type}}}
]=] .. generate_adj_num("pl")
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
return export
-- For Vim, so we get 4-space tabs
-- vim: set ts=4 sw=4 noet:
1tv1aiuywhjk9rq8rl4v1plg73nlme9
395267
395265
2026-05-20T19:26:58Z
咽頭べさ
33
395267
Scribunto
text/plain
-- Author: Benwing, based on early version by CodeCat.
--[[
FIXME: Nouns/adjectives to create to exemplify complex declensions:
-- riḍan (رِضًا or رِضًى)
--]]
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local ar_utilities = require("Module:ar-utilities")
local lang = require("Module:languages").getByCode("ar")
local u = require("Module:string/char")
local rfind = mw.ustring.find
local rsubn = mw.ustring.gsub
local rmatch = mw.ustring.match
local rsplit = mw.text.split
-- This is used in place of a transliteration when no manual
-- translit is specified and we're unable to automatically generate
-- one (typically because some vowel diacritics are missing).
local BOGUS_CHAR = u(0xFFFD)
-- hamza variants
local HAMZA = u(0x0621) -- hamza on the line (stand-alone hamza) = ء
local HAMZA_ON_ALIF = u(0x0623)
local HAMZA_ON_W = u(0x0624)
local HAMZA_UNDER_ALIF = u(0x0625)
local HAMZA_ON_Y = u(0x0626)
local HAMZA_ANY = "[" .. HAMZA .. HAMZA_ON_ALIF .. HAMZA_UNDER_ALIF .. HAMZA_ON_W .. HAMZA_ON_Y .. "]"
local HAMZA_PH = u(0xFFF0) -- hamza placeholder
-- various letters
local ALIF = u(0x0627) -- ʾalif = ا
local AMAQ = u(0x0649) -- ʾalif maqṣūra = ى
local AMAD = u(0x0622) -- ʾalif madda = آ
local TAM = u(0x0629) -- tāʾ marbūṭa = ة
local T = u(0x062A) -- tāʾ = ت
local HYPHEN = u(0x0640)
local N = u(0x0646) -- nūn = ن
local W = u(0x0648) -- wāw = و
local Y = u(0x064A) -- yā = ي
-- diacritics
local A = u(0x064E) -- fatḥa
local AN = u(0x064B) -- fatḥatān (fatḥa tanwīn)
local U = u(0x064F) -- ḍamma
local UN = u(0x064C) -- ḍammatān (ḍamma tanwīn)
local I = u(0x0650) -- kasra
local IN = u(0x064D) -- kasratān (kasra tanwīn)
local SK = u(0x0652) -- sukūn = no vowel
local SH = u(0x0651) -- šadda = gemination of consonants
local DAGGER_ALIF = u(0x0670)
local DIACRITIC_ANY_BUT_SH = "[" .. A .. I .. U .. AN .. IN .. UN .. SK .. DAGGER_ALIF .. "]"
-- common combinations
local NA = N .. A
local NI = N .. I
local AH = A .. TAM
local AT = A .. T
local AA = A .. ALIF
local AAMAQ = A .. AMAQ
local AAH = AA .. TAM
local AAT = AA .. T
local II = I .. Y
local IIN = II .. N
local IINA = II .. NA
local IY = II
local UU = U .. W
local UUN = UU .. N
local UUNA = UU .. NA
local AY = A .. Y
local AW = A .. W
local AYSK = AY .. SK
local AWSK = AW .. SK
local AAN = AA .. N
local AANI = AA .. NI
local AYN = AYSK .. N
local AYNI = AYSK .. NI
local AWN = AWSK .. N
local AWNA = AWSK .. NA
local AYNA = AYSK .. NA
local AYAAT = AY .. AAT
local UNU = "[" .. UN .. U .. "]"
-- optional diacritics/letters
local AOPT = A .. "?"
local AOPTA = A .. "?" .. ALIF
local IOPT = I .. "?"
local UOPT = U .. "?"
local UNOPT = UN .. "?"
local UNUOPT = UNU .. "?"
local SKOPT = SK .. "?"
-- lists of consonants
-- exclude tāʾ marbūṭa because we don't want it treated as a consonant
-- in patterns like أَفْعَل
local consonants_needing_vowels_no_tam = "بتثجحخدذرزسشصضطظعغفقكلمنهپچڤگڨڧأإؤئء"
-- consonants on the right side; includes alif madda
local rconsonants_no_tam = consonants_needing_vowels_no_tam .. "ويآ"
-- consonants on the left side; does not include alif madda
local lconsonants_no_tam = consonants_needing_vowels_no_tam .. "وي"
local CONS = "[" .. lconsonants_no_tam .. "]"
local CONSPAR = "([" .. lconsonants_no_tam .. "])"
local LRM = u(0x200E) --left-to-right mark
-- First syllable or so of elative/color-defect adjective
local ELCD_START = "^" .. HAMZA_ON_ALIF .. AOPT .. CONSPAR
local export = {}
--------------------
-- Utility functions
--------------------
function ine(x) -- If Not Empty
if x == nil then
return nil
elseif rfind(x, '^".*"$') then
local ret = rmatch(x, '^"(.*)"$')
return ret
elseif rfind(x, "^'.*'$") then
local ret = rmatch(x, "^'(.*)'$")
return ret
elseif x == "" then
return nil
else
return x
end
end
-- Compare two items, recursively comparing arrays.
-- FIXME, doesn't work for tables that aren't arrays.
function equals(x, y)
if type(x) == "table" and type(y) == "table" then
if #x ~= #y then
return false
end
for key, value in ipairs(x) do
if not equals(value, y[key]) then
return false
end
end
return true
end
return x == y
end
-- true if array contains item
function contains(tab, item)
for _, value in pairs(tab) do
if equals(value, item) then
return true
end
end
return false
end
-- append to array if element not already present
function insert_if_not(tab, item)
if not contains(tab, item) then
table.insert(tab, item)
end
end
-- version of rsubn() that discards all but the first return value
function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsub() that asserts that a match occurred
function assert_rsub(term, foo, bar)
local retval, numsub = rsubn(term, foo, bar)
assert(numsub > 0)
return retval
end
function make_link(arabic)
--return m_links.full_link(nil, arabic, lang, nil, "term", nil, {tr = "-"}, false)
return m_links.full_link({lang = lang, alt = arabic}, "term")
end
function track(page)
require("Module:debug").track("ar-nominals/" .. page)
return true
end
-------------------------------------
-- Functions for building inflections
-------------------------------------
-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}
local max_mods = 9 -- maximum number of modifiers
local mod_list = {"mod"} -- list of "mod", "mod2", "mod3", ...
for i=2,max_mods do
table.insert(mod_list, "mod" .. i)
end
-- Create and return the 'data' structure that will hold all of the
-- generated declensional forms, as well as other ancillary information
-- such as the possible numbers, genders and cases the the actual numbers
-- and states to store (in 'data.numbers' and 'data.states' respectively).
function init_data()
-- FORMS contains a table of forms for each inflectional category,
-- e.g. "nom_sg_ind" for nouns or "nom_m_sg_ind" for adjectives. The value
-- of an entry is an array of alternatives (e.g. different plurals), where
-- each alternative is either a string of the form "ARABIC" or
-- "ARABIC/TRANSLIT", or an array of such strings (this is used for
-- alternative spellings involving different hamza seats,
-- e.g. مُبْتَدَؤُون or مُبْتَدَأُون). Alternative hamza spellings are separated
-- in display by an "inner separator" (/), while alternatives on
-- the level of different plurals are separated by an "outer separator" (;).
return {forms = {}, title = nil, categories = {},
allgenders = {"m", "f"},
allstates = {"ind", "def", "con"},
allnumbers = {"sg", "du", "pl"},
states = {}, -- initialized later
numbers = {}, -- initialized later
engnumbers = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal"},
engnumberscap = {sg="singular", du="dual", pl="plural",
coll="collective", sing="singulative", pauc="paucal (3-10)"},
allcases = {"nom", "acc", "gen", "inf"},
allcases_with_lemma = {"nom", "acc", "gen", "inf", "lemma"},
-- index into endings array indicating correct ending for given
-- combination of state and case
statecases = {
ind = {nom = 1, acc = 2, gen = 3, inf = 10, lemma = 13},
def = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
-- used for a definite adjective modifying a construct-state noun
defcon = {nom = 4, acc = 5, gen = 6, inf = 11, lemma = 14},
con = {nom = 7, acc = 8, gen = 9, inf = 12, lemma = 15},
},
}
end
-- Initialize and return ARGS, ORIGARGS and DATA (see init_data()).
-- ARGS is a table of user-supplied arguments, massaged from the original
-- arguments by converting empty-string arguments to nil and appending
-- translit arguments to their base arguments with a separating slash.
-- ORIGARGS is the original table of arguments.
function init(origargs)
-- Massage arguments by converting empty arguments to nil, and
-- "" or '' arguments to empty.
local args = {}
for k, v in pairs(origargs) do
args[k] = ine(v)
end
-- Further massage arguments by appending translit arguments to the
-- corresponding base arguments, with a slash separator, as is expected
-- in the rest of the code.
--
-- FIXME: We should consider separating translit and base arguments by the
-- separators ; , | (used in overrides; see handle_lemma_and_overrides())
-- and matching up individual parts, to allow separate translit arguments
-- to be specified for overrides. But maybe not; the point of allowing
-- separate translit arguments is for compatibility with headword
-- templates such as "ar-noun" and "ar-adj", and those templates don't
-- handle override arguments.
local function dotr(arg, argtr)
if not args[arg] then
error("Argument '" .. argtr .."' specified but not corresponding base argument '" .. arg .. "'")
end
args[arg] = args[arg] .. "/" .. args[argtr]
end
-- By convention, corresponding to arg 1 is tr; corresponding to
-- head2, head3, ... is tr2, tr3, ...; corresponding to
-- modhead2, modhead3, ... is modtr2, modtr3, ...; corresponding to
-- modNhead2, modNhead3, ... is modNtr2, modNtr3, ..; corresponding to
-- all other arguments FOO, FOO2, ... is FOOtr, FOO2tr, ...
for k, v in pairs(args) do
if k == "tr" then
dotr(1, "tr")
elseif rfind(k, "tr[0-9]+$") then
dotr(assert_rsub(k, "tr([0-9]+)$", "head%1"), k)
elseif rfind(k, "tr$") then
dotr(assert_rsub(k, "tr$", ""), k)
end
end
-- Construct data.
local data = init_data()
return args, origargs, data
end
-- Parse the user-specified state spec and other related arguments. The
-- user can specify, using idafaN=, how modifiers are related to previous
-- words. The user can also manually specify which states are to appear;
-- whether to omit the definite article in the definite state; and
-- how/whether to restrict modifiers to a particular state, case or number.
-- Normally the modN_* parameters and basestate= do not need to be set
-- directly; instead, use idafaN=. It may be necessary to explicitly
-- specify state= in the presence of proper nouns or definite-only
-- adjectival expressions. NOTE: At the time this function is called,
-- data.numbers has not yet been initialized.
function parse_state_etc_spec(data, args)
local function check(arg, dataval, allvalues)
if args[arg] then
if not contains(allvalues, args[arg]) then
error("For " .. arg .. "=, value '" .. args[arg] .. "' should be one of " ..
table.concat(allvalues, ", "))
end
data[dataval] = args[arg]
end
end
local function check_boolean(arg, dataval)
check(arg, dataval, {"yes", "no"})
if data[dataval] == "yes" then
data[dataval] = true
elseif data[dataval] == "no" then
data[dataval] = false
end
end
-- Make sure no holes in mod values
for i=1,(#mod_list)-1 do
if args[mod_list[i+1]] and not args[mod_list[i]] then
error("Hole in modifier arguments -- " .. mod_list[i+1] ..
" present but not " .. mod_list[i])
end
end
-- FIXME! Remove this once we're sure there are no instances of mod2
-- that haven't been converted to modhead2.
if args["mod2"] then
track("mod2")
end
-- Set default value; may be overridden e.g. by arg["state"] or
-- by idafaN=.
data.states = data.allstates
-- List of pairs of idafaN/modN parameters
local idafa_mod_list = {{"idafa", "mod"}}
for i=2,max_mods do
table.insert(idafa_mod_list, {"idafa" .. i, "mod" .. i})
end
-- True if the value of an |idafa= param is a valid adjectival modifier
-- value.
local function valid_adjectival_idafaval(idafaval)
return idafaval == "adj" or idafaval == "adj-base" or
idafaval == "adj-mod" or rfind(idafaval, "^adj%-mod[0-9]+$")
end
-- Extract the referent (base or modifier) of an adjectival |idafa= param.
-- Assumes the value is valid.
local function adjectival_idafaval_referent(idafaval)
if idafaval == "adj" then
return "base"
end
return assert_rsub(idafaval, "^adj%-", "")
end
-- Convert a base/mod spec to an index: 0=base, 1=mod, 2=mod2, etc.
local function basemod_to_index(basemod)
if basemod == "base" then return 0 end
if basemod == "mod" then return 1 end
return tonumber(assert_rsub(basemod, "^mod", ""))
end
-- Recognize idafa spec and handle it.
-- We do the following:
-- (1) Check that if idafaN= is given, then modN= is also given.
-- (2) Check that adjectival modifiers aren't followed by idafa modifiers.
-- (3) Check that adjectival modifiers are modifying the base or an
-- ʾidāfa modifier, not another adjectival modifier.
-- (4) Support idafa values "adj-base", "adj-mod", "adj-mod2", "adj"
-- (="adj-base") etc. and check that we're referring to an earlier
-- word.
-- (5) For ʾidāfa modifiers, set basestate=con, set modN_case=gen,
-- set modN_idafa=true, and set modN_number to the number specified
-- in the parameter value (e.g. 'sg' or 'def-pl'); and if the
-- parameter value specifies a state (e.g. 'def' or 'ind-du'),
-- set modN_state= to this value, and if this is the last ʾidāfa
-- modifier, also set state= to this value; if this is not the last
-- ʾidāfa modifier, set modN_state=con and disallow a state to be
-- specified in the parameter value.
-- (6) For adjectival modifiers of the base, do nothing.
-- (7) For adjectival modifiers of ʾidāfa modifiers, set modN_case=gen;
-- set modN_idafa=false; and set modN_number=, modN_numgen= and
-- modN_state= to match the values of the idafa modifier.
-- error checking and find last ʾidāfa modifier
local last_is_idafa = true
local last_idafa_mod = "base"
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
if not args[mod] then
error("'" .. idafaparam .. "' parameter without corresponding '"
.. mod .. "' parameter")
end
if not valid_adjectival_idafaval(idafaval) then
-- We're a construct (ʾidāfa) modifier
if not last_is_idafa then
error("ʾidāfa modifier " .. paramval .. " follows adjectival modifier")
end
last_idafa_mod = mod
else
last_is_idafa = false
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
if basemod_to_index(adjref) >= basemod_to_index(mod) then
error(paramval .. " can only refer to an earlier element")
end
local idafaref = assert_rsub(adjref, "^mod", "idafa")
if not args[idafaref] then
error(paramval .. " cannot refer to a missing modifier")
elseif valid_adjectival_idafaval(args[idafaref]) then
error(paramval .. " cannot refer to an adjectival modifier")
end
end
end
end
end
-- Now go through and set all the modN_ data values appropriately.
for _, idafa_mod in ipairs(idafa_mod_list) do
local idafaparam = idafa_mod[1]
local mod = idafa_mod[2]
local idafaval = args[idafaparam]
if idafaval then
local paramval = idafaparam .. "=" .. idafaval
local bad_idafa = true
if idafaval == "yes" then
idafaval = "sg"
end
if idafaval == "ind-def" or contains(data.allstates, idafaval) then
idafaval = idafaval .. "-sg"
end
if not idafaval then
bad_idafa = false
elseif valid_adjectival_idafaval(idafaval) then
local adjref = adjectival_idafaval_referent(idafaval)
if adjref ~= "base" then
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = data[adjref .. "_state"]
-- if agreement is with ind-def, make it def
if data[mod .. "_state"] == "ind-def" then
data[mod .. "_state"] = "def"
end
data[mod .. "_number"] = data[adjref .. "_number"]
data[mod .. "_numgen"] = data[adjref .. "_numgen"]
data[mod .. "_idafa"] = false
end
bad_idafa = false
elseif contains(data.allnumbers, idafaval) then
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_number"] = idafaval
data[mod .. "_idafa"] = true
if mod ~= last_idafa_mod then
data[mod .. "_state"] = "con"
end
bad_idafa = false
elseif rfind(idafaval, "%-") then
local state_num = rsplit(idafaval, "%-")
-- Support ind-def as a possible value. We set modstate to
-- ind-def, which will signal definite agreement with adjectival
-- modifiers; then later on we change the value to ind.
if #state_num == 3 and state_num[1] == "ind" and state_num[2] == "def" then
state_num[1] = "ind-def"
state_num[2] = state_num[3]
table.remove(state_num)
end
if #state_num == 2 then
local state = state_num[1]
local num = state_num[2]
if (state == "ind-def" or contains(data.allstates, state))
and contains(data.allnumbers, num) then
if mod == last_idafa_mod then
if state == "ind-def" then
data.states = {"def"}
else
data.states = {state}
end
else
error(paramval .. " cannot specify a state because it is not the last ʾidāfa modifier")
end
data.basestate = "con"
data[mod .. "_case"] = "gen"
data[mod .. "_state"] = state
data[mod .. "_number"] = num
data[mod .. "_idafa"] = true
bad_idafa = false
end
end
end
if bad_idafa then
error(paramval .. " should be one of yes, def, sg, def-sg, adj, adj-base, adj-mod, adj-mod2 or similar")
end
end
end
if args["state"] == "ind-def" then
data.states = {"def"}
data.basestate = "ind"
elseif args["state"] then
data.states = rsplit(args["state"], ",")
for _, state in ipairs(data.states) do
if not contains(data.allstates, state) then
error("For state=, value '" .. state .. "' should be one of " ..
table.concat(data.allstates, ", "))
end
end
end
-- Now process explicit settings, so that they can override the
-- settings based on idafaN=.
check("basestate", "basestate", data.allstates)
check_boolean("noirreg", "noirreg")
check_boolean("omitarticle", "omitarticle")
data.prefix = args.prefix
for _, mod in ipairs(mod_list) do
check(mod .. "state", mod .. "_state", data.allstates)
check(mod .. "case", mod .. "_case", data.allcases)
check(mod .. "number", mod .. "_number", data.allnumgens)
check(mod .. "numgen", mod .. "_numgen", data.allnumgens)
check_boolean(mod .. "idafa", mod .. "_idafa")
check_boolean(mod .. "omitarticle", mod .. "_omitarticle")
data[mod .. "_prefix"] = args[mod .. "prefix"]
end
-- Make sure modN_numgen is initialized, to modN_number if necessary.
-- This simplifies logic in certain places, e.g. call_inflections().
-- Also convert ind-def to ind.
for _, mod in ipairs(mod_list) do
data[mod .. "_numgen"] = data[mod .. "_numgen"] or data[mod .. "_number"]
if data[mod .. "_state"] == "ind-def" then
data[mod.. "_state"] = "ind"
end
end
end
-- Parse the user-specified number spec. The user can manually specify which
-- numbers are to appear. Return true if |number= was specified.
function parse_number_spec(data, args)
if args["number"] then
data.numbers = rsplit(args["number"], ",")
for _, num in ipairs(data.numbers) do
if not contains(data.allnumbers, num) then
error("For number=, value '" .. num .. "' should be one of " ..
table.concat(data.allnumbers, ", "))
end
end
return true
else
data.numbers = data.allnumbers
return false
end
end
-- Determine which numbers will appear using the logic for nouns.
-- See comment just below.
function determine_noun_numbers(data, args, pls)
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, duals and plurals
-- appear; else, only singular (on the assumption that the word is a proper
-- noun or abstract noun that exists only in the singular); however,
-- singular won't appear if "-" given for singular, and similarly for dual.
if not parse_number_spec(data, args) then
data.numbers = {}
local sgarg1 = args[1]
local duarg1 = args["d"]
if sgarg1 ~= "-" then
table.insert(data.numbers, "sg")
end
if #pls["base"] > 0 then
-- Dual appears if either: explicit dual stem (not -) is given, or
-- default dual is used and explicit singular stem (not -) is given.
if (duarg1 and duarg1 ~= "-") or (not duarg1 and sgarg1 ~= "-") then
table.insert(data.numbers, "du")
end
table.insert(data.numbers, "pl")
elseif duarg1 and duarg1 ~= "-" then
-- If explicit dual but no plural given, include it. Useful for
-- dual tantum words.
table.insert(data.numbers, "du")
end
end
end
-- For stem STEM, convert to stem-and-type format and insert stem and type
-- into RESULTS, checking to make sure it's not already there. SGS is the
-- list of singular items to base derived forms off of (masculine or feminine
-- as appropriate), an array of length-two arrays of {COMBINED_STEM, TYPE} as
-- returned by stem_and_type(); ISFEM is true if this is feminine gender;
-- NUM is "sg", "du" or "pl". POS is the part of speech, generally "noun" or
-- "adjective".
function insert_stems(stem, results, sgs, isfem, num, pos)
if stem == "-" then
return
end
for _, sg in ipairs(sgs) do
local combined_stem, ty = export.stem_and_type(stem,
sg[1], sg[2], isfem, num, pos)
insert_if_not(results, {combined_stem, ty})
end
end
-- Handle manually specified overrides of individual forms. Separate
-- outer-level alternants with ; or , or the Arabic equivalents; separate
-- inner-level alternants with | (we can't use / because it's already in
-- use separating Arabic from translit).
--
-- Also determine lemma and allow it to be overridden.
-- Also allow POS (part of speech) to be overridden.
function handle_lemma_and_overrides(data, args)
local function handle_override(arg)
if args[arg] then
local ovval = {}
local alts1 = rsplit(args[arg], "[;,؛،]")
for _, alt1 in ipairs(alts1) do
local alts2 = rsplit(alt1, "|")
table.insert(ovval, alts2)
end
data.forms[arg] = ovval
end
end
local function do_overrides(mod)
for _, numgen in ipairs(data.allnumgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases) do
local arg = mod .. case .. "_" .. numgen .. "_" .. state
handle_override(arg)
if args[arg] and not data.noirreg then
-- insert_cat(data, mod, numgen,
-- "Arabic NOUNs with irregular SINGULAR",
-- "SINGULAR of irregular NOUN")
end
end
end
end
end
do_overrides("")
for _, mod in ipairs(mod_list) do
do_overrides(mod .. "_")
end
local function get_lemma(mod)
for _, numgen in ipairs(data.numgens()) do
for _, state in ipairs(data.states) do
local arg = mod .. "lemma_" .. numgen .. "_" .. state
if data.forms[arg] and #data.forms[arg] > 0 then
return data.forms[arg]
end
end
end
return nil
end
data.forms["lemma"] = get_lemma("")
for _, mod in ipairs(mod_list) do
data.forms[mod .. "_lemma"] = get_lemma(mod .. "_")
end
handle_override("lemma")
for _, mod in ipairs(mod_list) do
handle_override(mod .. "_lemma")
end
end
-- Return the part of speech based on the part of speech contained in
-- data.pos and MOD (either "", "mod_", "mod2_", etc., same as in
-- do_gender_number_1()). If we're a modifier, don't use data.pos but
-- instead choose based on whether modifier is adjectival or nominal
-- (ʾiḍāfa).
function get_pos(data, mod)
local ismod = mod ~= ""
if not ismod then
return data.pos
elseif data[mod .. "idafa"] then
return "နာမ်"
else
return "နာမဝိသေသန"
end
end
-- Find the stems associated with a particular gender/number combination.
-- ARGS is the set of all arguments. ARGPREFS is an array of argument prefixes
-- (e.g. "f" for the actual arguments "f", "f2", ..., for the feminine
-- singular; we allow more than one to handle "cpl"). SGS is a
-- "stem-type list" (see do_gender_number()), and is the list of stems to
-- base derived forms off of (masculine or feminine as appropriate), an array
-- of length-two arrays of {COMBINED_STEM, TYPE} as returned by
-- stem_and_type(). DEFAULT, ISFEM and NUM are as in do_gender_number().
-- MOD is either "", "mod_", "mod2_", etc. depending if we're working on a
-- base or modifier argument (in the latter case, basically if the argument
-- begins with "mod").
function do_gender_number_1(data, args, argprefs, sgs, default, isfem, num, mod)
local results = {}
local function handle_stem(stem)
insert_stems(stem, results, sgs, isfem, num, get_pos(data, mod))
end
-- If no arguments specified, use the default instead.
need_default = true
for _, argpref in ipairs(argprefs) do
if args[argpref] then
need_default = false
break
end
end
if need_default then
if not default then
return results
end
handle_stem(default)
return results
end
-- For explicitly specified arguments, make sure there's at least one
-- stem to generate off of; otherwise specifying e.g. 'sing=- pauc=فُلَان'
-- won't override paucal.
if #sgs == 0 then
sgs = {{"", ""}}
end
for _, argpref in ipairs(argprefs) do
if args[argpref] then
handle_stem(args[argpref])
end
local i = 2
while args[argpref .. i] do
handle_stem(args[argpref .. i])
i = i + 1
end
end
return results
end
-- For a given gender/number combination, parse and return the full set
-- of stems for both base and modifier. The return value is a
-- "stem specification", i.e. table with a "base" key for the base, a
-- "mod" key for the first modifier (see below), a "mod2" key for the
-- second modifier, etc. listing all stems for both the base and modifier(s).
-- The value of each key is a "stem-type list", i.e. an array of stem-type
-- pairs, where each element is a size-two array of {COMBINED_STEM, STEM_TYPE}.
-- COMBINED_STEM is a stem with attached transliteration in the form
-- STEM/TRANSLIT (where the transliteration is either manually specified in
-- the stem argument, e.g. 'pl=لُورْدَات/lordāt', or auto-transliterated from
-- the Arabic, with BOGUS_CHAR substituting for the transliteration if
-- auto-translit fails). STEM_TYPE is the declension of the stem, either
-- manually specified, e.g. 'بَبَّغَاء:di' for manually-specified diptote, or
-- auto-detected (see stem_and_type() and detect_type()).
--
-- DATA and ARGS are as in init(). ARGPREFS is an array of the prefixes for
-- the argument(s) specifying the stem (and optional translit and declension
-- type). For a given ARGPREF, we check ARGPREF, ARGPREF2, ARGPREF3, ... in
-- turn for the base, and modARGPREF, modARGPREF2, modARGPREF3, ... in turn
-- for the first modifier, and mod2ARGPREF, mod2ARGPREF2, mod2ARGPREF3, ...
-- for the second modifier, etc. SGS is a stem specification (see above),
-- giving the stems that are used to base derived forms off of (e.g. if a stem
-- type "smp" appears in place of a stem, the sound masculine plural of the
-- stems in SGS will be derived). DEFAULT is a single stem (i.e. a string) that
-- is used when no stems were explicitly given by the user (typically either
-- "f", "m", "d" or "p"), or nil for no default. ISFEM is true if we're
-- accumulating stems for a feminine number/gender category, and NUM is the
-- number (expected to be "sg", "du" or "pl") of the number/gender category
-- we're accumulating stems for.
--
-- About bases and modifiers: Note that e.g. in the noun phrase يَوْم الاِثْنَيْن
-- the head noun يَوْم is the base and the noun الاِثْنَيْن is the modifier.
-- In a noun phrase like البَحْر الأَبْيَض المُتَوَسِّط, there are two modifiers.
-- Note that modifiers come in two varieties, adjectival modifiers and
-- construct (ʾidāfa) modifiers. The first above noun phrase is an example
-- of a noun phrase with a construct modifier, where the base is fixed in
-- the construct state and the modifier is fixed in number and case
-- (which is always genitive) and possibly in state. The second above noun
-- phrase is an example of a noun phrase with two adjectival modifiers.
-- A construct modifier is generally a noun, whereas an adjectival modifier
-- is an adjective that usually agrees in state, number and case with the
-- base noun. (Note that in the case of multiple modifiers, it is possible
-- for e.g. the second modifier to be an adjectival modifier that agrees
-- with the first, construct, modifier, in which case its case will be fixed
-- to genitive, its number will be fixed to the same number as the first
-- modifier and its state will vary or not depending on whether the first
-- modifier's state varies. It is not possible in general to distinguish
-- adjectival and construct modifiers by looking at the values of
-- modN_state, modN_case or modN_number, since e.g. a third modifier could
-- have all of them specified and be either kind. Thus we have modN_idafa,
-- which is true for a construct modifier, false otherwise.)
function do_gender_number(data, args, argprefs, sgs, default, isfem, num)
local results = do_gender_number_1(data, args, argprefs, sgs["base"],
default, isfem, num, "")
basemodtable = {base=results}
for _, mod in ipairs(mod_list) do
local modn_argprefs = {}
for _, argpref in ipairs(argprefs) do
table.insert(modn_argprefs, mod .. argpref)
end
local modn_results = do_gender_number_1(data, args, modn_argprefs,
sgs[mod] or {}, default, isfem, num, mod .. "_")
basemodtable[mod] = modn_results
end
return basemodtable
end
-- Generate inflections for the given combined stem and type, for MOD
-- (either "" if we're working on the base or "mod_", "mod2_", etc. if we're
-- working on a modifier) and NUMGEN (number or number-gender combination,
-- of the sort that forms part of the keys in DATA.FORMS).
function call_inflection(combined_stem, ty, data, mod, numgen)
if ty == "-" then
return
end
if not inflections[ty] then
error("Unknown inflection type '" .. ty .. "'")
end
local ar, tr = split_arabic_tr(combined_stem)
inflections[ty](ar, tr, data, mod, numgen)
end
-- Generate inflections for the stems of a given number/gender combination
-- and for either the base or the modifier. STEMTYPES is a stem-type list
-- (see do_gender_number()), listing all the stems and corresponding
-- declension types. MOD is either "", "mod_", "mod2_", etc. depending on
-- whether we're working on the base or a modifier. NUMGEN is the number or
-- number-gender combination we're working on, of the sort that forms part
-- of the keys in DATA.FORMS, e.g. "sg" or "m_sg".
function call_inflections(stemtypes, data, mod, numgen)
local mod_with_modnumgen = mod ~= "" and data[mod .. "numgen"]
-- If modN_numgen= is given, do nothing if NUMGEN isn't the same
if mod_with_modnumgen and data[mod .. "numgen"] ~= numgen then
return
end
-- always call inflection() if mod_with_modnumgen since it may affect
-- other numbers (cf. يَوْم الاِثْنَيْن)
if mod_with_modnumgen or contains(data.numbers, rsub(numgen, "^.*_", "")) then
for _, stemtype in ipairs(stemtypes) do
call_inflection(stemtype[1], stemtype[2], data, mod, numgen)
end
end
end
-- Generate the entire set of inflections for a noun or adjective.
-- Also handle any manually-specified part of speech and any manual
-- inflection overrides. The value of INFLECTIONS is an array of stem
-- specifications, one per number, where each element is a size-two
-- array of a stem specification (containing the set of stems and
-- corresponding declension types for the base and any modifiers;
-- see do_gender_number()) and a NUMGEN string, i.e. a string identifying
-- the number or number/gender in question (e.g. "sg", "du", "pl",
-- "m_sg", "f_pl", etc.).
function do_inflections_and_overrides(data, args, inflections)
-- do this before generating inflections so POS change is reflected in
-- categories
if args["pos"] then
data.pos = args["pos"]
end
for _, inflection in ipairs(inflections) do
call_inflections(inflection[1]["base"] or {}, data, "", inflection[2])
for _, mod in ipairs(mod_list) do
call_inflections(inflection[1][mod] or {}, data,
mod .. "_", inflection[2])
end
end
handle_lemma_and_overrides(data, args)
end
-- Helper function for get_heads(). Parses the stems for either the
-- base or the modifier (see do_gender_number()). ARG1 is the argument
-- for the first stem and ARGN is the prefix of the arguments for the
-- remaining stems. For example, for the singular base, ARG1=1 and
-- ARGN="head"; for the first singular modifier, ARG1="mod" and
-- ARGN="modhead"; for the plural base, ARG1=ARGN="pl". The arguments
-- other than the first are numbered 2, 3, ..., which is appended to
-- ARGN. MOD is either "", "mod_", "mod2_", etc. depending if we're
-- working on a base or modifier argument. The returned value is an
-- array of stems, where each element is a size-two array of
-- {COMBINED_STEM, STEM_TYPE}. See do_gender_number().
function get_heads_1(data, args, arg1, argn, mod)
if not args[arg1] then
return {}
end
local heads
if args[arg1] == "-" then
heads = {{"", "-"}}
else
heads = {}
insert_stems(args[arg1], heads, {{args[arg1], ""}}, false, "sg",
get_pos(data, mod))
end
local i = 2
while args[argn .. i] do
local arg = args[argn .. i]
insert_stems(arg, heads, {{arg, ""}}, false, "sg",
get_pos(data, mod))
i = i + 1
end
return heads
end
-- Very similar to do_gender_number(), and returns the same type of
-- structure, but works specifically for the stems of the head (the
-- most basic gender/number combiation, e.g. singular for nouns,
-- masculine singular for adjectives and gendered nouns, collective
-- for collective nouns, etc.), including both base and modifier.
-- See do_gender_number(). Note that the actual return value is
-- two items, the first of which is the same type of structure
-- returned by do_gender_number() and the second of which is a boolean
-- indicating whether we were called from within a template documentation
-- page (in which case no user-specified arguments exist and we
-- substitute sample ones). The reason for this boolean is to indicate
-- whether sample arguments need to be substituted for other numbers
-- as well.
function get_heads(data, args, headtype)
if not args[1] and mw.title.getCurrentTitle().nsText == "ထာမ်ပလိက်" then
return {base={{"{{{1}}}", "tri"}}}, true
end
if not args[1] then error("Parameter 1 (" .. headtype .. " stem) may not be empty.") end
local base = get_heads_1(data, args, 1, "head", "")
basemodtable = {base=base}
for _, mod in ipairs(mod_list) do
local modn = get_heads_1(data, args, mod, mod .. "head", mod .. "_")
basemodtable[mod] = modn
end
return basemodtable, false
end
-- The main entry point for noun tables.
function export.show_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local sgs, is_template = get_heads(data, args, "ကိုန်ဨကဝုစ်")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, sgs, nil, false, "pl")
-- always do dual so cases like يَوْم الاِثْنَيْن work -- a singular with
-- a dual modifier, where data.number refers only the singular
-- but we need to go ahead and compute the dual so it parses the
-- "modd" modifier dual argument. When the modifier dual argument
-- is parsed, it will store the resulting dual declension for اِثْنَيْن
-- in the modifier slot for all numbers, including specifically
-- the singular.
local dus = do_gender_number(data, args, {"d"}, sgs, "d", false, "du")
parse_state_etc_spec(data, args)
determine_noun_numbers(data, args, pls)
do_inflections_and_overrides(data, args,
{{sgs, "sg"}, {dus, "du"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
function any_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return true
end
end
end
end
return false
end
function all_feminine(data, stem_spec)
for basemod, stemtypelist in pairs(stem_spec) do
-- Only check modifiers if modN_numgen= not given. If not given, the
-- modifier needs to be declined for all numgens; else only for the
-- given numgen, which should be explicitly specified.
if not (basemod ~= "base" and data[basemod .. "_numgen"]) then
for _, stemtype in ipairs(stemtypelist) do
if not rfind(stemtype[1], TAM .. UNUOPT .. "/") then
return false
end
end
end
end
return true
end
-- The main entry point for collective noun tables.
function export.show_coll_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.allnumbers = {"coll", "sing", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
local colls, is_template = get_heads(data, args, "collective")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
parse_state_etc_spec(data, args)
-- If collective noun is already feminine in form, don't try to
-- form a feminine singulative
local collfem = any_feminine(data, colls)
local sings = do_gender_number(data, args, {"sing"}, colls,
not already_feminine and "f" or nil, true, "sg")
local singfem = all_feminine(data, sings)
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear,
-- and if singulative given, dual and paucal appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "coll")
end
if #sings["base"] > 0 then
table.insert(data.numbers, "sing")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the collective, singulative, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{colls, "coll"}, {sings, "sing"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The main entry point for singulative noun tables.
function export.show_sing_noun(frame)
local args, origargs, data = init(frame:getParent().args)
data.pos = "နာမ်"
data.allnumbers = {"sing", "coll", "du", "pauc", "pl"}
data.engnumberscap["pl"] = "plural of variety"
data.numgens = function() return data.numbers end
data.allnumgens = data.allnumbers
parse_state_etc_spec(data, args)
local sings, is_template = get_heads(data, args, "singulative")
-- If all singulative nouns feminine in form, form a masculine collective
local singfem = all_feminine(data, sings)
local colls = do_gender_number(data, args, {"coll"}, sings,
singfem and "m" or nil, false, "sg")
local dus = do_gender_number(data, args, {"d"}, sings, "d", singfem, "du")
local paucs = do_gender_number(data, args, {"pauc"}, sings, "paucp",
singfem, "pl")
local pls = is_template and {base={{"{{{pl}}}", "tri"}}} or
do_gender_number(data, args, {"pl", "cpl"}, colls, nil, false, "pl")
-- Can manually specify which numbers are to appear, and exactly those
-- numbers will appear. Otherwise, if any plurals given, plurals appear;
-- if singulative given or derivable, it and dual and paucal will appear.
if not parse_number_spec(data, args) then
data.numbers = {}
if args[1] ~= "-" then
table.insert(data.numbers, "sing")
end
if #colls["base"] > 0 then
table.insert(data.numbers, "coll")
end
if #dus["base"] > 0 then
table.insert(data.numbers, "du")
end
if #paucs["base"] > 0 then
table.insert(data.numbers, "pauc")
end
if #pls["base"] > 0 then
table.insert(data.numbers, "pl")
end
end
-- Generate the singulative, collective, dual, paucal and plural forms
do_inflections_and_overrides(data, args,
{{sings, "sing"}, {colls, "coll"}, {dus, "du"}, {paucs, "pauc"}, {pls, "pl"}})
-- Make the table
return make_noun_table(data)
end
-- The implementation of the main entry point for adjective and
-- gendered noun tables.
function show_gendered(frame, isadj, pos)
local args, origargs, data = init(frame:getParent().args)
data.pos = pos
data.numgens = function()
local numgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.numbers) do
table.insert(numgens, gender .. "_" .. number)
end
end
return numgens
end
data.allnumgens = {}
for _, gender in ipairs(data.allgenders) do
for _, number in ipairs(data.allnumbers) do
table.insert(data.allnumgens, gender .. "_" .. number)
end
end
parse_state_etc_spec(data, args)
local msgs = get_heads(data, args, 'masculine singular')
-- Always do all of these so cases like يَوْم الاِثْنَيْن work.
-- See comment in show_noun().
local fsgs = do_gender_number(data, args, {"f"}, msgs, "f", true, "sg")
local mdus = do_gender_number(data, args, {"d"}, msgs, "d", false, "du")
local fdus = do_gender_number(data, args, {"fd"}, fsgs, "d", true, "du")
local mpls = do_gender_number(data, args, {"pl", "cpl"}, msgs,
isadj and "p" or nil, false, "pl")
local fpls = do_gender_number(data, args, {"fpl", "cpl"}, fsgs, "fp",
true, "pl")
if isadj then
parse_number_spec(data, args)
else
determine_noun_numbers(data, args, mpls)
end
-- Generate the singular, dual and plural forms
do_inflections_and_overrides(data, args,
{{msgs, "m_sg"}, {fsgs, "f_sg"}, {mdus, "m_du"}, {fdus, "f_du"},
{mpls, "m_pl"}, {fpls, "f_pl"}})
-- Make the table
if isadj then
return make_adj_table(data)
else
return make_gendered_noun_table(data)
end
end
-- The main entry point for gendered noun tables.
function export.show_gendered_noun(frame)
return show_gendered(frame, false, "နာမ်")
end
-- The main entry point for numeral tables. Same as using show_gendered_noun()
-- with pos=numeral.
function export.show_numeral(frame)
return show_gendered(frame, false, "ဂၞန်သၚ်္ချာ")
end
-- The main entry point for adjective tables.
function export.show_adj(frame)
return show_gendered(frame, true, "နာမဝိသေသန")
end
-- Inflection functions
function do_translit(term)
return (lang:transliterate(term)) or track("cant-translit") and BOGUS_CHAR
end
function split_arabic_tr(term)
if term == "" then
return "", ""
elseif not rfind(term, "/") then
return term, do_translit(term)
else
splitvals = rsplit(term, "/")
if #splitvals ~= 2 then
error("Must have at most one slash in a combined Arabic/translit expr: '" .. term .. "'")
end
return splitvals[1], splitvals[2]
end
end
function reorder_shadda(word)
-- shadda+short-vowel (including tanwīn vowels, i.e. -an -in -un) gets
-- replaced with short-vowel+shadda during NFC normalisation, which
-- MediaWiki does for all Unicode strings; however, it makes the
-- detection process inconvenient, so undo it.
word = rsub(word, "(" .. DIACRITIC_ANY_BUT_SH .. ")" .. SH, SH .. "%1")
return word
end
-- Combine PREFIX, AR/TR, and ENDING in that order. PREFIX and ENDING
-- can be of the form ARABIC/TRANSLIT. The Arabic and translit parts are
-- separated out and grouped together, resulting in a string of the
-- form ARABIC/TRANSLIT (TRANSLIT will always be present, computed
-- automatically if not present in the source). The return value is actually a
-- list of ARABIC/TRANSLIT strings because hamza resolution is applied to
-- ARABIC, which may produce multiple outcomes (all of which will have the
-- same TRANSLIT).
function combine_with_ending(prefix, ar, tr, ending)
local prefixar, prefixtr = split_arabic_tr(prefix)
local endingar, endingtr = split_arabic_tr(ending)
-- When calling hamza_seat(), leave out prefixes, which we expect to be
-- clitics like وَ. (In case the prefix is a separate word, it won't matter
-- whether we include it in the text passed to hamza_seat().)
allar = hamza_seat(ar .. endingar)
-- Convert ...īān to ...iyān in case of stems ending in -ī or -ū
-- (e.g. kubrī "bridge").
if rfind(endingtr, "^[aeiouāēīōū]") then
if rfind(tr, "ī$") then
tr = rsub(tr, "ī$", "iy")
elseif rfind(tr, "ū$") then
tr = rsub(tr, "ū$", "uw")
end
end
tr = prefixtr .. tr .. endingtr
allartr = {}
for _, arval in ipairs(allar) do
table.insert(allartr, prefixar .. arval .. "/" .. tr)
end
return allartr
end
-- Combine PREFIX, STEM/TR and ENDING in that order and insert into the
-- list of items in DATA[KEY], initializing it if empty and making sure
-- not to insert duplicates. ENDING can be a list of endings, will be
-- distributed over the remaining parts. PREFIX and/or ENDING can be
-- of the form ARABIC/TRANSLIT (the stem is already split into Arabic STEM
-- and Latin TR). Note that what's inserted into DATA[KEY] is actually a
-- list of ARABIC/TRANSLIT strings; if more than one is present in the list,
-- they represent hamza variants, i.e. different ways of writing a hamza
-- sound, such as مُبْتَدَؤُون vs. مُبْتَدَأُون (see init_data()).
function add_inflection(data, key, prefix, stem, tr, ending)
if data.forms[key] == nil then
data.forms[key] = {}
end
if type(ending) ~= "table" then
ending = {ending}
end
for _, endingval in ipairs(ending) do
insert_if_not(data.forms[key],
combine_with_ending(prefix, stem, tr, endingval))
end
end
-- Form inflections from combination of STEM, with transliteration TR,
-- and ENDINGS (and definite article where necessary, plus any specified
-- prefixes) and store in DATA, for the number or gender/number
-- determined by MOD ("", "mod_", "mod2_", etc.; see call_inflection()) and
-- NUMGEN ("sg", "du", "pl", or "m_sg", "f_pl", etc. for adjectives). ENDINGS
-- is an array of 15 values, each of which is a string or array of
-- alternatives. The order of ENDINGS is indefinite nom, acc, gen; definite
-- nom, acc, gen; construct-state nom, acc, gen; informal indefinite, definite,
-- construct; lemma indefinite, definite, construct. (Normally the lemma is
-- based off of the indefinite, but if the inflection has been restricted to
-- particular states, it comes from one of those states, in the order
-- indefinite, definite, construct.) See also add_inflection() for more info
-- on exactly what is inserted into DATA.
function add_inflections(stem, tr, data, mod, numgen, endings)
stem = canon_hamza(stem)
assert(#endings == 15)
local ismod = mod ~= ""
-- If working on modifier and modN_numgen= is given, it better agree with
-- NUMGEN; the case where it doesn't agree should have been caught in
-- call_inflections().
if ismod and data[mod .. "numgen"] then
assert(data[mod .. "numgen"] == numgen)
end
-- Return a list of combined of ar/tr forms, with the ending tacked on.
-- There may be more than one form because of alternative hamza seats that
-- may be supplied, e.g. مُبْتَدَؤُون or مُبْتَدَأُون (mubtadaʾūn "(grammatical) subjects").
local defstem, deftr
if stem == "?" or data[mod .. "omitarticle"] then
defstem = stem
deftr = tr
else
-- apply sun-letter assimilation and hamzat al-wasl elision
defstem = rsub("الْ" .. stem, "^الْ([سشصتثطدذضزژظنرل])", "ال%1ّ")
defstem = rsub(defstem, "^الْ([اٱ])([ًٌٍَُِ])", "ال%2%1")
deftr = rsub("al-" .. tr, "^al%-([sšṣtṯṭdḏḍzžẓnrḷ])", "a%1-%1")
end
-- For a given MOD spec, is the previous word (base or modifier) a noun?
-- We assume the base is always a noun in this case, and otherwise
-- look at the value of modN_idafa.
local function prev_mod_is_noun(mod)
if mod == "mod_" then
return true
end
if mod == "mod2_" then
return data["mod_idafa"]
end
modnum = assert_rsub(mod, "^mod([0-9]+)_$", "%1")
modnum = modnum - 1
return data["mod" .. modnum .. "_idafa"]
end
local numgens = ismod and data[mod .. "numgen"] and data.numgens() or {numgen}
-- "defcon" means definite adjective modifying construct state noun. We
-- add a ... before the adjective (and after the construct-state noun) to
-- indicate that a nominal modifier would go between noun and adjective.
local stems = {ind = stem, def = defstem, con = stem,
defcon = "... " .. defstem}
local trs = {ind = tr, def = deftr, con = tr, defcon = "... " .. deftr}
for _, ng in ipairs(numgens) do
for _, state in ipairs(data.allstates) do
for _, case in ipairs(data.allcases_with_lemma) do
-- We are generating the inflections for STATE, but sometimes
-- we want to use the inflected form of a different state, e.g.
-- if modN_state= or basestate= is set to some particular state.
-- If we're dealing with an adjectival modifier, then in
-- place of "con" we use "defcon" if immediately after a noun
-- (see comment above), else "def".
local thestate = ismod and data[mod .. "state"] or
ismod and not data[mod .. "idafa"] and state == "con" and
(prev_mod_is_noun(mod) and "defcon" or "def") or
not ismod and data.basestate or
state
local is_lemmainf = case == "lemma" or case == "inf"
-- Don't substitute value of modcase for lemma/informal "cases"
local thecase = is_lemmainf and case or
ismod and data[mod .. "case"] or case
add_inflection(data, mod .. case .. "_" .. ng .. "_" .. state,
data[mod .. "prefix"] or "",
stems[thestate], trs[thestate],
endings[data.statecases[thestate][thecase]])
end
end
end
end
-- Insert into a category and a type variable (e.g. m_sg_type) for the
-- declension type of a particular declension (e.g. masculine singular for
-- adjectives). MOD and NUMGEN are as in call_inflection(). CATVALUE is the
-- category and ENGVALUE is the English description of the declension type.
-- In these values, NOUN is replaced with either "noun" or "adjective",
-- SINGULAR is replaced with the English equivalent of the number in NUMGEN
-- (e.g. "singular", "dual" or "plural") while BROKSING is the same but uses
-- "broken plural" in place of "plural" and "broken paucal" in place of
-- "paucal".
function insert_cat(data, mod, numgen, catvalue, engvalue)
local singpl = data.engnumbers[rsub(numgen, "^.*_", "")]
assert(singpl ~= nil)
local broksingpl = rsub(singpl, "plural", "broken plural")
broksingpl = rsub(broksingpl, "paucal", "broken paucal")
if rfind(broksingpl, "broken plural") and (rfind(catvalue, "BROKSING") or
rfind(engvalue, "BROKSING")) then
-- table.insert(data.categories, "Arabic " .. data.pos .. "s with broken plural")
end
if rfind(catvalue, "irregular") or rfind(engvalue, "irregular") then
-- table.insert(data.categories, "Arabic irregular " .. data.pos .. "s")
end
catvalue = rsub(catvalue, "NOUN", data.pos)
catvalue = rsub(catvalue, "SINGULAR", singpl)
catvalue = rsub(catvalue, "BROKSING", broksingpl)
engvalue = rsub(engvalue, "NOUN", data.pos)
engvalue = rsub(engvalue, "SINGULAR", singpl)
engvalue = rsub(engvalue, "BROKSING", broksingpl)
-- add links to specialised grammatical terms
engvalue = rsub(engvalue, "triptote", "[[triptote]]")
engvalue = rsub(engvalue, "diptote", "[[diptote]]")
engvalue = rsub(engvalue, "broken plural", "BBB")
engvalue = rsub(engvalue, "sound plural", "SSS")
engvalue = rsub(engvalue, "broken", "[[broken plural|broken]]")
engvalue = rsub(engvalue, "sound", "[[sound plural|sound]]")
engvalue = rsub(engvalue, "BBB", "[[broken plural]]")
engvalue = rsub(engvalue, "SSS", "[[sound plural]]")
if mod == "" and catvalue ~= "" then
insert_if_not(data.categories, catvalue)
end
if engvalue ~= "" then
local key = mod .. numgen .. "_type"
if data.forms[key] == nil then
data.forms[key] = {}
end
insert_if_not(data.forms[key], engvalue)
end
if contains(data.states, "def") and not contains(data.states, "ind") then
-- insert_if_not(data.categories, "Arabic definite " .. data.pos .. "s")
end
end
-- Return true if we're handling modifier inflections and the modifier's
-- case is limited to an oblique case (gen or acc; typically genitive,
-- in an ʾidāfa construction). This is used when returning lemma
-- inflections -- the modifier part of the lemma should agree in case
-- with modifier's case if it's restricted in case.
function mod_oblique(mod, data)
return mod ~= "" and data[mod .. "case"] and (
data[mod .. "case"] == "acc" or data[mod .. "case"] == "gen")
end
-- Similar to mod_oblique but specifically when the modifier case is
-- limited to the accusative (which is rare or nonexistent in practice).
function mod_acc(mod, data)
return mod ~= "" and data[mod .. "case"] and data[mod .. "case"] == "acc"
end
-- Handle triptote and diptote inflections
function triptote_diptote(stem, tr, data, mod, numgen, is_dip, lc)
-- Remove any case ending
if rfind(stem, "[" .. UN .. U .. "]$") then
stem = rsub(stem, "[" .. UN .. U .. "]$", "")
tr = rsub(tr, "un?$", "")
end
-- special-case for صلوة pronounced ṣalāh; check translit
local is_aah = rfind(stem, TAM .. "$") and rfind(tr, "āh$")
if rfind(stem, TAM .. "$") then
if rfind(tr, "h$") then
tr = rsub(tr, "h$", "t")
elseif not rfind(tr, "t$") then
tr = tr .. "t"
end
end
add_inflections(stem, tr, data, mod, numgen,
{is_dip and U or UN,
is_dip and A or AN .. ((rfind(stem, "[" .. HAMZA_ON_ALIF .. TAM .. "]$")
or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. HAMZA .. "$")
) and "" or ALIF),
is_dip and A or IN,
U, A, I,
lc and UU or U,
lc and AA or A,
lc and II or I,
{}, {}, {}, -- omit informal inflections
{}, {}, {}, -- omit lemma inflections
})
-- add category and informal and lemma inflections
local tote = lc and "long construct" or is_dip and "diptote" or "triptote"
local singpl_tote = "BROKSING " .. tote
local cat_prefix = "Arabic NOUNs with " .. tote .. " BROKSING"
-- since we're checking translit for -āh we probably don't need to
-- check stem too
if is_aah or rfind(stem, "[" .. AMAD .. ALIF .. "]" .. TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"/t", "/t", "/t", -- informal pron. is -āt
"/h", "/h", "/t", -- lemma uses -āh
})
-- insert_cat(data, mod, numgen, cat_prefix .. " in -āh",
-- singpl_tote .. " in " .. make_link(HYPHEN .. AAH))
elseif rfind(stem, TAM .. "$") then
add_inflections(stem, rsub(tr, "t$", ""), data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "/t",
"", "", "/t",
})
-- insert_cat(data, mod, numgen, cat_prefix .. " in -a",
-- singpl_tote .. " in " .. make_link(HYPHEN .. AH))
elseif lc then
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", UU,
"", "", UU,
})
insert_cat(data, mod, numgen, cat_prefix,
singpl_tote)
else
-- also special-case the nisba ending, which has an informal
-- pronunciation.
if rfind(stem, IY .. SH .. "$") then
local infstem = rsub(stem, SH .. "$", "")
local inftr = rsub(tr, "iyy$", "ī")
-- add informal and lemma inflections separately
add_inflections(infstem, inftr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
{}, {}, {},
})
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
})
else
add_inflections(stem, tr, data, mod, numgen,
{{}, {}, {},
{}, {}, {},
{}, {}, {},
"", "", "",
"", "", "",
})
end
-- insert_cat(data, mod, numgen, "Arabic NOUNs with basic " .. tote .. " BROKSING",
-- "basic " .. singpl_tote)
end
end
-- Regular triptote
inflections["tri"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false)
end
-- Regular diptote
inflections["di"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, true)
end
-- Elative and color/defect adjective: usually same as diptote,
-- might be invariable
function elative_color_defect(stem, tr, data, mod, numgen)
if rfind(stem, "[" .. ALIF .. AMAQ .. "]$") then
invariable(stem, tr, data, mod, numgen)
else
triptote_diptote(stem, tr, data, mod, numgen, true)
end
end
-- Elative: usually same as diptote, might be invariable
inflections["el"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Color/defect adjective: Same as elative
inflections["cd"] = function(stem, tr, data, mod, numgen)
elative_color_defect(stem, tr, data, mod, numgen)
end
-- Triptote with lengthened ending in the construct state
inflections["lc"] = function(stem, tr, data, mod, numgen)
triptote_diptote(stem, tr, data, mod, numgen, false, true)
end
function in_defective(stem, tr, data, mod, numgen, tri)
if not rfind(stem, IN .. "$") then
error("'in' declension stem should end in -in: '" .. stem .. "'")
end
stem = rsub(stem, IN .. "$", "")
tr = rsub(tr, "in$", "")
local acc_ind_ending = tri and IY .. AN .. ALIF or IY .. A
add_inflections(stem, tr, data, mod, numgen,
{IN, acc_ind_ending, IN,
II, IY .. A, II,
II, IY .. A, II,
II, II, II,
-- FIXME: What should happen with the lemma when modifier case
-- is limited to the accusative and modifier state is e.g. definite?
-- Should the lemma end in -iya or -ī? In practice this will rarely
-- if ever happen.
mod_acc(mod, data) and acc_ind_ending or IN, II, II,
})
local tote = tri and "triptote" or "diptote"
-- insert_cat(data, mod, numgen, "Arabic NOUNs with " .. tote .. " BROKSING in -in",
-- "BROKSING " .. tote .. " in " .. make_link(HYPHEN .. IN))
end
function detect_in_type(stem, ispl)
if ispl and rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IN .. "$") then -- layālin
return "diin"
else -- other -in words
return "triin"
end
end
-- Defective in -in
inflections["in"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen,
detect_in_type(stem, rfind(numgen, "pl")) == "triin")
end
-- Defective in -in, force "triptote" variant
inflections["triin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, true)
end
-- Defective in -in, force "diptote" variant
inflections["diin"] = function(stem, tr, data, mod, numgen)
in_defective(stem, tr, data, mod, numgen, false)
end
-- Defective in -an (comes in two variants, depending on spelling with tall alif or alif maqṣūra)
inflections["an"] = function(stem, tr, data, mod, numgen)
local tall_alif
if rfind(stem, AN .. ALIF .. "$") then
tall_alif = true
stem = rsub(stem, AN .. ALIF .. "$", "")
elseif rfind(stem, AN .. AMAQ .. "$") then
tall_alif = false
stem = rsub(stem, AN .. AMAQ .. "$", "")
else
error("Invalid stem for 'an' declension type: " .. stem)
end
tr = rsub(tr, "an$", "")
if tall_alif then
add_inflections(stem, tr, data, mod, numgen,
{AN .. ALIF, AN .. ALIF, AN .. ALIF,
AA, AA, AA,
AA, AA, AA,
AA, AA, AA,
AN .. ALIF, AA, AA,
})
else
add_inflections(stem, tr, data, mod, numgen,
{AN .. AMAQ, AN .. AMAQ, AN .. AMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AAMAQ, AAMAQ, AAMAQ,
AN .. AMAQ, AAMAQ, AAMAQ,
})
end
-- FIXME: Should we distinguish between tall alif and alif maqṣūra?
-- insert_cat(data, mod, numgen, "Arabic NOUNs with BROKSING in -an",
-- "BROKSING in " .. make_link(HYPHEN .. AN .. (tall_alif and ALIF or AMAQ)))
end
function invariable(stem, tr, data, mod, numgen)
add_inflections(stem, tr, data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
-- insert_cat(data, mod, numgen, "Arabic NOUNs with invariable BROKSING",
-- "BROKSING invariable")
end
-- Invariable in -ā (non-loanword type)
inflections["inv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Invariable in -ā (loanword type, behaving in the dual as if ending in -a, I think!)
inflections["lwinv"] = function(stem, tr, data, mod, numgen)
invariable(stem, tr, data, mod, numgen)
end
-- Duals
inflections["d"] = function(stem, tr, data, mod, numgen)
if rfind(stem, ALIF .. NI .. "?$") then
stem = rsub(stem, AOPTA .. NI .. "?$", "")
elseif rfind(stem, AMAD .. NI .. "?$") then
stem = rsub(stem, AMAD .. NI .. "?$", HAMZA_PH)
else
error("Dual stem should end in -ān(i): '" .. stem .. "'")
end
tr = rsub(tr, "āni?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AANI, AYNI, AYNI,
AANI, AYNI, AYNI,
AA, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AAN, mo and AYN or AAN, mo and AYSK or AA,
})
-- insert_cat(data, mod, numgen, "", "dual in " .. make_link(HYPHEN .. AANI))
end
-- Sound masculine plural
inflections["smp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, UUNA .. "?$") then
error("Sound masculine plural stem should end in -ūn(a): '" .. stem .. "'")
end
stem = rsub(stem, UUNA .. "?$", "")
tr = rsub(tr, "ūna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{UUNA, IINA, IINA,
UUNA, IINA, IINA,
UU, II, II,
IIN, IIN, II,
mo and IIN or UUN, mo and IIN or UUN, mo and II or UU,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
-- insert_cat(data, mod, numgen, "Arabic NOUNs with sound masculine SINGULAR",
-- "sound masculine SINGULAR")
end
-- Sound feminine plural
inflections["sfp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, "[" .. ALIF .. AMAD .. "]" .. T .. UN .. "?$") then
error("Sound feminine plural stem should end in -āt(un): '" .. stem .. "'")
end
stem = rsub(stem, UN .. "$", "")
tr = rsub(tr, "un$", "")
add_inflections(stem, tr, data, mod, numgen,
{UN, IN, IN,
U, I, I,
U, I, I,
"", "", "",
"", "", "",
})
-- use SINGULAR because this might be used with the paucal
-- instead of plural
-- insert_cat(data, mod, numgen, "Arabic NOUNs with sound feminine SINGULAR",
-- "sound feminine SINGULAR")
end
-- Plural of defective in -an
inflections["awnp"] = function(stem, tr, data, mod, numgen)
if not rfind(stem, AWNA .. "?$") then
error("'awnp' plural stem should end in -awn(a): '" .. stem .. "'")
end
stem = rsub(stem, AWNA .. "?$", "")
tr = rsub(tr, "awna?$", "")
local mo = mod_oblique(mod, data)
add_inflections(stem, tr, data, mod, numgen,
{AWNA, AYNA, AYNA,
AWNA, AYNA, AYNA,
AWSK, AYSK, AYSK,
AYN, AYN, AYSK,
mo and AYN or AWN, mo and AYN or AWN, mo and AYSK or AWSK,
})
-- use SINGULAR because conceivably this might be used with the paucal
-- instead of plural
--insert_cat(data, mod, numgen, "Arabic NOUNs with sound SINGULAR in -awna",
-- "sound SINGULAR in " .. make_link(HYPHEN .. AWNA))
end
-- Unknown
inflections["?"] = function(stem, tr, data, mod, numgen)
add_inflections("?", "?", data, mod, numgen,
{"", "", "",
"", "", "",
"", "", "",
"", "", "",
"", "", "",
})
-- insert_cat(data, mod, numgen, "Arabic NOUNs with unknown SINGULAR",
-- "SINGULAR unknown")
end
-- Detect declension of noun or adjective stem or lemma. We allow triptotes,
-- diptotes and sound plurals to either come with ʾiʿrāb or not. We detect
-- some cases where vowels are missing, when it seems fairly unambiguous to
-- do so. ISFEM is true if we are dealing with a feminine stem (not
-- currently used and needs to be rethought). NUM is "sg", "du", or "pl",
-- depending on the number of the stem.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
--
-- Some unexpectedly diptote nouns/adjectives:
--
-- jiʿrān in ʾabū jiʿrān "dung beetle"
-- distributive numbers: ṯunāʾ "two at a time", ṯulāṯ/maṯlaṯ "three at a time",
-- rubāʿ "four at a time" (not a regular diptote pattern, cf. triptote
-- junāḥ "misdemeanor, sin", nujār "origin, root", nuḥām "flamingo")
-- jahannam (f.) "hell"
-- many names: jilliq/jillaq "Damascus", judda/jidda "Jedda", jibrīl (and
-- variants) "Gabriel", makka "Mecca", etc.
-- jibriyāʾ "pride"
-- kibriyāʾ "glory, pride"
-- babbaḡāʾ "parrot"
-- ʿayāyāʾ "incapable, tired"
-- suwaidāʾ "black bile, melancholy"
-- Note also: ʾajhar "day-blind" (color-defect) and ʾajhar "louder" (elative)
function export.detect_type(stem, isfem, num, pos)
local function dotrack(word)
track(word)
track(word .. "/" .. pos)
return true
end
-- Not strictly necessary because the caller (stem_and_type) already
-- reorders, but won't hurt, and may be necessary if this function is
-- called from an external caller.
stem = reorder_shadda(stem)
local origstem = stem
-- So that we don't get tripped up by alif madda, we replace alif madda
-- with the sequence hamza + fatḥa + alif before the regexps below.
stem = rsub(stem, AMAD, HAMZA .. AA)
if num == "du" then
if rfind(stem, ALIF .. NI .. "?$") then
return "d"
else
error("Malformed stem for dual, should end in the nominative dual ending -ān(i): '" .. origstem .. "'")
end
end
if rfind(stem, IN .. "$") then -- -in words
return detect_in_type(stem, num == "pl")
elseif rfind(stem, AN .. "[" .. ALIF .. AMAQ .. "]$") then
return "an"
elseif rfind(stem, AN .. "$") then
error("Malformed stem, fatḥatan should be over second-to-last letter: " .. origstem)
elseif num == "pl" and rfind(stem, AW .. SKOPT .. N .. AOPT .. "$") then
return "awnp"
elseif num == "pl" and rfind(stem, ALIF .. T .. UNOPT .. "$") and
-- Avoid getting tripped up by plurals like ʾawqāt "times",
-- ʾaḥwāt "fishes", ʾabyāt "verses", ʾazyāt "oils", ʾaṣwāt "voices",
-- ʾamwāt "dead (pl.)".
not rfind(stem, HAMZA_ON_ALIF .. A .. CONS .. SK .. CONS .. AAT .. UNOPT .. "$") then
return "sfp"
elseif num == "pl" and rfind(stem, W .. N .. AOPT .. "$") and
-- Avoid getting tripped up by plurals like ʿuyūn "eyes",
-- qurūn "horns" (note we check for U between first two consonants
-- so we correctly ignore cases like sinūn "hours" (from sana),
-- riʾūn "lungs" (from riʾa) and banūn "sons" (from ibn).
not rfind(stem, "^" .. CONS .. U .. CONS .. UUN .. AOPT .. "$") then
return "smp"
elseif rfind(stem, UN .. "$") then -- explicitly specified triptotes (we catch sound feminine plurals above)
return "tri"
elseif rfind(stem, U .. "$") then -- explicitly specified diptotes
return "di"
elseif -- num == "pl" and
( -- various diptote plural patterns; these are diptote even in the singular (e.g. yanāyir "January", falāfil "falafel", tuʾabāʾ "yawn, fatigue"
-- currently we sometimes end up with such plural patterns in the "singular" in a singular
-- ʾidāfa construction with plural modifier. (FIXME: These should be fixed to the correct number.)
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. IOPT .. Y .. "?" .. CONS .. "$") and dotrack("fawaakih") or -- fawākih, daqāʾiq, makātib, mafātīḥ
rfind(stem, "^" .. CONS .. AOPT .. CONS .. AOPTA .. CONS .. SH .. "$")
and not rfind(stem, "^" .. T) and dotrack("mawaadd") or -- mawādd, maqāmm, ḍawāll; exclude t- so we don't catch form-VI verbal nouns like taḍādd (HACK!!!)
rfind(stem, "^" .. CONS .. U .. CONS .. AOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("wuzaraa") or -- wuzarāʾ "ministers", juhalāʾ "ignorant (pl.)"
rfind(stem, ELCD_START .. SKOPT .. CONS .. IOPT .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("asdiqaa") or -- ʾaṣdiqāʾ
rfind(stem, ELCD_START .. IOPT .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("aqillaa") -- ʾaqillāʾ, ʾajillāʾ "important (pl.)", ʾaḥibbāʾ "lovers"
) then
return "di"
elseif num == "sg" and ( -- diptote singular patterns (nouns/adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. "$") and dotrack("qamraa") or -- qamrāʾ "moon-white, moonlight"; baydāʾ "desert"; ṣaḥrāʾ "desert-like, desert"; tayhāʾ "trackless, desolate region"; not pl. to avoid catching e.g. ʾabnāʾ "sons", ʾaḥmāʾ "fathers-in-law", ʾamlāʾ "steppes, deserts" (pl. of malan), ʾanbāʾ "reports" (pl. of nabaʾ)
rfind(stem, ELCD_START .. SK .. CONS .. A .. CONS .. "$") and dotrack("abyad") or -- ʾabyaḍ "white", ʾakbar "greater"; FIXME nouns like ʾaʿzab "bachelor", ʾaḥmad "Ahmed" but not ʾarnab "rabbit", ʾanjar "anchor", ʾabjad "abjad", ʾarbaʿ "four", ʾandar "threshing floor" (cf. diptote ʾandar "rarer")
rfind(stem, ELCD_START .. A .. CONS .. SH .. "$") and dotrack("alaff") or -- ʾalaff "plump", ʾaḥabb "more desirable"
-- do the following on the origstem so we can check specifically for alif madda
rfind(origstem, "^" .. AMAD .. CONS .. A .. CONS .. "$") and dotrack("aalam") -- ʾālam "more painful", ʾāḵar "other"
) then
return "di"
elseif num == "sg" and pos == "adjective" and ( -- diptote singular patterns (adjectives)
rfind(stem, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. "$") and dotrack("kaslaan") or -- kaslān "lazy", ʿaṭšān "thirsty", jawʿān "hungry", ḡaḍbān "angry", tayhān "wandering, perplexed"; but not nouns like qaṭrān "tar", šayṭān "devil", mawtān "plague", maydān "square"
-- rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. "$") and dotrack("laffaa") -- excluded because of too many false positives e.g. ḵawwān "disloyal", not to mention nouns like jannān "gardener"; only diptote example I can find is ʿayyān "incapable, weary" (diptote per Lane but not Wehr)
rfind(stem, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. "$") and dotrack("laffaa") -- laffāʾ "plump (fem.)"; but not nouns like jarrāʾ "runner", ḥaddāʾ "camel driver", lawwāʾ "wryneck"
) then
return "di"
elseif rfind(stem, AMAQ .. "$") then -- kaslā, ḏikrā (spelled with alif maqṣūra)
return "inv"
elseif rfind(stem, "[" .. ALIF .. SK .. "]" .. Y .. AOPTA .. "$") then -- dunyā, hadāyā (spelled with tall alif after yāʾ)
return "inv"
elseif rfind(stem, ALIF .. "$") then -- kāmērā, lībiyā (spelled with tall alif; we catch dunyā and hadāyā above)
return "lwinv"
elseif rfind(stem, II .. "$") then -- cases like كُوبْرِي kubrī "bridge" and صَوَانِي ṣawānī pl. of ṣīniyya; modern words that would probably end with -in
dotrack("ii")
return "inv"
elseif rfind(stem, UU .. "$") then -- FIXME: Does this occur? Check the tracking
dotrack("uu")
return "inv"
else
return "tri"
end
end
-- Replace hamza (of any sort) at the end of a word, possibly followed by
-- a nominative case ending or -in or -an, with HAMZA_PH, and replace alif
-- madda at the end of a word with HAMZA_PH plus fatḥa + alif. To undo these
-- changes, use hamza_seat().
function canon_hamza(word)
word = rsub(word, AMAD .. "$", HAMZA_PH .. AA)
word = rsub(word, HAMZA_ANY .. "([" .. UN .. U .. IN .. "]?)$", HAMZA_PH .. "%1")
word = rsub(word, HAMZA_ANY .. "(" .. AN .. "[" .. ALIF .. AMAQ .. "])$", HAMZA_PH .. "%1")
return word
end
-- Supply the appropriate hamza seat(s) for a placeholder hamza.
function hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
return ar_utilities.process_hamza(word)
end
return {word}
end
--[[
-- Supply the appropriate hamza seat for a placeholder hamza in a combined
-- Arabic/translation expression.
function split_and_hamza_seat(word)
if rfind(word, HAMZA_PH) then -- optimization to avoid many regexp substs
local ar, tr = split_arabic_tr(word)
-- FIXME: Do something with all values returned
ar = ar_utilities.process_hamza(ar)[1]
return ar .. "/" .. tr
end
return word
end
--]]
-- Return stem and type of an argument given the singular stem and whether
-- this is a plural argument. WORD may be of the form ARABIC, ARABIC/TR,
-- ARABIC:TYPE, ARABIC/TR:TYPE, or TYPE, for Arabic stem ARABIC with
-- transliteration TR and of type (i.e. declension) TYPE. If the type
-- is omitted, it is auto-detected using detect_type(). If the transliteration
-- is omitted, it is auto-transliterated from the Arabic. If only the type
-- is present, it is a sound plural type ("sf", "sm" or "awn"),
-- in which case the stem and translit are generated from the singular by
-- regular rules. SG may be of the form ARABIC/TR or ARABIC. ISFEM is true
-- if WORD is a feminine stem. NUM is either "sg", "du" or "pl" according to
-- the number of the stem. The return value will be in the ARABIC/TR format.
--
-- POS is the part of speech, generally "noun" or "adjective". Used to
-- distinguish nouns and adjectives of the فَعْلَان type. There are nouns of
-- this type and they generally are triptotes, e.g. قَطْرَان "tar"
-- and شَيْطَان "devil". An additional complication is that the user can set
-- the POS to something else, like "numeral". We don't use this POS for
-- modifiers, where we determine whether they are noun-like or adjective-like
-- according to whether mod_idafa= is true.
function export.stem_and_type(word, sg, sgtype, isfem, num, pos)
local rettype = nil
if rfind(word, ":") then
local split = rsplit(word, ":")
if #split > 2 then
error("More than one colon found in argument: '" .. word .. "'")
end
word, rettype = split[1], split[2]
end
local ar, tr = split_arabic_tr(word)
-- Need to reorder shaddas here so that shadda at the end of a stem
-- followed by ʾiʿrāb or a plural ending or whatever can get processed
-- correctly. This processing happens in various places so make sure
-- we return the reordered Arabic in all circumstances.
ar = reorder_shadda(ar)
local artr = ar .. "/" .. tr
-- Now return split-out ARABIC/TR and TYPE, with shaddas reordered in
-- the Arabic.
if rettype then
return artr, rettype
end
-- Likewise, do shadda reordering for the singular.
local sgar, sgtr = split_arabic_tr(sg)
sgar = reorder_shadda(sgar)
-- Apply a substitution to the singular Arabic and translit. If a
-- substitution could be made, return the combined ARABIC/TR with
-- substitutions made; else, return nil. The Arabic has ARFROM
-- replaced with ARTO, while the translit has TRFROM replaced with
-- TRTO, and if that doesn't match, replace TRFROM2 with TRTO2.
local function sub(arfrom, arto, trfrom, trto, trfrom2, trto2, trfrom3, trto3)
if rfind(sgar, arfrom) then
local arret = rsub(sgar, arfrom, arto)
local trret = sgtr
if rfind(sgtr, trfrom) then
trret = rsub(sgtr, trfrom, trto)
elseif trfrom2 and rfind(sgtr, trfrom2) then
trret = rsub(sgtr, trfrom2, trto2)
elseif trfrom3 and rfind(sgtr, trfrom3) then
trret = rsub(sgtr, trfrom3, trto3)
elseif not rfind(sgtr, BOGUS_CHAR) then
error("Transliteration '" .. sgtr .."' does not have same ending as Arabic '" .. sgar .. "'")
end
return arret .. "/" .. trret
else
return nil
end
end
if (num ~= "sg" or not isfem) and (word == "elf" or word == "cdf" or word == "intf" or word == "rf" or word == "f") then
error("Inference of form for inflection type '" .. word .. "' only allowed in singular feminine")
end
if num ~= "du" and word == "d" then
error("Inference of form for inflection type '" .. word .. "' only allowed in dual")
end
if num ~= "pl" and (word == "sfp" or word == "smp" or word == "awnp" or word == "cdp" or word == "sp" or word == "fp" or word == "p") then
error("Inference of form for inflection type '" .. word .. "' only allowed in plural")
end
local function is_intensive_adj(ar)
return rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SK .. AMAD .. N .. UOPT .. "$") or
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. N .. UOPT .. "$")
end
local function is_feminine_cd_adj(ar)
return pos == "adjective" and
(rfind(ar, "^" .. CONS .. A .. CONS .. SK .. CONS .. AOPTA .. HAMZA .. UOPT .. "$") or -- ʾḥamrāʾ/ʿamyāʾ/bayḍāʾ
rfind(ar, "^" .. CONS .. A .. CONS .. SH .. AOPTA .. HAMZA .. UOPT .. "$") -- laffāʾ
)
end
local function is_elcd_adj(ar)
return rfind(ar, ELCD_START .. SK .. CONS .. A .. CONS .. UOPT .. "$") or -- ʾabyaḍ "white", ʾakbar "greater"
rfind(ar, ELCD_START .. A .. CONS .. SH .. UOPT .. "$") or -- ʾalaff "plump", ʾaqall "fewer"
rfind(ar, ELCD_START .. SK .. CONS .. AAMAQ .. "$") or -- ʾaʿmā "blind", ʾadnā "lower"
rfind(ar, "^" .. AMAD .. CONS .. A .. CONS .. UOPT .. "$") -- ʾālam "more painful", ʾāḵar "other"
end
if word == "?" or
(rfind(word, "^[a-z][a-z]*$") and sgtype == "?") then
--if 'word' is a type, actual value inferred from sg; if sgtype is ?,
--propagate it to all derived types
return "", "?"
end
if word == "intf" then
if not is_intensive_adj(sgar) then
error("Singular stem not in CACCān form: " .. sgar)
end
local ret = (
sub(AMAD .. N .. UOPT .. "$", AMAD, "nu?$", "") or -- ends in -ʾān
sub(AOPTA .. N .. UOPT .. "$", AMAQ, "nu?$", "") -- ends in -ān
)
return ret, "inv"
end
if word == "elf" then
local ret = (
sub(ELCD_START .. SK .. "[" .. Y .. W .. "]" .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2" .. AMAQ, "ʔa(.)[yw]a(.)u?", "%1ū%2ā") or -- ʾajyad
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3" .. AMAQ, "ʔa(.)(.)a(.)u?", "%1u%2%3ā") or -- ʾakbar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH .. AMAQ, "ʔa(.)a(.)%2u?", "%1u%2%2ā") or -- ʾaqall
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. SK .. Y .. ALIF, "ʔa(.)(.)ā", "%1u%2yā") or -- ʾadnā
sub("^" .. AMAD .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
HAMZA_ON_ALIF .. U .. "%1" .. SK .. "%2" .. AMAQ, "ʔā(.)a(.)u?", "ʔu%1%2ā") -- ʾālam "more painful", ʾāḵar "other"
)
if not ret then
error("Singular stem not an elative adjective: " .. sgar)
end
return ret, "inv"
end
if word == "cdf" then
local ret = (
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. A .. "%2" .. SK .. "%3" .. AA .. HAMZA, "ʔa(.)(.)a(.)u?", "%1a%2%3āʔ") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. A .. "%2" .. SH .. AA .. HAMZA, "ʔa(.)a(.)%2u?", "%1a%2%2āʔ") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. A .. "%2" .. SK .. Y .. AA .. HAMZA, "ʔa(.)(.)ā", "%1a%2yāʔ") -- ʾaʿmā
)
if not ret then
error("Singular stem not a color/defect adjective: " .. sgar)
end
return ret, "cd" -- so plural will be correct
end
-- Regular feminine -- add ة, possibly with stem modifications
if word == "rf" then
sgar = canon_hamza(sgar)
if rfind(sgar, TAM .. UNUOPT .. "$") then
--Don't do this or we have problems when forming singulative from
--collective with a construct modifier that's feminine
--error("Singular stem is already feminine: " .. sgar)
return sgar .. "/" .. sgtr, "tri"
end
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AAH, "an$", "āh") or -- ends in -an
sub(IN .. "$", IY .. AH, "in$", "iya") or -- ends in -in
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AAH, "ā$", "āh") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AH, "un?$", "a", "$", "a") or -- anything else + -u(n)
sub("$", AH, "$", "a") -- anything else
)
return ret, "tri"
end
if word == "f" then
if sgtype == "cd" then
return export.stem_and_type("cdf", sg, sgtype, true, "sg", pos)
elseif sgtype == "el" then
return export.stem_and_type("elf", sg, sgtype, true, "sg", pos)
elseif sgtype =="di" and is_intensive_adj(sgar) then
return export.stem_and_type("intf", sg, sgtype, true, "sg", pos)
elseif sgtype == "di" and is_elcd_adj(sgar) then
-- If form is elative or color-defect, we don't know which of
-- the two it is, and each has a special feminine which isn't
-- the regular "just add ة", so shunt to unknown. This will
-- ensure that ?'s appear in place of the inflection -- also
-- for dual and plural.
return export.stem_and_type("?", sg, sgtype, true, "sg", pos)
else
return export.stem_and_type("rf", sg, sgtype, true, "sg", pos)
end
end
if word == "rm" then
sgar = canon_hamza(sgar)
--Don't do this or we have problems when forming collective from
--singulative with a construct modifier that's not feminine,
--e.g. شَجَرَة التُفَّاح
--if not rfind(sgar, TAM .. UNUOPT .. "$") then
-- error("Singular stem is not feminine: " .. sgar)
--end
local ret = (
sub(AAH .. UNUOPT .. "$", AN .. AMAQ, "ātun?$", "an", "ā[ht]$", "an") or -- in -āh
sub(IY .. AH .. UNUOPT .. "$", IN, "iyatun?$", "in", "iya$", "in") or -- ends in -iya
sub(AOPT .. TAM .. UNUOPT .. "$", "", "atun?$", "", "a$", "") or --ends in -a
sub("$", "", "$", "") -- do nothing
)
return ret, "tri"
end
if word == "m" then
-- FIXME: handle cd (color-defect)
-- FIXME: handle el (elative)
-- FIXME: handle int (intensive)
return export.stem_and_type("rm", sg, sgtype, false, "sg", pos)
end
-- The plural used for feminine adjectives. If the singular type is
-- color/defect or it looks like a feminine color/defect adjective,
-- use color/defect plural. Otherwise shunt to sound feminine plural.
if word == "fp" then
if sgtype == "cd" or is_feminine_cd_adj(sgar) then
return export.stem_and_type("cdp", sg, sgtype, true, "pl", pos)
else
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
end
end
if word == "sp" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
elseif isfem then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif sgtype == "an" then
return export.stem_and_type("awnp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
end
end
-- Conservative plural, as used for masculine plural adjectives.
-- If singular type is color-defect, shunt to color-defect plural; else
-- shunt to unknown, so ? appears in place of the inflections.
if word == "p" then
if sgtype == "cd" then
return export.stem_and_type("cdp", sg, sgtype, isfem, "pl", pos)
else
return export.stem_and_type("?", sg, sgtype, isfem, "pl", pos)
end
end
-- Special plural used for paucal plurals of singulatives. If ends in -ة
-- (most common), use strong feminine plural; if ends with -iyy (next
-- most common), use strong masculine plural; ends default to "p"
-- (conservative plural).
if word == "paucp" then
if rfind(sgar, TAM .. UNUOPT .. "$") then
return export.stem_and_type("sfp", sg, sgtype, true, "pl", pos)
elseif rfind(sgar, IY .. SH .. UNUOPT .. "$") then
return export.stem_and_type("smp", sg, sgtype, false, "pl", pos)
else
return export.stem_and_type("p", sg, sgtype, isfem, "pl", pos)
end
end
if word == "d" then
sgar = canon_hamza(sgar)
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "an$", "ayān") or -- ends in -an
sub(IN .. "$", IY .. AAN, "in$", "iyān") or -- ends in -in
sgtype == "lwinv" and sub(AOPTA .. "$", AT .. AAN, "[āa]$", "atān") or -- lwinv, ends in alif; allow translit with short -a
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AY .. AAN, "ā$", "ayān") or -- ends in alif or alif maqṣūra
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
--
-- NOTE: Collapsing the "h$" and "$" cases into "h?$" doesn't work
-- in the case of words ending in -āh, which end up having the
-- translit end in -tāntān.
sub(TAM .. UNU .. "$", T .. AAN, "[ht]un?$", "tān", "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa + -u(n)
sub(TAM .. "$", T .. AAN, "h$", "tān", "$", "tān") or -- ends in tāʾ marbuṭa
-- Same here as above
sub(UNU .. "$", AAN, "un?$", "ān", "$", "ān") or -- anything else + -u(n)
sub("$", AAN, "$", "ān") -- anything else
)
return ret, "d"
end
-- Strong feminine plural in -āt, possibly with stem modifications
if word == "sfp" then
sgar = canon_hamza(sgar)
sgar = rsub(sgar, AMAD .. "(" .. TAM .. UNUOPT .. ")$", HAMZA_PH .. AA .. "%1")
sgar = rsub(sgar, HAMZA_ANY .. "(" .. AOPT .. TAM .. UNUOPT .. ")$", HAMZA_PH .. "%1")
local ret = (
sub(AOPTA .. TAM .. UNUOPT .. "$", AYAAT, "ā[ht]$", "ayāt", "ātun?$", "ayāt") or -- ends in -āh
sub(AOPT .. TAM .. UNUOPT .. "$", AAT, "a$", "āt", "atun?$", "āt") or -- ends in -a
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "an$", "ayāt") or -- ends in -an
sub(IN .. "$", IY .. AAT, "in$", "iyāt") or -- ends in -in
sgtype == "inv" and (
sub(AOPT .. "[" .. ALIF .. AMAQ .. "]$", AYAAT, "ā$", "ayāt") -- ends in alif or alif maqṣūra
) or
sgtype == "lwinv" and (
sub(AOPTA .. "$", AAT, "[āa]$", "āt") -- loanword ending in tall alif; allow translit with short -a
) or
-- We separate the ʾiʿrāb and no-ʾiʿrāb cases even though we can
-- do a single Arabic regexp to cover both because we want to
-- remove u(n) from the translit only when ʾiʿrāb is present to
-- lessen the risk of removing -un in the actual stem. We also
-- allow for cases where the ʾiʿrāb is present in Arabic but not
-- in translit.
sub(UNU .. "$", AAT, "un?$", "āt", "$", "āt") or -- anything else + -u(n)
sub("$", AAT, "$", "āt") -- anything else
)
return ret, "sfp"
end
if word == "smp" then
sgar = canon_hamza(sgar)
local ret = (
sub(IN .. "$", UUN, "in$", "ūn") or -- ends in -in
-- See comments above for why we have two cases, one for UNU and
-- one for non-UNU
sub(UNU .. "$", UUN, "un?$", "ūn", "$", "ūn") or -- anything else + -u(n)
sub("$", UUN, "$", "ūn") -- anything else
)
return ret, "smp"
end
-- Color/defect plural; singular must be masculine or feminine
-- color/defect adjective
if word == "cdp" then
local ret = (
sub(ELCD_START .. SK .. W .. A .. CONSPAR .. UOPT .. "$",
"%1" .. UU .. "%2", "ʔa(.)wa(.)u?", "%1ū%2") or -- ʾaswad
sub(ELCD_START .. SK .. Y .. A .. CONSPAR .. UOPT .. "$",
"%1" .. II .. "%2", "ʔa(.)ya(.)u?", "%1ī%2") or -- ʾabyaḍ
sub(ELCD_START .. SK .. CONSPAR .. A .. CONSPAR .. UOPT .. "$",
"%1" .. U .. "%2" .. SK .. "%3", "ʔa(.)(.)a(.)u?", "%1u%2%3") or -- ʾaḥmar
sub(ELCD_START .. A .. CONSPAR .. SH .. UOPT .. "$",
"%1" .. U .. "%2" .. SH, "ʔa(.)a(.)%2u?", "%1u%2%2") or -- ʾalaff
sub(ELCD_START .. SK .. CONSPAR .. AAMAQ .. "$",
"%1" .. U .. "%2" .. Y, "ʔa(.)(.)ā", "%1u%2y") or -- ʾaʿmā
sub("^" .. CONSPAR .. A .. W .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. UU .. "%2", "(.)aw(.)āʔu?", "%1ū%2") or -- sawdāʾ
sub("^" .. CONSPAR .. A .. Y .. SKOPT .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. II .. "%2", "(.)ay(.)āʔu?", "%1ī%2") or -- bayḍāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SK .. CONSPAR .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SK .. "%3", "(.)a(.)(.)āʔu?", "%1u%2%3") or -- ʾḥamrāʾ/ʿamyāʾ
sub("^" .. CONSPAR .. A .. CONSPAR .. SH .. AA .. HAMZA .. UOPT .. "$", "%1" .. U .. "%2" .. SH, "(.)a(.)%2āʔu?", "%1u%2%2") -- laffāʾ
)
if not ret then
error("For 'cdp', singular must be masculine or feminine color/defect adjective: " .. sgar)
end
return ret, "tri"
end
if word == "awnp" then
local ret = (
sub(AN .. "[" .. ALIF .. AMAQ .. "]$", AWSK .. N, "an$", "awn") -- ends in -an
)
if not ret then
error("For 'awnp', singular must end in -an: " .. sgar)
end
return ret, "awnp"
end
return artr, export.detect_type(ar, isfem, num, pos)
end
-- need LRM here so multiple Arabic plurals end up agreeing in order with
-- the transliteration
local outersep = LRM .. "; "
local innersep = LRM .. "/"
-- Subfunction of show_form(), used to implement recursively generating
-- all combinations of elements from FORM and from each of the items in
-- LIST_OF_MODS, both of which are either arrays of strings or arrays of
-- arrays of strings, where the strings are in the form ARABIC/TRANSLIT,
-- as described in show_form(). TRAILING_ARTRMODS is an array of ARTRMOD
-- items, each of which is a two-element array of ARMOD (Arabic) and TRMOD
-- (transliteration), accumulating all of the suffixes generated so far
-- in the recursion process. Each time we recur we take the last MOD item
-- off of LIST_OF_MODS, separate each element in MOD into its Arabic and
-- Latin parts and to each Arabic/Latin pair we add all elements in
-- TRAILING_ARTRMODS, passing the newly generated list of ARTRMOD items
-- down the next recursion level with the shorter LIST_OF_MODS. We end up
-- returning a string to insert into the Wiki-markup table.
function show_form_1(form, list_of_mods, trailing_artrmods, use_parens)
if #list_of_mods == 0 then
local arabicvals = {}
local latinvals = {}
local parenvals = {}
-- Accumulate separately the Arabic and transliteration into
-- ARABICVALS and LATINVALS, then concatenate each down below.
-- However, if USE_PARENS, we put each transliteration directly
-- after the corresponding Arabic, in parens, and put the results
-- in PARENVALS, which get concatenated below. (This is used in the
-- title of the declension table.)
for _, artrmod in ipairs(trailing_artrmods) do
assert(#artrmod == 2)
local armod = artrmod[1]
local trmod = artrmod[2]
for _, subform in ipairs(form) do
local ar_span, tr_span
local ar_subspan, tr_subspan
local ar_subspans = {}
local tr_subspans = {}
if type(subform) ~= "table" then
subform = {subform}
end
for _, subsubform in ipairs(subform) do
local arabic, translit = split_arabic_tr(subsubform)
if arabic == "-" then
ar_subspan = "—"
tr_subspan = "—"
elseif arabic == "?" then
ar_subspan = "?"
tr_subspan = "?"
else
tr_subspan = (rfind(translit, BOGUS_CHAR) or rfind(trmod, BOGUS_CHAR)) and "?" or
require("Module:script utilities").tag_translit(translit .. trmod, lang, "default", 'style="color: var(--wikt-palette-grey-8,#888);"')
-- implement elision of al- after vowel
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a([sšṣtṯṭdḏḍzžẓnrḷl]%-)", "%1%2")
tr_subspan = rsub(tr_subspan, "([aeiouāēīōū][ %-])a(llāh)", "%1%2")
ar_subspan = m_links.full_link({lang = lang, term = arabic .. armod, tr = "-"})
end
insert_if_not(ar_subspans, ar_subspan)
insert_if_not(tr_subspans, tr_subspan)
end
ar_span = table.concat(ar_subspans, innersep)
tr_span = table.concat(tr_subspans, innersep)
if use_parens then
table.insert(parenvals, ar_span .. " (" .. tr_span .. ")")
else
table.insert(arabicvals, ar_span)
table.insert(latinvals, tr_span)
end
end
end
if use_parens then
return table.concat(parenvals, outersep)
else
local arabic_span = table.concat(arabicvals, outersep)
local latin_span = table.concat(latinvals, outersep)
if arabic_span == "?" then
return "?"
else
return arabic_span .. "<br />" .. latin_span
end
end
else
local last_mods = table.remove(list_of_mods)
local artrmods = {}
for _, mod in ipairs(last_mods) do
if type(mod) ~= "table" then
mod = {mod}
end
for _, submod in ipairs(mod) do
local armod, trmod = split_arabic_tr(submod)
-- If the value is -, we need to create a blank entry
-- rather than skipping it; if we have no entries at any
-- level, then there will be no overall entries at all
-- because the inside of the loop at the next level will
-- never be executed.
if armod == "-" then
armod = ""
trmod = ""
end
if armod ~= "" then armod = ' ' .. armod end
if trmod ~= "" then trmod = ' ' .. trmod end
for _, trailing_artrmod in ipairs(trailing_artrmods) do
local trailing_armod = trailing_artrmod[1]
local trailing_trmod = trailing_artrmod[2]
armod = armod .. trailing_armod
trmod = trmod .. trailing_trmod
artrmod = {armod, trmod}
table.insert(artrmods, artrmod)
end
end
end
return show_form_1(form, list_of_mods, artrmods, use_parens)
end
end
-- Generate a string to substitute into a particular form in a Wiki-markup
-- table. FORM is the set of inflected forms corresponding to the base,
-- either an array of strings (referring e.g. to different possible plurals)
-- or an array of arrays of strings (the first level referring e.g. to
-- different possible plurals and the inner level referring typically to
-- hamza-spelling variants). LIST_OF_MODS is an array of MODS elements, one
-- per modifier. Each MODS element is the set of inflected forms corresponding
-- to the modifier and is of the same form as FORM, i.e. an array of strings
-- or an array of arrays of strings. Each string is typically of the form
-- "ARABIC/TRANSLIT", i.e. an Arabic string and a Latin string separated
-- by a slash. We loop over all possible combinations of elements from
-- each array; this requires recursion.
function show_form(form, list_of_mods, use_parens)
if not form then
return "—"
elseif type(form) ~= "table" then
error("a non-table value was given in the list of inflected forms.")
end
if #form == 0 then
return "—"
end
-- We need to start the recursion with the third parameter containing
-- one blank element rather than no elements, otherwise no elements
-- will be propagated to the next recursion level.
return show_form_1(form, list_of_mods, {{"", ""}}, use_parens)
end
-- Create a Wiki-markup table using the values in DATA and the template in
-- WIKICODE.
function make_table(data, wikicode)
-- Function used as replace arg of call to rsub(). Replace the
-- specified param with its (HTML) value. The param references appear
-- as {{{PARAM}}} in the wikicode.
local function repl(param)
if param == "pos" then
return data.pos
elseif param == "info" then
return data.title and " (" .. data.title .. ")" or ""
elseif rfind(param, "type$") then
return table.concat(data.forms[param] or {"—"}, outersep .. "<br>")
else
local list_of_mods = {}
for _, mod in ipairs(mod_list) do
local mods = data.forms[mod .. "_" .. param]
if not mods or #mods == 0 then
-- We need one blank element rather than no element,
-- otherwise no elements will be propagated from one
-- recursion level to the next.
mods = {""}
end
table.insert(list_of_mods, mods)
end
return show_form(data.forms[param], list_of_mods, param == "lemma")
end
end
-- For states not in the list of those to be displayed, clear out the
-- corresponding inflections so they appear as a dash.
for _, state in ipairs(data.allstates) do
if not contains(data.states, state) then
for _, numgen in ipairs(data.numgens()) do
for _, case in ipairs(data.allcases) do
data.forms[case .. "_" .. numgen .. "_" .. state] = {}
end
end
end
end
return rsub(wikicode, "{{{([a-z_]+)}}}", repl) .. m_utilities.format_categories(data.categories, lang)
end
-- Generate part of the noun table for a given number spec NUM (e.g. sg)
function generate_noun_num(num)
return [=[! indefinite
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_]=] .. num .. [=[_ind}}}
| {{{inf_]=] .. num .. [=[_def}}}
| {{{inf_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_]=] .. num .. [=[_ind}}}
| {{{nom_]=] .. num .. [=[_def}}}
| {{{nom_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_]=] .. num .. [=[_ind}}}
| {{{acc_]=] .. num .. [=[_def}}}
| {{{acc_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_]=] .. num .. [=[_ind}}}
| {{{gen_]=] .. num .. [=[_def}}}
| {{{gen_]=] .. num .. [=[_con}}}
]=]
end
-- Make the noun table
function make_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" | dual
]=] .. generate_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" style="font-style:normal" colspan=3 | {{{]=] .. num .. [=[_type}}}
|-
]=] .. generate_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the gendered-noun table for a given numgen spec
-- NUM (e.g. m_sg)
function generate_gendered_noun_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! မခၞံဗဒှ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_m_]=] .. num .. [=[_con}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_con}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_m_]=] .. num .. [=[_con}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_con}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_m_]=] .. num .. [=[_con}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_con}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_m_]=] .. num .. [=[_con}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_con}}}
]=]
end
-- Make the gendered noun table
function make_gendered_noun_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'declension',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
for _, num in ipairs(data.numbers) do
if num == "du" then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
]=] .. generate_gendered_noun_num("du")
else
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ]=] .. data.engnumberscap[num] .. "\n" .. [=[
! class="outer" colspan=3 | ပုလ္လိၚ်
! class="outer" colspan=3 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=3 | {{{m_]=] .. num .. [=[_type}}}
! class="outer" style="font-style:normal" colspan=3 | {{{f_]=] .. num .. [=[_type}}}
]=] .. generate_gendered_noun_num(num)
end
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
-- Generate part of the adjective table for a given numgen spec NUM (e.g. m_sg)
function generate_adj_num(num)
return [=[|-
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
! ဟွံချိုတ်ပၠိုတ်
! မချိုတ်ပၠိုတ်
|-
! စေဝ်စၞောန်ဟွံဂြက်
| {{{inf_m_]=] .. num .. [=[_ind}}}
| {{{inf_m_]=] .. num .. [=[_def}}}
| {{{inf_f_]=] .. num .. [=[_ind}}}
| {{{inf_f_]=] .. num .. [=[_def}}}
|-
! မဒုၚ်ယၟု
| {{{nom_m_]=] .. num .. [=[_ind}}}
| {{{nom_m_]=] .. num .. [=[_def}}}
| {{{nom_f_]=] .. num .. [=[_ind}}}
| {{{nom_f_]=] .. num .. [=[_def}}}
|-
! ကမ္မကာရက
| {{{acc_m_]=] .. num .. [=[_ind}}}
| {{{acc_m_]=] .. num .. [=[_def}}}
| {{{acc_f_]=] .. num .. [=[_ind}}}
| {{{acc_f_]=] .. num .. [=[_def}}}
|-
! ဗဳဇဂကူ
| {{{gen_m_]=] .. num .. [=[_ind}}}
| {{{gen_m_]=] .. num .. [=[_def}}}
| {{{gen_f_]=] .. num .. [=[_ind}}}
| {{{gen_f_]=] .. num .. [=[_def}}}
]=]
end
-- Make the adjective table
function make_adj_table(data)
local wikicode = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = 'မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{{pos}}} {{{lemma}}}',
tall = 'yes',
palette = "green",
category = 'မလဟုတ်စှ်ေ',
class = 'tr-alongside', -- temp hack to prevent extra line break
}
}
if contains(data.numbers, "sg") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဨကဝုစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_sg_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_sg_type}}}
]=] .. generate_adj_num("sg")
end
if contains(data.numbers, "du") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=2 | ၜါလ္ပာ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
]=] .. generate_adj_num("du")
end
if contains(data.numbers, "pl") then
wikicode = wikicode .. [=[|-
! class="outer" rowspan=3 | ကိုန်ဗဟုဝစ်
! class="outer" colspan=2 | ပုလ္လိၚ်
! class="outer" colspan=2 | ဣတ္တိလိၚ်
|-
! class="outer" style="font-style:normal" colspan=2 | {{{m_pl_type}}}
! class="outer" style="font-style:normal" colspan=2 | {{{f_pl_type}}}
]=] .. generate_adj_num("pl")
end
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate{ title = 'inflection-table-bottom' }
return make_table(data, wikicode)
end
return export
-- For Vim, so we get 4-space tabs
-- vim: set ts=4 sw=4 noet:
6jrkk8f8whuess61mgcet6ftls6334i
ထာမ်ပလိက်:ajp-verb
10
19894
395263
28902
2026-05-20T19:06:46Z
咽頭べさ
33
395263
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|ကြိယာ|lang=ajp}}<!--
--><noinclude>{{documentation}}</noinclude>
pn60f89ajtrzv8q9tdddmg4d09nrabr
ထာမ်ပလိက်:acw-noun
10
27497
395239
38591
2026-05-20T18:14:14Z
咽頭べさ
33
395239
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|နာမ်|lang=acw}}<!--
--><noinclude>{{documentation}}</noinclude>
6yazm56n25ozfulhpmqadtx0dsff947
ထာမ်ပလိက်:ajp-pronoun
10
28031
395257
39283
2026-05-20T19:01:05Z
咽頭べさ
33
395257
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|သဗ္ဗနာမ်|lang=ajp}}<!--
--><noinclude>{{documentation}}</noinclude>
7epcz34me1lfxpfxy5j3q3r1r53gne6
ကဏ္ဍ:ကြိယာအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
42360
395232
56185
2026-05-20T18:05:24Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကြိယာ အာရဗဳ တူနဳယှေန်]] ဇရေင် [[ကဏ္ဍ:ကြိယာအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
56185
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
ကဏ္ဍ:ဝေါဟာအဓိကအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
42362
395237
176760
2026-05-20T18:09:13Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဝေါဟာအာရဗဳ တူနဳယှေန်နွံပ္ဍဲအဘိဓာန်ဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:ဝေါဟာအဓိကအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
56187
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
اسم
0
42420
395217
374124
2026-05-20T15:22:19Z
咽頭べさ
33
395217
wikitext
text/x-wiki
{{also|آسم|أسم|أشم}}
=={{=ar=}}==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ar|sem-pro|*šim-}}၊ နကဵုအဆက်နူ {{inh|ar|afa-pro|*sim-}}
===ဗွဟ်ရမ္သာၚ်===
{{ar-pr|اِسْم}}
* {{audio|ar|Ar-اسم.ogg}}
** {{a|afb|Gulf}} {{IPA|afb|/ɪ.sɪm/}}
===နာမ်===
{{ar-noun|اِسْم|m|pl=أَسْمَاء|pl2=أَسَامٍ}}
# ယၟု။
# နာမ။
# ဩဇာ။
# နာမ်။
===မဒုၚ်လွဳစ===
{{top2}}
* {{desc|acy|ism}}
* {{desc|arz|اسم|tr=ism}}
* {{desc|acw|اسم|tr=isim}}
* {{desc|mt|isem}}
* {{desc|ary|اسم|tr=ism}}
* {{desc|aeb|اسم|tr=ism}}
* {{desc|az|isim|bor=1}}
* {{desctree|fa-cls|اِسْم|bor=1}}
* {{desc|ms|isim|bor=1}}
* {{desc|sw|isimu|bor=1}}
{{bottom}}
==အာက်သေတ်ဗါဲဇြေနဳ==
===နာမ်===
{{az-noun-Arab|tr=ism|def-acc=اسمی|pl=اسملر}}
# {{alternative spelling of|az|ایسیم}}
==အာရဗဳဟဳဂျာဇြဳ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|اِسْم}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|acw|/i.sim/|[ɪsɪm]}}
===နာမ်===
{{acw-noun|g=m|tr=isim|pl=أسماء|pltr=ʔasmāʔ}}
# ယၟု။
==မလေဝ်==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{bor|ms|ar|اِسْم}}
===ဗွဟ်ရမ္သာၚ်===
* {{a|Johor-Selangor}} {{IPA|ms|/isem/}}
* {{a|Riau-Lingga}} {{IPA|ms|/isɪm/}}
===နာမ်===
{{ms-noun}}
# {{ms-jawi|isim}}
==တူရကဳအောက်ဒဝ်မာန်==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{der|ota|ar|اِسْم}}
===နာမ်===
{{ota-noun|tr=ism, isim|pl=اسملر}}
# ယၟု။
# နာမ်။
===မဒုၚ်လွဳစ===
* {{desc|tr|isim}}
==ပါရှေန်==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{bor|fa|ar|اِسْم}}
===ဗွဟ်ရမ္သာၚ်===
{{fa-IPA|ism}}
* {{audio|fa|Fa-اسم.ogg|a=Iran}}
===နာမ်===
{{fa-regional|اسم|اسم|исм}}
{{fa-noun|tr=esm|pl=اسمها|pl2=اسامی|pl2tr=asâmi|pl3=اَسْماء|pl3tr=asmâ(')}}
# ယၟု။
# နာမ။
# နာမ်။
===မဒုၚ်လွဳစ===
* {{desc|ba|исем|bor=1}}
* {{desc|chg|اسم|bor=1}}
** {{desc|uz|ism}}
** {{desc|ug|ئىسىم}}
* {{desc|gu|ઇસમ|bor=1}}
* {{desc|inc-hnd|-|bor=1}}
*: {{desc|hi|इस्म}}
*: {{desc|ur|اِسْم}}
* {{desc|kn|ಇಸಮು|bor=1}}
* {{desc|kk|есім|bor=1}}
* {{desc|mr|इसम|bor=1}}
* {{desc|ota|اسم|tr=ism, isim|bor=1}}
** {{desc|tr|isim}}
==အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာ==
{{ajp-root|و س م}}
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|اِسْم}}
===ဗွဟ်ရမ္သာၚ်===
* {{ajp-IPA|ʔism<p:ˈʔɪ.s(ɪ)m>|ʔusm<p:ˈʔʊ.s(ʊ)m>}}
* {{audio|ajp|LL-Q55633582 (ajp)-MahmoudM (AdrianAbdulBaha)-اسم.wav|a=Jerusalem}}
===Noun===
{{ajp-noun|g=m|tr=ʔism, ʔusm|pl=أسامي|pltr=ʔasāmi}}
# ယၟု။
# နာမ်။
==အာရဗဳ တူနဳယှေန်==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|aeb|ar|اِسْم}}
===နာမ်===
{{aeb-noun|g=m|tr=ʔism}}
# ယၟု။
# နာမ်။
# ယၟုမဟိမု။
==အူရဒူ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{der|ur|ar|اِسْم}}၊ နကဵုအဆက်နူ {{der|ur|sem-pro|*šim-}}
===ဗွဟ်ရမ္သာၚ်===
* {{ur-IPA|ism}}
===နာမ်===
{{ur-noun|head=اِسْم|g=m|tr=ism|hi=इस्म}}
# ယၟု၊ နာမ၊ ယၟုမဟိမု။
# နာမ်၊ နာမကော်ခဴလဝ်ခိုၚ်ခိုၚ်ကၠိုက်ကၠိုက်။
===နိရုတ် ၂===
{{lbor|ur|sa|असम}}
===ဗွဟ်ရမ္သာၚ် ၂===
* {{ur-IPA|asam}}
===နာမဝိသေသန===
{{ur-adj|tr=asam|hi=असम}}
# မဟွံတုပ်။
# ခလံက်ခနက်။
# ယၟုဟွံတုပ်။
# ဟွံဓဝ်ယာ။
osarwsc3la7e69ffo77atfv9h2wavi3
ကဏ္ဍ:နာမ်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
42443
395235
56342
2026-05-20T18:07:27Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:နာမ် အာရဗဳ တူနဳယှေန်]] ဇရေင် [[ကဏ္ဍ:နာမ်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
56342
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်မာလ်တဳဂမၠိုၚ်
14
47975
395208
165904
2026-05-20T13:56:56Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ထာမ်ပလိက်မာလ်တဳလေန်မနွံကဵုပၟိက်ဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်မာလ်တဳဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: Replace 'ပလေဝ်ဒါန်
162940
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်မာလ်တဳဂမၠိုၚ်]]
9set48vbsk4iu5viq4eyu8vv2mfiixx
395213
395208
2026-05-20T14:07:56Z
咽頭べさ
33
395213
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်မာလ်တဳဂမၠိုၚ်]][[ကဏ္ဍ:လာၚ်က္ဍိုပ်မအရေဝ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|မ]]
gl442cbbytypdeu14xr0jcltbdhu331
မဝ်ဂျူ:tt-translit
828
50707
395270
66333
2026-05-20T19:29:26Z
咽頭べさ
33
395270
Scribunto
text/plain
local export = {}
local rsubn = mw.ustring.gsub
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- apply rsub() repeatedly until no change
local function rsub_repeatedly(term, foo, bar)
while true do
local new_term = rsub(term, foo, bar)
if new_term == term then
return term
end
term = new_term
end
end
local tt = {
['б']='b',['Б']='B', ['в']='w',['В']='W', ['г']='g',['Г']='G', ['д']='d',['Д']='D',
['з']='z',['З']='Z', ['й']='y',['Й']='Y', ['к']='k',['К']='K', ['л']='l',['Л']='L',
['м']='m',['М']='M', ['н']='n',['Н']='N', ['п']='p',['П']='P', ['р']='r',['Р']='R',
['с']='s',['С']='S', ['т']='t',['Т']='T', ['ф']='f',['Ф']='F', ['х']='x',['Х']='X',
['ч']='ç',['Ч']='Ç', ['ш']='ş',['Ш']='Ş',
['җ']='c',['Җ']='C', ['ң']='ñ',['Ң']='Ñ', ['һ']='h',['Һ']='H',
['ж']='j',['Ж']='J', ['ц']='ts',['Ц']='Ts', ['щ']='şç',['Щ']='Şç', ['ё']='yo',['Ё']='Yo',
['а']='a',['А']='A', ['ы']='ı',['Ы']='I', ['о']='o',['О']='O', ['у']='u',['У']='U',
['ә']='ä',['Ә']='Ä', ['э']='e',['Э']='E', ['и']='i',['И']='İ', ['ө']='ö',['Ө']='Ö', ['ү']='ü',['Ү']='Ü',
--['я']='ya',['Я']='Ya', ['е']='ye',['Е']='Ye', ['ю']='yu',['Ю']='Yu',
--['е']='e',['Е']='E',
['ь']='ʹ',['Ь']='ʹ', ['ъ']='ʺ',['Ъ']='ʺ',
['ҡ']='q',['Ҡ']='Q', ['ғ']='ğ',['Ғ']='Ğ', ['Ӹ']='Iy',['ӹ']='ıy',
}
local consonants = 'БВГДЗЙКЛМНПРСТФХЧШҖҢҺбвгдзйклмнпрстфхчшҗңһЖЦЩжцщҠҒҡғ'
local vowels_hard = 'АЫӸОУаыӹоу'
local vowels_soft = 'ӘЭИӨҮәэиөү'
local vowels_iotated = 'ЯЕЮяею' -- ё is only in Russian loans
local consonants_soft2hard = {['К']='Ҡ', ['Г']='Ғ', ['к']='ҡ', ['г']='ғ'}
local vowels_hard2soft = {['А']='Ә', ['Ы']='Э', ['Ӹ']='И', ['О']='Ө', ['У']='Ү', ['а']='ә', ['ы']='э', ['ӹ']='и', ['о']='ө', ['у']='ү'}
local vowels_iotated_expanded_hard = {['Я']='Йа', ['Е']='Йы', ['Ю']='Йу', ['я']='йа', ['е']='йы', ['ю']='йу'}
local vowels_iotated_expanded_soft = {['Я']='Йә', ['Е']='Йэ', ['Ю']='Йү', ['я']='йә', ['е']='йэ', ['ю']='йү'}
local tt_Arab_New = {
-- [[s:mul:Рус мәктәпләре өчен татар теле дәреслеге/13]]
-- [[Wiktionary:Tatar entry guidelines]]
['ا']='а', ['ە']='ә',
['ب']='б', ['پ']='п', ['ت']='т',
['ج']='җ', ['چ']='ч', ['ح']='х',
['د']='д',
['ر']='р', ['ز']='з', ['ژ']='ж',
['س']='с', ['ش']='ш',
['ع']='ғ',
['ف']='ф', ['ق']='ҡ', ['ك']='к', ['گ']='г', ['ڭ']='ң',
['ل']='л',
['م']='м',
['ن']='н',
['ۇ']='ө', ['و']='ү', ['ۋ']='в',
['ھ']='һ',
['ىُ']='э', ['ی']='и',
['ئ']='ь', ['ࢭ']='ъ',
['ث']='с', ['خ']='х', ['ذ']='з', ['ص']='с', ['ض']='з', ['ط']='т', ['ظ']='з', ['غ']='ғ',
['۱']='1', ['۲']='2', ['۳']='3', ['۴']='4', ['۵']='5',
['۶']='6', ['۷']='7', ['۸']='8', ['۹']='9', ['۰']='0',
['١']='1', ['٢']='2', ['٣']='3', ['٤']='4', ['٥']='5',
['٦']='6', ['٧']='7', ['٨']='8', ['٩']='9', ['٠']='0',
['،']=',', ['؟']='?',
}
-- excluding ә/а. яңа имля has separate letters
--local vowels_soft2hard = {['э']='ы', ['и']='ӹ', ['ө']='о', ['ү']='у'}
-- XXX: keep и for now. less unsightly and more common than ый? can и vs. ый even be predicted accurately?
local vowels_soft2hard = {['э']='ы', ['и']='и', ['ө']='о', ['ү']='у'}
function export.tr(text, lang, sc)
if sc == 'tt-Arab' then
-- яңа имля.
-- automatic insertion of э/ы would be Cool
-- but maybe we don't have to worry about that
-- since яңалиф also omits them.
-- visualize the continuity between the two.
-- also, insertion would wreak havoc on иске имля
-- hacks for иске имля
text = rsub(text, '^او', 'ئو')
text = rsub(text, '^ای', 'ئی')
text = rsub(text, '^آ', 'ئا')
text = rsub(text, '^ا', 'ئ')
text = rsub(text, '([%p%s])او', '%1ئو')
text = rsub(text, '([%p%s])ای', '%1ئی')
text = rsub(text, '([%p%s])آ', '%1ئا')
text = rsub(text, '([%p%s])ا', '%1ئ')
text = rsub(text, 'ه$', 'ە')
text = rsub(text, 'ه([%p%s' .. mw.ustring.char(0x200C) .. '])', 'ە%1')
text = rsub(text, 'ه', 'ھ')
text = rsub(text, mw.ustring.char(0x200C), '') -- ZERO WIDTH NON-JOINER
text = rsub(text, '(.)' .. mw.ustring.char(0x0651), '%1%1') -- SHADDA
text = rsub(text, 'ىُ', tt_Arab_New) -- `э/ы` is not atomic in Unicode
text = rsub(text, '.', tt_Arab_New)
text = rsub(text, 'ии([әэөаү])', 'ий%1')
text = rsub(text, 'и([әэөаү])', 'й%1')
text = rsub(text, '([әэөаүи])и', '%1й')
text = rsub(text, 'ү([әэөаи])', 'в%1')
text = rsub(text, '([әэөаиү])ү', '%1в')
text = rsub(text,
'([^%p%s]+)',
function(text)
text = rsub(text, mw.ustring.format('^(ъ?)и([%s])', consonants), '%1й%2')
text = rsub(text, mw.ustring.format('^(ь)([%s])', consonants), '%1э%2')
if mw.ustring.match(text, '[ъаҡғ]') then
text = rsub(text, mw.ustring.format('([%s])', vowels_soft), vowels_soft2hard)
end
text = rsub(text, '^ъ', '')
text = rsub(text, '^ь', '')
return text
end
)
text = rsub(text, '.', tt)
return text
end
-- normalize pure vocalic e
text = rsub(text,
mw.ustring.format('([%s])([Ее])', consonants),
function(consonant, e)
local uniotated = {['Е']='Э', ['е']='э'}
return consonant .. uniotated[e]
end
)
-- simplify handling ый
text = rsub(text, 'Ы[Йй]', 'Ӹ')
text = rsub(text, 'ый', 'ӹ')
-- Russian loan sounds
-- XXX: an idea: identify Russian loans by adding an accent mark?
--text = rsub(text, 'ия', 'ийә')
-- process iotated soft vowels
text = rsub(text,
mw.ustring.format('([%s])([%s]*[%s])', vowels_iotated, consonants, vowels_soft),
function(vowel_iotated, following)
return vowels_iotated_expanded_soft[vowel_iotated] .. following
end
)
text = rsub(text,
mw.ustring.format('([%s])([%s]*)([Ьь])', vowels_iotated, consonants),
function(vowel_iotated, following, soft_sign)
return vowels_iotated_expanded_soft[vowel_iotated] .. following
end
)
text = rsub_repeatedly(text,
mw.ustring.format('([%s])([%s])', vowels_soft, vowels_iotated),
function(preceding, vowel_iotated)
return preceding .. vowels_iotated_expanded_soft[vowel_iotated]
end
)
-- process iotated hard vowels
text = rsub(text,
mw.ustring.format('([%s])', vowels_iotated),
function(vowel_iotated)
return vowels_iotated_expanded_hard[vowel_iotated]
end
)
-- verbal noun + 3rd person possessive
text = rsub(text, 'үйэ', 'үвэ')
-- q/ğ is indicated by using a hard vowel, even in soft vowel words
text = rsub(text,
mw.ustring.format('([КГкг])([%s]+)([%s])([Ъъ])', vowels_hard, consonants),
function(kg, vowel, following, soft_and_glottal_sign)
-- XXX: presumably this is what ъ means here
return consonants_soft2hard[kg] .. vowels_hard2soft[vowel] .. following .. 'ь'
end
)
text = rsub(text,
mw.ustring.format('([КГкг])([%s]+)([%s]+[%s])', vowels_hard, consonants, vowels_soft),
function(kg, vowel, following)
return consonants_soft2hard[kg] .. vowels_hard2soft[vowel] .. following
end
)
text = rsub(text,
mw.ustring.format('([КГкг])([%s]+)([%s])([Ьь])', vowels_hard, consonants),
function(kg, vowel, following, soft_sign)
return consonants_soft2hard[kg] .. vowels_hard2soft[vowel] .. following
end
)
text = rsub(text,
mw.ustring.format('([%s]?)([КГкг])([%s]?)', vowels_hard, vowels_hard),
function(preceding, kg, following)
return preceding .. (((following ~= '') or (preceding ~= '' and following == '')) and consonants_soft2hard[kg] or kg) .. following
end
)
text = rsub(text, '([КГкг])([Ъъ])', function(kg, hard_sign) return consonants_soft2hard[kg] end)
-- excrescent y/w after i/u
text = rsub_repeatedly(text, '([Ии])([' .. vowels_hard .. vowels_soft .. '])', '%1й%2')
text = rsub_repeatedly(text, '([УҮуү])([' .. vowels_hard .. vowels_soft .. '])', '%1в%2')
-- semivocalic w after vowels
text = rsub(text, '([' .. vowels_hard .. vowels_soft .. '])[УҮуү]', '%1в')
-- glottal stop after vowels
text = rsub(text, '([' .. vowels_hard .. vowels_soft .. '])[Ээ]', '%1ь')
text = rsub(text, '.', tt)
return text
end
return export
d5abeasv66no675nxhi3twrlimx4eu4
ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာဂမၠိုၚ်
14
51124
395259
166127
2026-05-20T19:02:37Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ထာမ်ပလိက်အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာလေန်မနွံကဵုပၟိက်ဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
163067
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာဂမၠိုၚ်]]
d5wtb3b646sefu4m5b1b90y126bkekl
ကဏ္ဍ:ဝိဘတ်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
56856
395236
74176
2026-05-20T18:08:06Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဝိဘတ် အာရဗဳ တူနဳယှေန်]] ဇရေင် [[ကဏ္ဍ:ဝိဘတ်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
74176
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
ကဏ္ဍ:ကြိယာဝိသေသနအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
57085
395233
74485
2026-05-20T18:06:02Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကြိယာဝိသေသန အာရဗဳ တူနဳယှေန်]] ဇရေင် [[ကဏ္ဍ:ကြိယာဝိသေသနအာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
74485
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
ကဏ္ဍ:ကၞာတ်အမှိက်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်
14
62030
395234
81253
2026-05-20T18:06:45Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ကၞာတ်အမှိက် အာရဗဳ တူနဳယှေန်]] ဇရေင် [[ကဏ္ဍ:ကၞာတ်အမှိက်အာရဗဳ တူနဳယှေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
81253
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအာရဗဳ တူနဳယှေန်]]
iahnnjkpvjw9on53txy8b2bmxg82nix
ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်ထာရိဖေန်ဂမၠိုၚ်
14
66482
395222
165680
2026-05-20T15:55:04Z
Intobesa.bot
1035
Intobesa.bot ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ထာမ်ပလိက်ထာရိဖေန်လေန်မနွံကဵုပၟိက်ဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:ထာမ်ပလိက်လာၚ်က္ဍိုပ်မအရေဝ်ထာရိဖေန်ဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်: Bot: ပလေဝ်ဒါန်
162772
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်ထာရိဖေန်ဂမၠိုၚ်]]
9vgv8fc90k72sxh70mm875l80wr2tzn
မဝ်ဂျူ:sem-arb-utilities
828
117551
395272
158336
2026-05-20T19:38:38Z
咽頭べさ
33
395272
Scribunto
text/plain
local export = {}
local m_str_utils = require("Module:string utilities")
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local m_headword = require("Module:headword")
local m_langs = require("Module:languages")
local m_params = require("Module:parameters")
local m_parse_utils = require("Module:parse utilities")
local m_affix = require("Module:affix")
local m_sc_utils = require("Module:script utilities")
local pluralize = require("Module:en-utilities").pluralize
local lg_ar = m_langs.getByCode("ar")
local lg_sem_arb = lg_ar:getFamily():getCode()
local rsplit = m_str_utils.split
local rsubn = m_str_utils.gsub
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local separator_langs = { ["mt"] = true, ["acy"] = true }
local color_langs = { ["mt"] = "red", ["ary"] = "red", ["ar"] = "green", ["shu"] = "yellow" }
local template_preview_per_langcode = { ["mt"] = "k-t-b", ["acy"] = "k-t-p" }
local lang
local sc
local function ifelse(cond, yes, no)
if cond then
return yes
end
return no
end
local function ucfirst(str)
if str == nil then
return str
end
return mw.language.getContentLanguage():ucfirst(str)
end
local function link(term, alt, id)
if term == "" or term == "—" then
return term
else
return m_links.full_link({
term = term,
alt = alt,
lang = lang,
id = id,
})
end
end
local function parse_inlines(term)
return m_parse_utils.parse_inline_modifiers(
term,
{
param_mods = {tr = {}, t = {}, pos = {}},
generate_obj = function(term) return {term} end,
}
)
end
local function make_part(noninline, lang)
local keys = {"tr", "t", "pos"}
local inline
if type(noninline) == "string" then
inline = parse_inlines(noninline)
else
inline = parse_inlines(noninline[1])
end
local return_value = {
term = m_sc_utils.tag_text(inline[1], lang),
}
for i, key in ipairs(keys) do
if inline[key] and noninline[key] then
error(
key .. " specified twice: "
.. "<" .. key .. ":" .. inline[key] .. ">"
.. " and "
.. "|" .. key .. "=" .. nonline[key]
)
end
return_value[key] = inline[key] or noninline[key]
end
if not return_value.tr then
return_value.tr = lang:transliterate(inline[1])
end
return return_value
end
local function make_parts(lang, raw_parts)
local parts = {}
for i, part in ipairs(raw_parts) do
parts[#parts + 1] = make_part(part, lang)
end
return {
parts = parts,
lang = lang,
sc = lang:findBestScript(parts[1][1]),
}
end
local function show_affix(lang, raw_parts)
return m_affix.show_affix(
make_parts(lang, raw_parts),
{},
lang
)
end
local appendices = {
["active participle"] = {
-- participles have verbal force in (most?) vernaculars
function(args, lang)
return ifelse(lang:getCode() == lg_ar:getCode(), "nominals", "verbs")
end,
derived = true,
},
["characteristic adjective"] = "nominals",
["color/defect adjective"] = {
"nominals",
fragment = "Color or defect adjectives",
},
["diminutive"] = "nominals",
["elative"] = "nominals",
["relative"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "suffix",
},
["id"] = {},
["id1"] = {
alias_of = "id",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["t"] = {
required = true,
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيَّة", "ـية"),
},
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
{args.suffix, pos="feminine nisba"},
}
)
)
end,
},
["relative-a"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـَة", "ـة"),
},
["t"] = {
required = true,
},
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
{args.suffix, pos="feminine ending"},
}
)
)
end,
},
["relative-linking"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "linking",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيّ", "ـي"),
},
["t"] = {
required = true,
},
["linking"] = {
required = true,
}
}
end,
title = function(args)
if args.pl then
return "relative adjectives (nisba)"
end
return "relative adjective (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
args.linking,
{args.suffix, pos = "nisba"},
}
)
)
end,
},
["relative-linking-noun"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "linking",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["t"] = {
required = true,
},
["linking"] = {
required = true,
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيّ", "ـي"),
}
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{args, args.linking, args.suffix}
)
)
end,
},
["form"] = {
"verbs",
params = {
[1] = {
alias_of = "wazn",
},
["wazn"] = {
required = true,
},
},
fragment = function(args) return "Form_" .. args.wazn end,
title = function(args) return "form " .. args.wazn end,
},
["instance noun"] = "nominals",
["noun of place"] = "nominals",
["occupational noun"] = "nominals",
["passive participle"] = {
"nominals",
derived = true,
},
["reduplicated"] = {
glossary = "reduplication",
},
["singulative noun"] = "nominals",
["tool noun"] = "nominals",
["verbal noun"] = "nominals",
}
local radicals = {
["Arab"] = {
["ء"] = true,
["ب"] = true,
["ت"] = true,
["ث"] = true,
["ج"] = true,
["ح"] = true,
["خ"] = true,
["د"] = true,
["ذ"] = true,
["ر"] = true,
["ز"] = true,
["س"] = true,
["ش"] = true,
["ص"] = true,
["ض"] = true,
["ط"] = true,
["ظ"] = true,
["ع"] = true,
["غ"] = true,
["ف"] = true,
["ق"] = true,
["ك"] = true,
["ل"] = true,
["م"] = true,
["ن"] = true,
["ه"] = true,
["و"] = true,
["ي"] = true,
["گ"] = true,
["چ"] = true,
["پ"] = true,
["ڭ"] = true,
},
["Latn"] = {
["'"] = true,
["b"] = true,
["c"] = true,
["ċ"] = true,
["d"] = true,
["δ"] = true,
["f"] = true,
["ġ"] = true,
["g"] = true,
["għ"] = true,
["h"] = true,
["ħ"] = true,
["j"] = true,
["k"] = true,
["l"] = true,
["m"] = true,
["n"] = true,
["p"] = true,
["q"] = true,
["r"] = true,
["s"] = true,
["ş"] = true,
["t"] = true,
["v"] = true,
["w"] = true,
["x"] = true,
["y"] = true,
["ż"] = true,
["z"] = true,
["θ"] = true,
}
}
local function validateRoot(rootTable, joined_root)
if type(rootTable) ~= "table" then
error("rootTable is not a table", 2)
end
local len = #rootTable
if len < 3 then
error("Root must have at least three radicals.")
end
if sc == nil then
sc = lang:findBestScript(joined_root):getCode()
end
for i, radical in ipairs(rootTable) do
if not radicals[sc][radical] then
error("Unrecognized radical " .. radical .. " in " .. joined_root)
end
end
end
function export.root(frame)
local output = {}
local categories = {}
local title = mw.title.getCurrentTitle()
local namespace = title.nsText
local fulltitle = title.fullText
if frame.args["lang"] then
lang = require("Module:languages").getByCode(frame.args["lang"])
else
error("Please provide a language code.")
end
local subpage = "Appendix:တံရိုဟ်" .. lang:getCanonicalName() .. "ဂမၠိုၚ်/"
local fulltitle = rsubn(fulltitle, rsubn(subpage, "([^%w])", "%%%1"), "")
local params = {
[1] = { list = true },
["nocat"] = { type = "boolean" },
["plain"] = { type = "boolean" },
["notext"] = { type = "boolean" },
["sense"] = {}
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local rootLetters = {}
local roots = args[1]
local plain = args["plain"]
if frame.args["plain"] then
plain = true
end
local langCode = lang:getCode()
local separator = " "
if separator_langs[langCode] then
separator = "-"
else
separator = " "
end
local roots_len = #roots
if #roots == 0 and namespace == "ထာမ်ပလိက်" then
if template_preview_per_langcode[langCode] ~= nil then
table.insert(rootLetters, rsplit(template_preview_per_langcode[langCode], separator))
else
table.insert(rootLetters, rsplit("ك ت ب", separator))
end
elseif #roots ~= 0 then
for _, root in ipairs(roots) do
table.insert(rootLetters, rsplit(root, separator))
end
else
table.insert(rootLetters, rsplit(fulltitle, separator))
end
local joined_roots = {}
for i, rootLetter in ipairs(rootLetters) do
table.insert(joined_roots, table.concat(rootLetter, separator))
validateRoot(rootLetter, joined_roots[i])
end
local sense = args["sense"]
local sense_formatted = ""
if sense ~= nil then
sense_formatted = " (" .. sense .. ") "
end
if fulltitle == joined_roots[1] then
if namespace == "" then
error("The root page should be in the Appendix namespace. Please move it to : [[" ..
subpage .. joined_roots[1] .. "]]")
end
if roots_len > 1 then
error("There should be only one root.")
end
table.insert(output,
m_headword.full_headword({ lang = lang, pos_category = "တံရိုဟ်", categories = {}, heads = { fulltitle }, nomultiwordcat = true, noposcat = true }))
if args["nocat"] then
return table.concat(output)
else
return table.concat(output) .. table.concat(categories)
end
else
local link_texts = {}
local term_counts = {}
for i, joined_root in ipairs(joined_roots) do
local link_text = subpage .. joined_root
table.insert(link_texts, link(link_text, joined_root .. sense_formatted, sense))
table.insert(
categories,
m_utilities.format_categories(
{ "ဝေါဟာ" .. lang:getCanonicalName() .. "မဆေၚ်စပ်ကဵုတံရိုဟ်နကဵုဝေါဟာ " .. joined_root .. sense_formatted },
lang)
)
table.insert(term_counts,
mw.site.stats.pagesInCategory(
"ဝေါဟာ" .. lang:getCanonicalName() .. "မဆေၚ်စပ်ကဵုတံရိုဟ်နကဵုဝေါဟာ " .. joined_root .. sense_formatted, "pages")
)
end
if args["nocat"] or plain then
if args["nocat"] then
return table.concat(link_texts, ", ")
else
return table.concat(link_texts, ", ") .. table.concat(categories)
end
else
local link_text_output = ""
for i, link_text in ipairs(link_texts) do
link_text_output = link_text_output ..
"\n|-\n| " .. link_text ..
"\n|-\n| [[:ကဏ္ဍ:ဝေါဟာ" ..
lang:getCanonicalName() ..
"မဆေၚ်စပ်ကဵုတံရိုဟ်နကဵုဝေါဟာ " ..
joined_roots[i] ..
sense_formatted .. "|" .. "မအရေဝ် " .. term_counts[i] .. (term_counts[i] == 1 and "" or " ဂမၠိုၚ်") .. "]]\n"
end
local color = "grey"
if color_langs[langCode] ~= nil then
color = color_langs[langCode]
end
local wikicode = mw.getCurrentFrame():expandTemplate {
title = 'inflection-table-top',
args = {
title = "-",
palette = color,
class = "floatright tr-alongside"
}
}
wikicode = wikicode .. [=[
! [[w:Semitic root|တံရိုဟ်]=] .. (#term_counts == 1 and "" or "s") .. [=[]]]=]
wikicode = wikicode .. link_text_output
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate {
title = 'inflection-table-bottom',
}
return wikicode .. table.concat(categories)
end
end
end
local function iffn(val, ...)
if type(val) == "function" then
return val(unpack(arg))
end
return val
end
function export.etym(frame)
local params = {
[1] = {
alias_of = "lang",
},
[2] = {
alias_of = "class"
},
["fragment"] = {},
["nocat"] = {
type = boolean,
},
["lang"] = {
type = "language",
replaced_by = false,
required = true,
},
["class"] = {
required = true,
},
}
local args, extra = m_params.process(frame:getParent().args, params, true)
local fixed_indices = {}
for k, v in pairs(extra) do
if type(k) == "number" then
k = k - 2
end
fixed_indices[k] = v
end
extra = fixed_indices
if args.lang:getFamily():getCode() ~= lg_sem_arb then
error(
args.lang:getCode()
.. "'s family is "
.. args.lang:getFamily():getCode()
.. ", not "
.. lg_sem_arb
)
end
local lookup = appendices[mw.ustring.lower(args.class)]
local lookup_args = {}
if not lookup then
error("Unrecognized word type " .. mw.ustring.lower(args.class))
end
if lookup.glossary then
return "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#" .. lookup.glossary .. "]]"
end
if lookup.params then
lookup_args = m_params.process(extra, iffn(lookup.params, args.lang))
end
local appendix = nil
if lookup.glossary then
appendix = "မသောၚ်ကၠးဝေါဟာ"
else
local appendix_lang = args.lang:getCanonicalName()
local appendix_title = ifelse(type(lookup) == "string", lookup, iffn(lookup[1], args.lang))
appendix = appendix_lang .. " " .. appendix_title
if not mw.title.new(appendix, "Appendix").exists then
appendix_lang = lg_ar:getCanonicalName()
appendix_title = ifelse(type(lookup) == "string", lookup, iffn(lookup[1], lg_ar))
appendix = appendix_lang .. " " .. appendix_title
end
end
local title = args.class
local desc = ""
local intro = ""
if lookup.derived then
intro = "derived from the "
end
if type(lookup) ~= "string" then
title = iffn(lookup.title, lookup_args, args.lang) or ""
desc = iffn(lookup.desc, lookup_args, args.lang) or ""
if mw.ustring.match(args.class, "^%u.*") then
if intro == "" then
title = ucfirst(title) or ""
else
intro = ucfirst(intro) or ""
end
end
end
local fragment = (
iffn(lookup.fragment, lookup_args, args.lang)
or ucfirst(iffn(lookup.title, {pl=true}, args.lang))
or pluralize(ucfirst(args.class))
) or ""
return (
intro
.. "[[Appendix:"
.. appendix
.. ifelse(fragment, "#" .. fragment, "")
.. "|"
.. title
.. "]] "
.. desc
)
end
return export
4azw8owswdylr4edfhqjl32jgfltthn
hemma
0
294800
395205
2026-05-20T13:50:40Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==မာလ်တဳ== ===ဗွဟ်ရမ္သာၚ်=== * {{IPA|mt|/ˈɛm.ma/}} * {{rhymes|mt|ɛmma|s=2}} ===ကြိယာဝိသေသန=== {{mt-adverb}} # {{alternative form of|mt|hemm}}: အတေံ။ ==နဝ်ဝေ ဗော်ခ်မဝ်== ===ပွံၚ်နဲတၞဟ်=== * {{alt|nb|hemmet}} ===ကြိယာ=== {{head|nb|verbf}} # {{inflection of|nb|hemme||simple past|;|past|p..."
395205
wikitext
text/x-wiki
==မာလ်တဳ==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|mt|/ˈɛm.ma/}}
* {{rhymes|mt|ɛmma|s=2}}
===ကြိယာဝိသေသန===
{{mt-adverb}}
# {{alternative form of|mt|hemm}}: အတေံ။
==နဝ်ဝေ ဗော်ခ်မဝ်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|nb|hemmet}}
===ကြိယာ===
{{head|nb|verbf}}
# {{inflection of|nb|hemme||simple past|;|past|part}}
==သွဳဒေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|sv|/²hɛmːa/}}
* {{audio|sv|Sv-hemma.ogg}}
* {{homophones|sv|hämma}}
===ကြိယာဝိသေသန===
{{sv-adv|-}}
# အပ္ဍဲသ္ၚိနကဵုတိဍာ်သ္ၚိဌာန်ဇကု။
====နာမဝိသေသန====
{{head|sv|adjective}}
# အပ္ဍဲတိဍာ်ဌာန်ဒၞာဲညးမဂွံအယုက်နကဵုသ္ၚိဌာန်ဇကု။
ac76yzd3cczt75f5t34m83go637ypzr
ထာမ်ပလိက်:mt-adv
10
294801
395206
2026-05-20T13:52:07Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:mt-headword|show|ကြိယာဝိသေသန}}<!-- --><noinclude>{{documentation}}</noinclude>"
395206
wikitext
text/x-wiki
{{#invoke:mt-headword|show|ကြိယာဝိသေသန}}<!--
--><noinclude>{{documentation}}</noinclude>
38kmaweygjsqk85a3l5m89ncblodh1b
395228
395206
2026-05-20T16:33:00Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:mt-adverb]] ဇရေင် [[ထာမ်ပလိက်:mt-adv]]
395206
wikitext
text/x-wiki
{{#invoke:mt-headword|show|ကြိယာဝိသေသန}}<!--
--><noinclude>{{documentation}}</noinclude>
38kmaweygjsqk85a3l5m89ncblodh1b
ထာမ်ပလိက်:mt-adverb/documentation
10
294802
395207
2026-05-20T13:54:21Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> {{hwcat}}"
395207
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
{{hwcat}}
f8u1ebax0fek1lf9jgky9pqli0yk03y
မဝ်ဂျူ:mt-headword/doc
828
294803
395209
2026-05-20T14:01:14Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|mt}} </includeonly>"
395209
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
{{module cat|mt}}
</includeonly>
c7rcvz9svqyhitqmnflgyue7w2ebdkl
ကဏ္ဍ:မဝ်ဂျူမာလ်တဳဂမၠိုၚ်
14
294804
395210
2026-05-20T14:02:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » '''မဝ်ဂျူဂမ..."
395210
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » '''မဝ်ဂျူဂမၠိုၚ်'''
:[[:ကဏ္ဍ:မဝ်ဂျူဂမၠိုၚ်|မဝ်ဂျူ]]ဘာသာမာလ်တဳ၊ မနွံကဵုလုပ်အဝေါၚ်ကုဒ် Lua နကဵုမကၠောန်ဗဒှ် ကဵု မစဳရေၚ်ယဵုဒုၚ်သ္ပမာန်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမာလ်တဳ]][[ကဏ္ဍ:မဝ်ဂျူဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|မ]]
f6m9ngq66kuycf2t0kf5bggj9d7hsmi
မဝ်ဂျူ:category tree/lang/mt
828
294805
395211
2026-05-20T14:03:57Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "local labels = {} local handlers = {} local lang = require("Module:languages").getByCode("mt") require("Module:category tree/lang/sem-arb").add_labels_and_handlers(labels, handlers, lang) return {LABELS = labels, HANDLERS = handlers}"
395211
Scribunto
text/plain
local labels = {}
local handlers = {}
local lang = require("Module:languages").getByCode("mt")
require("Module:category tree/lang/sem-arb").add_labels_and_handlers(labels, handlers, lang)
return {LABELS = labels, HANDLERS = handlers}
2wrrvnytmelskpp5znl4vohm69q31cb
ကဏ္ဍ:ကြိယာဝိသေသနမာလ်တဳဂမၠိုၚ်
14
294806
395214
2026-05-20T14:09:10Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{auto cat}}"
395214
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
395218
395214
2026-05-20T15:25:00Z
咽頭べさ
33
395218
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » [[:ကဏ္ဍ:ဝေါဟာအဓိကမာလ်တဳဂမၠိုၚ်|ဝေါဟာတံသ္ဇိုၚ်]] » '''ကြိယာဝိသေသနဂမၠိုၚ်'''
:ဝေါဟာမာလ်တဳမပြုပြေၚ်ပြံၚ်လှာဲလဝ်ပိုဒ်လိက်ဂမၠိုၚ်၊ ပိုတ်ဂမၠိုၚ် ကဵု ဇၟန်လိက်တပ်ပ်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာမာလ်တဳ]][[ကဏ္ဍ:ကြိယာဝိသေသနဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|မ]]
tm2f019c71hadyd176vda9jmsk4d0r9
ကဏ္ဍ:ကာရန်:မာလ်တဳ/ɛmma
14
294807
395219
2026-05-20T15:27:54Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » :ကဏ္ဍ:ကာရန..."
395219
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » [[:ကဏ္ဍ:ကာရန်:မာလ်တဳ|ကာရန်ဂမၠိုၚ်]] » -ɛmma
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]]မနွံကာရန် ɛmma ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:မာလ်တဳ|ɛmma]]
ks5yl9zk7y5swog0aejkw8xkksgtbk4
hemm
0
294808
395220
2026-05-20T15:48:34Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|Hemm}} ==လူဇေန်ဘာဂျ်== ===ကြိယာ=== {{head|lb|verb form}} # {{inflection of|lb|hemmen||2|s|impr}} ==မာလ်တဳ== ===ဗွဟ်ရမ္သာၚ်=== * {{IPA|mt|/ɛmm/}} * {{rhymes|mt|ɛmm|s=1}} ===ကြိယာဝိသေသန=== {{mt-adv}} # အတေံ။ ===ပွံၚ်နဲတၞဟ်=== * {{alt|mt|hemma}} * {{alt|mt|hemmi||Nadur}} ===နာမ်..."
395220
wikitext
text/x-wiki
{{also|Hemm}}
==လူဇေန်ဘာဂျ်==
===ကြိယာ===
{{head|lb|verb form}}
# {{inflection of|lb|hemmen||2|s|impr}}
==မာလ်တဳ==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|mt|/ɛmm/}}
* {{rhymes|mt|ɛmm|s=1}}
===ကြိယာဝိသေသန===
{{mt-adv}}
# အတေံ။
===ပွံၚ်နဲတၞဟ်===
* {{alt|mt|hemma}}
* {{alt|mt|hemmi||Nadur}}
===နာမ်===
{{mt-noun|g=m|p=hemum}}
# သောက၊ မအောန်စိုတ်၊ လၞီစိုတ်။
#: {{syn|mt|niket}}
==ထာရိဖေန်==
===နိရုတ်===
{{bor+|rif|ary|هَمَّ}}
===ကြိယာ===
{{rif-verb}}
# သကဵုဆက်စပ်၊ သကဵုစိုတ်လဵု၊ သကဵုစောဲလာံ။
# သကဵုဒှ်မစိုတ်လုပ်စ။
# သကဵုဒဒိုက်စိုတ်၊ သကဵုမအောန်စိုတ်။
1ljt2g3jtokuw9jcqc2wbf7pumxihtw
ထာမ်ပလိက်:rif-verb
10
294809
395221
2026-05-20T15:49:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:ber-headword|show|ကြိယာ|lang=rif}}<!-- --><noinclude>{{documentation}}{{tcat|hw}}</noinclude>"
395221
wikitext
text/x-wiki
{{#invoke:ber-headword|show|ကြိယာ|lang=rif}}<!--
--><noinclude>{{documentation}}{{tcat|hw}}</noinclude>
3qrdxtcj3qzi0haiu7sdww7yzxld6am
ထာမ်ပလိက်:rif-verb/documentation
10
294810
395223
2026-05-20T15:58:38Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> <includeonly> {{hwcat}} </includeonly>"
395223
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
<includeonly>
{{hwcat}}
</includeonly>
elpzcmslcafdfn44moqjbuiifyvt4a6
ကဏ္ဍ:ကြိယာထာရိဖေန်ဂမၠိုၚ်
14
294811
395224
2026-05-20T16:07:09Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာထာရိဖေန်|ထာရိဖေန်]] » :ကဏ္ဍ:..."
395224
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာထာရိဖေန်|ထာရိဖေန်]] » [[:ကဏ္ဍ:ဝေါဟာအဓိကထာရိဖေန်ဂမၠိုၚ်|ဝေါဟာတံသ္ဇိုၚ်]] » '''ကြိယာဂမၠိုၚ်'''
:ဝေါဟာထာရိဖေန်ပွမယဵုဒုၚ်မစၞောန်ထ္ၜးအတေံ၊ မက္တဵုဒှ်ပရောဟိုတ် ဝါ ကဆံၚ်ဒတန်ဂမၠိုၚ်။
[[ကဏ္ဍ:ဘာသာထာရိဖေန်]][[ကဏ္ဍ:ကြိယာဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ထ]]
1zw09ehijn097p9rzvf2w8whq9a5dld
ကဏ္ဍ:ဝေါဟာထာရိဖေန်ကၠုၚ်နူဝေါဟာအာရဗဳ မဝ်ရဝ်ကာန်ဂမၠိုၚ်
14
294812
395225
2026-05-20T16:15:41Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာထာရိဖေန်]]"
395225
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာထာရိဖေန်]]
4zr9kvrf7c79az044mk7yz8jwb0oup9
ကဏ္ဍ:ဝေါဟာထာရိဖေန်လွဳလဝ် နူဝေါဟာအာရဗဳ မဝ်ရဝ်ကာန်ဂမၠိုၚ်
14
294813
395226
2026-05-20T16:24:51Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာထာရိဖေန်]]"
395226
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာထာရိဖေန်]]
4zr9kvrf7c79az044mk7yz8jwb0oup9
ကဏ္ဍ:ကာရန်:မာလ်တဳ/ɛmm
14
294814
395227
2026-05-20T16:30:10Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » :ကဏ္ဍ:ကာရန..."
395227
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]] » [[:ကဏ္ဍ:ကာရန်:မာလ်တဳ|ကာရန်ဂမၠိုၚ်]] » -ɛmm
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာမာလ်တဳ|မာလ်တဳ]]မနွံကာရန် ɛmm ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:မာလ်တဳ|ɛmm]]
kb4hjrh54b1a01z9uhgnzjr9lmviaon
ထာမ်ပလိက်:mt-adverb
10
294815
395229
2026-05-20T16:33:00Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:mt-adverb]] ဇရေင် [[ထာမ်ပလိက်:mt-adv]]
395229
wikitext
text/x-wiki
#REDIRECT [[ထာမ်ပလိက်:mt-adv]]
84wgb74phfo8vejb6b0dmeek6h5g3vz
ထာမ်ပလိက်:mt-adv/documentation
10
294816
395230
2026-05-20T16:34:53Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> {{hwcat}}"
395230
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
{{hwcat}}
f8u1ebax0fek1lf9jgky9pqli0yk03y
ⵀⴻⵎⵎ
0
294817
395231
2026-05-20T16:37:09Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==ထာရိဖေန်== ===ကြိယာ=== {{head|rif|ကြိယာ}} # သကဵုဆက်စပ်၊ သကဵုစိုတ်လဵု၊ သကဵုစောဲလာံ။ # သကဵုဒှ်မစိုတ်လုပ်စ။ # သကဵုဒဒိုက်စိုတ်၊ သကဵုမအောန်စိုတ်။"
395231
wikitext
text/x-wiki
==ထာရိဖေန်==
===ကြိယာ===
{{head|rif|ကြိယာ}}
# သကဵုဆက်စပ်၊ သကဵုစိုတ်လဵု၊ သကဵုစောဲလာံ။
# သကဵုဒှ်မစိုတ်လုပ်စ။
# သကဵုဒဒိုက်စိုတ်၊ သကဵုမအောန်စိုတ်။
h3qiovpzzrgse49ikc95zeu1qv90je3
هم
0
294818
395238
2026-05-20T18:11:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|همـ|ہم}} =={{=ar=}}== {{was wotd|၂၀၂၆|မေ|၂၁}} ===ဗွဟ်ရမ္သာၚ်=== {{ar-pr|هُمْ}} * {{audio|ar|Ar-هم.ogg}} ===သဗ္ဗနာမ်=== {{head|ar|pronoun|head=هُمْ|g=m-p|ဗီုပြၚ်ဝုတ်ဒိုဟ်|ـهُم|ဝါ|ـهِم}} # ညးတံ။ ===ဗွဟ်ရမ္သာၚ် ၂ === {{ar-pr|هُمْ,هِمْ}} ===သဗ္ဗန..."
395238
wikitext
text/x-wiki
{{also|همـ|ہم}}
=={{=ar=}}==
{{was wotd|၂၀၂၆|မေ|၂၁}}
===ဗွဟ်ရမ္သာၚ်===
{{ar-pr|هُمْ}}
* {{audio|ar|Ar-هم.ogg}}
===သဗ္ဗနာမ်===
{{head|ar|pronoun|head=هُمْ|g=m-p|ဗီုပြၚ်ဝုတ်ဒိုဟ်|ـهُم|ဝါ|ـهِم}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{ar-pr|هُمْ,هِمْ}}
===သဗ္ဗနာမ်===
{{head|ar|pronoun|head=ـهُمْ|tr=-hum|head2=ـهِمْ|tr2=-him|g=m-p}} (''enclitic form of'' {{m|ar|هُم}})
# ညးဂမၠိုၚ်၊ ဍေံတံ။
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
{{ar-pr|هَمَّ}}
====ကြိယာ====
{{ar-verb|I/a~u.pass.vn:هَمّ,مَهَمَّة}}
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
===ဗွဟ်ရမ္သာၚ် ၄ ===
{{ar-pr|هَمّ}}
===နာမ်===
{{ar-noun|هَمّ|m|pl=هُمُوم}}
# {{ar-verbal noun of|هَمَّ|form=I}}
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-noun|هَمّ|pl=هُمُوم}}
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၅ ===
{{ar-pr|هِمّ}}
===နာမဝိသေသန===
{{ar-adj+|هِمّ|pl=أَهْمَام|fpl=هَمَائِم,+}}
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-adj|هِمّ|m|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
=====နိဿဲ=====
* {{R:ar:Wehr-4|هم}}
===နာမ်===
{{ar-noun+|هِمّ|m|pl=أَهْمَام}}
# မၞိဟ်တြုံဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-gendered-noun|هِمّ|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
===နိဿဲ===
* {{R:ar:Freytag|volume=4|page=406}}
* {{R:ar:Kazimirski|volume=2|page=1442}}
* {{R:ar:Steingass|page=1181}}
* {{R:ar:Wehr-4|هم}}
* {{R:ar:Wehr-5-de|page=1355–1356}}
==ချာကထိုၚ်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|chg|𐽷𐽰𐽹|ts=häm||{{w|Old Uyghur alphabet|Old Uyghur script}}}}
===နိရုတ်===
{{bor+|chg|fa-cls|هَم}}
===သမ္ဗန္ဓ===
{{head|chg|conjunction|ts=häm}}
# သီုၜါ... ကဵု...
# ကဵု။
# လေဝ်။
===မဒုၚ်လွဳစ===
* {{desc|ug|ھەم}}
* {{desc|uz|ham}}
==အာရဗဳ အဳဂျေပ်==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|arz|/ˈhommæ/}}
===သဗ္ဗနာမ်===
{{head|arz|pronoun|tr=humma|g=p}}
# ညးတံ။
===အဆက်လက္ကရဴ===
{{head|arz|suffix|head=ـهم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
==အာရဗဳဟဳဂျာဇြဳ==
{{acw-root|ه م م}}
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هُمْ}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|acw|/ˈhum.ma/|[ˈhʊmma]}}
===သဗ္ဗနာမ်===
{{acw-pronoun|tr=humma|g=p}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{IPA|acw|/ˈhum/|[ˈhʊm]}}
===အဆက်လက္ကရဴ===
{{head|acw|suffix|head=ـهُم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
* {{IPA|acw|/ˈhamm/|[ˈham]}}
===နာမ်===
{{acw-noun|g=m|tr=hamm|pl=هموم|pltr=humūm}}
# ဓဝိၚ်၊ မဂွိၚ်က္တဴ၊ ဂဝိၚ်၊ မဂွိၚ်စံၚ်တဴ။
# သောက၊ ပရိဒေဝ၊ ဒဒိုက်၊ လၞီ။
==အာရဗဳ အဳရတ်==
===နိရုတ်===
{{bor+|acm|fa-ira|هَم}}
===ကြိယာဝိသေသန===
{{head|acm|adverb|tr=hamm}}
# လေဝ်၊ လေဝ်ကီု၊ ၜိုန်၊ အပြံၚ်အလှာဲသီုဖအိုတ်မွဲမွဲတ္ၚဲ။
==တူရကဳ အာန်နာတဝ်လဳယာန်တြေံ==
===နိရုတ်===
{{bor+|trk-oat|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|trk-oat|conjunction|tr=hem|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|az|həm}}
* {{desc|gag|hem}}
* {{desctree|ota|هم|tr=hem}}
==တူရကဳအောက်ဒဝ်မာန်==
===နိရုတ်===
{{inh+|ota|trk-oat|tr=häm|هَمْ}}၊ နကဵုအဆက်နူ {{der|ota|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|ota|conjunction|tr=häm|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|tr|hem}}
==ပါရှေန်==
===နိရုတ်===
{{root|fa|ine-pro|*sem-}}
ဝေါဟာကၠုၚ်နူ {{inherited|fa|pal|hm|tr=ham}}၊ နကဵုအဆက်နူ {{inherited|fa|peo|𐏃𐎶|ts=ham(a)}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{inherited|fa|ira-pro|*hamHáh}}၊ နူအဆက်နကဵု {{inherited|fa|iir-pro|*samHás}}၊ မဆက်ဆေန်နူ {{inherited|fa|ine-pro|*somHós}}
===ပွံၚ်နဲတၞဟ်===
* {{alt|fa|ـم|tr=-am||colloquial}}
===ဗွဟ်ရမ္သာၚ်===
{{fa-IPA|ham|teh=am|kbl=am}}
* {{rhyme|fa|am|s=1}}
* This word never takes stress.
===ကြိယာဝိသေသန===
{{head|fa|adverb|tr=ham}}
# လေဝ်၊ ကီုလေဝ်။
#: {{syn|fa|نیز|tr=nizl}}
===သဗ္ဗနာမ်===
{{head|fa|pronoun|tr=ham}}
# ညးတၞဟ်မွဲမွဲ; {{short for|fa|همدیگر|tr=hamdigar}}
===မဒုၚ်လွဳစ===
* {{desc|hy|համ|t=and, both|bor=1}}
* {{desc|ba|һәм|t=and|bor=1}}
* {{desctree|chg|هم|ts=häm|bor=1}}
* {{desc|tt|һәм|t=and|bor=1}}
* {{desc|acm|هم|t=still|bor=1}}
* {{desctree|trk-oat|هَمْ|tr=hem|bor=1}}
===နိရုတ် ၂ ===
{{bor+|fa|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{fa-IPA|ham(m)}}
===နာမ်===
{{fa-noun|tr=ham}}
# လၞီ၊ သောက။
#: {{syn|fa|غم|tr=ġam}}
==အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هُمْ}}
===ပွံၚ်နဲတၞဟ်===
* {{alter|ajp|همه}}
===ဗွဟ်ရမ္သာၚ်===
* {{ajp-IPA|homme<p:ˈhʊm.me>}}
* {{audio|ajp|LL-Q55633582 (ajp)-MahmoudM (AdrianAbdulBaha)-همه.wav|a=Jerusalem}}
===သဗ္ဗနာမ်===
{{ajp-pronoun|head=هم|g=p|tr=homme|encl=ـهم|encltr=-hom}}
# ညးတံ။
#: {{syn|ajp|هن|tr=hinne}}
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|ـهُمْ}} ဝါ {{m|ar|ـهِمْ}}
====အဆက်လက္ကရဴ====
{{ajp-suffix|head=ـهم|g=p|tr=-hom}}
# {{senseid|ajp|enclitic}} {{form of|ajp|ဗီုပြၚ်ဝုတ်ဒိုဟ်|هم|tr=homme}}
# ညးဂမၠိုၚ်၊ ဣတေံ၊ ဍေံတံ။
#: {{syn|ajp|ـهن|tr=-hen}}
===နိရုတ် ၃ ===
{{ajp-root|ه م م}}
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هَمَّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{ajp-IPA|hamm<p:ham>}}
* {{audio|ajp|LL-Q55633582 (ajp)-Khalil.rantissi-هَمّ.wav|a=al-Lidd}}
====ကြိယာ====
{{ajp-verb|head=همّ|I|tr=hamm|pres=بهمّ|prestr=bihimm}}
# သကဵုဂွိၚ်ဂွာဲ၊ သကဵုစောဲလာံ။
==အာရဗဳ တူနဳယှေန်==
====အဆက်လက္ကရဴ====
{{head|aeb|suffix|head='''ـهُمْ'''|tr=-hum|g=p}}
# ညးတံ၊ ဣတေံ။
qahqga1xwfta2t73hr3jrxqinmibiid
395266
395238
2026-05-20T19:19:38Z
咽頭べさ
33
395266
wikitext
text/x-wiki
{{also|همـ|ہم}}
=={{=ar=}}==
{{was wotd|၂၀၂၆|မေ|၂၁}}
===ဗွဟ်ရမ္သာၚ်===
{{ar-pr|هُمْ}}
* {{audio|ar|Ar-هم.ogg}}
===သဗ္ဗနာမ်===
{{head|ar|pronoun|head=هُمْ|g=m-p|ဗီုပြၚ်ဝုတ်ဒိုဟ်|ـهُم|ဝါ|ـهِم}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{ar-pr|هُمْ,هِمْ}}
===သဗ္ဗနာမ် ၂ ===
{{head|ar|pronoun|head=ـهُمْ|tr=-hum|head2=ـهِمْ|tr2=-him|g=m-p}} (''enclitic form of'' {{m|ar|هُم}})
# ညးဂမၠိုၚ်၊ ဍေံတံ။
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
{{ar-pr|هَمَّ}}
====ကြိယာ====
{{ar-verb|I/a~u.pass.vn:هَمّ,مَهَمَّة}}
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
===ဗွဟ်ရမ္သာၚ် ၄ ===
{{ar-pr|هَمّ}}
===နာမ်===
{{ar-noun|هَمّ|m|pl=هُمُوم}}
# {{ar-verbal noun of|هَمَّ|form=I}}
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-noun|هَمّ|pl=هُمُوم}}
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၅ ===
{{ar-pr|هِمّ}}
===နာမဝိသေသန===
{{ar-adj+|هِمّ|pl=أَهْمَام|fpl=هَمَائِم,+}}
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-adj|هِمّ|m|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
=====နိဿဲ=====
* {{R:ar:Wehr-4|هم}}
===နာမ်===
{{ar-noun+|هِمّ|m|pl=أَهْمَام}}
# မၞိဟ်တြုံဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-gendered-noun|هِمّ|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
===နိဿဲ===
* {{R:ar:Freytag|volume=4|page=406}}
* {{R:ar:Kazimirski|volume=2|page=1442}}
* {{R:ar:Steingass|page=1181}}
* {{R:ar:Wehr-4|هم}}
* {{R:ar:Wehr-5-de|page=1355–1356}}
==ချာကထိုၚ်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|chg|𐽷𐽰𐽹|ts=häm||{{w|Old Uyghur alphabet|Old Uyghur script}}}}
===နိရုတ်===
{{bor+|chg|fa-cls|هَم}}
===သမ္ဗန္ဓ===
{{head|chg|conjunction|ts=häm}}
# သီုၜါ... ကဵု...
# ကဵု။
# လေဝ်။
===မဒုၚ်လွဳစ===
* {{desc|ug|ھەم}}
* {{desc|uz|ham}}
==အာရဗဳ အဳဂျေပ်==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|arz|/ˈhommæ/}}
===သဗ္ဗနာမ်===
{{head|arz|pronoun|tr=humma|g=p}}
# ညးတံ။
===အဆက်လက္ကရဴ===
{{head|arz|suffix|head=ـهم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
==အာရဗဳဟဳဂျာဇြဳ==
{{acw-root|ه م م}}
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هُمْ}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|acw|/ˈhum.ma/|[ˈhʊmma]}}
===သဗ္ဗနာမ်===
{{acw-pronoun|tr=humma|g=p}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{IPA|acw|/ˈhum/|[ˈhʊm]}}
===အဆက်လက္ကရဴ===
{{head|acw|suffix|head=ـهُم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
* {{IPA|acw|/ˈhamm/|[ˈham]}}
===နာမ်===
{{acw-noun|g=m|tr=hamm|pl=هموم|pltr=humūm}}
# ဓဝိၚ်၊ မဂွိၚ်က္တဴ၊ ဂဝိၚ်၊ မဂွိၚ်စံၚ်တဴ။
# သောက၊ ပရိဒေဝ၊ ဒဒိုက်၊ လၞီ။
==အာရဗဳ အဳရတ်==
===နိရုတ်===
{{bor+|acm|fa-ira|هَم}}
===ကြိယာဝိသေသန===
{{head|acm|adverb|tr=hamm}}
# လေဝ်၊ လေဝ်ကီု၊ ၜိုန်၊ အပြံၚ်အလှာဲသီုဖအိုတ်မွဲမွဲတ္ၚဲ။
==တူရကဳ အာန်နာတဝ်လဳယာန်တြေံ==
===နိရုတ်===
{{bor+|trk-oat|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|trk-oat|conjunction|tr=hem|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|az|həm}}
* {{desc|gag|hem}}
* {{desctree|ota|هم|tr=hem}}
==တူရကဳအောက်ဒဝ်မာန်==
===နိရုတ်===
{{inh+|ota|trk-oat|tr=häm|هَمْ}}၊ နကဵုအဆက်နူ {{der|ota|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|ota|conjunction|tr=häm|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|tr|hem}}
==ပါရှေန်==
===နိရုတ်===
{{root|fa|ine-pro|*sem-}}
ဝေါဟာကၠုၚ်နူ {{inherited|fa|pal|hm|tr=ham}}၊ နကဵုအဆက်နူ {{inherited|fa|peo|𐏃𐎶|ts=ham(a)}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{inherited|fa|ira-pro|*hamHáh}}၊ နူအဆက်နကဵု {{inherited|fa|iir-pro|*samHás}}၊ မဆက်ဆေန်နူ {{inherited|fa|ine-pro|*somHós}}
===ပွံၚ်နဲတၞဟ်===
* {{alt|fa|ـم|tr=-am||colloquial}}
===ဗွဟ်ရမ္သာၚ်===
{{fa-IPA|ham|teh=am|kbl=am}}
* {{rhyme|fa|am|s=1}}
* This word never takes stress.
===ကြိယာဝိသေသန===
{{head|fa|adverb|tr=ham}}
# လေဝ်၊ ကီုလေဝ်။
#: {{syn|fa|نیز|tr=nizl}}
===သဗ္ဗနာမ်===
{{head|fa|pronoun|tr=ham}}
# ညးတၞဟ်မွဲမွဲ; {{short for|fa|همدیگر|tr=hamdigar}}
===မဒုၚ်လွဳစ===
* {{desc|hy|համ|t=and, both|bor=1}}
* {{desc|ba|һәм|t=and|bor=1}}
* {{desctree|chg|هم|ts=häm|bor=1}}
* {{desc|tt|һәм|t=and|bor=1}}
* {{desc|acm|هم|t=still|bor=1}}
* {{desctree|trk-oat|هَمْ|tr=hem|bor=1}}
===နိရုတ် ၂ ===
{{bor+|fa|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{fa-IPA|ham(m)}}
===နာမ်===
{{fa-noun|tr=ham}}
# လၞီ၊ သောက။
#: {{syn|fa|غم|tr=ġam}}
==အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هُمْ}}
===ပွံၚ်နဲတၞဟ်===
* {{alter|ajp|همه}}
===ဗွဟ်ရမ္သာၚ်===
* {{ajp-IPA|homme<p:ˈhʊm.me>}}
* {{audio|ajp|LL-Q55633582 (ajp)-MahmoudM (AdrianAbdulBaha)-همه.wav|a=Jerusalem}}
===သဗ္ဗနာမ်===
{{ajp-pronoun|head=هم|g=p|tr=homme|encl=ـهم|encltr=-hom}}
# ညးတံ။
#: {{syn|ajp|هن|tr=hinne}}
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|ـهُمْ}} ဝါ {{m|ar|ـهِمْ}}
====အဆက်လက္ကရဴ====
{{ajp-suffix|head=ـهم|g=p|tr=-hom}}
# {{senseid|ajp|enclitic}} {{form of|ajp|ဗီုပြၚ်ဝုတ်ဒိုဟ်|هم|tr=homme}}
# ညးဂမၠိုၚ်၊ ဣတေံ၊ ဍေံတံ။
#: {{syn|ajp|ـهن|tr=-hen}}
===နိရုတ် ၃ ===
{{ajp-root|ه م م}}
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هَمَّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{ajp-IPA|hamm<p:ham>}}
* {{audio|ajp|LL-Q55633582 (ajp)-Khalil.rantissi-هَمّ.wav|a=al-Lidd}}
====ကြိယာ====
{{ajp-verb|head=همّ|I|tr=hamm|pres=بهمّ|prestr=bihimm}}
# သကဵုဂွိၚ်ဂွာဲ၊ သကဵုစောဲလာံ။
==အာရဗဳ တူနဳယှေန်==
====အဆက်လက္ကရဴ====
{{head|aeb|suffix|head='''ـهُمْ'''|tr=-hum|g=p}}
# ညးတံ၊ ဣတေံ။
1vkq9v7mmqf8c8jbjd8rima0ps6orov
395268
395266
2026-05-20T19:27:42Z
咽頭べさ
33
/* ကြိယာ */
395268
wikitext
text/x-wiki
{{also|همـ|ہم}}
=={{=ar=}}==
{{was wotd|၂၀၂၆|မေ|၂၁}}
===ဗွဟ်ရမ္သာၚ်===
{{ar-pr|هُمْ}}
* {{audio|ar|Ar-هم.ogg}}
===သဗ္ဗနာမ်===
{{head|ar|pronoun|head=هُمْ|g=m-p|ဗီုပြၚ်ဝုတ်ဒိုဟ်|ـهُم|ဝါ|ـهِم}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{ar-pr|هُمْ,هِمْ}}
===သဗ္ဗနာမ် ၂ ===
{{head|ar|pronoun|head=ـهُمْ|tr=-hum|head2=ـهِمْ|tr2=-him|g=m-p}} (''enclitic form of'' {{m|ar|هُم}})
# ညးဂမၠိုၚ်၊ ဍေံတံ။
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
{{ar-pr|هَمَّ}}
====ကြိယာ====
{{ar-verb|I/a~u.pass.vn:هَمّ,مَهَمَّة}}
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
===ဗွဟ်ရမ္သာၚ် ၄ ===
{{ar-pr|هَمّ}}
===နာမ်===
{{ar-noun|هَمّ|m|pl=هُمُوم}}
# {{ar-verbal noun of|هَمَّ|form=I}}
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-noun|هَمّ|pl=هُمُوم}}
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၅ ===
{{ar-pr|هِمّ}}
===နာမဝိသေသန===
{{ar-adj+|هِمّ|pl=أَهْمَام|fpl=هَمَائِم,+}}
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-adj|هِمّ|m|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
=====နိဿဲ=====
* {{R:ar:Wehr-4|هم}}
===နာမ်===
{{ar-noun+|هِمّ|m|pl=أَهْمَام}}
# မၞိဟ်တြုံဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-gendered-noun|هِمّ|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
===နိဿဲ===
* {{R:ar:Freytag|volume=4|page=406}}
* {{R:ar:Kazimirski|volume=2|page=1442}}
* {{R:ar:Steingass|page=1181}}
* {{R:ar:Wehr-4|هم}}
* {{R:ar:Wehr-5-de|page=1355–1356}}
==ချာကထိုၚ်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|chg|𐽷𐽰𐽹|ts=häm||{{w|Old Uyghur alphabet|Old Uyghur script}}}}
===နိရုတ်===
{{bor+|chg|fa-cls|هَم}}
===သမ္ဗန္ဓ===
{{head|chg|conjunction|ts=häm}}
# သီုၜါ... ကဵု...
# ကဵု။
# လေဝ်။
===မဒုၚ်လွဳစ===
* {{desc|ug|ھەم}}
* {{desc|uz|ham}}
==အာရဗဳ အဳဂျေပ်==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|arz|/ˈhommæ/}}
===သဗ္ဗနာမ်===
{{head|arz|pronoun|tr=humma|g=p}}
# ညးတံ။
===အဆက်လက္ကရဴ===
{{head|arz|suffix|head=ـهم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
==အာရဗဳဟဳဂျာဇြဳ==
{{acw-root|ه م م}}
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هُمْ}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|acw|/ˈhum.ma/|[ˈhʊmma]}}
===သဗ္ဗနာမ်===
{{acw-pronoun|tr=humma|g=p}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{IPA|acw|/ˈhum/|[ˈhʊm]}}
===အဆက်လက္ကရဴ===
{{head|acw|suffix|head=ـهُم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
* {{IPA|acw|/ˈhamm/|[ˈham]}}
===နာမ်===
{{acw-noun|g=m|tr=hamm|pl=هموم|pltr=humūm}}
# ဓဝိၚ်၊ မဂွိၚ်က္တဴ၊ ဂဝိၚ်၊ မဂွိၚ်စံၚ်တဴ။
# သောက၊ ပရိဒေဝ၊ ဒဒိုက်၊ လၞီ။
==အာရဗဳ အဳရတ်==
===နိရုတ်===
{{bor+|acm|fa-ira|هَم}}
===ကြိယာဝိသေသန===
{{head|acm|adverb|tr=hamm}}
# လေဝ်၊ လေဝ်ကီု၊ ၜိုန်၊ အပြံၚ်အလှာဲသီုဖအိုတ်မွဲမွဲတ္ၚဲ။
==တူရကဳ အာန်နာတဝ်လဳယာန်တြေံ==
===နိရုတ်===
{{bor+|trk-oat|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|trk-oat|conjunction|tr=hem|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|az|həm}}
* {{desc|gag|hem}}
* {{desctree|ota|هم|tr=hem}}
==တူရကဳအောက်ဒဝ်မာန်==
===နိရုတ်===
{{inh+|ota|trk-oat|tr=häm|هَمْ}}၊ နကဵုအဆက်နူ {{der|ota|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|ota|conjunction|tr=häm|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|tr|hem}}
==ပါရှေန်==
===နိရုတ်===
{{root|fa|ine-pro|*sem-}}
ဝေါဟာကၠုၚ်နူ {{inherited|fa|pal|hm|tr=ham}}၊ နကဵုအဆက်နူ {{inherited|fa|peo|𐏃𐎶|ts=ham(a)}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{inherited|fa|ira-pro|*hamHáh}}၊ နူအဆက်နကဵု {{inherited|fa|iir-pro|*samHás}}၊ မဆက်ဆေန်နူ {{inherited|fa|ine-pro|*somHós}}
===ပွံၚ်နဲတၞဟ်===
* {{alt|fa|ـم|tr=-am||colloquial}}
===ဗွဟ်ရမ္သာၚ်===
{{fa-IPA|ham|teh=am|kbl=am}}
* {{rhyme|fa|am|s=1}}
* This word never takes stress.
===ကြိယာဝိသေသန===
{{head|fa|adverb|tr=ham}}
# လေဝ်၊ ကီုလေဝ်။
#: {{syn|fa|نیز|tr=nizl}}
===သဗ္ဗနာမ်===
{{head|fa|pronoun|tr=ham}}
# ညးတၞဟ်မွဲမွဲ; {{short for|fa|همدیگر|tr=hamdigar}}
===မဒုၚ်လွဳစ===
* {{desc|hy|համ|t=and, both|bor=1}}
* {{desc|ba|һәм|t=and|bor=1}}
* {{desctree|chg|هم|ts=häm|bor=1}}
* {{desc|tt|һәм|t=and|bor=1}}
* {{desc|acm|هم|t=still|bor=1}}
* {{desctree|trk-oat|هَمْ|tr=hem|bor=1}}
===နိရုတ် ၂ ===
{{bor+|fa|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{fa-IPA|ham(m)}}
===နာမ်===
{{fa-noun|tr=ham}}
# လၞီ၊ သောက။
#: {{syn|fa|غم|tr=ġam}}
==အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هُمْ}}
===ပွံၚ်နဲတၞဟ်===
* {{alter|ajp|همه}}
===ဗွဟ်ရမ္သာၚ်===
* {{ajp-IPA|homme<p:ˈhʊm.me>}}
* {{audio|ajp|LL-Q55633582 (ajp)-MahmoudM (AdrianAbdulBaha)-همه.wav|a=Jerusalem}}
===သဗ္ဗနာမ်===
{{ajp-pronoun|head=هم|g=p|tr=homme|encl=ـهم|encltr=-hom}}
# ညးတံ။
#: {{syn|ajp|هن|tr=hinne}}
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|ـهُمْ}} ဝါ {{m|ar|ـهِمْ}}
====အဆက်လက္ကရဴ====
{{ajp-suffix|head=ـهم|g=p|tr=-hom}}
# {{senseid|ajp|enclitic}} {{form of|ajp|ဗီုပြၚ်ဝုတ်ဒိုဟ်|هم|tr=homme}}
# ညးဂမၠိုၚ်၊ ဣတေံ၊ ဍေံတံ။
#: {{syn|ajp|ـهن|tr=-hen}}
===နိရုတ် ၃ ===
{{ajp-root|ه م م}}
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هَمَّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{ajp-IPA|hamm<p:ham>}}
* {{audio|ajp|LL-Q55633582 (ajp)-Khalil.rantissi-هَمّ.wav|a=al-Lidd}}
====ကြိယာ====
{{ajp-verb|head=همّ|I|pres=بهمّ}}
# သကဵုဂွိၚ်ဂွာဲ၊ သကဵုစောဲလာံ။
==အာရဗဳ တူနဳယှေန်==
====အဆက်လက္ကရဴ====
{{head|aeb|suffix|head='''ـهُمْ'''|tr=-hum|g=p}}
# ညးတံ၊ ဣတေံ။
e7mx0ac4eifkqvcbhenf7hdzfmx1n5g
395269
395268
2026-05-20T19:28:16Z
咽頭べさ
33
ကလေင်ပလီု မူတၟိ[[Special:Diff/395268|395268]]နကု[[Special:Contributions/咽頭べさ|咽頭べさ]] ([[User talk:咽頭べさ|ဓရီုကျာ]])
395269
wikitext
text/x-wiki
{{also|همـ|ہم}}
=={{=ar=}}==
{{was wotd|၂၀၂၆|မေ|၂၁}}
===ဗွဟ်ရမ္သာၚ်===
{{ar-pr|هُمْ}}
* {{audio|ar|Ar-هم.ogg}}
===သဗ္ဗနာမ်===
{{head|ar|pronoun|head=هُمْ|g=m-p|ဗီုပြၚ်ဝုတ်ဒိုဟ်|ـهُم|ဝါ|ـهِم}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{ar-pr|هُمْ,هِمْ}}
===သဗ္ဗနာမ် ၂ ===
{{head|ar|pronoun|head=ـهُمْ|tr=-hum|head2=ـهِمْ|tr2=-him|g=m-p}} (''enclitic form of'' {{m|ar|هُم}})
# ညးဂမၠိုၚ်၊ ဍေံတံ။
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
{{ar-pr|هَمَّ}}
====ကြိယာ====
{{ar-verb|I/a~u.pass.vn:هَمّ,مَهَمَّة}}
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
===ဗွဟ်ရမ္သာၚ် ၄ ===
{{ar-pr|هَمّ}}
===နာမ်===
{{ar-noun|هَمّ|m|pl=هُمُوم}}
# {{ar-verbal noun of|هَمَّ|form=I}}
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-noun|هَمّ|pl=هُمُوم}}
{{ar-rootbox|ه م م}}
===ဗွဟ်ရမ္သာၚ် ၅ ===
{{ar-pr|هِمّ}}
===နာမဝိသေသန===
{{ar-adj+|هِمّ|pl=أَهْمَام|fpl=هَمَائِم,+}}
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-adj|هِمّ|m|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
=====နိဿဲ=====
* {{R:ar:Wehr-4|هم}}
===နာမ်===
{{ar-noun+|هِمّ|m|pl=أَهْمَام}}
# မၞိဟ်တြုံဗျုထဴ။
=====မလဟုတ်စှ်ေ=====
{{ar-decl-gendered-noun|هِمّ|f=هِمَّة|pl=أَهْمَام|fpl=هَمَائِم|fpl2=هِمَّات}}
===နိဿဲ===
* {{R:ar:Freytag|volume=4|page=406}}
* {{R:ar:Kazimirski|volume=2|page=1442}}
* {{R:ar:Steingass|page=1181}}
* {{R:ar:Wehr-4|هم}}
* {{R:ar:Wehr-5-de|page=1355–1356}}
==ချာကထိုၚ်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|chg|𐽷𐽰𐽹|ts=häm||{{w|Old Uyghur alphabet|Old Uyghur script}}}}
===နိရုတ်===
{{bor+|chg|fa-cls|هَم}}
===သမ္ဗန္ဓ===
{{head|chg|conjunction|ts=häm}}
# သီုၜါ... ကဵု...
# ကဵု။
# လေဝ်။
===မဒုၚ်လွဳစ===
* {{desc|ug|ھەم}}
* {{desc|uz|ham}}
==အာရဗဳ အဳဂျေပ်==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|arz|/ˈhommæ/}}
===သဗ္ဗနာမ်===
{{head|arz|pronoun|tr=humma|g=p}}
# ညးတံ။
===အဆက်လက္ကရဴ===
{{head|arz|suffix|head=ـهم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
==အာရဗဳဟဳဂျာဇြဳ==
{{acw-root|ه م م}}
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هُمْ}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|acw|/ˈhum.ma/|[ˈhʊmma]}}
===သဗ္ဗနာမ်===
{{acw-pronoun|tr=humma|g=p}}
# ညးတံ။
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{IPA|acw|/ˈhum/|[ˈhʊm]}}
===အဆက်လက္ကရဴ===
{{head|acw|suffix|head=ـهُم|tr=-hum|g=p}}
# ဍေံတံ၊ ညးတံဂမၠိုၚ်။
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|acw|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၃ ===
* {{IPA|acw|/ˈhamm/|[ˈham]}}
===နာမ်===
{{acw-noun|g=m|tr=hamm|pl=هموم|pltr=humūm}}
# ဓဝိၚ်၊ မဂွိၚ်က္တဴ၊ ဂဝိၚ်၊ မဂွိၚ်စံၚ်တဴ။
# သောက၊ ပရိဒေဝ၊ ဒဒိုက်၊ လၞီ။
==အာရဗဳ အဳရတ်==
===နိရုတ်===
{{bor+|acm|fa-ira|هَم}}
===ကြိယာဝိသေသန===
{{head|acm|adverb|tr=hamm}}
# လေဝ်၊ လေဝ်ကီု၊ ၜိုန်၊ အပြံၚ်အလှာဲသီုဖအိုတ်မွဲမွဲတ္ၚဲ။
==တူရကဳ အာန်နာတဝ်လဳယာန်တြေံ==
===နိရုတ်===
{{bor+|trk-oat|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|trk-oat|conjunction|tr=hem|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|az|həm}}
* {{desc|gag|hem}}
* {{desctree|ota|هم|tr=hem}}
==တူရကဳအောက်ဒဝ်မာန်==
===နိရုတ်===
{{inh+|ota|trk-oat|tr=häm|هَمْ}}၊ နကဵုအဆက်နူ {{der|ota|fa|tr=ham|هم}}
===သမ္ဗန္ဓ===
{{head|ota|conjunction|tr=häm|head=هَمْ}}
# သီုၜါ... ကဵု...
===မဒုၚ်လွဳစ===
* {{desc|tr|hem}}
==ပါရှေန်==
===နိရုတ်===
{{root|fa|ine-pro|*sem-}}
ဝေါဟာကၠုၚ်နူ {{inherited|fa|pal|hm|tr=ham}}၊ နကဵုအဆက်နူ {{inherited|fa|peo|𐏃𐎶|ts=ham(a)}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{inherited|fa|ira-pro|*hamHáh}}၊ နူအဆက်နကဵု {{inherited|fa|iir-pro|*samHás}}၊ မဆက်ဆေန်နူ {{inherited|fa|ine-pro|*somHós}}
===ပွံၚ်နဲတၞဟ်===
* {{alt|fa|ـم|tr=-am||colloquial}}
===ဗွဟ်ရမ္သာၚ်===
{{fa-IPA|ham|teh=am|kbl=am}}
* {{rhyme|fa|am|s=1}}
* This word never takes stress.
===ကြိယာဝိသေသန===
{{head|fa|adverb|tr=ham}}
# လေဝ်၊ ကီုလေဝ်။
#: {{syn|fa|نیز|tr=nizl}}
===သဗ္ဗနာမ်===
{{head|fa|pronoun|tr=ham}}
# ညးတၞဟ်မွဲမွဲ; {{short for|fa|همدیگر|tr=hamdigar}}
===မဒုၚ်လွဳစ===
* {{desc|hy|համ|t=and, both|bor=1}}
* {{desc|ba|һәм|t=and|bor=1}}
* {{desctree|chg|هم|ts=häm|bor=1}}
* {{desc|tt|һәм|t=and|bor=1}}
* {{desc|acm|هم|t=still|bor=1}}
* {{desctree|trk-oat|هَمْ|tr=hem|bor=1}}
===နိရုတ် ၂ ===
{{bor+|fa|ar|هَمّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
{{fa-IPA|ham(m)}}
===နာမ်===
{{fa-noun|tr=ham}}
# လၞီ၊ သောက။
#: {{syn|fa|غم|tr=ġam}}
==အာရဗဳလပ်ဗေန်ထေန်သမၠုၚ်ကျာ==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هُمْ}}
===ပွံၚ်နဲတၞဟ်===
* {{alter|ajp|همه}}
===ဗွဟ်ရမ္သာၚ်===
* {{ajp-IPA|homme<p:ˈhʊm.me>}}
* {{audio|ajp|LL-Q55633582 (ajp)-MahmoudM (AdrianAbdulBaha)-همه.wav|a=Jerusalem}}
===သဗ္ဗနာမ်===
{{ajp-pronoun|head=هم|g=p|tr=homme|encl=ـهم|encltr=-hom}}
# ညးတံ။
#: {{syn|ajp|هن|tr=hinne}}
===နိရုတ် ၂ ===
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|ـهُمْ}} ဝါ {{m|ar|ـهِمْ}}
====အဆက်လက္ကရဴ====
{{ajp-suffix|head=ـهم|g=p|tr=-hom}}
# {{senseid|ajp|enclitic}} {{form of|ajp|ဗီုပြၚ်ဝုတ်ဒိုဟ်|هم|tr=homme}}
# ညးဂမၠိုၚ်၊ ဣတေံ၊ ဍေံတံ။
#: {{syn|ajp|ـهن|tr=-hen}}
===နိရုတ် ၃ ===
{{ajp-root|ه م م}}
ဝေါဟာကၠုၚ်နူ {{inh|ajp|ar|هَمَّ}}
===ဗွဟ်ရမ္သာၚ် ၂ ===
* {{ajp-IPA|hamm<p:ham>}}
* {{audio|ajp|LL-Q55633582 (ajp)-Khalil.rantissi-هَمّ.wav|a=al-Lidd}}
====ကြိယာ====
{{ajp-verb|head=همّ|I|tr=hamm|pres=بهمّ|prestr=bihimm}}
# သကဵုဂွိၚ်ဂွာဲ၊ သကဵုစောဲလာံ။
==အာရဗဳ တူနဳယှေန်==
====အဆက်လက္ကရဴ====
{{head|aeb|suffix|head='''ـهُمْ'''|tr=-hum|g=p}}
# ညးတံ၊ ဣတေံ။
1vkq9v7mmqf8c8jbjd8rima0ps6orov
ထာမ်ပလိက်:acw-noun/documentation
10
294819
395240
2026-05-20T18:14:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> {{hwcat}}"
395240
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
{{hwcat}}
f8u1ebax0fek1lf9jgky9pqli0yk03y
ဝိက်ရှေန်နရဳ:မအရေဝ်သွက်တ္ၚဲဏအ်/၂၀၂၆/မေ၂၁
4
294820
395241
2026-05-20T18:20:10Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။ : သဗ္ဗနာမ် ၂ ညးဂမၠိုၚ်၊ ဍေံတံ။ : ကြိယာ # သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။ # သကဵုဒဒိုက်စိုတ်။ # သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထု..."
395241
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
: သဗ္ဗနာမ် ၂
ညးဂမၠိုၚ်၊ ဍေံတံ။
: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
dbed6cud8un8mtlef2mp9bwyiu49k7s
395242
395241
2026-05-20T18:20:59Z
咽頭べさ
33
395242
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
: သဗ္ဗနာမ် ၂
# ညးဂမၠိုၚ်၊ ဍေံတံ။
: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
8fv6prm96p59i48ysor5ow8mzxfe41n
395243
395242
2026-05-20T18:21:16Z
咽頭べさ
33
395243
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
:သဗ္ဗနာမ် ၂
# ညးဂမၠိုၚ်၊ ဍေံတံ။
: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
adb4tfxykj102u3x2scuq3c4tvmd8jk
395244
395243
2026-05-20T18:22:19Z
咽頭べさ
33
395244
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
#: သဗ္ဗနာမ် ၂
# ညးဂမၠိုၚ်၊ ဍေံတံ။
#: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
#: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
#: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
o2pnngal76gm0d46o6lu6a6aiz2sksp
395245
395244
2026-05-20T18:22:55Z
咽頭べさ
33
395245
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
#: သဗ္ဗနာမ် ၂
# ညးဂမၠိုၚ်၊ ဍေံတံ။
#: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
#: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
#: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
duh7cubhvnn6vz864p1f0xorz64mz6g
395246
395245
2026-05-20T18:23:10Z
咽頭べさ
33
395246
wikitext
text/x-wiki
{{WOTD|هم|သဗ္ဗနာမ်| ညးတံ။
#: သဗ္ဗနာမ် ၂
# ညးဂမၠိုၚ်၊ ဍေံတံ။
#: ကြိယာ
# သကဵုဂွိၚ်က္တဴ၊ သကဵုမသ္ပဟွံလောဲသွာ၊ သကဵုဒှ်သောက။
# သကဵုဒဒိုက်စိုတ်။
# သကဵုစောဲလာံ၊ သကဵုဒုၚ်ပထုဲ၊ သကဵုစိုတ်လီု။
# သကဵုဒှ်နကဵုမစိုတ်လုပ်စ။
# သကဵုရန်တၟံ၊ သကဵုဒှ်လ္ပာ်နာနာသာ်နကဵု၊ သကဵုပွမက္တဵုဒှ်မစတိတ်တရဴ၊ သကဵုမက္တဵုဒှ်ကၠုၚ်မဖျေံလဝ်သန္နိဋ္ဌာန်နကဵုဝေါဟာ {{+obj|ar|:بِ}}
#: နာမ်
# ဓဝိၚ်၊ ဂွိၚ်၊ ဂဝိၚ်၊ မဂွိၚ်က္တဴ။
# သောက၊ ပရိဒေဝ၊ ပရေၚ်မဒှ်ဒဒိုက်၊ လၞီ။
# ပံၚ်မ၊ ခဏ၊ ပရေၚ်မၞုံကဵုပၟိက်။
#: နာမဝိသေသန
# မလီုဒ္ဂေတ်ပဋိပတ်၊ ဆေၚ်စပ်ကဵုလက်သန်ကြံၚ်က္ဍုဟ်ဗျုထဴ။|audio=Ar-هم.ogg|မေ|၂၁}}
qowmwgm8k4i95faxoarsl87y88e5vn6
ထာမ်ပလိက်:ar-decl-noun
10
294821
395247
2026-05-20T18:24:59Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:ar-nominals|show_noun}}<!-- --><noinclude>{{documentation}}</noinclude>"
395247
wikitext
text/x-wiki
{{#invoke:ar-nominals|show_noun}}<!--
--><noinclude>{{documentation}}</noinclude>
4bugtypmel4edp2ome7glv8ni4rnwnk
ထာမ်ပလိက်:ar-decl-noun/documentation
10
294822
395249
2026-05-20T18:50:09Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} This template displays an inflection table for Arabic nouns. The parameters are largely the same as for the headword template {{temp|ar-noun}}, and in general it is possible to copy such a template, change its name to {{temp|ar-decl-noun}}, and get an appropriate declension table. (Ideally, delete extraneous stuff such as the gender and args with no equivalents below, such as {{para|cons}} an..."
395249
wikitext
text/x-wiki
{{documentation subpage}}
This template displays an inflection table for Arabic nouns. The parameters are largely the same as for the headword template {{temp|ar-noun}}, and in general it is possible to copy such a template, change its name to {{temp|ar-decl-noun}}, and get an appropriate declension table. (Ideally, delete extraneous stuff such as the gender and args with no equivalents below, such as {{para|cons}} and {{para|f}}.)
See also {{temp|ar-decl-adj}}.
==Base parameters==
; {{para|1}}
: The stem used in the singular, including vowels, of one of the following forms:
:# most commonly, just <code>STEM</code>, i.e. an Arabic stem where the transliteration automatically determined and the inflection type inferred from the stem (this inference is very accurate and rarely makes mistakes);
:# <code>STEM/TR</code> with manual transliteration supplied (use only when the automatic translit is wrong or can't be determined);
:# <code>STEM:TYPE</code> with an explicitly specified inflection type (see below);
:# <code>STEM/TR:TYPE</code> with both manual transliteration and explicitly specified inflection;
:# <code>?</code> to indicate an unknown singular (used more often the masculine plural of adjectives, and occasionally in nouns to specify an unknown dual);
:# <code>-</code> for words without a singular (e.g. {{m|ar|نَاس||people}}).
: Note that manual transliteration can also be specified using separate parameters, as with headword templates like {{temp|ar-noun}}.
; {{para|head2}}, {{para|head3}}, ...
: Additional singular stems.
; {{para|tr}}, {{para|tr2}}, {{para|tr3}}, ...
: Alternative way to specify manual transliteration for {{para|1}}, {{para|head2}}, {{para|head3}}, ..., respectively, instead of using the <code>STEM/TR</code> specification. Provided for compatibility with headword templates.
; {{para|pl}}, {{para|pl2}}, ...
: The stem(s) used in the plural, including vowels. Has the same forms as for the singular stem(s), with the addition that the value can be a raw inflection <code>TYPE</code>: e.g. <code>sp</code> to infer a strong plural from the singular and its gender; <code>sfp</code>, <code>smp</code> or <code>awnp</code> to construct a strong plural from the singular with a specified ending.
; {{para|pltr}}, {{para|pl2tr}}, ...
: Alternative way to specify manual transliteration for {{para|pl}}, {{para|pl2}}, ..., respectively, instead of using the <code>STEM/TR</code> specification. Provided for compatibility with headword templates. Similar parameters are available for duals.
; {{para|d}}, {{para|d2}}, ...
: The stem(s) used in the dual, including vowels. Same form as for plurals. Doesn't need to be present in most cases as it's inferred from the singular. Can be <code>-</code> for words without a dual when it would otherwise appear (which happens when the noun has a plural specified); can be <code>?</code> to indicate that the dual exists but is unknown (e.g. it is currently used in {{m|ar|بِيَانُو|tr=biyānō||[[piano]]}}).
; {{para|dtr}}, {{para|d2tr}}, ...
: See {{para|pltr}}, {{para|pl2tr}}, ...
; {{para|number}}
: Explicitly control which numbers appear. The value is a comma-separated list of one of more of <code>sg</code>, <code>du</code>, <code>pl</code>. By default, the singular appears unless it is specified as <code>-</code>; the dual appears when both the singular and plural appear; and the plural appears when at least one plural is given.
; {{para|state}}
: Explicitly control which states appear. The value is a comma-separated list of one of more of <code>ind</code>, <code>def</code>, <code>con</code> (standing for indefinite, definite, construct). By default, all states appear. (Alternatively, the value can be <code>ind-def</code>, for proper nouns that are syntactically definite but morphologically indefinite. This is equivalent to setting the value to <code>def</code> and adding {{para|basestate|ind}}.) Currently, non-"appearing" states are displayed with a dash in place of the appropriate declension members instead of not appearing at all.
; {{para|basestate}}
: Override the morphological state. The value is one of <code>ind</code>, <code>def</code> or <code>con</code>. This can be used e.g. with proper nouns, which are syntactically definite but morphologically indefinite; but using {{para|state|ind-def}} for this case is preferred.
; {{para|omitarticle}}
: If specified, omit the definite article that is otherwise automatically added in the definite state.
; {{para|prefix}}
: Specify a prefix to appear before the base word and before any definite article. This is typically a clitic such as {{m|ar|وَ|tr=wa-||and}} or {{m|ar|بِ|tr=bi-||in, with, by}}, but can be a separate word such as {{m|ar|فِي||in}}, in which a space is needed after the word and the whole thing, space and all, needs to be enclosed in quotes since leading and trailing spaces are normally removed in named template arguments.
; {{para|nom_sg_ind}}, {{para|nom_sg_def}}, {{para|nom_sg_con}}, ...
: Override particular forms. The param name is a combination of case (<code>nom/acc/gen/inf</code> where <code>inf</code> is the informal form), number (<code>sg/du/pl</code>) and state (<code>ind/def/con</code>). The value can have semicolons or commas (or Arabic equivalents) to separate distinct stems and a vertical bar to separate alternative spellings for a given stem (typically different possible hamza seats). When overrides are specified, the page will be placed in a category indicating irregular declension such as [[:Category:Arabic irregular nouns]] (or [[:Category:Arabic irregular pronouns]], etc. depending on the part of speech), unless {{para|noirreg}} is given a value.
; {{para|lemma}}
: Override the lemma (displayed at the head of the declension table).
; {{para|noirreg}}
: If specified, don't place the page in an irregular-declension category when overrides are specified.
; {{para|pos}}
: Override the part of speech (displayed at the head of the declension table).
==Modifier parameters==
; Stem: {{para|mod}},{{para|modhead2}},{{para|modhead3}},...
;; Alternative manual translit params: {{para|modtr}},{{para|modtr2}}, ...
; Plural: {{para|modpl}},{{para|modpl2}},...
;; Alternative manual translit params: {{para|modpltr}},{{para|modpl2tr}}, ...
; Dual: {{para|modd}},{{para|modd2}},...
;; Alternative manual translit params: {{para|moddtr}},{{para|modd2tr}}, ...
; Nature of modifier, high-level (''ʾiḍāfa'' or adjectival): {{para|idafa}}
; Nature of modifier, low-level: {{para|modstate}},{{para|modcase}},{{para|modnumber}},{{para|modidafa}}
; Other: {{para|modomitarticle}},{{para|modprefix}}
: Specify another word that is declined separately as a modifier. Generally only {{para|mod}} is needed, but multiple heads can be given ({{para|modhead2}}, etc., which will be distributed over the base form(s)), as well as separate plural ({{para|modpl}}, etc.) and dual ({{para|modd}}, etc.) forms. All the forms for specifying a base stem, base plural stem, etc. are available in the corresponding modifier stems, and alternative manual translit params also exist. If the modifier has a fixed genitive case in an ''ʾiḍāfa'' construction, {{para|idafa}} should be specified, e.g. {{para|idafa|def}} for a definite-state singular ''ʾiḍāfa'' modifier. See the list below of possible values for this parameter, and the numerous examples below. It is also possible to manually specify the case, state and/or number of the modifier using the lower-level parameters {{para|modstate}}, {{para|modcase}}, {{para|modnumber}}, and/or {{para|modidafa}} possibly in conjunction with {{para|basestate}}, but this is rarely needed. (Underlyingly, the various values of {{para|idafa}} are implemented by setting these low-level parameters. {{para|idafa}} can be combine with the low-level parameters, with the explicitly-specified values overriding the values induced by {{para|idafa}}.)
; {{para|mod2}},{{para|mod2head2}},{{para|mod2head3}},...; {{para|mod2pl}},{{para|mod2pl2}},...; {{para|mod2d}},{{para|mod2d2}},...; etc. Also {{para|idafa2}}. Also {{para|mod2state}},{{para|mod2tr}}, etc.
: Specify a second modifying word. All parameters specific to the first modifying word have corresponding parameters for the second and higher modifying words. The values for {{para|idafa2}} are the same as for {{para|idafa}}, but in addition it is necessary to specify e.g. {{para|idafa2|adj-mod}} for an adjectival modifier that modifies a previous ''ʾiḍāfa'' modifier.
; {{para|mod3}},{{para|mod3head2}},{{para|mod3head3}},...; {{para|mod3pl}},{{para|mod3pl2}},...; {{para|mod3d}},{{para|mod3d2}},...; etc. Also {{para|idafa3}}. Also {{para|mod3state}},{{para|mod3tr}}, etc.
: Specify a third modifying word, etc. up to {{para|mod9}}.
==Inflection types==
; <code>tri</code>
: Regular triptote.
; <code>di</code>
: Regular diptote.
; <code>in</code>
: Noun ending in ''-in'', such as {{m|ar|بَانٍ}}. This automatically selects the triptote or diptote variant according to the number (singular vs. plural) and the form of the noun.
; <code>triin</code>
: Noun ending in ''-in'', forcing the "triptote" variant (with indefinite accusative in ''-iyan'').
; <code>diin</code>
: Noun ending in ''-in'', forcing the "diptote" variant (with indefinite accusative in ''-iya''). Most but not all plural nouns use this variant. (Specifically, ''-iya'' is used with nouns whose pattern is analogous to a diptote pattern, such as {{m|ar|أَيَادٍ||hands}} and {{m|ar|لَيَالٍ||nights}}, which correspond to the diptote pattern ''CaCāCiC''. The "singular" ''-iyan'' is used with plural nouns such as {{m|ar|أَيْدٍ||hands}}, which corresponds to the triptote pattern ''ʾaCCuC''.)
; <code>inv</code>
: Invariable declension, such as {{m|ar|ذِكْرَى||remembrance}} or {{m|ar|دُنْيَا||world}}. Typically ends in alif or alif maqṣūra, but this is not required. Such words will have sound feminine plurals in ''-ayāt'' and duals in ''-ayān''.
; <code>lwinv</code>
: Invariable declension, loanword-type. Always ends in tall alif. Such words will have sound feminine plurals in ''-āt'' and duals in ''-atān'', as if the alif was a tāʾ marbūṭa.
; <code>an</code>
: Noun ending in ''-an'', such as {{m|ar|مُسْتَشْفًى}} or {{m|ar|عَصًا}}.
; <code>lc</code>
: Noun with a lengthened construct ending, such as {{m|ar|أَبٌ}} with construct {{m|ar|أَبُو}}.
; <code>smp</code>
: Sound masculine plural in ''-ūn(a)/-īn(a)''.
; <code>sfp</code>
: Sound feminine plural in ''-āt-''.
; <code>awnp</code>
: Plural ending in ''-awn(a)'', esp. of adjectives, such as {{m|ar|أَدْنَوْنَ}} plural of {{m|ar|أَدْنَى||closer, lower}}.
; <code>sp</code>
: Select the appropriate plural form if known, else a strong plural. Equivalent to <code>sfp</code> for feminines, <code>awnp</code> for masculines if the singular is of type <code>an</code>, <code>smp</code> for other masculines.
; <code>d</code>
: Select the appropriate dual form.
; <code>?</code>
: Indicate that the declension is unknown. All inflections will appear as question marks.
==ʾIdāfa parameter values==
; <code>sg</code>, <code>du</code>, <code>pl</code>
: An ''ʾidāfa'' modifier that can exist in multiple states and is of the specified number, e.g. indefinite-state {{m|ar|غُرْفَة نَوْم|tr=ḡurfat nawm|gloss=bedroom}}, with corresponding definite state {{m|ar||غُرْفَة ال-نَوْم|tr=ḡurfat an-nawm}}.
; <code>yes</code>
: Same as <code>sg</code>.
; <code>STATE-NUM</code>
: An ''ʾidāfa'' modifier that exists in a fixed state (<code>def</code>, <code>ind</code> or <code>ind-def</code>) and number (<code>sg</code>, <code>du</code> or <code>pl</code>) .
; <code>STATE</code>
: Same as <code>STATE-sg</code>.
; <code>adj</code> ''or'' <code>adj-base</code>
: An adjectival modifier that modifies the base word. Unnecessary to specify; this is the default.
; <code>adj-mod</code>, <code>adj-mod2</code>, etc.
: An adjectival modifier that modifies a previous modifier word, which must be an ''ʾidāfa'' modifier.
==Examples==
===A simple example===
Normally, it is sufficient to copy the headword declaration for a noun and make minor changes, in particular changing the template name from <code>{{temp|ar-noun|...}}</code> to <code>{{temp|ar-decl-noun|...}}</code> and removing the gender. For example, for the noun {{m|ar|مَدْرَسَة||school}}, the headword is declared as follows:
<code><nowiki>{{ar-noun|مَدْرَسَة|f|pl=مَدَارِس}}</nowiki></code>
and a declension template can easily be declared by the above minor changes, yielding the following:
<code><nowiki>{{ar-decl-noun|مَدْرَسَة|pl=مَدَارِس}}</nowiki></code>
which produces the following:
{{ar-decl-noun|مَدْرَسَة|pl=مَدَارِس}}
Note that the plural {{m|ar|مَدَارِس||schools}} is a diptote, and this is automatically determined by its shape. Generally, diptotes have a shape different from triptotes, and the code is very good at auto-detecting the declension.
===A more complicated example===
The same trick for generating declensions from headword templates usually works with more complex examples, as well, e.g. with {{m|ar|قَفًا||nape}}. For this noun, the headword is declared as follows:
<code><nowiki>{{ar-noun|قَفًا|m|g2=f|d=قَفَوَان|pl=أَقْفِيَة|pl2=أَقْفٍ|pl3=أَقْفَاء|pl4=قُفِيّ|pl5=قِفِيّ}}</nowiki></code>
Removing the gender and changing the template name yields this:
<code><nowiki>{{ar-decl-noun|قَفًا|d=قَفَوَان|pl=أَقْفِيَة|pl2=أَقْفٍ|pl3=أَقْفَاء|pl4=قُفِيّ|pl5=قِفِيّ}}</nowiki></code>
which produces a correct declension table, even though there is an irregular dual and five broken plurals of three different declensions:
{{ar-decl-noun|قَفًا|d=قَفَوَان|pl=أَقْفِيَة|pl2=أَقْفٍ|pl3=أَقْفَاء|pl4=قُفِيّ|pl5=قِفِيّ}}
In general, the code is very good at figuring out the correct declension from the form of the stem, and almost always gets it right (but see the following section).
===An example where the declension must be manually specified===
The code is very good at guessing the declension of a noun or adjective based on its form, but sometimes it needs help. An example is off-shape diptotes, e.g. {{m|ar|بَبَّغَاء||[[parrot]]}} (also {{m|ar|بَبْغَاء}} and {{m|ar|بَبَغَاء}}), which needs an annotation like <code>:di</code>:
<code><nowiki>{{ar-decl-noun|بَبْغَاء:di|head2=بَبَّغَاء:di|head3=بَبَغَاء:di|d=بَبْغَاوَان|d2=بَبَّغَاوَان|d3=بَبَغَاوَان|pl=بَبْغَاوَات|pl2=بَبَّغَاوَات|pl3=بَبَغَاوَات}}</nowiki></code>
which produces
{{ar-decl-noun|بَبْغَاء:di|head2=بَبَّغَاء:di|head3=بَبَغَاء:di|d=بَبْغَاوَان|d2=بَبَّغَاوَان|d3=بَبَغَاوَان|pl=بَبْغَاوَات|pl2=بَبَّغَاوَات|pl3=بَبَغَاوَات}}
===Nisba nouns===
Nisba nouns use special headword templates. A basic nisba noun headword template like this, for {{m|ar|مِصْرِيّ||[[Egyptian]] person}}:
<code><nowiki>{{ar-noun-nisba|مِصْرِيّ}}</nowiki></code>
can be converted to a declension template as follows:
<code><nowiki>{{ar-decl-noun|مِصْرِيّ|pl=sp}}</nowiki></code>
This produces
{{ar-decl-noun|مِصْرِيّ|pl=sp}}
Note that it is necessary to specify the plural; otherwise the declension table will have only singular. However, it is unnecessary to write out the plural; it is enough to just specify the type (in this case <code>sp</code> for sound plural), and the actual form will be inferred from the singular.
When the plural is overridden in the headword, conversion is even easier. An example is {{m|ar|عَرَبِيّ||Arab}}. The nisba noun headword template is:
<code><nowiki>{{ar-noun-nisba|عَرَبِيّ|pl=عَرَب}}</nowiki></code>
This converts easily to a declension template:
<code><nowiki>{{ar-decl-noun|عَرَبِيّ|pl=عَرَب}}</nowiki></code>
producing
{{ar-decl-noun|عَرَبِيّ|pl=عَرَب}}
===Definite proper nouns===
Definite proper nouns like {{m|ar|الإِسْلَام||Islam}} exist only in the definite state. This can be specified using {{para|state|def}}. The stem should be specified without the definite article, e.g.
<code><nowiki>{{ar-decl-noun|إِسْلَام|state=def}}</nowiki></code>
which produces
{{ar-decl-noun|إِسْلَام|state=def}}
===Indefinite proper nouns===
Proper nouns like {{m|ar|مِصْر}} or {{m|ar|أَحْمَد}} or {{m|ar|مُحَمَّد}} are morphologically declined only in the indefinite state, but are syntactically definite, and are often diptote. This can be specified using {{para|state|ind-def}} and adding a {{m|ar|ـُ}} diacritic after the stem if needed, e.g.
<code><nowiki>{{ar-decl-noun|مِصْرُ|state=ind-def}}</nowiki></code>
which produces
{{ar-decl-noun|مِصْرُ|state=ind-def}}
Note how the noun is declined as if it is indefinite, but is listed as definite. This would matter, for example, in that a modifying adjective would be in the definite state. (See below for the example of {{m|ar|كَانُون الثَانِي}}.)
===Irregular nouns===
Irregular nouns can be specified using overrides.
====Irregular example 1====
One complex example is the word {{m|ar|ذُو||owner (of)}}, which exists only in the construct state and is somewhere between a noun and a demonstrative pronoun.
Its declension can be specified as follows:
<code><nowiki>{{ar-decl-noun|ذ:lc|d=ذَوَان|pl=أُولُون/ʾulūn|pl2=ذَوُون|state=con}}</nowiki></code>
yielding
{{ar-decl-noun|ذ:lc|d=ذَوَان|pl=أُولُون/ʾulūn|pl2=ذَوُون|state=con}}
Note that this declension uses a number of advanced features:
# The singular behaves as a long-construct noun, and is thus specified as <code>ذ:lc</code>, with an annotation indicating that it is a long-construct noun.
# The declension is restricted to be construct-state-only using {{para|state|con}}.
# The plural {{m|ar|أُولُو|tr=ʾulū}} is the construct state of a sound masculine plural noun, and hence it is given in the form it would occur if it existed in other states. Furthermore, the pronunciation is irregular, with the first vowel spelled long but pronounced short; as a result, the transliteration is explicitly given with a short vowel. Note that this is automatically declined as nominative {{m|ar|أُولُو|tr=ʾulū}}, accusative/genitive {{m|ar|أُولِِي|tr=ʾulī}}, with the ending changed appropriately while keeping the stem of both the Arabic and explicit transliteration. (Note, the written-out transliteration of the hamza <code>ʾ</code> appears backwards due to display issues. Underlyingly it is written correctly, as can be seen by editing this page to examine its source code.)
====Irregular example 2====
An even more complex irregular noun is {{m|ar|اِمْرُؤ||man}}, which has assimilation between stem and ending in the singular and a different stem {{m|ar|المَرْء}} in the definite state (both singular and dual). The declension is specified as follows:
<pre><nowiki>
{{ar-decl-noun|اِمْرَأ|nom_sg_ind=اِمْرُؤٌ|acc_sg_ind=اِمْرَأً|gen_sg_ind=اِمْرِئٍ|inf_sg_ind=?
|nom_sg_def=الْمَرْءُ|acc_sg_def=الْمَرْءَ|gen_sg_def=الْمَرْءِ|inf_sg_def=?
|nom_sg_con=اِمْرُؤُ|acc_sg_con=اِمْرَأَ|gen_sg_con=اِمْرِئِ|inf_sg_con=?
|nom_du_def=الْمَرْآنِ|acc_du_def=الْمَرْأَيْنِ|gen_du_def=الْمَرْأَيْنِ|inf_du_def=الْمَرْأَيْن
|lemma=اِمْرُؤ
|number=sg,du
}}
</nowiki></pre>
Here we have to override the entire singular declension and the definite state of the dual declension in order to get the right forms. We specify the stem as {{m|ar|اِمْرَأ}} so that the non-overridden part of the dual is correct, but that means we need to override the lemma to get the indefinite nominative singular as the lemma. We also have to explicitly specify the numbers we want to appear; otherwise only singular would appear.
Note that the dual {{m|ar|اِمْرَآنِ}}, with ''ʾalif madda'', is automatically constructed correctly from the stem {{m|ar|اِمْرَأ}}. See below.
===Hamza seats===
It was noted above that the dual of the stem {{m|ar|اِمْرَأ||man}} was correctly constructed as {{m|ar|اِمْرَآنِ}}, with an ''ʾalif madda'' hamza seat. In general, the code has extensive knowledge of the rules regarding the correct hamza seat in various circumstances and should essentially always get this correct. An example of this knowledge at work is the declension of the words {{m|ar|شَيْء||thing}} and {{m|ar|مُبْتَدَأ||(grammatical) subject}}, declared as follows:
* <code><nowiki>{{ar-decl-noun|شَيْء|pl=أَشْيَاء}}</nowiki></code>
* <code><nowiki>{{ar-decl-noun|مُبْتَدَأ|pl=sp}}</nowiki></code>
and appearing as follows:
{{ar-decl-noun|شَيْء|pl=أَشْيَاء}}
{{ar-decl-noun|مُبْتَدَأ|pl=sp}}
In the former case, the hamza-on-the-line {{m|ar|ء|tr=-}} automatically changes into {{m|ar|ئ|tr=-}} when the accusative and dual endings are added. In the latter case, the hamza at the end of the stem {{m|ar|مُبْتَدَأ}} changes in various ways depending on the ending, e.g. becoming {{m|ar|ئ|tr=-}} before {{m|ar|ـِين}} and becoming {{m|ar|آ|tr=-}} before {{m|ar|ـَان}}. Before {{m|ar|ـُون}}, there are two possible seats, yielding either {{m|ar|مُبْتَدَأُون}} or {{m|ar|مُبْتَدَؤُون}}. Both forms are displayed in the declension table, separated by the second-level separator (a slash). (The first-level separator, a semicolon, separates distinct stems, especially in the plural.)
===Modifiers===
====ʾiḍāfa construction #1====
Some phrases appear as lemmas in Wiktionary. An example is the ''ʾiḍāfa'' construction {{m|ar|بَيْت المُقَدَّس}} or {{m|ar|بَيْت المَقْدِس}}, both meaning [[Jerusalem]] (literally ''house of the holy place''). This is composed of {{m|ar|بَيْت||house}} in the construct state, declined according to case, plus {{m|ar|مُقَدَّس}} or {{m|ar|مَقْدِس}} in the definite state, genitive case. The declension for this phrase can be expressed as follows:
<code><nowiki>{{ar-decl-noun|بَيْت|mod=مُقَدَّس|modhead2=مَقْدِس|idafa=def}}</nowiki></code>
which produces
{{ar-decl-noun|بَيْت|mod=مُقَدَّس|modhead2=مَقْدِس|idafa=def}}
====ʾiḍāfa construction #2====
The previous example had a both head noun and modifier in the singular. However, they can disagree, in which case {{para|idafa}} should reflect the number of the modifier. An example is {{m|ar|يَوْم الاِثْنَيْن||Monday}} (literally "day of the two"), where {{m|ar|اِثْنَيْن||two}} appears in the dual. The declension for this phrase can be expressed as follows:
<code><nowiki>{{ar-decl-noun|يَوْم|mod=-|modd=اِثْنَان|idafa=def-du}}</nowiki></code>
which produces
{{ar-decl-noun|يَوْم|mod=-|modd=اِثْنَان|idafa=def-du}}
Note that we express {{m|ar|اِثْنَان||two}} in the nominative case and without the definite article; the use of {{para|idafa|def-du}} will cause the correct case and state to be generated. We also need to code the modifier using {{para|modd}} to express the fact that it is a dual (<code>modd</code> is <code>mod</code> + <code>d</code> for "dual").
====ʾiḍāfa construction #3====
The previous examples had a head noun appearing only in the singular, and only in the definite state. However, many phrases using ʾiḍāfa can appear in all states (definite, indefinite and construct), according to the state of the modifying noun. For example, "bedroom" is {{m|ar|غُرْفَة نَوْم|tr=ḡurfat nawm|lit=room of sleep}}, while "the bedroom" is {{m|ar||غُرْفَة النَوْم|tr=ḡurfat an-nawm}} and "her bedroom" is {{m|ar||غُرْفَة نَوْمِهَا|tr=ḡurfat nawmihā}}. It also exists in the plural ({{m|ar||غُرَف نَوْم}}) and dual (({{m|ar||غُرْفَتَان نَوْم}}). This can be expressed using {{para|idafa|sg}}, which does not constrain the state, as follows:
<code><nowiki>{{ar-decl-noun|غُرْفَة|pl=غُرَف|mod=نَوْم|idafa=sg}}</nowiki></code>
which produces
{{ar-decl-noun|غُرْفَة|pl=غُرَف|mod=نَوْم|idafa=sg}}
====ʾiḍāfa construction #4====
An example similar to the previous one but which uses a singulative noun is {{m|ar|دُودَة فَرَاشَة|tr=dūdat farāša||caterpillar|lit=worm of butterfly}}. {{m|ar|دُودَة||worm}} is a singulative noun, so we use a singulative noun template. {{m|ar|فَرَاشَة||butterfly}} is in the singular; in this case, we have to use {para|idafa|sing}} since that's the closest we can get to a singular number. (For collective nouns we would use {{para|idafa|coll}} to indicate the singular.) The declension for this phrase can be expressed as follows:
<code><nowiki>{{ar-decl-sing-noun|دُودَة|pl=دِيدَان|mod=فَرَاشَة|idafa=sing}}</nowiki></code>
which produces
{{ar-decl-sing-noun|دُودَة|pl=دِيدَان|mod=فَرَاشَة|idafa=sing}}
As with the previous example, the value of {{para|idafa}} does not constrain the state; thus it will exist in the indefinite {{m|ar|ﺩُﻭﺩَﺓ ﻑَﺭَﺎﺷَﺓ|tr=dūdat farāša}}, the definite {{m|ar||ﺩُﻭﺩَﺓ الﻑَﺭَﺎﺷَﺓ|tr=dūdat al-farāša}} and the construct state {{m|ar||ﺩُﻭﺩَﺓ ﻑَﺭَﺎﺷَة أَحْمَد|tr=dūdat farāšat ʾaḥmad}}.
====Adjectival modifier #1====
Things are different for adjectival modifiers, which do not need to have their case, state or number fixed. An example is the declension for {{m|ar|زَوْبَعَة شَدِيدَة|tr=zawbaʿa šadīda||hurricane}}, literally "strong storm". Both noun and adjective need to be declined for case, state and number. This can be expressed as follows:
<code><nowiki>{{ar-decl-noun|زَوْبَعَة|pl=زَوَابِع|mod=شَدِيدَة|modpl=شَدِيدَة}}</nowiki></code>
which produces
{{ar-decl-noun|زَوْبَعَة|pl=زَوَابِع|mod=شَدِيدَة|modpl=شَدِيدَة}}
Note the need to express the plural of both noun and modifier. The modifier happens to be the same in the plural as the singular, because inanimate plural nouns are treated as feminine singular; but the dual will be different. In this case there is no need for {{para|idafa}} because an adjectival modifier of the base word is the default.
====Adjectival modifier #2====
Another example is the declension for {{m|ar|الْوِلَايَات الْمُتَّحِدَة||United States}}. This noun appears only in the definite state and in the plural. This can be expressed as follows:
<code><nowiki>{{ar-decl-noun|-|pl=وِلَايَات|state=def|mod=-|modpl=مُتَّحِدَة}}</nowiki></code>
which produces
{{ar-decl-noun|-|pl=وِلَايَات|state=def|mod=-|modpl=مُتَّحِدَة}}
Note the use of a <code>-</code> to indicate no singular, with both the main noun and modifier expressed as plurals, so that the declension table labels them as plural rather than singular.
====Adjectival construction #3====
A tricky example is {{m|ar|كَانُون الثَانِي||[[January]]|lit=the second Kānūn}}. Despite appearances this is an adjectival construction, not an ʾiḍāfa construction. {{m|ar|كَانُون}} is actually a diptote proper noun, morphologically indefinite but syntactically definite, i.e. its declension is indefinite but it is treated grammatically as definite for the purposes of modifiers. This can be expressed using the lower-level parameters to override parts of what is normally generated by {{para|idafa}} (including in its default value of {{para|idafa|adj}}). The declension for this phrase can be expressed as follows:
<code><nowiki>{{ar-decl-noun|كَانُون:di|mod=ثَانٍ|state=ind-def}}</nowiki></code>
which produces
{{ar-decl-noun|كَانُون:di|mod=ثَانٍ|state=ind-def}}
In this case, we use {{para|state=ind-def}}, which sets the overall state to definite, but declines the base noun as indefinite. (This is equivalent to using <code>|state=def|basestate=ind</code>.) This is consistent with the fact that the expression is grammatically definite and its modifier will appear with the definite article. Note also that we need to write the modifier in its indefinite form {{m|ar|ثَانٍ}}; the appropriate definite form is automatically generated.
Other similar examples are {{m|ar|أَمْرِيكَا الشَمَالِيَّة||[[North America]]}}, {{m|ar|كُورِيَا الجَنُوبِيَّة|tr=kōriyā l-janūbiyya||[[South Korea]]}} and {{m|ar|فِرْجِينِيَا الغَرْبِيَّة||[[West Virginia]]}}.
====Prefix example #1====
An example where {{para|prefix}} (actually {{para|modprefix}}) comes in handy is the phrase {{m|ar|التَوْرَاة وَالإِنْجِيل|tr=at-tawrāh wa-l-ʾinjīl}}. The declension for this phrase can be expressed as follows:
<code><nowiki>{{ar-decl-noun|تَوْرَاة|mod=إِنْجِيل|modprefix=وَ/wa-|state=def}}</nowiki></code>
which produces
{{ar-decl-noun|تَوْرَاة|mod=إِنْجِيل|modprefix=وَ/wa-|state=def}}
Note the use of a prefix to handle the conjunction {{m|ar|وَ|tr=wa-||and}}, and the automatic implementation of elision in the transliteration.
Another prefix example is found in the documentation for {{temp|ar-decl-numeral}}.
====Prefix example #2====
A similar example occurs with numbers, such as {{m|ar|تِسْعَة وَعِشْرُون|tr=tisʿa wa-ʿišrūn||[[twenty-nine]]}}. The declension can be expressed as follows:
<code><nowiki>{{ar-decl-numeral|تِسْعَة|f=تِسْع|mod=عِشْرُون|modprefix=وَ/wa-|state=ind,def}}</nowiki></code>
which produces
{{ar-decl-numeral|-|pl=تِسْعَة|f=-|fpl=تِسْع|mod=-|modpl=عِشْرُون|modf=-|modfpl=عِشْرُون|modprefix=وَ/wa-|state=ind,def}}
====Multiple modifiers #1====
Things get more complicated when multiple modifiers are involved, because there are various possibilities: Each of the modifiers can independently be adjectival or ''ʾidāfa'', and a second or further-on adjectival modifier can modify an earlier ''ʾidāfa'' modifier rather than the base.
Perhaps the simplest case is when all modifiers are adjectival. An example is {{m|ar|غُدَّة بَصَلِيَّة إِحْلِيلِيَّة|tr=ḡudda baṣaliyya ʾiḥlīliyya||[[bulbourethral gland]]|lit=bulbous urethral gland}}. This can appear in multiple states and numbers, e.g. definite plural {{m|ar|الغُدَد البَصَلِيَّة الإِحْلِيلِيَّة|tr=al-ḡudad al-baṣaliyya l-ʾiḥlīliyya}}. This can be expressed as follows:
<code><nowiki>{{ar-decl-noun|غُدَّة|pl=غُدَد|mod=بَصَلِيَّة|modpl=بَصَلِيَّة|mod2=إِحْلِيلِيَّة|mod2pl=إِحْلِيلِيَّة}}</nowiki></code>
which produces
{{ar-decl-noun|غُدَّة|pl=غُدَد|mod=بَصَلِيَّة|modpl=بَصَلِيَّة|mod2=إِحْلِيلِيَّة|mod2pl=إِحْلِيلِيَّة}}
Note that the non-personal plural of the feminine adjective {{m|ar|بَصَلِيَّة||[[bulbous]]}} happens to be the same as the singular since non-personal nouns take feminine singular agreement, but the {{para|modpl}} parameter still needs to be expressed; likewise for {{m|ar|إِحْلِيلِيَّة||[[urethral]]}}.
====Multiple modifiers #2====
Another example with entirely adjectival modifiers is {{m|ar|البَحْر الأَبْيَض المُتَوَسِّط||[[Mediterranean Sea]]}}, this time only in the definite singular. This can be expressed with a {{para|state|def}} parameter, as follows:
<code><nowiki>{{ar-decl-noun|بَحْر|mod=أَبْيَض|mod2=مُتَوَسِّط|state=def}}</nowiki></code>
which produces
{{ar-decl-noun|بَحْر|mod=أَبْيَض|mod2=مُتَوَسِّط|state=def}}
====Multiple modifiers #3====
Consider {{m|ar|مُنَظَّمَة التَحْرِير الفِلَسْطِينِيَّة|tr=munaẓẓamat at-taḥrīr al-filasṭīniyya||Palestine Liberation Organization}}. {{m|ar|مُنَظَّمَة||[[organization]]}} has an ''ʾidāfa'' modifier {{m|ar|تَحْرِير||[[liberation]]}} and a second adjectival modifier {{m|ar|فِلَسْطِينِيّ||[[Palestinian]]}} (the fact that this modifies {{m|ar|مُنَظَّمَة}} and not {{m|ar|تَحْرِير}} is clear from the feminine gender of the adjective). The first, ''ʾidāfa'' modifier appears only in the definite state, which can be expressed by {{para|idafa|def}}, and the fact that the second adjectival modifier modifies the base noun could be expressed by {{para|idafa2|adj}}, but this is the default and so can be omitted, as follows:
<code><nowiki>{{ar-decl-noun|مُنَظَّمَة|mod=تَحْرِير|mod2=فِلَسْطِينِيَّة|idafa=def}}</nowiki></code>
which produces
{{ar-decl-noun|مُنَظَّمَة|mod=تَحْرِير|mod2=فِلَسْطِينِيَّة|idafa=def}}
====Multiple modifiers #4====
Another example is {{m|ar|جَنُوب القَارَّة الأَفْرِيقِيَّة|tr=janūb al-qārra l-ʾafrīqiyya||Southern Africa|lit=the South of the African continent}}. In this case {{m|ar|قَارَّة||[[continent]]}} is an ''ʾidāfa'' modifier of {{m|ar|جَنُوب||[[south]]}}, and {{m|ar|أَفْرِيقِيّ||[[African]]}} modifies {{m|ar|قَارَّة}}, meaning it will agree in case, number and state (in this case, fixed to genitive singular definite). This can be expressed as follows, with a parameter {{para|idafa2|adj-mod}} indicating that the second modifier is an adjectival modifier of the first modifier:
<code><nowiki>{{ar-decl-noun|جَنُوب|mod=قَارَّة|mod2=أَفْرِيقِيَّة|idafa=def|idafa2=adj-mod}}</nowiki></code>
which produces
{{ar-decl-noun|جَنُوب|mod=قَارَّة|mod2=أَفْرِيقِيَّة|idafa=def|idafa2=adj-mod}}
====Multiple modifiers #5====
A similar example requiring {{para|idafa|ind-def}} is {{m|ar|جُمْهُورِيَّة غِينِيَا الاِسْتِوَائِيَّة|tr=jumhūriyyat ḡīniyā l-istiwāʾiyya||Republic of Equatorial Guinea}}. In this case, {{m|ar|غِينِيَا||[[Guinea]]}} is a proper noun, grammatically definite but morphologically indefinite (similar to {{m|ar|مِصْر||[[Egypt]]}}, above), and {{m|ar|اِسْتِوَائِيّ||[[equatorial]]}} agrees with it, requiring the definite state. This is signalled using {{para|idafa|ind-def}}:
<code><nowiki>{{ar-decl-noun|جُمْهُورِيَّة|mod=غِينِيَا|mod2=اِسْتِوَائِيَّة|state=def|idafa=ind-def|idafa2=adj-mod}}</nowiki></code>
which produces
{{ar-decl-noun|جُمْهُورِيَّة|mod=غِينِيَا|mod2=اِسْتِوَائِيَّة|state=def|idafa=ind-def|idafa2=adj-mod}}
====Multiple modifiers #6====
An example with two ''ʾidāfa'' modifiers which can appear in various states and numbers is {{m|ar|وَاجِهَة بَرمَجَة تَطْبِيقَات|tr=wājihat barmajat taṭbīqāt||[[application programming interface]]}}, declined as follows:
<code><nowiki>{{ar-decl-noun|وَاجِهَة|pl=وَاجِهَات|mod=بَرْمَجَة|mod2=-|mod2pl=تَطْبِيقَات|idafa=yes|idafa2=pl}}</nowiki></code>
which produces
{{ar-decl-noun|وَاجِهَة|pl=وَاجِهَات|mod=بَرْمَجَة|mod2=-|mod2pl=تَطْبِيقَات|idafa=yes|idafa2=pl}}
====Multiple modifiers #7====
A complex example with three modifiers is {{m|ar|نِصْف الكُرَة الأَرْضِيَّة الشَمَالِيّ|tr=niṣf al-kura l-ʾarḍiyya š-šamāliyy||[[Northern Hemisphere]]|lit=the northern half of the earthly ball}}. The first modifier is an ''ʾidāfa''; the second is adjectival, modifying the first, and the third is adjectival, modifying the base. This would be specified as follows:
<code><nowiki>{{ar-decl-noun|نِصْف|mod=كُرَة|mod2=أَرْضِيَّة|mod3=شَمَالِيّ|idafa=def|idafa2=adj-mod}}</nowiki></code>
which produces
{{ar-decl-noun|نِصْف|mod=كُرَة|mod2=أَرْضِيَّة|mod3=شَمَالِيّ|idafa=def|idafa2=adj-mod}}
<includeonly>
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်အာရဗဳဂမၠိုၚ်|{{BASEPAGENAME}}]]
</includeonly>
27xj9lr2kk77kktbb7ugtc7c0ui1on8
ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်အာရဗဳဂမၠိုၚ်
14
294823
395250
2026-05-20T18:52:19Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏအာရဗဳဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|အ]]"
395250
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏအာရဗဳဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|အ]]
piu5d18euxlez9cz3g2vb8dp81wdw8a
ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏအာရဗဳဂမၠိုၚ်
14
294824
395251
2026-05-20T18:53:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်အာရဗဳဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|အ]]"
395251
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်အာရဗဳဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|အ]]
sshqjkcx5ltsoav3rpf0oahgxua41gb
ထာမ်ပလိက်:ar-decl-gendered-noun
10
294825
395252
2026-05-20T18:54:58Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:ar-nominals|show_gendered_noun}}<!-- --><noinclude>{{documentation}}</noinclude>"
395252
wikitext
text/x-wiki
{{#invoke:ar-nominals|show_gendered_noun}}<!--
--><noinclude>{{documentation}}</noinclude>
2q5zovp93n30idg64hb7tb2quk69hog
ထာမ်ပလိက်:ar-decl-gendered-noun/documentation
10
294826
395253
2026-05-20T18:55:57Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} This template displays an inflection table for Arabic gendered nouns, i.e. nouns that have a feminine equivalent (e.g. {{m|ar|أَمْرِيكِيّ||[[American]]}}). The parameters are identical to {{temp|ar-decl-adj}}, but the table displayed is a bit different because it displays the construct state in addition to indefinite and definite (hence there are six columns across, three for mascu..."
395253
wikitext
text/x-wiki
{{documentation subpage}}
This template displays an inflection table for Arabic gendered nouns, i.e. nouns that have a feminine equivalent (e.g. {{m|ar|أَمْرِيكِيّ||[[American]]}}). The parameters are identical to {{temp|ar-decl-adj}}, but the table displayed is a bit different because it displays the construct state in addition to indefinite and definite (hence there are six columns across, three for masculine and three for feminine).
See also {{temp|ar-decl-noun}}.
==Examples==
===A simple example===
For participles, nisbas and similar adjectives that take sound plurals, it is enough to simply specify a single stem with a sound masculine plural, e.g. for the noun {{m|ar|مُسْلِم||[[Muslim]]}}, a simple declaration works:
<code>{{temp|ar-decl-gendered-noun|مُسْلِم|pl=sp}}</code>
This yields
{{ar-decl-gendered-noun|مُسْلِم|pl=sp}}
===A slightly more complex example===
For {{m|ar|تُرْكِيّ||[[Turk]]}}, the masculine plurals need to be given explicitly:
<code><nowiki>{{ar-decl-gendered-noun|تُرْكِيّ|pl=أَتْرَاك|pl2=تُرْك}}</nowiki></code>
This yields
{{ar-decl-gendered-noun|تُرْكِيّ|pl=أَتْرَاك|pl2=تُرْك}}
For more complex examples, generally it is sufficient to copy the headword declaration for a noun and make minor changes, mostly just changing the template name from <code>{{temp|ar-noun|...}}</code> to <code>{{temp|ar-decl-gendered-noun|...}}</code>. For <code>{{temp|ar-noun-nisba}}</code>, you may need to add {{para|pl|sp}}, since the strong masculine plural is generated automatically by <code>{{temp|ar-noun-nisba}}</code>.
<includeonly>
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်အာရဗဳဂမၠိုၚ်|{{BASEPAGENAME}}]]
</includeonly>
cg8os1o0mlzjn9mqy7dtnhpd7ged5ox
ထာမ်ပလိက်:R:ar:Kazimirski
10
294827
395254
2026-05-20T18:57:11Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:quote|call_template |template=cite-book |fr |last=Kazimirski |first=Albin de Biberstein |authorlink=Albert Kazimirski de Biberstein |title=Dictionnaire arabe-français contenant toutes les racines de la langue arabe, leurs dérivés, tant dans l’idiome vulgaire que dans l’idiome littéral, ainsi que les dialectes d’Alger et de Maroc |location=Paris |publisher=Maisonneuve et C<sup>ie</sup> |year=1860 |p..."
395254
wikitext
text/x-wiki
{{#invoke:quote|call_template
|template=cite-book
|fr
|last=Kazimirski
|first=Albin de Biberstein
|authorlink=Albert Kazimirski de Biberstein
|title=Dictionnaire arabe-français contenant toutes les racines de la langue arabe, leurs dérivés, tant dans l’idiome vulgaire que dans l’idiome littéral, ainsi que les dialectes d’Alger et de Maroc
|location=Paris
|publisher=Maisonneuve et C<sup>ie</sup>
|year=1860
|pageparam=page
|entry={{lang|ar|{{{1|{{{entry|{{pagename}}}}}}}}}}
|url={{#switch:{{{volume|}}}|1=https://archive.org/details/dictionnairearab01bibeuoft|2=https://archive.org/details/dictionnairearab02bibeuoft|#default=https://archive.org/details/dictionnairearab01bibeuoft}}
|pageurl={{#switch:{{{volume|}}}|1=https://archive.org/stream/dictionnairearab01bibeuoft#page/{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+|}}|2=https://archive.org/stream/dictionnairearab02bibeuoft#page/{{#invoke:string/templates|match|{{{page|{{{pages}}}}}}|[0-9]+|}}}}
|propagateparams=volume
|allowparams=1,entry
}}<noinclude>[[ကဏ္ဍ:ထာမ်ပလိက်နိဿဲအာရဗဳဂမၠိုၚ်|Kazimirski]]</noinclude>
5xestjiguukrjz5203fh5ncsspnqqfp
ထာမ်ပလိက်:acw-pronoun
10
294828
395255
2026-05-20T18:58:39Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:sem-arb-headword|show|သဗ္ဗနာမ်|lang=acw}}<!-- --><noinclude>{{documentation}}</noinclude>"
395255
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|သဗ္ဗနာမ်|lang=acw}}<!--
--><noinclude>{{documentation}}</noinclude>
lwru9zber87lkv5a90xl33wxptb877a
ထာမ်ပလိက်:acw-pronoun/documentation
10
294829
395256
2026-05-20T18:59:28Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> {{hwcat}}"
395256
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
{{hwcat}}
f8u1ebax0fek1lf9jgky9pqli0yk03y
ထာမ်ပလိက်:ajp-pronoun/documentation
10
294830
395258
2026-05-20T19:01:30Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} This template is for displaying the headword line of South Levantine Arabic [[pronoun]]s. ==Parameters== ; {{para|head}} and {{para|head2}}, {{para|head3}} ... : Overrides the displayed headword. : Additional parameters are available if there are multiple possible vocalized equivalents of page name. ; {{para|tr}} and {{para|tr2}}, {{para|tr3}} ... : Transliteration. : If multiple vocalised..."
395258
wikitext
text/x-wiki
{{documentation subpage}}
This template is for displaying the headword line of South Levantine Arabic [[pronoun]]s.
==Parameters==
; {{para|head}} and {{para|head2}}, {{para|head3}} ...
: Overrides the displayed headword.
: Additional parameters are available if there are multiple possible vocalized equivalents of page name.
; {{para|tr}} and {{para|tr2}}, {{para|tr3}} ...
: Transliteration.
: If multiple vocalised variants of the page name were provided, then each one has a corresponding numbered {{para|tr<var>N</var>}} parameter.
{{hwcat}}
kta94phtpr9vwgn7nkl8j5lv6bjt0fz
ထာမ်ပလိက်:ajp-suffix
10
294831
395260
2026-05-20T19:04:09Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:sem-arb-headword|show|အဆက်လက္ကရဴ|lang=ajp}}<!-- --><noinclude>{{documentation}}</noinclude>"
395260
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|အဆက်လက္ကရဴ|lang=ajp}}<!--
--><noinclude>{{documentation}}</noinclude>
gojazyc3aw93xg5m79hzjyb4nvsflcp
ထာမ်ပလိက်:ajp-suffix/documentation
10
294832
395261
2026-05-20T19:04:54Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} {{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. --> {{hwcat}}"
395261
wikitext
text/x-wiki
{{documentation subpage}}
{{documentation needed}}<!-- Replace this with a short description of the purpose of the template, and how to use it. -->
{{hwcat}}
f8u1ebax0fek1lf9jgky9pqli0yk03y
ထာမ်ပလိက်:ajp-verb/documentation
10
294833
395262
2026-05-20T19:06:19Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{#invoke:sem-arb-headword|show|ကြိယာ|lang=ajp}}<!-- --><noinclude>{{documentation}}</noinclude>"
395262
wikitext
text/x-wiki
{{#invoke:sem-arb-headword|show|ကြိယာ|lang=ajp}}<!--
--><noinclude>{{documentation}}</noinclude>
pn60f89ajtrzv8q9tdddmg4d09nrabr
395264
395262
2026-05-20T19:07:27Z
咽頭べさ
33
395264
wikitext
text/x-wiki
{{documentation subpage}}
This template is for displaying the headword line of South Levantine Arabic [[verb]]s.
==Main parameters==
; {{para|1}}
: Verb form.
; {{para|head}} and {{para|head2}}, {{para|head3}} ...
: Overrides the displayed headword.
: Additional parameters are available if there are multiple possible vocalized equivalents of page name.
; {{para|tr}} and {{para|tr2}}, {{para|tr3}} ...
: Transliteration.
: If multiple vocalized variants of the page name were provided, then each one has a corresponding numbered {{para|tr''N''}} parameter.
; {{para|pres}} and {{para|pres2}}, {{para|pres3}} ...
: Present form.
: Additional parameters are available if there are multiple possible present forms.
; {{para|prestr}} and {{para|pres2tr}}, {{para|pres3tr}} ...
: Transliteration of present forms.
: If multiple non-past forms were provided, then each one has a corresponding numbered {{para|pres''N''tr}} parameter.
; {{para|subj}} and {{para|subj2}}, {{para|subj3}} ...
: Subjunctive form.
: Additional parameters are available if there are multiple possible subjunctive forms.
; {{para|subjtr}} and {{para|subj2tr}}, {{para|subj3tr}} ...
: Transliteration of subjunctive forms.
: If multiple subjunctive forms were provided, then each one has a corresponding numbered {{para|subj''N''tr}} parameter.
{{hwcat}}
fw123k6q0vk3h7evhqukqqek1wldx80