Wiktionary omwiktionary https://om.wiktionary.org/wiki/Fuula_Dura MediaWiki 1.47.0-wmf.9 case-sensitive Media Special Talk User User talk Wiktionary Wiktionary talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk TimedText TimedText talk Module Module talk Event Event talk Module:syllables 828 26651 81997 81993 2026-07-04T17:50:45Z EyobAbebe7 3540 81997 Scribunto text/plain local p = {} local vowels = {a=true,e=true,i=true,o=true,u=true} local digraphs = { dh="D", ch="C", ny="N", ph="P", sh="S", ts="T", zy="Z" } -- Gabatee qubee dachaa gara iddoo duraatti deebisuuf gargaaru local reverse_digraphs = { D="dh", C="ch", N="ny", P="ph", S="sh", T="ts", Z="zy" } -- ===================== -- TOKENIZE (keeps real chars too) -- ===================== local function tokenize(word) local tokens = {} local i = 1 while i <= mw.ustring.len(word) do local two = mw.ustring.sub(word, i, i+1) if digraphs[two] then table.insert(tokens, digraphs[two]) i = i + 2 else table.insert(tokens, mw.ustring.sub(word, i, i)) i = i + 1 end end return tokens end -- ===================== -- DETOKENIZE (restores digraphs) -- ===================== local function detokenize(str) for k, v in pairs(reverse_digraphs) do str = string.gsub(str, k, v) end return str end -- ===================== -- CHECK TYPE -- ===================== local function isV(c) return vowels[c] == true end local function isC(c) return not isV(c) end -- ===================== -- SYLLABLE BUILDER (IMPORTANT FIX) -- ===================== local function syllabify(word) local t = tokenize(word) local syllables = {} local i = 1 while i <= #t do local syll = {} -- STEP 1: onset (C cluster) while i <= #t and isC(t[i]) do table.insert(syll, t[i]) i = i + 1 end -- STEP 2: nucleus (V) while i <= #t and isV(t[i]) do table.insert(syll, t[i]) i = i + 1 end -- STEP 3: coda (optional C, but stop before next vowel) while i <= #t and isC(t[i]) do -- lookahead: if next is vowel → break (onset rule) if t[i+1] and isV(t[i+1]) then break end table.insert(syll, t[i]) i = i + 1 end table.insert(syllables, table.concat(syll)) end return syllables end -- ===================== -- MAIN -- ===================== function p.split(frame) local word = frame.args[1] or "" -- RAKKOO HUDHAA SIRREESSUU: &#39; gara ' deebisa word = mw.text.decode(word) word = mw.ustring.lower(mw.text.trim(word)) local s = syllabify(word) -- Firiin erga walitti qabamee booda gara qubee dachaatti deebisuu local result = table.concat(s, "-") return detokenize(result) end function p.count(frame) local word = frame.args[1] or "" -- RAKKOO HUDHAA SIRREESSUU word = mw.text.decode(word) word = mw.text.trim(word) if word == "" then return "0" end local syll = p.split(frame) local _, n = mw.ustring.gsub(syll, "-", "-") return tostring(n + 1) end return p qr6jmtob839k1cw4kdq09vc5ez1l9jr Module:adjective 828 62062 81998 81926 2026-07-05T05:28:50Z EyobAbebe7 3540 81998 Scribunto text/plain local export = {} -- ===================================== -- 1. HELPER: Check for long vowels (aa, ee, ii, uu) -- (JS: /(aa|ee|ii|uu)$/.test) -- ===================================== local function ends_with_long_vowel(str) return mw.ustring.match(str, "aa$") or mw.ustring.match(str, "ee$") or mw.ustring.match(str, "ii$") or mw.ustring.match(str, "uu$") end -- ===================================== -- 2. TOKENIZER (ch, dh, ny, ph, sh, ts, zy) -- ===================================== local function tokenize_oromo(text) local digraphs = { ["ch"] = true, ["dh"] = true, ["ny"] = true, ["ph"] = true, ["sh"] = true, ["ts"] = true, ["zy"] = true } local tokens = {} local i = 1 local len = mw.ustring.len(text) while i <= len do local two = mw.ustring.sub(text, i, i + 1) if mw.ustring.len(two) == 2 and digraphs[two] then table.insert(tokens, two) i = i + 2 else table.insert(tokens, mw.ustring.sub(text, i, i)) i = i + 1 end end return tokens end -- ===================================== -- 3. VCC DETECTOR -- ===================================== local function is_vccuu(word) local stem = mw.ustring.sub(word, 1, -3) -- removes 'uu' local tokens = tokenize_oromo(stem) local vowels = { a=true, e=true, i=true, o=true, u=true } local consonants_at_end = 0 for i = #tokens, 1, -1 do if vowels[tokens[i]] then break end consonants_at_end = consonants_at_end + 1 end return consonants_at_end >= 2 end -- ===================================== -- 4. LONG VOWEL + CONSONANT CHECK -- ===================================== local function ends_with_long_vowel_plus_consonant(stem) local tokens = tokenize_oromo(stem) local len = #tokens if len < 2 then return false end local last = tokens[len] local prev = tokens[len - 1] local vowels = { a=true, e=true, i=true, o=true, u=true } local is_consonant = not vowels[last] local is_long_vowel = (prev == "aa" or prev == "ee" or prev == "ii" or prev == "oo" or prev == "uu") -- Fallback yoo tokenizer qubee wal-fakkaataa addaan baase if not is_long_vowel and len >= 3 then local prev2 = tokens[len - 2] if vowels[prev] and prev == prev2 then is_long_vowel = true end end return is_long_vowel and is_consonant end -- ===================================== -- 5. MAIN FUNCTION: Generate Forms -- ===================================== function export.get_adjective_forms(word) if not word or word == "" then return { error = "Verb galchi." } end word = mw.ustring.lower(mw.text.trim(word)) if not mw.ustring.match(word, "uu$") then return { error = "Verb Afaan Oromoo 'uu'n xumuramuu qaba." } end local male = "" local female = "" local plural = "" local stem2 = mw.ustring.sub(word, 1, -3) -- Default stem (removes 'uu') -- ===================================== -- EXACT oochuu, eechuu, ichuu, uchuu -- ===================================== if mw.ustring.match(word, "eechuu$") or mw.ustring.match(word, "ichuu$") or mw.ustring.match(word, "uchuu$") or mw.ustring.match(word, "oochuu$") then local stem_chuu = mw.ustring.sub(word, 1, -5) male = stem_chuu .. "chaa" female = stem_chuu .. "chituu" plural = stem_chuu .. "chitoota" -- ===================================== -- jjechuu, jechuu, ochuu -- ===================================== elseif mw.ustring.match(word, "jjechuu$") then local root = mw.ustring.sub(word, 1, -7) male = root .. "etaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "jechuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "edhaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "ochuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "odhaa" female = root .. "ootuu" plural = root .. "ootota" -- ===================================== -- ', w, y, h endings ['wyh]uu -- ===================================== elseif mw.ustring.match(word, "oo['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "ssuu" plural = root .. "ssota" elseif mw.ustring.match(word, "o['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" elseif mw.ustring.match(word, "aa['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -4) male = stem2 .. "aa" female = root .. "ooftuu" plural = root .. "ooftota" elseif mw.ustring.match(word, "[aeio]ta['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "oftuu" plural = root .. "oftoota" elseif mw.ustring.match(word, "[aeiou]ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "a'oota" elseif mw.ustring.match(word, "ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "eessota" elseif mw.ustring.match(word, "a['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "atuu" plural = root .. "atota" elseif mw.ustring.match(word, "ii['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "i['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "toota" elseif mw.ustring.match(word, "e['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "etuu" plural = root .. "etota" elseif mw.ustring.match(word, "u['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" -- ===================================== -- dhuu endings -- ===================================== elseif mw.ustring.match(word, "[ae]dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "iidhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "idhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "ituu" plural = root .. "itota" elseif mw.ustring.match(word, "uudhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "udhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" elseif mw.ustring.match(word, "dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" -- ===================================== -- nyuu, shuu -- ===================================== elseif mw.ustring.match(word, "nyuu$") then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" elseif mw.ustring.match(word, "shuu$") then male = stem2 .. "aa" female = stem2 .. "tuu" plural = stem2 .. "toota" -- ===================================== -- Consonant + chuu -- ===================================== elseif mw.ustring.match(word, "[bcdfghjklmnpqrstvwxyz]chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "chaa" female = base .. "chituu" plural = base .. (is_long and "chitota" or "chitoota") -- ===================================== -- General chuu -- ===================================== elseif mw.ustring.match(word, "chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "taa" female = base .. "ttuu" plural = base .. (is_long and "ttota" or "ttoota") -- ===================================== -- V + CC + uu -- ===================================== elseif is_vccuu(word) then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" -- ===================================== -- cuu -- ===================================== elseif mw.ustring.match(word, "cuu$") then local base = mw.ustring.sub(word, 1, -4) male = base .. "caa" female = base .. "ccuu" plural = base .. "ccitoota" -- ===================================== -- [d j x t]uu -- ===================================== elseif mw.ustring.match(word, "[djxt]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local c = mw.ustring.sub(word, -3, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. c .. "uu" plural = base .. c .. (is_long and "ota" or "oota") -- ===================================== -- [bg]uu -- ===================================== elseif mw.ustring.match(word, "[bg]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "duu" plural = base .. (is_long and "dota" or "doota") -- ===================================== -- [fklmnprsvz]uu -- ===================================== elseif mw.ustring.match(word, "[fklmnprsvz]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "tuu" plural = base .. (is_long and "tota" or "toota") -- ===================================== -- quu / phuu / zyuu -- ===================================== elseif mw.ustring.match(word, "quu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") elseif mw.ustring.match(word, "phuu$") or mw.ustring.match(word, "zyuu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") -- ===================================== -- RULE NOT FOUND (Fallback) -- ===================================== else return { error = "Rule kanaaf hin jiru." } end return { male = male, female = female, plural = plural, word = word } end -- ===================================== -- 6. TEMPLATE ENTRY POINT (LIST OUTPUT) -- ===================================== function export.generate(frame) local args = frame.args if not args[1] and not args.word and not args.verb then args = frame:getParent().args end local word = args[1] or args.word or args.verb -- Yoo parameter hin kennamne maqaa fuulaa irraa fudhata if not word or word == "" then local pagename = mw.title.getCurrentTitle().text if mw.ustring.match(pagename, "uu$") then word = pagename else word = "gochuu" end end local results = export.get_adjective_forms(word) if results.error then return "<strong class='error'>" .. results.error .. "</strong>" end local lines = {} table.insert(lines, "====Derived terms====") table.insert(lines, "* {{l|om|" .. results.male .. "}} (male adjective)") table.insert(lines, "* {{l|om|" .. results.female .. "}} (female adjective)") table.insert(lines, "* {{l|om|" .. results.plural .. "}} (plural adjective)") return table.concat(lines, "\n") end return export njybap4nbpj9lxuox46kg3ukso1lyzb 81999 81998 2026-07-05T05:44:36Z EyobAbebe7 3540 81999 Scribunto text/plain local export = {} -- ===================================== -- 1. HELPER: Check for long vowels (aa, ee, ii, uu) -- (JS: /(aa|ee|ii|uu)$/.test) -- ===================================== local function ends_with_long_vowel(str) return mw.ustring.match(str, "aa$") or mw.ustring.match(str, "ee$") or mw.ustring.match(str, "ii$") or mw.ustring.match(str, "uu$") end -- ===================================== -- 2. TOKENIZER (ch, dh, ny, ph, sh, ts, zy) -- ===================================== local function tokenize_oromo(text) local digraphs = { ["ch"] = true, ["dh"] = true, ["ny"] = true, ["ph"] = true, ["sh"] = true, ["ts"] = true, ["zy"] = true } local tokens = {} local i = 1 local len = mw.ustring.len(text) while i <= len do local two = mw.ustring.sub(text, i, i + 1) if mw.ustring.len(two) == 2 and digraphs[two] then table.insert(tokens, two) i = i + 2 else table.insert(tokens, mw.ustring.sub(text, i, i)) i = i + 1 end end return tokens end -- ===================================== -- 3. VCC DETECTOR -- ===================================== local function is_vccuu(word) local stem = mw.ustring.sub(word, 1, -3) -- removes 'uu' local tokens = tokenize_oromo(stem) local vowels = { a=true, e=true, i=true, o=true, u=true } local consonants_at_end = 0 for i = #tokens, 1, -1 do if vowels[tokens[i]] then break end consonants_at_end = consonants_at_end + 1 end return consonants_at_end >= 2 end -- ===================================== -- 4. LONG VOWEL + CONSONANT CHECK -- ===================================== local function ends_with_long_vowel_plus_consonant(stem) local tokens = tokenize_oromo(stem) local len = #tokens if len < 2 then return false end local last = tokens[len] local prev = tokens[len - 1] local vowels = { a=true, e=true, i=true, o=true, u=true } local is_consonant = not vowels[last] local is_long_vowel = (prev == "aa" or prev == "ee" or prev == "ii" or prev == "oo" or prev == "uu") -- Fallback yoo tokenizer qubee wal-fakkaataa addaan baase if not is_long_vowel and len >= 3 then local prev2 = tokens[len - 2] if vowels[prev] and prev == prev2 then is_long_vowel = true end end return is_long_vowel and is_consonant end -- ===================================== -- 5. MAIN FUNCTION: Generate Forms -- ===================================== function export.get_adjective_forms(word) if not word or word == "" then return { error = "Verb galchi." } end word = mw.ustring.lower(mw.text.trim(word)) if not mw.ustring.match(word, "uu$") then return { error = "Verb Afaan Oromoo 'uu'n xumuramuu qaba." } end local male = "" local female = "" local plural = "" local stem2 = mw.ustring.sub(word, 1, -3) -- Default stem (removes 'uu') -- ===================================== -- EXACT oochuu, eechuu, ichuu, uchuu -- ===================================== if mw.ustring.match(word, "eechuu$") or mw.ustring.match(word, "ichuu$") or mw.ustring.match(word, "uchuu$") or mw.ustring.match(word, "oochuu$") then local stem_chuu = mw.ustring.sub(word, 1, -5) male = stem_chuu .. "chaa" female = stem_chuu .. "chituu" plural = stem_chuu .. "chitoota" -- ===================================== -- jjechuu, jechuu, ochuu -- ===================================== elseif mw.ustring.match(word, "jjechuu$") then local root = mw.ustring.sub(word, 1, -7) male = root .. "etaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "jechuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "edhaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "ochuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "odhaa" female = root .. "ootuu" plural = root .. "ootota" -- ===================================== -- ', w, y, h endings ['wyh]uu -- ===================================== elseif mw.ustring.match(word, "oo['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "ssuu" plural = root .. "ssota" elseif mw.ustring.match(word, "o['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" elseif mw.ustring.match(word, "aa['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -4) male = stem2 .. "aa" female = root .. "ooftuu" plural = root .. "ooftota" elseif mw.ustring.match(word, "[aeio]ta['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "oftuu" plural = root .. "oftoota" elseif mw.ustring.match(word, "[aeiou]ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "a'oota" elseif mw.ustring.match(word, "ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "eessota" elseif mw.ustring.match(word, "a['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "atuu" plural = root .. "atota" elseif mw.ustring.match(word, "ii['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "i['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "toota" elseif mw.ustring.match(word, "e['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "etuu" plural = root .. "etota" elseif mw.ustring.match(word, "u['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" -- ===================================== -- dhuu endings -- ===================================== elseif mw.ustring.match(word, "[ae]dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "iidhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "idhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "ituu" plural = root .. "itota" elseif mw.ustring.match(word, "uudhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "udhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" elseif mw.ustring.match(word, "dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" -- ===================================== -- nyuu, shuu -- ===================================== elseif mw.ustring.match(word, "nyuu$") then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" elseif mw.ustring.match(word, "shuu$") then male = stem2 .. "aa" female = stem2 .. "tuu" plural = stem2 .. "toota" -- ===================================== -- Consonant + chuu -- ===================================== elseif mw.ustring.match(word, "[bcdfghjklmnpqrstvwxyz]chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "chaa" female = base .. "chituu" plural = base .. (is_long and "chitota" or "chitoota") -- ===================================== -- General chuu -- ===================================== elseif mw.ustring.match(word, "chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "taa" female = base .. "ttuu" plural = base .. (is_long and "ttota" or "ttoota") -- ===================================== -- V + CC + uu -- ===================================== elseif is_vccuu(word) then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" -- ===================================== -- cuu -- ===================================== elseif mw.ustring.match(word, "cuu$") then local base = mw.ustring.sub(word, 1, -4) male = base .. "caa" female = base .. "ccuu" plural = base .. "ccitoota" -- ===================================== -- [d j x t]uu -- ===================================== elseif mw.ustring.match(word, "[djxt]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local c = mw.ustring.sub(word, -3, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. c .. "uu" plural = base .. c .. (is_long and "ota" or "oota") -- ===================================== -- [bg]uu -- ===================================== elseif mw.ustring.match(word, "[bg]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "duu" plural = base .. (is_long and "dota" or "doota") -- ===================================== -- [fklmnprsvz]uu -- ===================================== elseif mw.ustring.match(word, "[fklmnprsvz]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "tuu" plural = base .. (is_long and "tota" or "toota") -- ===================================== -- quu / phuu / zyuu -- ===================================== elseif mw.ustring.match(word, "quu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") elseif mw.ustring.match(word, "phuu$") or mw.ustring.match(word, "zyuu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") -- ===================================== -- RULE NOT FOUND (Fallback) -- ===================================== else return { error = "Rule kanaaf hin jiru." } end return { male = male, female = female, plural = plural, word = word } end -- ===================================== -- 6. TEMPLATE ENTRY POINT (LIST OUTPUT) -- ===================================== function export.generate(frame) local args = frame.args if not args[1] and not args.word and not args.verb then args = frame:getParent().args end local word = args[1] or args.word or args.verb -- Yoo parameter hin kennamne maqaa fuulaa irraa fudhata if not word or word == "" then local pagename = mw.title.getCurrentTitle().text if mw.ustring.match(pagename, "uu$") then word = pagename else word = "gochuu" end end local results = export.get_adjective_forms(word) if results.error then return "<strong class='error'>" .. results.error .. "</strong>" end local lines = {} table.insert(lines, "====Derived terms====") table.insert(lines, "* [[" .. results.male .. "]] (male adjective)") table.insert(lines, "* [[" .. results.female .. "]] (female adjective)") table.insert(lines, "* [[" .. results.plural .. "]] (plural adjective)") return table.concat(lines, "\n") end return export 679j8faf5cz89udyweiicw2p3odio29 82000 81999 2026-07-05T05:58:32Z EyobAbebe7 3540 82000 Scribunto text/plain local export = {} -- ===================================== -- 1. HELPER: Check for long vowels (aa, ee, ii, uu) -- (JS: /(aa|ee|ii|uu)$/.test) -- ===================================== local function ends_with_long_vowel(str) return mw.ustring.match(str, "aa$") or mw.ustring.match(str, "ee$") or mw.ustring.match(str, "ii$") or mw.ustring.match(str, "uu$") end -- ===================================== -- 2. TOKENIZER (ch, dh, ny, ph, sh, ts, zy) -- ===================================== local function tokenize_oromo(text) local digraphs = { ["ch"] = true, ["dh"] = true, ["ny"] = true, ["ph"] = true, ["sh"] = true, ["ts"] = true, ["zy"] = true } local tokens = {} local i = 1 local len = mw.ustring.len(text) while i <= len do local two = mw.ustring.sub(text, i, i + 1) if mw.ustring.len(two) == 2 and digraphs[two] then table.insert(tokens, two) i = i + 2 else table.insert(tokens, mw.ustring.sub(text, i, i)) i = i + 1 end end return tokens end -- ===================================== -- 3. VCC DETECTOR -- ===================================== local function is_vccuu(word) local stem = mw.ustring.sub(word, 1, -3) -- removes 'uu' local tokens = tokenize_oromo(stem) local vowels = { a=true, e=true, i=true, o=true, u=true } local consonants_at_end = 0 for i = #tokens, 1, -1 do if vowels[tokens[i]] then break end consonants_at_end = consonants_at_end + 1 end return consonants_at_end >= 2 end -- ===================================== -- 4. LONG VOWEL + CONSONANT CHECK -- ===================================== local function ends_with_long_vowel_plus_consonant(stem) local tokens = tokenize_oromo(stem) local len = #tokens if len < 2 then return false end local last = tokens[len] local prev = tokens[len - 1] local vowels = { a=true, e=true, i=true, o=true, u=true } local is_consonant = not vowels[last] local is_long_vowel = (prev == "aa" or prev == "ee" or prev == "ii" or prev == "oo" or prev == "uu") -- Fallback yoo tokenizer qubee wal-fakkaataa addaan baase if not is_long_vowel and len >= 3 then local prev2 = tokens[len - 2] if vowels[prev] and prev == prev2 then is_long_vowel = true end end return is_long_vowel and is_consonant end -- ===================================== -- 5. MAIN FUNCTION: Generate Forms -- ===================================== function export.get_adjective_forms(word) if not word or word == "" then return { error = "Verb galchi." } end word = mw.ustring.lower(mw.text.trim(word)) if not mw.ustring.match(word, "uu$") then return { error = "Verb Afaan Oromoo 'uu'n xumuramuu qaba." } end local male = "" local female = "" local plural = "" local stem2 = mw.ustring.sub(word, 1, -3) -- Default stem (removes 'uu') -- ===================================== -- EXACT oochuu, eechuu, ichuu, uchuu -- ===================================== if mw.ustring.match(word, "eechuu$") or mw.ustring.match(word, "ichuu$") or mw.ustring.match(word, "uchuu$") or mw.ustring.match(word, "oochuu$") then local stem_chuu = mw.ustring.sub(word, 1, -5) male = stem_chuu .. "chaa" female = stem_chuu .. "chituu" plural = stem_chuu .. "chitoota" -- ===================================== -- jjechuu, jechuu, ochuu -- ===================================== elseif mw.ustring.match(word, "jjechuu$") then local root = mw.ustring.sub(word, 1, -7) male = root .. "etaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "jechuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "edhaa" female = root .. "ettuu" plural = root .. "ettoota" elseif mw.ustring.match(word, "ochuu$") then local root = mw.ustring.sub(word, 1, -6) male = root .. "odhaa" female = root .. "ootuu" plural = root .. "ootota" -- ===================================== -- ', w, y, h endings ['wyh]uu -- ===================================== elseif mw.ustring.match(word, "oo['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "ssuu" plural = root .. "ssota" elseif mw.ustring.match(word, "o['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" elseif mw.ustring.match(word, "aa['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -4) male = stem2 .. "aa" female = root .. "ooftuu" plural = root .. "ooftota" elseif mw.ustring.match(word, "[aeio]ta['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "oftuu" plural = root .. "oftoota" elseif mw.ustring.match(word, "[aeiou]ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "a'oota" elseif mw.ustring.match(word, "ga['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "eessuu" plural = root .. "eessota" elseif mw.ustring.match(word, "a['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "atuu" plural = root .. "atota" elseif mw.ustring.match(word, "ii['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "i['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "toota" elseif mw.ustring.match(word, "e['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "etuu" plural = root .. "etota" elseif mw.ustring.match(word, "u['wyh]uu$") then local root = mw.ustring.sub(stem2, 1, -2) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" -- ===================================== -- dhuu endings -- ===================================== elseif mw.ustring.match(word, "[ae]dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "iidhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "idhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "ituu" plural = root .. "itota" elseif mw.ustring.match(word, "uudhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "tuu" plural = root .. "tota" elseif mw.ustring.match(word, "udhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "utuu" plural = root .. "utota" elseif mw.ustring.match(word, "dhuu$") then local root = mw.ustring.sub(stem2, 1, -3) male = stem2 .. "aa" female = root .. "otuu" plural = root .. "otota" -- ===================================== -- nyuu, shuu -- ===================================== elseif mw.ustring.match(word, "nyuu$") then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" elseif mw.ustring.match(word, "shuu$") then male = stem2 .. "aa" female = stem2 .. "tuu" plural = stem2 .. "toota" -- ===================================== -- Consonant + chuu -- ===================================== elseif mw.ustring.match(word, "[bcdfghjklmnpqrstvwxyz]chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "chaa" female = base .. "chituu" plural = base .. (is_long and "chitota" or "chitoota") -- ===================================== -- General chuu -- ===================================== elseif mw.ustring.match(word, "chuu$") then local base = mw.ustring.sub(word, 1, -5) local is_long = ends_with_long_vowel(base) male = base .. "taa" female = base .. "ttuu" plural = base .. (is_long and "ttota" or "ttoota") -- ===================================== -- V + CC + uu -- ===================================== elseif is_vccuu(word) then male = stem2 .. "aa" female = stem2 .. "ituu" plural = stem2 .. "itoota" -- ===================================== -- cuu -- ===================================== elseif mw.ustring.match(word, "cuu$") then local base = mw.ustring.sub(word, 1, -4) male = base .. "caa" female = base .. "ccuu" plural = base .. "ccitoota" -- ===================================== -- [d j x t]uu -- ===================================== elseif mw.ustring.match(word, "[djxt]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local c = mw.ustring.sub(word, -3, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. c .. "uu" plural = base .. c .. (is_long and "ota" or "oota") -- ===================================== -- [bg]uu -- ===================================== elseif mw.ustring.match(word, "[bg]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "duu" plural = base .. (is_long and "dota" or "doota") -- ===================================== -- [fklmnprsvz]uu -- ===================================== elseif mw.ustring.match(word, "[fklmnprsvz]uu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "tuu" plural = base .. (is_long and "tota" or "toota") -- ===================================== -- quu / phuu / zyuu -- ===================================== elseif mw.ustring.match(word, "quu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -2) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") elseif mw.ustring.match(word, "phuu$") or mw.ustring.match(word, "zyuu$") then local base = mw.ustring.sub(word, 1, -3) local root = mw.ustring.sub(base, 1, -3) local is_long = ends_with_long_vowel(root) male = base .. "aa" female = base .. "xuu" plural = base .. (is_long and "xota" or "xoota") -- ===================================== -- RULE NOT FOUND (Fallback) -- ===================================== else return { error = "Rule kanaaf hin jiru." } end return { male = male, female = female, plural = plural, word = word } end -- ===================================== -- 6. TEMPLATE ENTRY POINT (LIST OUTPUT) -- ===================================== function export.generate(frame) local args = frame.args if not args[1] and not args.word and not args.verb then args = frame:getParent().args end local word = args[1] or args.word or args.verb -- Yoo parameter hin kennamne maqaa fuulaa irraa fudhata if not word or word == "" then local pagename = mw.title.getCurrentTitle().text if mw.ustring.match(pagename, "uu$") then word = pagename else word = "gochuu" end end local results = export.get_adjective_forms(word) if results.error then return "<strong class='error'>" .. results.error .. "</strong>" end local lines = {} table.insert(lines, "* [[" .. results.male .. "]] (male adjective)") table.insert(lines, "* [[" .. results.female .. "]] (female adjective)") table.insert(lines, "* [[" .. results.plural .. "]] (plural adjective)") table.insert(lines, "* [[" .. results.word .. "dhaan]] (adverb)") return table.concat(lines, "\n") end return export 77bxrrzt301y368qgr11q26npwzwhcg