ဝိက်ရှေန်နရဳ
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.7
case-sensitive
မဳဒဳယာ
တၟေင်
ဓရီုကျာ
ညးလွပ်
ညးလွပ် ဓရီုကျာ
ဝိက်ရှေန်နရဳ
ဝိက်ရှေန်နရဳ ဓရီုကျာ
ဝှာင်
ဝှာင် ဓရီုကျာ
မဳဒဳယာဝဳကဳ
မဳဒဳယာဝဳကဳ ဓရီုကျာ
ထာမ်ပလိက်
ထာမ်ပလိက် ဓရီုကျာ
ရီု
ရီု ဓရီုကျာ
ကဏ္ဍ
ကဏ္ဍ ဓရီုကျာ
အဆက်လက္ကရဴ
အဆက်လက္ကရဴ ဓရီုကျာ
ကာရန်
ကာရန် ဓရီုကျာ
အဘိဓာန်
အဘိဓာန် ဓရီုကျာ
ဗီုပြၚ်သိုၚ်တၟိ
ဗီုပြၚ်သိုၚ်တၟိ ဓရီုကျာ
TimedText
TimedText talk
မဝ်ဂျူ
မဝ်ဂျူ ဓရီုကျာ
Event
Event talk
မဝ်ဂျူ:labels/data/topical
828
1005
397266
394735
2026-06-20T19:10:40Z
咽頭べさ
33
397266
Scribunto
text/plain
local labels = {}
-- This file is split into two sections: topical labels and labels for set-type categories.
-- Each section is sorted alphabetically.
-- Topical labels
labels["ABDL"] = {
display = "[[ABDL]]",
topical_categories = true,
}
labels["Abrahamism"] = {
display = "[[Abrahamism#Noun|Abrahamism]]",
topical_categories = true,
}
labels["accounting"] = {
display = "[[accounting#Noun|accounting]]",
topical_categories = true,
}
labels["acoustics"] = {
display = "[[acoustics]]",
topical_categories = true,
}
labels["acting"] = {
display = "[[acting#Noun|acting]]",
topical_categories = true,
}
labels["advertising"] = {
display = "[[advertising#Noun|advertising]]",
topical_categories = true,
}
labels["aeronautics"] = {
display = "[[aeronautics]]",
topical_categories = true,
}
labels["aerospace"] = {
display = "[[aerospace]]",
topical_categories = true,
}
labels["aesthetic"] = {
aliases = {"aesthetics"},
display = "[[aesthetic]]",
topical_categories = "Aesthetics",
}
labels["agriculture"] = {
aliases = {"farming"},
display = "[[agriculture]]",
topical_categories = true,
}
labels["Ahmadiyya"] = {
aliases = {"Ahmadiyyat", "Ahmadi"},
display = "[[Ahmadiyya]]",
topical_categories = true,
}
labels["aircraft"] = {
display = "[[aircraft]]",
topical_categories = true,
}
labels["alchemy"] = {
display = "[[alchemy]]",
topical_categories = true,
}
labels["alcoholic beverages"] = {
aliases = {"alcohol"},
display = "[[alcoholic#Adjective|alcoholic]] [[beverage]]s",
topical_categories = true,
}
labels["alcoholism"] = {
display = "[[alcoholism]]",
topical_categories = true,
}
labels["algebra"] = {
display = "[[algebra]]",
topical_categories = true,
}
labels["algebraic geometry"] = {
display = "[[algebraic geometry]]",
topical_categories = true,
}
labels["algebraic topology"] = {
display = "[[algebraic topology]]",
topical_categories = true,
}
labels["alt-right"] = {
aliases = {"Alt-right", "altright", "Altright"},
display = "[[alt-right]]",
topical_categories = true,
}
labels["alternative medicine"] = {
display = "[[alternative medicine]]",
topical_categories = true,
}
labels["amateur radio"] = {
aliases = {"ham radio"},
display = "[[amateur radio]]",
topical_categories = true,
}
labels["American football"] = {
display = "[[American football]]",
topical_categories = "Football (American)",
}
labels["analytic geometry"] = {
display = "[[analytic geometry]]",
topical_categories = "Geometry",
}
labels["analytical chemistry"] = {
display = "[[analytical]] [[chemistry]]",
topical_categories = true,
}
labels["anarchism"] = {
display = "[[anarchism]]",
topical_categories = true,
}
labels["anatomy"] = {
display = "[[anatomy|ကွတ်ဗေဒခန္ဓ]]",
topical_categories = "ကွတ်ဗေဒခန္ဓ",
}
labels["Ancient Greece"] = {
display = "[[Ancient Greece]]",
topical_categories = true,
}
labels["Ancient Rome"] = {
display = "[[Ancient Rome]]",
topical_categories = true,
}
labels["Anglicanism"] = {
aliases = {"Anglican"},
display = "[[Anglicanism]]",
topical_categories = true,
}
labels["animation"] = {
display = "[[animation]]",
topical_categories = true,
}
labels["anime"] = {
display = "[[anime]]",
topical_categories = "Japanese fiction",
}
labels["anthropology"] = {
display = "[[anthropology]]",
topical_categories = true,
}
labels["arachnology"] = {
display = "[[arachnology]]",
topical_categories = true,
}
labels["Arabian god"] = {
display = "[[Arabian]] [[mythology]]",
topical_categories = "Arabian deities",
}
labels["archaeological culture"] = {
aliases = {"archeological culture", "archaeological cultures", "archeological cultures"},
display = "[[archaeology]]",
topical_categories = "Archaeological cultures",
}
labels["archaeology"] = {
aliases = {"archeology"},
display = "[[archaeology]]",
topical_categories = true,
}
labels["archery"] = {
display = "[[archery]]",
topical_categories = true,
}
labels["architecture"] = {
display = "[[architecture]]",
topical_categories = true,
}
labels["arithmetic"] = {
display = "[[arithmetic]]",
topical_categories = true,
}
labels["Armenian mythology"] = {
display = "[[Armenian]] [[mythology]]",
topical_categories = true,
}
labels["art"] = {
aliases = {"arts"},
display = "[[art#Noun|art]]",
topical_categories = true,
}
labels["artificial intelligence"] = {
aliases = {"AI"},
display = "[[artificial intelligence]]",
topical_categories = true,
}
labels["artillery"] = {
display = "[[weaponry]]",
topical_categories = true,
}
labels["Arthurian legend"] = {
aliases = {"Arthurian mythology"},
display = "[[w:Arthurian legend|Arthurian legend]]",
topical_categories = "Arthurian mythology",
}
labels["astrology"] = {
aliases = {"horoscope", "zodiac"},
display = "[[astrology]]",
topical_categories = true,
}
labels["astronautics"] = {
aliases = {"rocketry"},
display = "[[astronautics]]",
topical_categories = true,
}
labels["astronomy"] = {
display = "[[astronomy|ကွတ်ဗေဒနက်သတ်]]",
topical_categories = "ကွတ်ဗေဒနက်သတ်",
}
labels["astrophysics"] = {
display = "[[astrophysics]]",
topical_categories = true,
}
labels["Asturian mythology"] = {
display = "[[Asturian]] [[mythology]]",
topical_categories = true,
}
labels["athletics"] = {
display = "[[athletics]]",
topical_categories = true,
}
labels["Australian Aboriginal mythology"] = {
display = "[[w:Australian Aboriginal religion and mythology|Australian Aboriginal mythology]]",
topical_categories = true,
}
labels["Australian rules football"] = {
display = "[[Australian rules football]]",
topical_categories = true,
}
labels["autism"] = {
display = "[[autism]]",
topical_categories = true,
}
labels["automotive"] = {
aliases = {"automotives"},
display = "[[automotive]]",
topical_categories = true,
}
labels["aviation"] = {
aliases = {"air transport"},
display = "[[aviation]]",
topical_categories = true,
}
labels["backgammon"] = {
display = "[[backgammon]]",
topical_categories = true,
}
labels["bacteria"] = {
display = "[[bacteriology]]",
topical_categories = true,
}
labels["bacteriology"] = {
display = "[[bacteriology]]",
topical_categories = true,
}
labels["badminton"] = {
display = "[[badminton]]",
topical_categories = true,
}
labels["baking"] = {
display = "[[baking#Noun|baking]]",
topical_categories = true,
}
labels["ball games"] = {
aliases = {"ball sports"},
display = "[[ball game]]s",
topical_categories = true,
}
labels["ballet"] = {
display = "[[ballet]]",
topical_categories = true,
}
labels["Bangladeshi politics"] = {
display = "[[w:Politics of Bangladesh|Bangladeshi politics]]",
topical_categories = true,
}
labels["banking"] = {
display = "[[banking#Noun|banking]]",
topical_categories = true,
}
labels["baseball"] = {
display = "[[baseball]]",
topical_categories = true,
}
labels["basketball"] = {
display = "[[basketball]]",
topical_categories = true,
}
labels["BDSM"] = {
display = "[[BDSM]]",
topical_categories = true,
}
labels["beekeeping"] = {
display = "[[beekeeping]]",
topical_categories = true,
}
labels["beer"] = {
display = "[[beer]]",
topical_categories = true,
}
labels["betting"] = {
display = "[[gambling#Noun|gambling]]",
topical_categories = true,
}
labels["biblical"] = {
aliases = {"Bible", "bible", "Biblical"},
display = "[[Bible|biblical]]",
topical_categories = "Bible",
}
labels["billiards"] = {
display = "[[billiards]]",
topical_categories = true,
}
labels["bingo"] = {
display = "[[bingo]]",
topical_categories = true,
}
labels["biochemistry"] = {
display = "[[biochemistry]]",
topical_categories = true,
}
labels["biology"] = {
display = "[[biology]]",
topical_categories = true,
}
labels["biotechnology"] = {
display = "[[biotechnology]]",
topical_categories = true,
}
labels["birdwatching"] = {
display = "[[birdwatching#Noun|birdwatching]]",
topical_categories = true,
}
labels["blacksmithing"] = {
display = "[[blacksmithing]]",
topical_categories = true,
}
labels["blogging"] = {
display = "[[blogging#Noun|blogging]]",
topical_categories = "Internet",
}
labels["board games"] = {
aliases = {"board game"},
display = "[[board game]]s",
topical_categories = true,
}
labels["board sports"] = {
display = "[[boardsport|board sports]]",
topical_categories = true,
}
labels["bodybuilding"] = {
display = "[[bodybuilding#Noun|bodybuilding]]",
topical_categories = true,
}
labels["botany"] = {
display = "[[botany]]",
topical_categories = true,
}
labels["bowling"] = {
display = "[[bowling#Noun|bowling]]",
topical_categories = true,
}
labels["bowls"] = {
aliases = {"lawn bowls", "crown green bowls"},
display = "[[bowls]]",
topical_categories = "Bowls (game)",
}
labels["boxing"] = {
display = "[[boxing#Noun|boxing]]",
topical_categories = true,
}
labels["brewing"] = {
display = "[[brewing#Noun|brewing]]",
topical_categories = true,
}
labels["bridge"] = {
display = "[[bridge#English:_game|bridge]]",
topical_categories = true,
}
labels["broadcasting"] = {
display = "[[broadcasting#Noun|broadcasting]]",
topical_categories = true,
}
labels["bryology"] = {
display = "[[bryology]]",
topical_categories = true,
}
labels["Buddhism"] = {
display = "[[Buddhism|ဗုဒ္ဓဘာသာ]]",
topical_categories = "ဗုဒ္ဓဘာသာ",
}
labels["Buddhist deity"] = {
aliases = {"Buddhist goddess", "Buddhist god"},
display = "[[Buddhism|ဗုဒ္ဓဘာသာ]]",
topical_categories = "ဒေဝတဴဗုဒ္ဓဘာသာ",
}
labels["bullfighting"] = {
display = "[[bullfighting]]",
topical_categories = true,
}
labels["business"] = {
aliases = {"professional"},
display = "[[business]]",
topical_categories = true,
}
labels["Byzantine Empire"] = {
display = "[[Byzantine Empire]]",
topical_categories = true,
}
labels["calculus"] = {
display = "[[calculus]]",
topical_categories = true,
}
labels["calligraphy"] = {
display = "[[calligraphy]]",
topical_categories = true,
}
labels["Canadian football"] = {
display = "[[Canadian football]]",
topical_categories = true,
}
labels["canoeing"] = {
display = "[[canoeing#Noun|canoeing]]",
topical_categories = "Water sports",
}
labels["capitalism"] = {
display = "[[capitalism]]",
topical_categories = true,
}
labels["card games"] = {
aliases = {"cards", "card game", "playing card"},
display = "[[card game]]s",
topical_categories = true,
}
labels["cardiology"] = {
display = "[[cardiology]]",
topical_categories = true,
}
labels["carpentry"] = {
display = "[[carpentry]]",
topical_categories = true,
}
labels["cartography"] = {
display = "[[cartography]]",
topical_categories = true,
}
labels["cartomancy"] = {
display = "[[cartomancy]]",
topical_categories = true,
}
labels["castells"] = {
display = "[[castells]]",
topical_categories = true,
}
labels["category theory"] = {
display = "[[category theory]]",
topical_categories = true,
}
labels["Catholicism"] = {
aliases = {"catholicism", "Catholic", "catholic"},
display = "[[Catholicism]]",
topical_categories = true,
}
labels["caving"] = {
display = "[[caving#Noun|caving]]",
topical_categories = true,
}
labels["cellular automata"] = {
display = "[[cellular automata]]",
topical_categories = true,
}
labels["Celtic mythology"] = {
display = "[[Celtic]] [[mythology]]",
topical_categories = true,
}
labels["ceramics"] = {
display = "[[ceramics]]",
topical_categories = true,
}
labels["cheerleading"] = {
display = "[[cheerleading#Noun|cheerleading]]",
topical_categories = true,
}
labels["chemical element"] = {
display = "[[chemistry|ကွတ်ဗေဒဓါတု]]",
topical_categories = "ဓါတ်ဆေၚ်စပ်ကဵုကွတ်ဗေဒဓါတု",
}
labels["chemical engineering"] = {
display = "[[chemical engineering]]",
topical_categories = true,
}
labels["chemistry"] = {
display = "[[chemistry|ကွတ်ဗေဒဓါတု]]",
topical_categories = "ကွတ်ဗေဒဓါတု",
}
labels["chess"] = {
display = "[[chess]]",
topical_categories = true,
}
labels["children's games"] = {
display = "[[children|children's]] [[game]]s",
topical_categories = true,
}
labels["Church of England"] = {
aliases = {"C of E", "CofE"},
Wikipedia = "Church of England",
topical_categories = true,
}
labels["Chinese astronomy"] = {
display = "[[Chinese]] [[astronomy]]",
topical_categories = true,
}
labels["Chinese calligraphy"] = {
display = "[[Chinese]] [[calligraphy]]",
topical_categories = "Calligraphy",
}
labels["Chinese constellation"] = {
display = "[[Chinese]] [[astronomy]]",
topical_categories = "Constellations",
}
labels["Chinese folk religion"] = {
display = "[[Chinese]] [[folk religion]]",
topical_categories = "Religion",
}
labels["Chinese linguistics"] = {
display = "[[Chinese]] [[linguistics]]",
topical_categories = "Linguistics",
}
labels["Chinese mythology"] = {
display = "[[Chinese]] [[mythology]]",
topical_categories = true,
}
labels["Chinese philosophy"] = {
display = "[[Chinese]] [[philosophy]]",
topical_categories = true,
}
labels["Chinese phonetics"] = {
display = "[[Chinese]] [[phonetics]]",
topical_categories = true,
}
labels["Chinese religion"] = {
display = "[[religion|သာသၞာ]][[Chinese|ကြုက်]]",
topical_categories = "သာသၞာ",
}
labels["Chinese star"] = {
display = "[[Chinese]] [[astronomy]]",
topical_categories = "Stars",
}
labels["Christianity"] = {
aliases = {"christianity", "Christian", "christian"},
display = "[[Christianity|သာသၞာခရေတ်]]",
topical_categories = "သာသၞာခရေတ်",
}
labels["Church of the East"] = {
display = "[[Church of the East]]",
topical_categories = true,
}
labels["cinematography"] = {
aliases = {"filmology"},
display = "[[cinematography]]",
topical_categories = true,
}
labels["cladistics"] = {
display = "[[cladistics]]",
topical_categories = "Taxonomy",
}
labels["classical mechanics"] = {
display = "[[classical mechanics]]",
topical_categories = true,
}
labels["classical studies"] = {
display = "[[classical studies]]",
topical_categories = true,
}
labels["climatology"] = {
display = "[[climatology]]",
topical_categories = true,
}
labels["climate change"] = {
display = "[[climate change]]",
topical_categories = true,
}
labels["climbing"] = {
aliases = {"rock climbing"},
display = "[[climbing#Noun|climbing]]",
topical_categories = true,
}
labels["clinical psychology"] = {
display = "[[clinical]] [[psychology]]",
topical_categories = true,
}
labels["clothing"] = {
display = "[[clothing#Noun|clothing]]",
topical_categories = true,
}
labels["cloud computing"] = {
display = "[[cloud computing]]",
topical_categories = "Computing",
}
labels["collectible card games"] = {
aliases = {"trading card games", "collectible cards", "trading cards"},
display = "collectible card games",
topical_categories = true,
}
labels["combinatorics"] = {
display = "[[combinatorics]]",
topical_categories = true,
}
labels["comedy"] = {
display = "[[comedy]]",
topical_categories = true,
}
labels["commercial law"] = {
display = "[[commercial#Adjective|commercial]] [[law]]",
topical_categories = true,
}
labels["comics"] = {
display = "[[comics]]",
topical_categories = true,
}
labels["communication"] = {
aliases = {"communications"},
display = "[[communication]]",
topical_categories = true,
}
labels["communism"] = {
aliases = {"Communism"},
display = "[[communism]]",
topical_categories = true,
}
labels["compilation"] = {
aliases = {"compiler"},
display = "[[software]] [[compilation]]",
topical_categories = true,
}
labels["complex analysis"] = {
display = "[[complex analysis]]",
topical_categories = true,
}
labels["computational linguistics"] = {
display = "[[computational linguistics]]",
topical_categories = true,
}
labels["computer chess"] = {
display = "[[computer chess]]",
topical_categories = true,
}
labels["computer games"] = {
aliases = {"computer game", "computer gaming"},
display = "[[computer game]]s",
topical_categories = "Video games",
}
labels["computer graphics"] = {
display = "[[computer graphics]]",
topical_categories = true,
}
labels["computer hardware"] = {
display = "[[computer]] [[hardware]]",
topical_categories = true,
}
labels["computer languages"] = {
aliases = {"computer language", "programming language"},
display = "[[computer language]]s",
topical_categories = true,
}
labels["computer science"] = {
aliases = {"comp sci", "CompSci", "compsci"},
display = "[[computer science]]",
topical_categories = true,
}
labels["computer security"] = {
display = "[[computer security]]",
topical_categories = true,
}
labels["computing"] = {
aliases = {"computer", "computers"},
display = "[[computing#နာမ်|ပွမတော်တၟော်]]",
topical_categories = "ပွမတော်တၟော်",
}
labels["computing theory"] = {
aliases = {"comptheory"},
display = "[[computing#Noun|computing]] [[theory]]",
topical_categories = "Theory of computing",
}
labels["conchology"] = {
display = "[[conchology]]",
topical_categories = true,
}
labels["Confucianism"] = {
display = "[[Confucianism]]",
topical_categories = true,
}
labels["conlanging"] = {
aliases = {"constructed languages", "constructed language"},
display = "[[conlanging]]",
topical_categories = true,
}
labels["conservatism"] = {
display = "[[conservatism]]",
topical_categories = true,
}
labels["construction"] = {
display = "[[construction]]",
topical_categories = true,
}
labels["cooking"] = {
aliases = {"culinary", "cuisine", "cookery", "gastronomy"},
display = "[[cooking#Noun|cooking]]",
topical_categories = true,
}
labels["copyright"] = {
aliases = {"copyright law", "intellectual property", "intellectual property law", "IP law"},
display = "[[copyright]] [[law]]",
topical_categories = true,
}
labels["cosmetics"] = {
aliases = {"cosmetology"},
display = "[[cosmetics]]",
topical_categories = true,
}
labels["cosmology"] = {
display = "[[cosmology]]",
topical_categories = true,
}
labels["creationism"] = {
aliases = {"baraminology"},
display = "[[creationism#English|creationism]]",
topical_categories = true,
}
labels["cribbage"] = {
display = "[[cribbage]]",
topical_categories = true,
}
labels["cricket"] = {
display = "[[cricket]]",
topical_categories = true,
}
labels["crime"] = {
display = "[[crime]]",
topical_categories = true,
}
labels["criminal law"] = {
display = "[[criminal law]]",
topical_categories = true,
}
labels["criminology"] = {
display = "[[criminology]]",
topical_categories = true,
}
labels["croquet"] = {
display = "[[croquet]]",
topical_categories = true,
}
labels["cryptocurrencies"] = {
aliases = {"cryptocurrency"},
display = "[[cryptocurrency|cryptocurrencies]]",
topical_categories = "Cryptocurrency",
}
labels["cryptography"] = {
display = "[[cryptography]]",
topical_categories = true,
}
labels["cryptozoology"] = {
display = "[[cryptozoology]]",
topical_categories = true,
}
labels["crystallography"] = {
display = "[[crystallography]]",
topical_categories = true,
}
labels["cultural anthropology"] = {
display = "[[cultural anthropology]]",
topical_categories = true,
}
labels["curling"] = {
display = "[[curling]]",
topical_categories = true,
}
labels["cybernetics"] = {
display = "[[cybernetics]]",
topical_categories = true,
}
labels["cybersecurity"] = {
display = "[[cybersecurity]]",
topical_categories = "Networking",
}
labels["cycle racing"] = {
display = "[[w:cycle sport|cycle racing]]",
topical_categories = true,
}
labels["cycling"] = {
aliases = {"bicycling"},
display = "[[cycling#Noun|cycling]]",
topical_categories = true,
}
labels["cytology"] = {
display = "[[cytology]]",
topical_categories = true,
}
labels["dance"] = {
aliases = {"dancing"},
display = "[[dance#Noun|dance]]",
topical_categories = true,
}
labels["darts"] = {
display = "[[darts]]",
topical_categories = true,
}
labels["data management"] = {
display = "[[data management]]",
topical_categories = true,
}
labels["data modeling"] = {
display = "[[data modeling]]",
topical_categories = true,
}
labels["databases"] = {
aliases = {"database"},
display = "[[database]]s",
topical_categories = true,
}
labels["decision theory"] = {
display = "[[decision theory]]",
topical_categories = true,
}
labels["deltiology"] = {
display = "[[deltiology]]",
topical_categories = true,
}
labels["demography"] = {
display = "[[demography]]",
topical_categories = true,
}
labels["demoscene"] = {
topical_categories = true,
}
labels["dentistry"] = {
display = "[[dentistry]]",
topical_categories = true,
}
labels["dermatology"] = {
display = "[[dermatology]]",
topical_categories = true,
}
labels["design"] = {
display = "[[design#Noun|design]]",
topical_categories = true,
}
labels["dice games"] = {
aliases = {"dice"},
display = "[[dice game]]s",
topical_categories = true,
}
labels["dictation"] = {
display = "[[dictation]]",
topical_categories = true,
}
labels["differential geometry"] = {
display = "[[differential geometry]]",
topical_categories = true,
}
labels["diplomacy"] = {
display = "[[diplomacy]]",
topical_categories = true,
}
labels["disc golf"] = {
display = "[[disc golf]]",
topical_categories = true,
}
labels["divination"] = {
display = "[[divination]]",
topical_categories = true,
}
labels["diving"] = {
display = "[[diving#Noun|diving]]",
topical_categories = true,
}
labels["dominoes"] = {
display = "[[dominoes]]",
topical_categories = true,
}
labels["dou dizhu"] = {
display = "[[w:Dou dizhu|dou dizhu]]",
topical_categories = true,
}
labels["drama"] = {
display = "[[drama]]",
topical_categories = true,
}
labels["dressage"] = {
display = "[[dressage]]",
topical_categories = true,
}
labels["earth science"] = {
display = "[[earth science]]",
topical_categories = "Earth sciences",
}
labels["Eastern Catholicism"] = {
aliases = {"Eastern Catholic"},
display = "[[w:Eastern Catholic Churches|Eastern Catholicism]]",
topical_categories = true,
}
labels["Eastern Orthodoxy"] = {
aliases = {"Eastern Orthodox"},
display = "[[Eastern Orthodoxy]]",
topical_categories = true,
}
labels["eating disorders"] = {
aliases = {"eating disorder"},
display = "[[eating disorder]]s",
topical_categories = true,
}
labels["ecclesiastical"] = {
display = "[[ecclesiastical]]",
topical_categories = "Christianity",
}
labels["ecology"] = {
display = "[[ecology]]",
topical_categories = true,
}
labels["economics"] = {
display = "[[economics]]",
topical_categories = true,
}
labels["education"] = {
display = "[[education]]",
topical_categories = true,
}
labels["Egyptian god"] = {
aliases = {"Egyptian goddess", "Egyptian deity"},
display = "[[Egyptian]] [[mythology]]",
topical_categories = "Egyptian deities",
}
labels["Egyptian mythology"] = {
display = "[[Egyptian]] [[mythology]]",
topical_categories = true,
}
labels["Egyptology"] = {
display = "[[Egyptology]]",
topical_categories = "Ancient Egypt",
}
labels["electrencephalography"] = {
display = "[[electrencephalography]]",
topical_categories = true,
}
labels["electrical engineering"] = {
display = "[[electrical engineering]]",
topical_categories = true,
}
labels["electricity"] = {
display = "[[electricity]]",
topical_categories = true,
}
labels["electrodynamics"] = {
display = "[[electrodynamics]]",
topical_categories = true,
}
labels["electromagnetism"] = {
display = "[[electromagnetism]]",
topical_categories = true,
}
labels["electronics"] = {
display = "[[electronics]]",
topical_categories = true,
}
labels["embryology"] = {
display = "[[embryology]]",
topical_categories = true,
}
labels["emergency services"] = {
display = "[[emergency services]]",
topical_categories = true,
}
labels["emergency medicine"] = {
display = "[[emergency medicine]]",
topical_categories = true,
}
labels["endocrinology"] = {
display = "[[endocrinology]]",
topical_categories = true,
}
labels["engineering"] = {
display = "[[engineering#Noun|engineering]]",
topical_categories = true,
}
labels["enterprise engineering"] = {
display = "[[enterprise engineering]]",
topical_categories = true,
}
labels["entomology"] = {
display = "[[entomology]]",
topical_categories = true,
}
labels["epidemiology"] = {
display = "[[epidemiology]]",
topical_categories = true,
}
labels["epistemology"] = {
display = "[[epistemology]]",
topical_categories = true,
}
labels["equestrianism"] = {
aliases = {"equestrian", "horses", "horsemanship"},
display = "[[equestrianism]]",
topical_categories = true,
}
labels["espionage"] = {
display = "[[espionage]]",
topical_categories = true,
}
labels["ethics"] = {
display = "[[ethics]]",
topical_categories = true,
}
labels["ethnography"] = {
display = "[[ethnography]]",
topical_categories = true,
}
labels["ethology"] = {
display = "[[ethology]]",
topical_categories = true,
}
labels["European folklore"] = {
display = "[[European]] [[folklore]]",
topical_categories = true,
}
labels["European Union"] = {
aliases = {"EU"},
display = "[[European Union]]",
topical_categories = true,
}
labels["evolutionary theory"] = {
aliases = {"evolutionary biology"},
display = "[[evolutionary theory]]",
topical_categories = true,
}
labels["exercise"] = {
display = "[[exercise]]",
topical_categories = true,
}
labels["eye color"] = {
display = "[[eye]] [[color]]",
topical_categories = "Eye colors",
}
labels["falconry"] = {
display = "[[falconry]]",
topical_categories = true,
}
labels["fantasy"] = {
display = "[[fantasy]]",
topical_categories = true,
}
labels["farriery"] = {
display = "[[farriery]]",
topical_categories = true,
}
labels["fascism"] = {
display = "[[fascism]]",
topical_categories = true,
}
labels["fashion"] = {
display = "[[fashion]]",
topical_categories = true,
}
labels["feminism"] = {
display = "[[feminism]]",
topical_categories = true,
}
labels["fencing"] = {
display = "[[fencing#Noun|fencing]]",
topical_categories = true,
}
labels["feudalism"] = {
display = "[[feudalism|feudalism]]",
topical_categories = true,
}
labels["fiction"] = {
aliases = {"fictional"},
display = "[[fiction]]",
topical_categories = true,
}
labels["field hockey"] = {
display = "[[field hockey]]",
topical_categories = true,
}
labels["figure skating"] = {
display = "[[figure skating]]",
topical_categories = true,
}
labels["file format"] = {
display = "[[file format]]",
topical_categories = "File formats",
}
labels["film"] = {
display = "[[film#Noun|film]]",
topical_categories = true,
}
labels["film genre"] = {
aliases = {"cinema"},
display = "[[film#Noun|film]]",
topical_categories = "Film genres",
}
labels["finance"] = {
display = "[[finance#Noun|finance]]",
topical_categories = true,
}
labels["Finnic mythology"] = {
aliases = {"Finnish mythology"},
display = "[[Finnic]] [[mythology]]",
topical_categories = true,
}
labels["firearms"] = {
aliases = {"firearm"},
display = "[[firearm]]s",
topical_categories = true,
}
labels["firefighting"] = {
display = "[[firefighting]]",
topical_categories = true,
}
labels["fishing"] = {
aliases = {"angling"},
display = "[[fishing#Noun|fishing]]",
topical_categories = true,
}
labels["flamenco"] = {
display = "[[flamenco]]",
topical_categories = true,
}
labels["fluid dynamics"] = {
display = "[[fluid dynamics]]",
topical_categories = true,
}
labels["fluid mechanics"] = {
display = "[[fluid mechanics]]",
topical_categories = "Mechanics",
}
labels["folklore"] = {
display = "[[folklore]]",
topical_categories = true,
}
labels["forestry"] = {
display = "[[forestry]]",
topical_categories = true,
}
labels["Forteana"] = {
display = "[[Forteana]]",
topical_categories = true,
}
labels["Freemasonry"] = {
aliases = {"freemasonry"},
display = "[[Freemasonry]]",
topical_categories = true,
}
labels["functional analysis"] = {
display = "[[functional analysis]]",
topical_categories = true,
}
labels["furniture"] = {
display = "[[furniture]]",
topical_categories = true,
}
labels["furry fandom"] = {
display = "[[furry#Noun|furry]] [[fandom]]",
topical_categories = true,
}
labels["fuzzy logic"] = {
display = "[[fuzzy logic]]",
topical_categories = true,
}
labels["Gaelic football"] = {
display = "[[Gaelic football]]",
topical_categories = true,
}
labels["gambling"] = {
display = "[[gambling#Noun|gambling]]",
topical_categories = true,
}
labels["game theory"] = {
display = "[[game theory]]",
topical_categories = true,
}
labels["games"] = {
aliases = {"game"},
display = "[[game#Noun|games]]",
topical_categories = true,
}
labels["gaming"] = {
display = "[[gaming#Noun|gaming]]",
topical_categories = true,
}
labels["genealogy"] = {
display = "[[genealogy]]",
topical_categories = true,
}
labels["general semantics"] = {
display = "[[general semantics]]",
topical_categories = true,
}
labels["genetics"] = {
display = "[[genetics]]",
topical_categories = true,
}
labels["geography"] = {
display = "[[geography]]",
topical_categories = true,
}
labels["geology"] = {
display = "[[geology]]",
topical_categories = true,
}
labels["geological period"] = {
Wikipedia = "Geological period",
topical_categories = "Geological periods",
}
labels["geometry"] = {
display = "[[geometry]]",
topical_categories = true,
}
labels["geomorphology"] = {
display = "[[geomorphology]]",
topical_categories = true,
}
labels["geopolitics"] = {
display = "[[geopolitics]]",
topical_categories = true,
}
labels["gerontology"] = {
display = "[[gerontology]]",
topical_categories = true,
}
labels["glassblowing"] = {
display = "[[glassblowing]]",
topical_categories = true,
}
labels["Gnosticism"] = {
aliases = {"gnosticism"},
display = "[[Gnosticism]]",
topical_categories = true,
}
labels["go"] = {
aliases = {"Go", "game of go", "game of Go"},
display = "{{l|en|go|id=game}}",
topical_categories = true,
}
labels["golf"] = {
display = "[[golf]]",
topical_categories = true,
}
labels["government"] = {
display = "[[government]]",
topical_categories = true,
}
labels["grammar"] = {
display = "[[grammar|သဒ္ဒာ]]",
topical_categories = "သဒ္ဒာ",
}
labels["grammatical case"] = {
display = "[[grammar|သဒ္ဒာ]]",
topical_categories = "ကိစ္စဆေၚ်စပ်ကဵုသဒ္ဒာ",
}
labels["grammatical mood"] = {
display = "[[grammar|သဒ္ဒာ]]",
topical_categories = "စိုတ်ဓာတ်ဆေၚ်စပ်ကဵုသဒ္ဒာ",
}
labels["graph theory"] = {
display = "[[graph theory]]",
topical_categories = true,
}
labels["graphic design"] = {
display = "[[graphic design]]",
topical_categories = true,
}
labels["graphical user interface"] = {
aliases = {"GUI"},
display = "[[graphical user interface]]",
topical_categories = true,
}
labels["Greek mythology"] = {
display = "[[Greek]] [[mythology]]",
topical_categories = true,
}
labels["group theory"] = {
display = "[[group theory]]",
topical_categories = true,
}
labels["gun mechanisms"] = {
aliases = {"firearm mechanism", "firearm mechanisms", "gun mechanism"},
display = "[[firearm]]s",
topical_categories = true,
}
labels["gun sports"] = {
aliases = {"shooting sports"},
display = "[[gun]] [[sport]]s",
topical_categories = true,
}
labels["gymnastics"] = {
display = "[[gymnastics]]",
topical_categories = true,
}
labels["gynaecology"] = {
aliases = {"gynecology"},
display = "[[gynaecology]]",
topical_categories = true,
}
labels["hair color"] = {
display = "[[hair]] [[color]]",
topical_categories = "Hair colors",
}
labels["hairdressing"] = {
display = "[[hairdressing]]",
topical_categories = true,
}
labels["handball"] = {
display = "[[handball]]",
topical_categories = true,
}
labels["Hawaiian mythology"] = {
display = "[[Hawaiian]] [[mythology]]",
topical_categories = true,
}
labels["headwear"] = {
display = "[[clothing#Noun|clothing]]",
topical_categories = true,
}
labels["healthcare"] = {
display = "[[healthcare]]",
topical_categories = true,
}
labels["helminthology"] = {
display = "[[helminthology]]",
topical_categories = true,
}
labels["hematology"] = {
aliases = {"haematology"},
display = "[[hematology]]",
topical_categories = true,
}
labels["heraldry"] = {
display = "[[heraldry]]",
topical_categories = true,
}
labels["herbalism"] = {
display = "[[herbalism]]",
topical_categories = true,
}
labels["herpetology"] = {
display = "[[herpetology]]",
topical_categories = true,
}
labels["Hinduism"] = {
display = "[[Hinduism|သာသၞာဟိန္ဒူ]]",
topical_categories = "သာသၞာဟိန္ဒူ",
}
labels["Hindutva"] = {
display = "[[Hindutva]]",
topical_categories = true,
}
labels["historiography"] = {
display = "[[historiography]]",
topical_categories = true,
}
labels["history"] = {
display = "[[history|ဝၚ်]]",
topical_categories = "ဝၚ်",
}
labels["historical linguistics"] = {
display = "[[historical linguistics]]",
topical_categories = "Linguistics",
}
labels["hockey"] = {
display = "[[field hockey]] or [[ice hockey]]",
topical_categories = {"Field hockey", "Ice hockey"},
}
labels["homeopathy"] = {
display = "[[homeopathy]]",
topical_categories = true,
}
labels["horse color"] = {
display = "[[horse]] [[color]]",
topical_categories = "Horse colors",
}
labels["horse racing"] = {
display = "[[horse racing]]",
topical_categories = true,
}
labels["horticulture"] = {
aliases = {"gardening"},
display = "[[horticulture]]",
topical_categories = true,
}
labels["HTML"] = {
display = "[[Hypertext Markup Language|HTML]]",
topical_categories = true,
}
labels["human resources"] = {
display = "[[human resources]]",
topical_categories = true,
}
labels["humanities"] = {
display = "[[humanities]]",
topical_categories = true,
}
labels["hunting"] = {
display = "[[hunting#Noun|hunting]]",
topical_categories = true,
}
labels["hurling"] = {
display = "[[hurling#Noun|hurling]]",
topical_categories = true,
}
labels["hydroacoustics"] = {
Wikipedia = "Hydroacoustics",
topical_categories = true,
}
labels["hydrology"] = {
display = "[[hydrology]]",
topical_categories = true,
}
labels["ice hockey"] = {
display = "[[ice hockey]]",
topical_categories = true,
}
labels["ichthyology"] = {
display = "[[ichthyology]]",
topical_categories = true,
}
labels["idol fandom"] = {
display = "[[idol]] [[fandom]]",
topical_categories = true,
}
labels["immunochemistry"] = {
display = "[[immunochemistry]]",
topical_categories = true,
}
labels["immunology"] = {
display = "[[immunology]]",
topical_categories = true,
}
labels["import/export"] = {
display = "[[import#Noun|import]]/[[export#Noun|export]]",
topical_categories = true,
}
labels["Indo-European studies"] = {
aliases = {"indo-european studies"},
display = "[[Indo-European studies]]",
topical_categories = true,
}
labels["information science"] = {
display = "[[information science]]",
topical_categories = true,
}
labels["information theory"] = {
display = "[[information theory]]",
topical_categories = true,
}
labels["information technology"] = {
aliases = {"IT"},
display = "[[information technology]]",
topical_categories = "Computing",
}
labels["inheritance law"] = {
display = "[[inheritance law]]",
topical_categories = true,
}
labels["inorganic chemistry"] = {
display = "[[inorganic chemistry]]",
topical_categories = true,
}
labels["insurance"] = {
display = "[[insurance]]",
topical_categories = true,
}
labels["international law"] = {
display = "[[international law|တၚ်သၞောဝ်ဥပဒေစၟိန်ပြမာန်လဝ်နကဵုရးဍုၚ်ဂမၠိုၚ်]]",
topical_categories = "တၚ်သၞောဝ်ဥပဒေစၟိန်ပြမာန်လဝ်နကဵုရးဍုၚ်",
}
labels["international relations"] = {
display = "[[international relations|ပွမဆက်ဆေန်လဝ်နကဵုရးဍုၚ်ဂမၠိုၚ်]]",
topical_categories = "ပွမဆက်ဆေန်လဝ်နကဵုရးဍုၚ်",
}
labels["international standards"] = {
aliases = {"international standard", "ISO", "International Organization for Standardization", "International Organisation for Standardisation"},
Wikipedia = "en:International standard",
display = "တၚ်မကၞာတ်လဝ်နကဵုရးဍုၚ်ဂမၠိုၚ်",
}
labels["Internet"] = {
aliases = {"internet", "online"},
display = "[[Internet|အိန်တာနေတ်]]",
topical_categories = "အိန်တာနေတ်",
}
labels["Iranian mythology"] = {
display = "[[Iranian]] [[mythology]]",
topical_categories = true,
}
labels["Irish mythology"] = {
display = "[[Irish]] [[mythology]]",
topical_categories = true,
}
labels["Islam"] = {
aliases = {"islam", "Islamic", "Muslim"},
Wikipedia = "အေဿလာမ်",
display = "အေတ်ဿလာမ်",
topical_categories = "အေတ်ဿလာမ်",
}
labels["Islamic finance"] = {
aliases = {"Islamic banking", "Muslim finance", "Muslim banking", "Sharia-compliant finance"},
Wikipedia = "Islamic finance",
topical_categories = true,
}
labels["Islamic law"] = {
aliases = {"Islamic legal", "Sharia"},
Wikipedia = "Sharia",
topical_categories = true,
}
labels["Jainism"] = {
display = "[[Jainism]]",
topical_categories = true,
}
labels["Japanese god"] = {
display = "[[Japanese]] [[mythology]]",
topical_categories = "Japanese deities",
}
labels["Japanese mythology"] = {
display = "[[Japanese]] [[mythology]]",
topical_categories = true,
}
labels["Java programming language"] = {
aliases = {"JavaPL", "Java PL"},
display = "[[w:Java (programming language)|Java programming language]]",
topical_categories = true,
}
labels["jazz"] = {
display = "[[jazz#Noun|jazz]]",
topical_categories = true,
}
labels["jewelry"] = {
aliases = {"jewellery"},
display = "[[jewelry]]",
topical_categories = true,
}
labels["Jewish law"] = {
aliases = {"Halacha", "Halachah", "Halakha", "Halakhah", "halacha", "halachah", "halakha", "halakhah", "Jewish Law", "jewish law"},
display = "[[Jewish]] [[law]]",
topical_categories = true,
}
labels["Germanic paganism"] = {
aliases = {"Asatru", "Ásatrú", "Germanic neopaganism", "Germanic Paganism", "Heathenry", "heathenry", "Norse neopaganism", "Norse paganism"},
display = "[[Germanic#Adjective|Germanic]] [[paganism]]",
topical_categories = true,
}
labels["journalism"] = {
display = "[[journalism]]",
topical_categories = "Mass media",
}
labels["Judaism"] = {
display = "[[Judaism]]",
topical_categories = true,
}
labels["judo"] = {
display = "[[judo]]",
topical_categories = true,
}
labels["juggling"] = {
display = "[[juggling#Noun|juggling]]",
topical_categories = true,
}
labels["karuta"] = {
display = "[[karuta]]",
topical_categories = true,
}
labels["kendo"] = {
display = "[[kendo]]",
topical_categories = true,
}
labels["knitting"] = {
display = "[[knitting#Noun|knitting]]",
topical_categories = true,
}
labels["labour"] = {
aliases = {"labor", "labour movement", "labor movement"},
display = "[[labour]]",
topical_categories = true,
}
labels["lacrosse"] = {
display = "[[lacrosse]]",
topical_categories = true,
}
labels["law"] = {
aliases = {"legal"},
display = "[[law#English|law]]",
topical_categories = true,
}
labels["law enforcement"] = {
aliases = {"police", "policing"},
display = "[[law enforcement]]",
topical_categories = true,
}
labels["leftism"] = {
display = "[[leftism]]",
topical_categories = true,
}
labels["letterpress"] = {
aliases = {"metal type", "metal typesetting"},
display = "[[letterpress]] [[typography]]",
topical_categories = "Typography",
}
labels["lexicography"] = {
display = "[[lexicography]]",
topical_categories = true,
}
labels["LGBTQ"] = {
aliases = {"LGBT", "LGBT+", "LGBT*", "LGBTQ+", "LGBTQ*", "LGBTQIA", "LGBTQIA+", "LGBTQIA*"},
display = "[[LGBTQ]]",
topical_categories = true,
}
labels["liberalism"] = {
display = "[[liberalism]]",
topical_categories = true,
}
labels["library science"] = {
display = "[[library science]]",
topical_categories = true,
}
labels["lichenology"] = {
display = "[[lichenology]]",
topical_categories = true,
}
labels["limnology"] = {
display = "[[limnology]]",
topical_categories = "Ecology",
}
labels["lipid"] = {
display = "[[biochemistry]]",
topical_categories = "Lipids",
}
labels["linear algebra"] = {
aliases = {"vector algebra"},
display = "[[linear algebra]]",
topical_categories = true,
}
labels["linguistic morphology"] = {
display = "[[linguistic]] [[morphology]]",
topical_categories = true,
}
labels["linguistics"] = {
aliases = {"philology"},
display = "[[linguistics|ကွတ်ဘာသာဗေဒ]]",
topical_categories = "ကွတ်ဘာသာဗေဒ",
}
labels["literature"] = {
display = "[[literature|လိက်ပတ်]]",
topical_categories = "လိက်ပတ်",
}
labels["logic"] = {
display = "[[logic]]",
topical_categories = true,
}
labels["logistics"] = {
display = "[[logistics]]",
topical_categories = true,
}
labels["luge"] = {
display = "[[luge]]",
topical_categories = true,
}
labels["machining"] = {
display = "[[machining#Noun|machining]]",
topical_categories = true,
}
labels["machine learning"] = {
aliases = {"ML"},
display = "[[machine learning]]",
topical_categories = true,
}
labels["macroeconomics"] = {
display = "[[macroeconomics]]",
topical_categories = "Economics",
}
labels["mahjong"] = {
display = "[[mahjong]]",
topical_categories = true,
}
labels["malacology"] = {
display = "[[malacology]]",
topical_categories = true,
}
labels["mammalogy"] = {
display = "[[mammalogy]]",
topical_categories = true,
}
labels["management"] = {
display = "[[management]]",
topical_categories = true,
}
labels["manga"] = {
display = "[[manga]]",
topical_categories = "Japanese fiction",
}
labels["manhua"] = {
display = "[[manhua]]",
topical_categories = "Chinese fiction",
}
labels["manhwa"] = {
display = "[[manhwa]]",
topical_categories = "Korean fiction",
}
labels["Manichaeism"] = {
display = "[[Manichaeism]]",
topical_categories = true,
}
labels["manufacturing"] = {
display = "[[manufacturing#Noun|manufacturing]]",
topical_categories = true,
}
labels["Maoism"] = {
display = "[[Maoism]]",
topical_categories = true,
}
labels["marching"] = {
display = "[[marching#Noun|marching]]",
topical_categories = true,
}
labels["marine biology"] = {
aliases = {"coral science"},
display = "[[marine biology]]",
topical_categories = true,
}
labels["marketing"] = {
display = "[[marketing#Noun|marketing]]",
topical_categories = true,
}
labels["martial arts"] = {
display = "[[martial arts]]",
topical_categories = true,
}
labels["Marxism"] = {
display = "[[Marxism]]",
topical_categories = true,
}
labels["masonry"] = {
display = "[[masonry]]",
topical_categories = true,
}
labels["massage"] = {
display = "[[massage]]",
topical_categories = true,
}
labels["materials science"] = {
display = "[[materials science]]",
topical_categories = true,
}
labels["mathematical analysis"] = {
aliases = {"analysis"},
display = "[[mathematical analysis]]",
topical_categories = true,
}
labels["mathematics"] = {
aliases = {"math", "maths"},
display = "[[mathematics]]",
topical_categories = true,
}
labels["measure theory"] = {
display = "[[measure theory]]",
topical_categories = true,
}
labels["mechanical engineering"] = {
display = "[[mechanical engineering]]",
topical_categories = true,
}
labels["mechanics"] = {
display = "[[mechanics]]",
topical_categories = true,
}
labels["media"] = {
display = "[[media]]",
topical_categories = true,
}
labels["mediaeval folklore"] = {
aliases = {"medieval folklore"},
display = "[[mediaeval]] [[folklore]]",
topical_categories = "European folklore",
}
labels["medical genetics"] = {
display = "[[medical]] [[genetics]]",
topical_categories = true,
}
labels["medical sign"] = {
display = "[[medicine]]",
topical_categories = "Medical signs and symptoms",
}
labels["medicine"] = {
aliases = {"medical"},
display = "[[medicine]]",
topical_categories = true,
}
labels["Meitei god"] = {
display = "[[Meitei]] [[mythology]]",
topical_categories = "Meitei deities",
}
labels["mental health"] = {
display = "[[mental health]]",
topical_categories = true,
}
labels["Mesopotamian mythology"] = {
display = "[[Mesopotamian]] [[mythology]]",
topical_categories = true,
}
labels["metadata"] = {
display = "[[metadata]]",
topical_categories = "Data management",
}
labels["metallurgy"] = {
display = "[[metallurgy]]",
topical_categories = true,
}
labels["metalworking"] = {
display = "[[metalworking]]",
topical_categories = true,
}
labels["metaphysics"] = {
display = "[[metaphysics]]",
topical_categories = true,
}
labels["meteorology"] = {
display = "[[meteorology]]",
topical_categories = true,
}
labels["Methodism"] = {
aliases = {"Methodist", "methodism", "methodist"},
display = "[[Methodism]]",
topical_categories = true,
}
labels["metrology"] = {
display = "[[metrology|ကွတ်ဗေဒနက်သတ်]]",
topical_categories = "ကွတ်ဗေဒနက်သတ်",
}
labels["microbiology"] = {
display = "[[microbiology]]",
topical_categories = true,
}
labels["microelectronics"] = {
display = "[[microelectronics]]",
topical_categories = true,
}
labels["micronationalism"] = {
display = "[[micronationalism]]",
topical_categories = true,
}
labels["microscopy"] = {
display = "[[microscopy]]",
topical_categories = true,
}
labels["milling"] = {
display = "[[milling]]",
topical_categories = true,
}
labels["military"] = {
display = "[[military|ပရေၚ်ပၞာန်]]",
topical_categories = "ပရေၚ်ပၞာန်",
}
labels["mineralogy"] = {
display = "[[mineralogy]]",
topical_categories = true,
}
labels["mining"] = {
display = "[[mining#Noun|mining]]",
topical_categories = true,
}
labels["molecular biology"] = {
display = "[[molecular biology]]",
topical_categories = true,
}
labels["monarchy"] = {
display = "[[monarchy]]",
topical_categories = true,
}
labels["money"] = {
display = "[[money |ကွတ်ပညာဂြပ်ရတ်]]",
topical_categories = "ကွတ်ပညာဂြပ်ရတ်",
}
labels["Mormonism"] = {
display = "[[Mormonism]]",
topical_categories = true,
}
labels["motorcycling"] = {
aliases = {"motorcycle", "motorcycles", "motorbike"},
display = "[[motorcycling#Noun|motorcycling]]",
topical_categories = "Motorcycles",
}
-- There are other types of racing, but 99% of the time "racing" on its own refers to motorsports
labels["motor racing"] = {
aliases = {"motor sport", "motorsport", "motorsports", "racing"},
display = "[[motor racing]]",
topical_categories = true,
}
labels["multiplicity"] = {
display = "{{l|en|multiplicity|id=multiple personalities}}",
topical_categories = "Multiplicity (psychology)",
}
labels["music"] = {
display = "[[music|ဂဳတ]]",
topical_categories = "ဂဳတ",
}
labels["music industry"] = {
Wikipedia = "Music industry",
topical_categories = true,
}
labels["mycology"] = {
display = "[[mycology]]",
topical_categories = true,
}
labels["mythology"] = {
display = "[[mythology]]",
topical_categories = true,
}
labels["nanotechnology"] = {
display = "[[nanotechnology]]",
topical_categories = true,
}
labels["narratology"] = {
display = "[[narratology]]",
topical_categories = true,
}
labels["nautical"] = {
display = "[[nautical]]",
topical_categories = true,
}
labels["navigation"] = {
display = "[[navigation]]",
topical_categories = true,
}
labels["Nazism"] = { -- see also Neo-Nazism
aliases = {"nazism", "Nazi", "nazi", "Nazis", "nazis"},
Wikipedia = "Nazism",
topical_categories = true,
}
labels["nematology"] = {
display = "[[nematology]]",
topical_categories = "Zoology",
}
labels["neo-Nazism"] = { -- but also this is often used to indicate Nazi-used jargon; cf "white supremacist ideology"
aliases = {"Neo-Nazism", "Neo-nazism", "neo-nazism", "Neo-Nazi", "Neo-nazi", "neo-Nazi", "neo-nazi", "Neo-Nazis", "Neo-nazis", "neo-Nazis", "neo-nazis", "NeoNazism", "Neonazism", "neoNazism", "neonazism", "NeoNazi", "Neonazi", "neoNazi", "neonazi", "NeoNazis", "Neonazis", "neoNazis", "neonazis"},
Wikipedia = "Neo-Nazism",
topical_categories = true,
}
labels["netball"] = {
display = "[[netball]]",
topical_categories = true,
}
labels["networking"] = {
display = "[[networking#Noun|networking]]",
topical_categories = true,
}
labels["neuroanatomy"] = {
display = "[[neuroanatomy]]",
topical_categories = true,
}
labels["neurology"] = {
display = "[[neurology]]",
topical_categories = true,
}
labels["neuroscience"] = {
display = "[[neuroscience]]",
topical_categories = true,
}
labels["neurosurgery"] = {
display = "[[neurosurgery]]",
topical_categories = true,
}
labels["newspapers"] = {
display = "[[newspaper]]s",
topical_categories = true,
}
labels["Norse god"] = {
aliases = {"Norse goddess", "Norse deity"},
display = "[[Norse]] [[mythology]]",
topical_categories = "Norse deities",
}
labels["Norse mythology"] = {
display = "[[Norse]] [[mythology]]",
topical_categories = true,
}
labels["nuclear physics"] = {
display = "[[nuclear physics]]",
topical_categories = true,
}
labels["number theory"] = {
display = "[[number theory]]",
topical_categories = true,
}
labels["numismatics"] = {
display = "[[numismatics]]",
topical_categories = "Currency",
}
labels["nutrition"] = {
display = "[[nutrition]]",
topical_categories = true,
}
labels["object-oriented programming"] = {
aliases = {"object-oriented", "OOP"},
display = "[[object-oriented programming]]",
topical_categories = true,
}
labels["obstetrics"] = {
aliases = {"obstetric"},
display = "[[obstetrics]]",
topical_categories = true,
}
labels["occult"] = {
display = "[[occult]]",
topical_categories = true,
}
labels["oceanography"] = {
display = "[[oceanography]]",
topical_categories = true,
}
labels["oenology"] = {
display = "[[oenology]]",
topical_categories = true,
}
labels["oil industry"] = {
aliases = {"oil drilling"},
display = "[[w:Petroleum industry|oil industry]]",
topical_categories = true,
}
labels["oncology"] = {
display = "[[oncology]]",
topical_categories = true,
}
labels["online gaming"] = {
aliases = {"online games", "MMO", "MMORPG"},
display = "[[online]] [[gaming#Noun|gaming]]",
topical_categories = "Video games",
}
labels["opera"] = {
display = "[[opera]]",
topical_categories = true,
}
labels["operating systems"] = {
display = "[[operating system]]s",
topical_categories = "Software",
}
labels["ophthalmology"] = {
display = "[[ophthalmology]]",
topical_categories = true,
}
labels["optics"] = {
display = "[[optics]]",
topical_categories = true,
}
labels["organic chemistry"] = {
display = "[[organic chemistry|ကွတ်ဗေဒဓါတုအာဝ်ဂဲနေတ်]]",
topical_categories = "ကွတ်ဗေဒဓါတုအာဝ်ဂဲနေတ်",
}
labels["ornithology"] = {
display = "[[ornithology]]",
topical_categories = true,
}
labels["orthodontics"] = {
display = "[[orthodontics]]",
topical_categories = "Dentistry",
}
labels["orthography"] = {
display = "[[orthography]]",
topical_categories = true,
}
labels["paganism"] = {
aliases = {"pagan", "neopagan", "neopaganism", "neo-pagan", "neo-paganism"},
display = "[[paganism]]",
topical_categories = true,
}
labels["pain"] = {
display = "[[medicine]]",
topical_categories = true,
}
labels["paintball"] = {
display = "[[paintball]]",
topical_categories = true,
}
labels["painting"] = {
display = "[[painting#Noun|painting]]",
topical_categories = true,
}
labels["palaeography"] = {
aliases = {"paleography"},
display = "[[palaeography]]",
topical_categories = true,
}
labels["paleontology"] = {
aliases = {"palaeontology"},
display = "[[paleontology]]",
topical_categories = true,
}
labels["palmistry"] = {
display = "[[palmistry]]",
topical_categories = true,
}
labels["palynology"] = {
display = "[[palynology]]",
topical_categories = true,
}
labels["parapsychology"] = {
display = "[[parapsychology]]",
topical_categories = true,
}
labels["parasitology"] = {
display = "[[parasitology]]",
topical_categories = true,
}
labels["particle physics"] = {
display = "[[particle physics]]",
topical_categories = true,
}
labels["pasteurisation"] = {
display = "[[pasteurisation]]",
topical_categories = true,
}
labels["patent law"] = {
aliases = {"patents"},
display = "[[patent#Noun|patent]] [[law]]",
topical_categories = true,
}
labels["pathology"] = {
display = "[[pathology]]",
topical_categories = true,
}
labels["pensions"] = {
display = "[[pension]]s",
topical_categories = true,
}
labels["pesäpallo"] = {
aliases = {"pesapallo"},
display = "[[pesäpallo]]",
topical_categories = true,
}
labels["petrochemistry"] = {
display = "[[petrochemistry]]",
topical_categories = true,
}
labels["petrology"] = {
display = "[[petrology]]",
topical_categories = true,
}
labels["pharmacology"] = {
display = "[[pharmacology]]",
topical_categories = true,
}
labels["pharmacy"] = {
display = "[[pharmacy]]",
topical_categories = true,
}
labels["pharyngology"] = {
display = "[[pharyngology]]",
topical_categories = true,
}
labels["philately"] = {
display = "[[philately]]",
topical_categories = true,
}
labels["philosophy"] = {
display = "[[philosophy]]",
topical_categories = true,
}
labels["phonetics"] = {
display = "[[phonetics]]",
topical_categories = true,
}
labels["phonology"] = {
display = "[[phonology]]",
topical_categories = true,
}
labels["photography"] = {
display = "[[photography]]",
topical_categories = true,
}
labels["phrenology"] = {
display = "[[phrenology]]",
topical_categories = true,
}
labels["physical chemistry"] = {
display = "[[physical chemistry]]",
topical_categories = true,
}
labels["physics"] = {
display = "[[physics]]",
topical_categories = true,
}
labels["physiology"] = {
display = "[[physiology]]",
topical_categories = true,
}
labels["phytopathology"] = {
display = "[[phytopathology]]",
topical_categories = true,
}
labels["pinball"] = {
display = "[[pinball]]",
topical_categories = true,
}
labels["planetology"] = {
display = "[[planetology]]",
topical_categories = true,
}
labels["playground games"] = {
aliases = {"playground game"},
display = "[[playground]] [[game]]s",
topical_categories = true,
}
labels["poetry"] = {
display = "[[poetry]]",
topical_categories = true,
}
labels["Pokémon"] = {
display = "''[[w:Pokémon|Pokémon]]''",
topical_categories = true,
}
labels["poker"] = {
display = "[[poker]]",
topical_categories = true,
}
labels["poker slang"] = {
display = "[[poker]] [[slang]]",
topical_categories = "Poker",
}
labels["political science"] = {
display = "[[political science]]",
topical_categories = true,
}
labels["politics"] = {
aliases = {"political"},
display = "[[politics]]",
topical_categories = true,
}
labels["Australian politics"] = {
display = "[[w:Politics of Australia|Australian politics]]",
topical_categories = true,
}
labels["Canadian politics"] = {
display = "[[w:Politics of Canada|Canadian politics]]",
topical_categories = true,
}
labels["European politics"] = {
display = "[[w:Politics of Europe|European politics]]",
topical_categories = true,
}
labels["EU politics"] = {
display = "[[w:Politics of the European Union|EU politics]]",
topical_categories = true,
}
labels["French politics"] = {
display = "[[w:Politics of France|French politics]]",
topical_categories = true,
}
labels["German politics"] = {
display = "[[w:Politics of Germany|German politics]]",
topical_categories = true,
}
labels["Hong Kong politics"] = {
aliases = {"HK politics"},
display = "[[w:Politics of Hong Kong|HK politics]]",
topical_categories = true,
}
labels["Indian politics"] = {
display = "[[w:Politics of India|Indian politics]]",
topical_categories = true,
}
labels["Indonesian politics"] = {
aliases = {"Indonesia politics"},
display = "[[w:Politics of Indonesia|Indonesian politics]]",
topical_categories = true,
}
labels["Irish politics"] = {
display = "[[w:Politics of the Republic of Ireland|Irish politics]]",
topical_categories = true,
}
labels["Malaysian politics"] = {
aliases = {"Malaysia politics"},
display = "[[w:Politics of Malaysia|Malaysian politics]]",
topical_categories = true,
}
labels["New Zealand politics"] = {
display = "[[w:Politics of New Zealand|New Zealand politics]]",
topical_categories = true,
}
labels["Pakistani politics"] = {
display = "[[w:Politics of Pakistan|Pakistani politics]]",
topical_categories = true,
}
labels["Palestinian politics"] = {
aliases = {"Palestine politics"},
display = "[[w:Politics of the Palestinian National Authority|Palestinian politics]]",
topical_categories = true,
}
labels["Philippine politics"] = {
aliases = {"Filipino politics"},
display = "[[w:Politics of the Philippines|Philippine politics]]",
topical_categories = true,
}
labels["Philmont Scout Ranch"] = {
aliases = {"Philmont"},
display = "[[w:Philmont Scout Ranch|Philmont Scout Ranch]]",
topical_categories = true,
}
labels["Spanish politics"] = {
display = "[[w:Politics of Spain|Spanish politics]]",
topical_categories = true,
}
labels["Swiss politics"] = {
display = "[[w:Politics of Switzerland|Swiss politics]]",
topical_categories = true,
}
labels["UK politics"] = {
display = "[[w:Politics of the United Kingdom|UK politics]]",
topical_categories = true,
}
labels["UN"] = {
display = "[[United Nations|UN]]",
topical_categories = "United Nations",
}
labels["US politics"] = {
display = "[[w:Politics of the United States|US politics]]",
topical_categories = true,
}
labels["pornography"] = {
aliases = {"porn", "porno"},
display = "[[pornography]]",
topical_categories = true,
}
labels["Portuguese folklore"] = {
display = "[[Portuguese#Adjective|Portuguese]] [[folklore]]",
topical_categories = "European folklore",
}
labels["post"] = {
display = "[[post#Etymology 2|post]]",
topical_categories = true,
}
labels["potential theory"] = {
display = "[[potential theory]]",
topical_categories = true,
}
labels["pottery"] = {
display = "[[pottery]]",
topical_categories = "Ceramics",
}
labels["pragmatics"] = {
display = "[[pragmatics]]",
topical_categories = true,
}
labels["printing"] = {
display = "[[printing#Noun|printing]]",
topical_categories = true,
}
labels["probability theory"] = {
display = "[[probability theory]]",
topical_categories = true,
}
labels["professional wrestling"] = {
aliases = {"pro wrestling"},
display = "[[professional wrestling]]",
topical_categories = true,
}
labels["programming"] = {
aliases = {"computer programming"},
display = "[[programming#Noun|programming]]",
topical_categories = true,
}
labels["property law"] = {
aliases = {"land law", "real estate law"},
display = "[[property law]]",
topical_categories = true,
}
labels["prosody"] = {
display = "[[prosody]]",
topical_categories = true,
}
labels["Protestantism"] = {
aliases = {"protestantism", "Protestant", "protestant"},
display = "[[Protestantism]]",
topical_categories = true,
}
labels["pseudoscience"] = {
display = "[[pseudoscience]]",
topical_categories = true,
}
labels["psychiatry"] = {
display = "[[psychiatry]]",
topical_categories = true,
}
labels["psychoanalysis"] = {
display = "[[psychoanalysis]]",
topical_categories = true,
}
labels["psychology"] = {
display = "[[psychology]]",
topical_categories = true,
}
labels["psychotherapy"] = {
display = "[[psychotherapy]]",
topical_categories = true,
}
labels["publishing"] = {
display = "[[publishing#Noun|publishing]]",
topical_categories = true,
}
labels["pulmonology"] = {
display = "[[pulmonology]]",
topical_categories = true,
}
labels["pyrotechnics"] = {
display = "[[pyrotechnics]]",
topical_categories = true,
}
labels["QAnon"] = {
aliases = {"Qanon"},
Wikipedia = "QAnon",
topical_categories = true,
}
labels["Quakerism"] = {
display = "[[Quakerism]]",
topical_categories = true,
}
labels["quantum computing"] = {
display = "[[quantum computing]]",
topical_categories = true,
}
labels["quantum mechanics"] = {
aliases = {"quantum physics"},
display = "[[quantum mechanics]]",
topical_categories = true,
}
-- TODO: What kind of topic is "radiation"? Is it specific kinds of radiation? That would be a set-type category.
labels["radiation"] = {
display = "[[physics]]",
topical_categories = true,
}
labels["radio"] = {
display = "[[radio]]",
topical_categories = true,
}
labels["Raëlism"] = {
display = "[[Raëlism]]",
topical_categories = true,
}
labels["rail transport"] = {
aliases = {"rail", "railroading", "railroads"},
display = "[[rail transport]]",
topical_categories = "Rail transportation",
}
labels["Rastafari"] = {
aliases = {"Rasta", "rasta", "Rastafarian", "rastafarian", "Rastafarianism"},
display = "[[Rastafari]]",
topical_categories = true,
}
labels["real estate"] = {
display = "[[real estate]]",
topical_categories = true,
}
labels["real tennis"] = {
display = "[[real tennis]]",
topical_categories = "Tennis",
}
labels["recreational mathematics"] = {
display = "[[recreational mathematics]]",
topical_categories = "Mathematics",
}
labels["Reddit"] = {
display = "[[Reddit]]",
topical_categories = true,
}
labels["regular expressions"] = {
aliases = {"regex"},
display = "[[regular expression]]s",
topical_categories = true,
}
labels["relativity"] = {
display = "[[relativity]]",
topical_categories = true,
}
labels["religion"] = {
display = "[[religion]]",
topical_categories = true,
}
labels["rhetoric"] = {
display = "[[rhetoric]]",
topical_categories = true,
}
labels["road transport"] = {
aliases = {"roads"},
display = "[[w:road transport|road transport]]",
topical_categories = true,
}
labels["robotics"] = {
display = "[[robotics]]",
topical_categories = true,
}
labels["rock paper scissors"] = {
topical_categories = true,
}
labels["roleplaying games"] = {
aliases = {"role playing games", "role-playing games", "RPG", "RPGs"},
display = "[[roleplaying game]]s",
topical_categories = "Role-playing games",
}
labels["roller derby"] = {
display = "[[roller derby]]",
topical_categories = true,
}
labels["Roman Catholicism"] = {
aliases = {"Roman Catholic", "Roman Catholic Church"},
display = "[[Roman Catholicism|ဘာသာကာတ်တလေတ်ရဝ်မာန်]]",
topical_categories = "ကာတ်တလေတ်ရဝ်မာန်",
}
labels["Roman Empire"] = {
display = "[[Roman Empire]]",
topical_categories = true,
}
labels["Roman mythology"] = {
display = "[[Roman]] [[mythology]]",
topical_categories = true,
}
labels["Roman numerals"] = {
display = "[[Roman numeral]]s",
topical_categories = true,
}
labels["roofing"] = {
display = "[[roofing#Noun|roofing]]",
topical_categories = true,
}
labels["rosiculture"] = {
display = "[[rosiculture]]",
topical_categories = true,
}
labels["rowing"] = {
display = "[[rowing#Noun|rowing]]",
topical_categories = true,
}
labels["Rubik's Cube"] = {
aliases = {"Rubik's cubes"},
display = "[[Rubik's Cube]]",
topical_categories = true,
}
labels["rugby"] = {
display = "[[rugby]]",
topical_categories = true,
}
labels["rugby league"] = {
display = "[[rugby league]]",
topical_categories = true,
}
labels["rugby union"] = {
display = "[[rugby union]]",
topical_categories = true,
}
labels["sailing"] = {
display = "[[sailing#Noun|sailing]]",
topical_categories = true,
}
labels["science fiction"] = {
aliases = {"scifi", "sci fi", "sci-fi"},
display = "[[science fiction]]",
topical_categories = true,
}
labels["sciences"] = {
aliases = {"science", "scientific"},
display = "[[sciences]]",
topical_categories = true,
}
labels["Scientology"] = {
display = "[[Scientology]]",
topical_categories = true,
}
-- Note: this is the usual term, not "Scottish law".
labels["Scots law"] = {
aliases = {"Scottish law", "Scotland law", "Scots Law", "Scottish Law", "Scotland Law"},
Wikipedia = true,
topical_categories = true,
}
labels["Scouting"] = {
aliases = {"scouting"},
display = "[[scouting]]",
topical_categories = true,
}
labels["Scrabble"] = {
display = "''[[Scrabble]]''",
topical_categories = true,
}
labels["scrapbooks"] = {
display = "[[scrapbook]]s",
topical_categories = true,
}
labels["sculpture"] = {
display = "[[sculpture]]",
topical_categories = true,
}
labels["seduction community"] = {
display = "[[w:Seduction community|seduction community]]",
topical_categories = true,
}
labels["seismology"] = {
display = "[[seismology]]",
topical_categories = true,
}
labels["semantics"] = {
display = "[[semantics]]",
topical_categories = true,
}
labels["semiotics"] = {
display = "[[semiotics]]",
topical_categories = true,
}
labels["semiconductors"] = {
display = "[[semiconductor]]s",
topical_categories = true,
}
labels["set theory"] = {
display = "[[set theory]]",
topical_categories = true,
}
labels["sewing"] = {
display = "[[sewing#Noun|sewing]]",
topical_categories = true,
}
labels["sex"] = {
display = "[[sex|လိၚ်]]",
topical_categories = "လိၚ်",
}
labels["sexology"] = {
display = "[[sexology]]",
topical_categories = true,
}
labels["sex position"] = {
display = "[[sex]]",
topical_categories = "Sex positions",
}
labels["sexuality"] = {
display = "[[sexuality]]",
topical_categories = true,
}
labels["Shaivism"] = {
display = "[[Shaivism]]",
topical_categories = true,
}
labels["shamanism"] = {
aliases = {"Shamanism"},
display = "[[shamanism]]",
topical_categories = true,
}
labels["Shi'ism"] = {
aliases = {"Shia", "Shi'ite", "Shi'i"},
display = "[[Shia Islam]]",
topical_categories = true,
}
labels["Shinto"] = {
display = "[[Shinto]]",
topical_categories = true,
}
labels["ship parts"] = {
display = "[[nautical]]",
topical_categories = "Ship parts",
}
labels["shipping"] = {
display = "[[shipping#Noun|shipping]]",
topical_categories = true,
}
labels["shoemaking"] = {
display = "[[shoemaking]]",
topical_categories = true,
}
labels["shogi"] = {
display = "[[shogi]]",
topical_categories = true,
}
labels["signal processing"] = {
display = "[[w:Signal processing|signal processing]]",
topical_categories = true,
}
labels["Sikhism"] = {
display = "[[Sikhism]]",
topical_categories = true,
}
labels["singing"] = {
display = "[[singing#Noun|singing]]",
topical_categories = true,
}
labels["skateboarding"] = {
display = "[[skateboarding#Noun|skateboarding]]",
topical_categories = true,
}
labels["skating"] = {
display = "[[skating#Noun|skating]]",
topical_categories = true,
}
labels["skiing"] = {
display = "[[skiing#Noun|skiing]]",
topical_categories = true,
}
labels["Slavic god"] = {
display = "[[Slavic]] [[mythology]]",
topical_categories = "Slavic deities",
}
labels["Slavic mythology"] = {
display = "[[Slavic]] [[mythology]]",
topical_categories = true,
}
labels["smoking"] = {
display = "[[smoking#Noun|smoking]]",
topical_categories = true,
}
labels["snooker"] = {
display = "[[snooker#Noun|snooker]]",
topical_categories = true,
}
labels["snowboarding"] = {
display = "[[snowboarding#Noun|snowboarding]]",
topical_categories = true,
}
labels["soccer"] = {
aliases = {"football", "association football"},
display = "[[soccer]]",
topical_categories = "Football (soccer)",
}
labels["social sciences"] = {
aliases = {"social science"},
display = "[[social science]]s",
topical_categories = true,
}
labels["socialism"] = {
display = "[[socialism]]",
topical_categories = true,
}
labels["social media"] = {
display = "[[social media]]",
topical_categories = true,
}
labels["sociolinguistics"] = {
display = "[[sociolinguistics]]",
topical_categories = true,
}
labels["sociology"] = {
display = "[[sociology]]",
topical_categories = true,
}
labels["softball"] = {
display = "[[softball]]",
topical_categories = true,
}
labels["software"] = {
display = "[[software]]",
topical_categories = true,
}
labels["software architecture"] = {
display = "[[software architecture]]",
topical_categories = {"Software engineering", "Programming"},
}
labels["software engineering"] = {
aliases = {"software development"},
display = "[[software engineering]]",
topical_categories = true,
}
labels["soil science"] = {
display = "[[soil science]]",
topical_categories = true,
}
labels["sound"] = {
display = "[[sound#Noun|sound]]",
topical_categories = true,
}
labels["sound engineering"] = {
display = "[[sound engineering]]",
topical_categories = true,
}
labels["South Korean idol fandom"] = {
display = "[[South Korean]] [[idol]] [[fandom]]",
topical_categories = true,
}
labels["South Park"] = {
display = "''[[w:South Park|South Park]]''",
topical_categories = true,
}
labels["Soviet Union"] = {
aliases = {"USSR"},
display = "[[Soviet Union]]",
topical_categories = true,
}
labels["space flight"] = {
aliases = {"spaceflight", "space travel"},
display = "[[space flight]]",
topical_categories = "Space",
}
labels["space science"] = {
aliases = {"space"},
display = "[[space science]]",
topical_categories = "Space",
}
labels["spectroscopy"] = {
display = "[[spectroscopy]]",
topical_categories = true,
}
labels["speedrunning"] = {
aliases = {"speedrun", "speedruns"},
display = "[[speedrunning]]",
topical_categories = true,
}
labels["spinning"] = {
display = "[[spinning]]",
topical_categories = true,
}
labels["spiritualism"] = {
display = "[[spiritualism]]",
topical_categories = true,
}
labels["sports"] = {
aliases = {"sport"},
display = "[[sports]]",
topical_categories = true,
}
labels["squash"] = {
display = "[[w:squash (sport)|squash]]",
topical_categories = true,
}
labels["statistical mechanics"] = {
display = "[[statistical mechanics]]",
topical_categories = true,
}
labels["statistics"] = {
display = "[[statistics]]",
topical_categories = true,
}
labels["Star Wars"] = {
display = "''[[Star Wars]]''",
topical_categories = true,
}
labels["stock market"] = {
display = "[[stock market]]",
topical_categories = true,
}
labels["stock ticker symbol"] = {
aliases = {"stock symbol"},
display = "[[stock ticker symbol]]",
topical_categories = "Stock symbols for companies",
}
labels["subculture"] = {
display = "[[subculture]]",
topical_categories = "Culture",
}
labels["Sufism"] = {
aliases = {"Sufi Islam"},
display = "[[w:Sufism|Sufism]]",
topical_categories = true,
}
labels["sumo"] = {
display = "[[sumo]]",
topical_categories = true,
}
labels["supply chain"] = {
display = "[[supply chain]]",
topical_categories = true,
}
labels["surfing"] = {
display = "[[surfing#Noun|surfing]]",
topical_categories = true,
}
labels["surgery"] = {
display = "[[surgery]]",
topical_categories = true,
}
labels["surveying"] = {
display = "[[surveying#Noun|surveying]]",
topical_categories = true,
}
labels["sushi"] = {
display = "[[sushi]]",
topical_categories = true,
}
labels["swimming"] = {
display = "[[swimming#Noun|swimming]]",
topical_categories = true,
}
labels["swords"] = {
display = "[[sword]]s",
topical_categories = true,
}
labels["systematics"] = {
display = "[[systematics]]",
topical_categories = "Taxonomy",
}
labels["systems engineering"] = {
display = "[[systems engineering]]",
topical_categories = true,
}
labels["systems theory"] = {
display = "[[systems theory]]",
topical_categories = true,
}
labels["table tennis"] = {
display = "[[table tennis]]",
topical_categories = true,
}
labels["Taoism"] = {
aliases = {"Daoism"},
display = "[[Taoism]]",
topical_categories = true,
}
labels["tarot"] = {
display = "[[tarot]]",
topical_categories = "Cartomancy",
}
labels["taxation"] = {
aliases = {"tax", "taxes"},
display = "[[taxation]]",
topical_categories = true,
}
labels["taxonomy"] = {
display = "[[taxonomy]]",
topical_categories = true,
}
labels["technology"] = {
display = "[[technology|ကွတ်ပညာစက်]]",
topical_categories = "ကွတ်ပညာစက်",
}
labels["telecommunications"] = {
aliases = {"telecommunication", "telecom"},
display = "[[telecommunications]]",
topical_categories = true,
}
labels["telegraphy"] = {
display = "[[telegraphy]]",
topical_categories = true,
}
labels["telephony"] = {
aliases = {"telephone", "telephones"},
display = "[[telephony]]",
topical_categories = true,
}
labels["television"] = {
aliases = {"TV"},
display = "[[television]]",
topical_categories = true,
}
labels["Tumblr aesthetic"] = {
display = "[[Tumblr]] aesthetic",
topical_categories = "Aesthetics",
}
labels["tennis"] = {
display = "[[tennis]]",
topical_categories = true,
}
labels["teratology"] = {
display = "[[teratology]]",
topical_categories = true,
}
labels["Tetris"] = {
display = "[[Tetris]]",
topical_categories = true,
}
labels["textiles"] = {
display = "[[textiles]]",
topical_categories = true,
}
labels["theater"] = {
aliases = {"theatre"},
display = "[[theater]]",
topical_categories = true,
}
labels["theology"] = {
display = "[[theology]]",
topical_categories = true,
}
labels["thermodynamics"] = {
display = "[[thermodynamics]]",
topical_categories = true,
}
labels["Tibetan Buddhism"] = {
display = "[[Tibetan Buddhism |ဗုဒ္ဓဘာသာတိဗိတ်]]",
topical_categories = "ဗုဒ္ဓဘာသာ",
}
labels["tiddlywinks"] = {
display = "[[tiddlywinks]]",
topical_categories = true,
}
labels["TikTok aesthetic"] = {
display = "[[TikTok]] aesthetic",
topical_categories = "Aesthetics",
}
labels["time"] = {
display = "[[time|အခိၚ်]]",
topical_categories = "အခိၚ်",
}
labels["topology"] = {
display = "[[topology]]",
topical_categories = true,
}
labels["tort law"] = {
display = "[[tort law]]",
topical_categories = "Law",
}
labels["tourism"] = {
display = "[[tourism]]",
topical_categories = true,
}
labels["toxicology"] = {
display = "[[toxicology]]",
topical_categories = true,
}
labels["trading"] = {
display = "[[trading#Noun|trading]]",
topical_categories = true,
}
labels["trading cards"] = {
display = "[[trading card]]s",
topical_categories = true,
}
labels["traditional Chinese medicine"] = {
aliases = {"TCM", "Chinese medicine"},
display = "[[traditional Chinese medicine]]",
topical_categories = true,
}
labels["traditional Korean medicine"] = {
aliases = {"Korean medicine"},
display = "{{w|lang=en|traditional Korean medicine|t=ဂဥုဲကိုဝ်ရဳယျာ}}",
topical_categories = "ဂဥုဲကိုဝ်ရဳယျာ",
}
labels["transgender"] = {
display = "[[transgender]]",
topical_categories = true,
}
labels["translation studies"] = {
display = "[[translation studies]]",
topical_categories = true,
}
labels["transport"] = {
aliases = {"transportation"},
display = "[[transport]]",
topical_categories = true,
}
labels["traumatology"] = {
display = "[[traumatology]]",
topical_categories = "Emergency medicine",
}
labels["travel"] = {
display = "[[travel]]",
topical_categories = true,
}
labels["trigonometry"] = {
display = "[[trigonometry]]",
topical_categories = true,
}
labels["trigonometric function"] = {
display = "[[trigonometry]]",
topical_categories = "Trigonometric functions",
}
labels["trust law"] = {
display = "[[trust law]]",
topical_categories = "Law",
}
labels["two-up"] = {
display = "[[two-up]]",
topical_categories = true,
}
labels["Twitter"] = {
aliases = {"twitter"},
display = "[[Twitter#နာမ်မကိတ်ညဳ|ဓဝေတ်တာ]]",
topical_categories = "ဓဝေတ်တာ",
}
labels["typography"] = {
aliases = {"typesetting"},
display = "[[typography]]",
topical_categories = true,
}
labels["ufology"] = {
display = "[[ufology]]",
topical_categories = true,
}
labels["underwater diving"] = {
aliases = {"scuba", "scuba diving"},
display = "[[underwater]] [[diving#Noun|diving]]",
topical_categories = true,
}
labels["Unicode"] = {
aliases = {"Unicode standard"},
Wikipedia = true,
topical_categories = true,
}
labels["urban studies"] = {
aliases = {"urbanism", "urban planning"},
display = "[[urban studies]]",
topical_categories = true,
}
labels["urology"] = {
display = "[[urology]]",
topical_categories = true,
}
labels["Vaishnavism"] = {
display = "[[Vaishnavism]]",
topical_categories = true,
}
labels["Valentinianism"] = {
aliases = {"valentinianism"},
display = "[[w:Valentinianism|Valentinianism]]",
topical_categories = true,
}
labels["Vedic religion"] = {
aliases = {"Vedic Hinduism", "Ancient Hinduism", "ancient Hinduism", "Vedism", "Vedicism"},
display = "[[w:Historical Vedic religion|Vedic religion]]",
topical_categories = true,
}
labels["vegetable"] = {
aliases = {"vegetables"},
display = "[[vegetable]]",
topical_categories = "Vegetables",
}
labels["vehicles"] = {
aliases = {"vehicle"},
display = "[[vehicle]]s",
topical_categories = true,
}
labels["veterinary medicine"] = {
display = "[[veterinary medicine]]",
topical_categories = true,
}
labels["video compression"] = {
display = "[[w:Video compression|video compression]]",
topical_categories = true,
}
labels["video games"] = {
aliases = {"video game", "video gaming"},
display = "[[video game|ဗဳဒဳယဝ်ဂိန်ဂမၠိုၚ်]]",
topical_categories = "ဗဳဒဳယဝ်ဂိန်",
}
labels["virology"] = {
display = "[[virology|ကွတ်ပညာဂစိုတ်စၟဝါၚ်ရာတ်]]",
topical_categories = "ကွတ်ပညာဂစိုတ်စၟဝါၚ်ရာတ်",
}
labels["virus"] = {
display = "[[virology|ကွတ်ပညာဂစိုတ်စၟဝါၚ်ရာတ်]]",
topical_categories = "ကွတ်ပညာဂစိုတ်စၟဝါၚ်ရာတ်",
}
labels["viticulture"] = {
display = "[[viticulture]]",
topical_categories = {"Horticulture", "Wine"},
}
labels["volcanology"] = {
aliases = {"vulcanology"},
display = "[[volcanology]]",
topical_categories = true,
}
labels["volleyball"] = {
display = "[[volleyball]]",
topical_categories = true,
}
labels["voodoo"] = {
display = "[[voodoo]]",
topical_categories = true,
}
labels["water sports"] = {
aliases = {"watersport", "watersports", "water sport"},
display = "[[watersport|water sports]]",
topical_categories = true,
}
labels["weather"] = {
topical_categories = true,
}
labels["weaving"] = {
display = "[[weaving#Noun|weaving]]",
topical_categories = true,
}
labels["web design"] = {
display = "[[web design]]",
topical_categories = true,
aliases = {"Web design"}
}
labels["web development"] = {
display = "[[web development]]",
topical_categories = {"Programming", "Web design"},
}
labels["weightlifting"] = {
display = "[[weightlifting]]",
topical_categories = true,
}
labels["white supremacy"] = { -- but also this is often used to indicate white-supremacist-used jargon; cf "Nazism"
aliases = {"white nationalism", "white nationalist", "white power", "white racism", "white supremacist ideology", "white supremacism", "white supremacist"},
Wikipedia = "White supremacy",
topical_categories = "White supremacist ideology",
}
labels["wine"] = {
display = "[[wine]]",
topical_categories = true,
}
labels["winemaking"] = {
display = "[[winemaking]]",
topical_categories = "Wine",
}
labels["woodworking"] = {
display = "[[woodworking]]",
topical_categories = true,
}
labels["World War I"] = {
aliases = {"World War 1", "WWI", "WW I", "WW1", "WW 1"},
Wikipedia = "World War I",
topical_categories = true,
}
labels["World War II"] = {
aliases = {"World War 2", "WWII", "WW II", "WW2", "WW 2"},
Wikipedia = "World War II",
topical_categories = true,
}
labels["winter sports"] = {
display = "[[winter sport]]s",
topical_categories = true,
}
labels["wrestling"] = {
display = "[[wrestling#Noun|wrestling]]",
topical_categories = true,
}
labels["writing"] = {
display = "[[writing#Noun|writing]]",
topical_categories = true,
}
labels["Yazidism"] = {
aliases = {"Yezidism"},
display = "[[Yazidism]]",
topical_categories = true,
}
labels["yoga"] = {
display = "[[yoga]]",
topical_categories = true,
}
labels["zoology"] = {
display = "[[zoology|ကွတ်ပညာဗေဒသတ္တ]]",
topical_categories = "ကွတ်ပညာဗေဒသတ္တ",
}
labels["zootomy"] = {
display = "[[zootomy]]",
topical_categories = "Animal body parts",
}
labels["Zoroastrianism"] = {
display = "[[Zoroastrianism]]",
topical_categories = true,
}
-- Labels with set-type categories
-- TODO: These are probably misuses of the label template, and should be deprecated
labels["amino acid"] = {
display = "[[biochemistry]]",
topical_categories = "Amino acids",
}
labels["architectural element"] = {
aliases = {"architectural elements"},
display = "[[architecture]]",
topical_categories = "Architectural elements",
}
labels["artistic work"] = {
display = "[[art#Noun|art]]",
topical_categories = "Artistic works",
}
labels["asterism"] = {
display = "[[uranography]]",
topical_categories = "Asterisms",
}
labels["biblical character"] = {
aliases = {"Biblical character", "biblical figure", "Biblical figure"},
display = "[[Bible|biblical]]",
topical_categories = "Biblical characters",
}
labels["bibliography"] = {
display = "[[bibliography]]",
topical_categories = true,
}
labels["bicycle parts"] = {
display = "[[w:List of bicycle parts|cycling]]",
topical_categories = true,
}
labels["book of the bible"] = {
display = "[[Bible|biblical]]",
topical_categories = "Books of the Bible",
}
labels["brass instruments"] = {
aliases = {"brass instrument"},
display = "[[music|ပညာဂဳတ]]",
topical_categories = "ပညာဂဳတ",
}
labels["canid"] = {
display = "[[zoology|ကွတ်ပညာဗေဒသတ္တ]]",
topical_categories = "ခေန်နေတ်",
}
labels["carbohydrate"] = {
display = "[[biochemistry]]",
topical_categories = "Carbohydrates",
}
labels["carboxylic acid"] = {
display = "[[organic chemistry]]",
topical_categories = "Carboxylic acids",
}
labels["coenzyme"] = {
display = "[[biochemistry]]",
topical_categories = "Coenzymes",
}
labels["conspiracy theories"] = {
aliases = {"conspiracy theory", "conspiracy"},
display = "[[conspiracy theory#Noun|conspiracy theories]]",
topical_categories = true,
}
labels["constellation"] = {
display = "[[astronomy]]",
topical_categories = "Constellations",
}
labels["cookware"] = {
display = "[[cooking#Noun|cooking]]",
topical_categories = "Cookware and bakeware",
}
labels["currencies"] = { -- Don't merge with "numismatics", as the category is different.
aliases = {"currency"},
display = "[[numismatics]]",
topical_categories = "Currencies",
}
labels["dances"] = {
display = "[[dance#Noun|dance]]",
topical_categories = true,
}
labels["demonym"] = {
display = "[[demonym]]",
topical_categories = "Demonyms",
}
labels["disease"] = {
aliases = {"diseases"},
display = "[[pathology]]",
topical_categories = "Diseases",
}
labels["E number"] = {
display = "[[food]] [[manufacture]]",
plain_categories = "European food additive numbers",
}
labels["Egyptian god"] = {
display = "[[Egyptian]] [[mythology]]",
topical_categories = "Egyptian deities",
}
labels["element symbol"] = {
display = "[[chemistry]]",
plain_categories = "Symbols for chemical elements",
}
labels["enzyme"] = {
display = "[[biochemistry]]",
topical_categories = "Enzymes",
}
labels["fatty acid"] = {
display = "[[organic chemistry]]",
topical_categories = "Fatty acids",
}
labels["felid"] = {
aliases = {"cat"},
display = "[[zoology|ကွတ်ပညာဗေဒသတ္တ]]",
topical_categories = "ဖိလေတ်",
}
labels["fictional character"] = {
display = "[[fiction]]",
topical_categories = "Fictional characters",
}
labels["figure of speech"] = {
display = "[[rhetoric]]",
topical_categories = "Figures of speech",
}
labels["fish"] = {
display = "[[zoology|ကွတ်ပညာဗေဒသတ္တ]]",
topical_categories = "ကွတ်ပညာဗေဒသတ္တ",
}
labels["footwear"] = {
display = "[[footwear]]",
topical_categories = true,
}
labels["functional group prefix"] = {
display = "[[organic chemistry]]",
topical_categories = "Functional group prefixes",
}
labels["functional group suffix"] = {
display = "[[organic chemistry]]",
topical_categories = "Functional group suffixes",
}
labels["functional programming"] = {
display = "[[functional programming]]",
topical_categories = "Programming",
}
labels["galaxy"] = {
display = "[[astronomy]]",
topical_categories = "Galaxies",
}
labels["genetic disorder"] = {
display = "[[medical]] [[genetics]]",
topical_categories = "Genetic disorders",
}
labels["Greek god"] = {
aliases = {"Greek goddess"},
display = "[[Greek]] [[mythology]]",
topical_categories = "Greek deities",
}
labels["hand games"] = {
aliases = {"hand game"},
display = "[[hand]] [[game]]s",
topical_categories = true,
}
labels["heraldic charge"] = {
aliases = {"heraldiccharge"},
display = "[[heraldry]]",
topical_categories = "Heraldic charges",
}
labels["Hindu god"] = {
display = "[[Hinduism]]",
topical_categories = "Hindu deities",
}
labels["historical currencies"] = {
aliases = {"historical currency"},
display = "[[numismatics|ကွတ်ပညာဂၞန်သၚ်္ချာ]]",
sense_categories = "ဆေၚ်စပ်ကဵုဝၚ်",
topical_categories = "ဩန်မရပ်စပ်စကာဆေၚ်စပ်ကဵုဝၚ်",
}
labels["historical period"] = {
aliases = {"historical periods"},
display = "[[history|ဝၚ်]]",
topical_categories = "အခိၚ်ကာလဆေၚ်စပ်ကဵုဝၚ်",
}
labels["hormone"] = {
display = "[[biochemistry]]",
topical_categories = "Hormones",
}
labels["hydrocarbon chain prefix"] = {
display = "[[organic chemistry]]",
topical_categories = "Hydrocarbon chain prefixes",
}
labels["hydrocarbon chain suffix"] = {
display = "[[organic chemistry]]",
topical_categories = "Hydrocarbon chain suffixes",
}
labels["incoterm"] = {
display = "[[Incoterm]]",
topical_categories = "Incoterms",
}
labels["inorganic compound"] = {
display = "[[inorganic chemistry]]",
topical_categories = "Inorganic compounds",
}
labels["isotope"] = {
display = "[[physics]]",
topical_categories = "Isotopes",
}
labels["labour law"] = {
display = "[[labour law]]",
topical_categories = "Law",
}
labels["landforms"] = {
display = "[[geography]]",
topical_categories = true,
}
labels["logical fallacy"] = {
display = "[[rhetoric]]",
topical_categories = "Logical fallacies",
}
labels["lutherie"] = {
display = "[[lutherie]]",
topical_categories = true,
}
labels["Mesopotamian god"] = {
display = "[[Mesopotamian]] [[mythology]]",
topical_categories = "Mesopotamian deities",
}
labels["metamaterial"] = {
display = "[[physics]]",
topical_categories = "Metamaterials",
}
labels["military ranks"] = {
aliases = {"military rank"},
display = "[[military|ပရေၚ်ပၞာန်]]",
topical_categories = "ကရုၚ်တန်ပရေၚ်ပၞာန်",
}
labels["military unit"] = {
display = "[[military|ပရေၚ်ပၞာန်]]",
topical_categories = "ယူနေတ်ပရေၚ်ပၞာန်",
}
labels["mineral"] = {
display = "[[mineralogy]]",
topical_categories = "Minerals",
}
labels["mobile phones"] = {
aliases = {"cell phone", "cell phones", "mobile phone", "mobile telephony"},
display = "[[mobile telephone|mobile telephony]]",
topical_categories = true,
}
labels["muscle"] = {
display = "[[anatomy]]",
topical_categories = "Muscles",
}
labels["mushroom"] = {
aliases = {"mushrooms"},
display = "[[mycology]]",
topical_categories = "Mushrooms",
}
labels["musical instruments"] = {
aliases = {"musical instrument"},
display = "[[music|ပညာဂဳတ]]",
topical_categories = "ပညာဂဳတ",
}
labels["music genre"] = {
display = "[[music|ပညာဂဳတ]]",
topical_categories = "ဂကူတွိၚ်ဂဳတ",
}
labels["musician"] = {
display = "[[music|ပညာဂဳတ]]",
topical_categories = "သၟာဂဳတ",
}
labels["mythological creature"] = {
aliases = {"mythological creatures"},
display = "[[mythology]]",
topical_categories = "Mythological creatures",
}
labels["neurotoxin"] = {
display = "[[neurotoxicology]]",
topical_categories = "Neurotoxins",
}
labels["neurotransmitter"] = {
display = "[[biochemistry]]",
topical_categories = "Neurotransmitters",
}
labels["organic compound"] = {
display = "[[organic chemistry]]",
topical_categories = "Organic compounds",
}
labels["part of speech"] = {
display = "[[grammar]]",
topical_categories = "Parts of speech",
}
labels["particle"] = {
display = "[[physics]]",
topical_categories = "Subatomic particles",
}
labels["percussion instruments"] = {
aliases = {"percussion instrument"},
display = "[[music|ပညာဂဳတ]]",
topical_categories = "ပညာဂဳတ",
}
labels["pharmaceutical drug"] = {
display = "[[pharmacology]]",
topical_categories = "Pharmaceutical drugs",
}
labels["pharmaceutical effect"] = {
display = "[[pharmacology]]",
topical_categories = "Pharmaceutical effects",
}
labels["plant"] = {
display = "[[botany]]",
topical_categories = "Plants",
}
labels["plant disease"] = {
display = "[[phytopathology]]",
topical_categories = "Plant diseases",
}
labels["poison"] = {
display = "[[toxicology]]",
topical_categories = "Poisons",
}
labels["political subdivision"] = {
display = "[[government]]",
topical_categories = "Political subdivisions",
}
labels["protein"] = {
aliases = {"proteins"},
display = "[[biochemistry]]",
topical_categories = "Proteins",
}
labels["rock"] = {
display = "[[petrology]]",
topical_categories = "Rocks",
}
labels["Roman god"] = {
aliases = {"Roman goddess"},
display = "[[Roman]] [[mythology]]",
topical_categories = "Roman deities",
}
labels["schools"] = {
display = "[[education]]",
topical_categories = true,
}
labels["self-harm"] = {
aliases = {"selfharm", "self harm", "self-harm community"},
display = "[[self-harm]]",
topical_categories = true,
}
labels["SEO"] = {
display = "[[search engine optimization|SEO]]",
topical_categories = {"Internet", "Marketing"},
}
labels["skeleton"] = {
display = "[[anatomy]]",
topical_categories = true,
}
labels["standard of identity"] = {
display = "[[standard of identity|standards of identity]]",
topical_categories = "Standards of identity",
}
labels["star"] = {
display = "[[astronomy]]",
topical_categories = "Stars",
}
labels["steroid"] = {
display = "[[biochemistry]]",
topical_categories = "Steroids",
}
labels["steroid hormone"] = {
aliases = {"steroid drug"},
display = "[[biochemistry]], [[steroids]]",
topical_categories = "Hormones",
}
labels["string instruments"] = {
aliases = {"string instrument"},
display = "[[music]]",
topical_categories = true,
}
labels["surface feature"] = {
display = "[[planetology]]",
topical_categories = "Planetary nomenclature",
}
labels["sugar acid"] = {
display = "[[organic chemistry]]",
topical_categories = "Sugar acids",
}
labels["symptom"] = {
display = "[[medicine]]",
topical_categories = "Medical signs and symptoms",
}
labels["taxonomic name"] = {
display = "[[taxonomy]]",
topical_categories = "Taxonomic names",
}
labels["tincture"] = {
display = "[[heraldry]]",
topical_categories = "Heraldic tinctures",
}
labels["veterinary disease"] = {
display = "[[veterinary medicine]]",
topical_categories = "Veterinary diseases",
}
labels["video game genre"] = {
display = "[[video game]]s",
topical_categories = "Video game genres",
}
labels["vitamin"] = {
display = "[[biochemistry]]",
topical_categories = "Vitamins",
}
labels["watercraft"] = {
display = "[[nautical]]",
topical_categories = true,
}
labels["weaponry"] = {
aliases = {"weapon", "weapons"},
display = "[[weaponry]]",
topical_categories = "Weapons",
}
labels["Wicca"] = {
display = "[[Wicca]]",
topical_categories = true,
}
labels["wiki jargon"] = {
aliases = {"wiki"},
display = "[[wiki]] [[jargon]]",
topical_categories = "Wiki",
}
labels["Wikimedia jargon"] = {
aliases = {"WMF", "WMF jargon", "Wiktionary", "Wiktionary jargon", "Wikipedia", "Wikipedia jargon"},
display = "[[w:Wikimedia Foundation|Wikimedia]] [[jargon]]",
topical_categories = "Wikimedia",
}
labels["wind instruments"] = {
aliases = {"wind instrument"},
display = "[[music]]",
topical_categories = true,
}
labels["woodwind instruments"] = {
aliases = {"woodwind instrument"},
display = "[[music]]",
topical_categories = true,
}
labels["xiangqi"] = {
aliases = {"Chinese chess"},
display = "[[xiangqi]]",
topical_categories = true,
}
labels["yoga pose"] = {
aliases = {"asana"},
display = "[[yoga]]",
topical_categories = "Yoga poses",
}
labels["zodiac constellations"] = {
display = "[[astronomy]]",
topical_categories = "Constellations in the zodiac",
}
-- Deprecated/do not use warning (ambiguous, unsuitable etc)
labels["deprecated label"] = {
aliases = {"emergency", "greekmyth", "industry", "morphology", "musici", "quantum", "vector"},
display = "<span style=\"color:red;\"><b>deprecated label</b></span>",
deprecated = true,
}
return require("Module:labels").finalize_data(labels)
20jkhke1dcda7wg8v07n1wnv3nradfg
မဝ်ဂျူ:grc-utilities
828
1556
397305
293162
2026-06-21T10:00:36Z
咽頭べさ
33
397305
Scribunto
text/plain
local export = {}
local m_data = mw.loadData("Module:grc-utilities/data")
local m_string_utils = require("Module:string utilities")
local concat = table.concat
local full_link = require("Module:links").full_link
local gsub = m_string_utils.gsub
local match = m_string_utils.match
local insert = table.insert
local ipairs = ipairs
local sparseConcat = require("Module:table").sparseConcat
local standard_diacritics -- defined below
local tag_text = require("Module:script utilities").tag_text
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local umatch = mw.ustring.match
local lang = require("Module:languages").getByCode("grc")
local sc = require("Module:scripts").getByCode("Polyt")
local groups = m_data.groups
local canonical = m_data.canonical
local diacritic_order = m_data.diacritic_order
local diacritical_conversions = m_data.diacritical_conversions
local diacritics = m_data.diacritics
local diacritic = m_data.diacritic
local macron = diacritics.macron
local breve = diacritics.breve
local spacing_macron = diacritics.spacing_macron
local spacing_breve = diacritics.spacing_breve
local rough = diacritics.rough
local smooth = diacritics.smooth
local diaeresis = diacritics.diaeresis
local acute = diacritics.acute
local grave = diacritics.grave
local circumflex = diacritics.circum
local subscript = diacritics.subscript
local combining_diacritic = m_data.combining_diacritic
local UTF8_char = ".[\128-\191]*"
local basic_Greek = "[\206-\207][\128-\191]" -- excluding first line of Greek and Coptic block: ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;Ϳ
local info = {}
-- The tables are shared among different characters so that they can be checked
-- for equality if needed, and to use less space.
local vowel_t = { vowel = true }
local iota_t = { vowel = true, offglide = true }
local upsilon_t = { vowel = true, offglide = true }
-- These don't need any contents.
local breathy_cons_t = {}
-- local consonant_t = {}
local diacritic_t = { diacritic = true }
-- Needed for equality comparisons.
local breathing_t = { diacritic = true }
local function add_info(characters, t)
if type(characters) == "string" then
for character in characters:gmatch(UTF8_char) do
info[character] = t
end
else
for _, character in ipairs(characters) do
info[character] = t
end
end
end
add_info({ macron, breve,
diaeresis,
acute, grave, circumflex,
subscript,
}, diacritic_t)
add_info({rough, smooth}, breathing_t)
add_info("ΑΕΗΟΩαεηοω", vowel_t)
add_info("Ιι", iota_t)
add_info("Υυ", upsilon_t)
add_info("ϜϝΡρ", breathy_cons_t)
local not_recognized = {}
setmetatable(info, { __index = function(t, key)
return not_recognized
end})
-- Perform a function on each Unicode character in a string.
local function forEach(str, func)
for char in str:gmatch(UTF8_char) do
func(char)
end
end
function export.contains_vowel(token)
return not not umatch(toNFD(token), '[ΑΕΗΙΟΥΩαεηιουω]')
end
function export.tag(term, face)
return tag_text(term, lang, sc, face)
end
function export.link(term, face, alt, tr)
return full_link({ term = term, alt = alt, lang = lang, sc = sc, tr = tr }, face)
end
-- Convert spacing to combining diacritics, and nonstandard to standard polytonic Greek.
function export.standardDiacritics(text)
return toNFD((toNFD(text):gsub(UTF8_char, diacritical_conversions)))
end
standard_diacritics = export.standardDiacritics
-- Convert variant letter forms to the canonical form, and decompose.
function export.canonicalize(text)
text = standard_diacritics(text)
-- Compose, since the characters in `canonical` are in form NFC.
text = toNFC(text):gsub(UTF8_char .. grave, canonical) -- for ϗ̀
:gsub(UTF8_char, canonical)
-- Decompose on return.
return toNFD(text)
end
--[=[ This function arranges diacritics in the following order:
1. macron or breve
2. breathings or diaeresis
3. acute, circumflex, or grave
4. iota subscript
Used by [[Module:typing-aids]].
Returns an error if a sequence of diacritics contains more than one
of each category.
]=]
local function reorderDiacriticSequence(diacritics)
local output = {}
forEach(diacritics,
function (diacritic)
local index = diacritic_order[diacritic]
if not output[index] then
output[index] = diacritic
else
-- Place breve after macron.
if diacritic == breve then
index = index + 1
end
-- The following might have odd results when there
-- are three or more diacritics.
insert(output, index, diacritic)
-- [[Special:WhatLinksHere/Wiktionary:Tracking/grc-utils/too many diacritics]]
require("Module:debug").track("grc-utils/too many diacritics")
--[[
local m_templates = require("Module:grc-utilities/templates")
error("There are two diacritics, " ..
m_templates.addDottedCircle(output[index]) .. " and " ..
m_templates.addDottedCircle(diacritic) ..
" that belong in the same position. There should be only one."
)
--]]
end
end)
return sparseConcat(output)
end
function export.reorderDiacritics(text)
return (gsub(toNFD(text), combining_diacritic .. combining_diacritic .. "+", reorderDiacriticSequence))
end
--[=[
This breaks a word into meaningful "tokens", which are
individual letters or diphthongs with their diacritics.
Used by [[Module:grc-accent]] and [[Module:grc-pronunciation]].
--]=]
local function make_tokens(text)
local tokens, prev_info = {}, {}
local token_i, vowel_count = 1, 0 -- Vowel count tracks.
local prev, prev_vowel_info
for character in text:gmatch(UTF8_char) do
local curr_info = info[character]
-- Split vowels between tokens if not a diphthong.
if curr_info.vowel then
vowel_count = vowel_count + 1
if vowel_count == 2 and curr_info.offglide and not (
prev_vowel_info == iota_t or -- ιι → ι, ι; ιυ → ι, υ
prev_vowel_info == upsilon_t and curr_info == upsilon_t -- υυ → υ, υ
) then
vowel_count, prev_vowel_info = 0, nil
elseif prev then
token_i = token_i + 1
vowel_count, prev_vowel_info = 1, curr_info
else
vowel_count, prev_vowel_info = 1, curr_info
end
tokens[token_i] = (tokens[token_i] or "") .. character
elseif curr_info.diacritic then
vowel_count, prev_vowel_info = 0, nil
tokens[token_i] = (tokens[token_i] or "") .. character
if prev_info and (prev_info.diacritic or prev_info.vowel) then
if character == diaeresis or character == subscript then
-- Split the diphthong in the current token if a diaeresis or subscript
-- was found: the first letter, then the second letter plus any diacritics.
local previous_vowel, vowel_with_diaeresis = tokens[token_i]:match("^(" .. basic_Greek .. ")(" .. basic_Greek .. ".+)")
if previous_vowel then
tokens[token_i], tokens[token_i + 1] = previous_vowel, vowel_with_diaeresis
token_i = token_i + 1
else
-- The vowel preceding the vowel with the diaeresis will already be
-- placed in the previous token if it has a diacritic:
-- Περικλῆῐ̈ → Π ε ρ ι κ λ ῆ ῐ̈
--[[
mw.log('Diaeresis was found in ' .. text .. ', but the previous token ' ..
require("Module:Unicode data").add_dotted_circle(tokens[token_i]) ..
' couldn’t be split because it does not consist of two Basic Greek characters followed by other characters.')
--]]
end
-- If there is only a diaeresis, it could still be the first vowel of a
-- diphthong:
-- αὐτοϋιός → αὐ τ ο *ϋι* ό ς
if character == diaeresis and prev_info.vowel then
vowel_count, prev_vowel_info = 1, prev_info
end
end
elseif prev_info == breathy_cons_t then
if curr_info ~= breathing_t then
mw.log(("The character %s in %s should not have the accent %s on it."):format(
prev, text, require("Module:grc-utilities/templates").addDottedCircle(character)))
end
elseif prev then
-- prev can be nil when passed a bare diacritic (as in Translingual diacritic entries)
mw.log("The character " .. prev .. " cannot have a diacritic on it.")
end
else
vowel_count = 0
if prev then
token_i = token_i + 1
end
tokens[token_i] = (tokens[token_i] or "") .. character
end
prev = character
prev_info = curr_info
end
return tokens
end
local cache = {}
function export.tokenize(text)
text = toNFD(text)
if not cache[text] then
cache[text] = make_tokens(text)
end
return cache[text]
end
function export.syllableCount(word)
local tokens = export.tokenize(word)
local syllables = 0
for _, token in ipairs(tokens) do
if export.contains_vowel(token) then
syllables = syllables + 1
end
end
return syllables
end
--[=[ Places diacritics in the following order:
1. breathings or diaeresis
2. acute, circumflex, or grave
3. macron or breve
4. iota subscript
Used by [[Module:grc-pronunciation]]. ]=]
function export.pronunciationOrder(text)
text = standard_diacritics(text)
if match(text, groups[1]) then
text = gsub(text,
diacritic .. diacritic .. "+",
function(sequence)
-- Put breathing and diaeresis first, then accents, then macron or breve
return concat{
match(sequence, groups[2]) or "",
match(sequence, groups[3]) or "",
match(sequence, groups[1]) or "",
match(sequence, groups[4]) or ""
}
end)
text = gsub(text, macron, spacing_macron) -- combining to spacing macron
text = gsub(text, breve, spacing_breve) -- combining to spacing breve
end
return toNFC(text)
end
return export
5aa4dic63x4uljccacqp8731e2c5u23
မဝ်ဂျူ:grc-accent
828
2101
397304
293167
2026-06-21T09:58:31Z
咽頭べさ
33
397304
Scribunto
text/plain
local export = {}
local m_data = mw.loadData("Module:grc-utilities/data")
local m_grc_utils = require("Module:grc-utilities")
local m_str_utils = require("Module:string utilities")
local m_table = require("Module:table")
local diacritic = m_data.diacritic
local diacritics = m_data.diacritics
local ACUTE = diacritics.acute
local GRAVE = diacritics.grave
local CIRCUMFLEX = diacritics.circum
local DIAERESIS = diacritics.diaeresis
local SMOOTH = diacritics.smooth
local ROUGH = diacritics.rough
local MACRON = diacritics.macron
local BREVE = diacritics.breve
local SUBSCRIPT = diacritics.subscript
local UNDERTIE = m_str_utils.char(0x035C)
local diacritic_pattern = m_data.all
local diacritic_groups = m_data.diacritic_groups
local tonal_diacritic = diacritic_groups[3] -- acute, grave, circumflex
local long_diacritics = MACRON .. SUBSCRIPT .. CIRCUMFLEX
local optional_length = m_data.length.optional
local either_vowel = "[ΑαΙιΥυ]"
local canonicalize = m_grc_utils.canonicalize
local concat = table.concat
local contains_vowel = m_grc_utils.contains_vowel
local find = m_str_utils.find
local gsub = m_str_utils.gsub
local insert = table.insert
local lower = m_str_utils.lower
local mark_implied_length -- defined below
local match = m_str_utils.match
local shallow_copy = m_table.shallowCopy
local standard_diacritics = m_grc_utils.standardDiacritics
local tag = m_grc_utils.tag
local tokenize = m_grc_utils.tokenize
local toNFD = mw.ustring.toNFD
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local function if_not_empty(var)
if var == "" then
return nil
else
return var
end
end
local function is_diphthong(token)
return find(token, "[ΑαΕεΗηΙιΟοΥυΩω]" .. optional_length .. DIAERESIS .. "?[ΙιΥυ]") and true or false
end
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
local function _check(funcName, expectType)
if type(expectType) == "string" then
return function(argIndex, arg, nilOk)
checkType(funcName, argIndex, arg, expectType, nilOk)
end
else
return function(argIndex, arg, expectType, nilOk)
if type(expectType) == "table" then
checkTypeMulti(funcName, argIndex, arg, expectType, nilOk)
else
checkType(funcName, argIndex, arg, expectType, nilOk)
end
end
end
end
--[[
A vowel with a breve or a lone epsilon or omicron is considered short.
Everything else is considered long, including unmarked alphas, iotas, and
upsilons. Sigh.
]]
local function is_short(token)
if find(token, BREVE) or find(token, '[ΕΟεο]') and not find(token, '[ιυ]') then
return true
else
return false
end
end
local function conditional_gsub(...)
local str, count = gsub(...)
if count and count > 0 then
return str
else
return nil
end
end
local accent_adding_functions = {
-- This will not throw an error if η or ω has a macron on it.
[CIRCUMFLEX] = function(vowel)
return (gsub(
vowel,
"([ΑαΗηΙιΥυΩω])" .. MACRON .. "?(" .. diacritic_groups[2] .. "?)(" .. SUBSCRIPT .. "?)$",
"%1%2" .. CIRCUMFLEX .. "%3"
))
end,
[ACUTE] = function(vowel)
return (
conditional_gsub(vowel,
"([Εε])([Ωω])",
"%1" .. ACUTE .. "%2") or
gsub(vowel,
"([ΑαΕεΗηΙιΟοΥυΩω]" .. optional_length .. diacritic_groups[2] .. "?)(" .. SUBSCRIPT .. "?)$",
"%1" .. ACUTE .. "%2"))
end,
[MACRON] = function(vowel)
if find(vowel, "[" .. long_diacritics .. "]") or is_diphthong(vowel) then
return vowel
elseif find(vowel, "[ΕΟεο]") then
error("The vowel " .. vowel ..
" is short, so a macron cannot be added to it.")
else
return (gsub(vowel, "(" .. either_vowel .. ")", "%1" .. MACRON))
end
end,
[BREVE] = function(vowel)
if find(vowel, "[" .. long_diacritics .. "]") then
error("The vowel " .. vowel ..
" has an iota subscript, a macron, or a circumflex, so a breve cannot be added to it.")
elseif is_diphthong(vowel) then
error("The vowel " .. vowel ..
" is a diphthong, so a breve cannot be added to it.")
else
return (gsub(vowel, "(" .. either_vowel .. ")", "%1" .. BREVE))
end
end,
-- This will insert a diaeresis on a single iota or upsilon, or on a
-- iota or upsilon that is the second element of a diphthong.
-- It does nothing if the vowel has a breathing on it.
[DIAERESIS] = function(vowel)
return (gsub(
vowel,
"([ΙιΥυ]" .. optional_length .. ")(" .. tonal_diacritic .. "?)$",
"%1" .. DIAERESIS .. "%2"
))
end
}
-- Assumes decomposed vowels (NFD).
local function add(vowel, accent)
if type(accent_adding_functions[accent]) == "function" then
return accent_adding_functions[accent](vowel)
end
error("No function for adding " .. accent)
end
function export.strip_accent(word)
word = toNFD(word)
-- Parentheses suppress second return value of gsub, the number of substitutions.
return (gsub(word, diacritic_pattern, ''))
end
function export.strip_tone(word)
word = toNFD(word)
if find(word, CIRCUMFLEX) then
word = shallow_copy(tokenize(word))
for i = 1, #word do
-- Add a macron to every vowel with a circumflex and remove the circumflex.
word[i] = gsub(word[i],
'^([αΑιΙυΥ])(' .. diacritic_groups[2] .. '*)' .. CIRCUMFLEX .. '$',
'%1' .. MACRON .. '%2')
end
word = table.concat(word)
end
return (gsub(word, tonal_diacritic, ''))
end
function export.ult(word)
word = toNFD(word)
if find(word, tonal_diacritic) then
return word
end
word = shallow_copy(tokenize(word))
for i, token in m_table.reverseIpairs(word) do
if contains_vowel(token) then
--fortunately accents go last in combining order
word[i] = add(token, ACUTE)
break
end
end
return concat(word, '')
end
--[[ WARNING: Given an unmarked α ι υ, this function will return a circmflex.
That said, if you ran into this situation in the first place, you probably
are doing something wrong. ]] --
function export.circ(word)
word = toNFD(word)
if find(word, tonal_diacritic) then
return word
end
word = shallow_copy(tokenize(word))
for i, token in m_table.reverseIpairs(word) do
if contains_vowel(token) then
if is_short(token) then
word[i] = add(token, ACUTE)
else
word[i] = add(token, CIRCUMFLEX)
end
break
end
end
return concat(word, '')
end
function export.penult(orig)
local word = toNFD(orig)
if find(word, tonal_diacritic) then
return word
end
word = shallow_copy(tokenize(word))
local syllables = 0
for i, token in m_table.reverseIpairs(word) do
if token == '-' then
return orig
elseif contains_vowel(token) then
syllables = syllables + 1
if syllables == 2 then
word[i] = add(token, ACUTE)
return concat(word, '')
end
end
end
return export.circ(orig)
end
function export.pencirc(orig)
local word = toNFD(orig)
if find(word, tonal_diacritic) then
return word
end
word = shallow_copy(tokenize(word))
local syllables = 0
local long_ult = false
for i, token in m_table.reverseIpairs(word) do
if token == '-' then return orig end
if contains_vowel(token) then
syllables = syllables + 1
if syllables == 1 and not is_short(token) then
long_ult = true
if word[#word] == 'αι' or word[#word] == 'οι' then long_ult = false end
elseif syllables == 2 then
if is_short(token) or long_ult then
word[i] = add(token, ACUTE)
else
word[i] = add(token, CIRCUMFLEX)
end
return concat(word, '')
end
end
end
return export.circ(orig)
end
function export.antepenult(orig)
local word = toNFD(orig)
if find(word, tonal_diacritic) then
return word
end
word = shallow_copy(tokenize(word))
local syllables = 0
local long_ult = false
for i, token in m_table.reverseIpairs(word) do
if token == '-' then return orig end
if contains_vowel(token) then
syllables = syllables + 1
if syllables == 1 and not is_short(token) then
long_ult = true
if word[#word] == 'αι' or word[#word] == 'οι' then long_ult = false end
elseif syllables == 2 and long_ult then
word[i] = add(token, ACUTE)
return concat(word, '')
elseif syllables == 3 then
word[i] = add(token, ACUTE)
return concat(word, '')
end
end
end
return export.pencirc(orig)
end
--[[
Counts from the beginning or end of the word, and returns the position and
type of the first accent found. Position means the number of vowels
(syllables) that have been encountered, not the number of characters.
Arguments:
- word: string (Ancient Greek word)
- from_end: boolean (whether to count from the end of the word)
]]
local accent_cache = {[true] = {}, [false] = {}}
function export.detect_accent(word, from_end)
local check = _check("detect_accent")
check(1, word, "string")
check(2, from_end, "boolean", true)
local cache = accent_cache[from_end == true][toNFD(word)]
if cache then
return unpack(cache)
end
local names = {
[ACUTE] = "acute",
[GRAVE] = "grave",
[CIRCUMFLEX] = "circumflex",
}
local syllable = 0
local accent_name
for _, token in (from_end and m_table.reverseIpairs or ipairs)(tokenize(word)) do
if contains_vowel(token) then
syllable = syllable + 1
accent_name = names[match(token, tonal_diacritic)]
if accent_name then
accent_cache[from_end == true][toNFD(word)] = {syllable, accent_name}
return syllable, accent_name
end
end
end
return nil
end
--[[
Returns classification based on first accent found
when traveling back from the end of the word.
]]
function export.get_accent_term(word)
local syllable, accent_name = export.detect_accent(word, true)
local terms = {
["grave"] = {"barytone"},
["acute"] = {"oxytone", "paroxytone", "proparoxytone"},
["circumflex"] = {"perispomenon", "properispomenon"},
}
local ordinals = {"first", "second", "third", "fourth", "fifth",}
local term
if syllable and accent_name then
term = terms[accent_name][syllable]
end
if term then
return term
else
return nil,
syllable and 'There is no term for a word with a ' .. accent_name ..
' accent on the ' .. ordinals[syllable] ..
' syllable from the end of the word.'
or 'No accent found.'
end
end
-- is_noun is a boolean or nil; if it is true, αι and οι will be
-- treated as short.
function export.get_length(token, short_diphthong)
local token = toNFD(lower(token))
if not contains_vowel(token) then
return nil
-- error("The thing supplied to get_length does not have any vowels")
end
-- η, ω; ᾳ, ῃ, ῳ; ᾱ, ῑ, ῡ; diphthongs
if find(token, "[ηω" .. long_diacritics .. "]") then
return "long"
end
if short_diphthong and find(token, "^[αο]ι") then
return "short"
end
if is_diphthong(token) then
return "long"
end
-- ε, ο; ᾰ, ῐ, ῠ
if find(token, "[εο" .. BREVE .. "]") then
return "short"
end
-- anything else
return "either"
end
-- Takes a table of tokens and returns a table containing tables of each vowel's
-- characteristics.
function export.get_vowel_info(tokens, short_diphthong)
if type(tokens) ~= "table" then
error("The argument to get_vowel_info must be a table.")
end
local vowels = {}
local vowel_i = 1
if find(tokens[#tokens], m_data.consonant .. "$") then
short_diphthong = false
end
for i, token in m_table.reverseIpairs(tokens) do
if contains_vowel(token) then
if vowel_i ~= 1 then
short_diphthong = false
end
local length, accent =
export.get_length(token, short_diphthong),
if_not_empty(match(token,
"[" .. ACUTE .. GRAVE .. CIRCUMFLEX .. "]"))
vowels[vowel_i] = {
index = i,
length = length,
accent = accent,
}
vowel_i = vowel_i + 1
end
end
return vowels
end
function export.mark_implied_length(word, return_tokens, short_diphthong)
word = toNFD(word)
-- Do nothing if there are no vowel letters that could be ambiguous.
if not find(word, either_vowel) then
if return_tokens then
return tokenize(word)
else
return word
end
end
local tokens = shallow_copy(tokenize(word))
local vowels = export.get_vowel_info(tokens, short_diphthong)
if #vowels >= 2 then
local ultima = vowels[1]
local ultima_i = ultima.index
local penult = vowels[2]
local penult_i = penult.index
if penult.length == "either" and ultima.length == "short" then
if penult.accent == CIRCUMFLEX then
tokens[penult_i] = add(tokens[penult_i], MACRON)
elseif penult.accent == ACUTE then
tokens[penult_i] = add(tokens[penult_i], BREVE)
end
elseif penult.length == "long" and ultima.length == "either" then
if penult.accent == CIRCUMFLEX then
tokens[ultima_i] = add(tokens[ultima_i], BREVE)
elseif penult.accent == ACUTE then
tokens[ultima_i] = add(tokens[ultima_i], MACRON)
end
end
local antepenult = vowels[3]
if antepenult and antepenult.accent and ultima.length == "either" then
tokens[ultima_i] = add(tokens[ultima_i], BREVE)
end
end
if return_tokens then
return tokens
else
return concat(tokens)
end
end
mark_implied_length = export.mark_implied_length
-- Returns a table of any ambiguous vowels in the text, language-tagged.
function export.find_ambig(text, noTag)
local lengthDiacritic = "[" .. MACRON .. BREVE .. CIRCUMFLEX .. SUBSCRIPT .. "]"
local aiu_diacritic = "^(" .. either_vowel .. ")(" .. diacritic .. "*)$"
-- breaks the word into units
local output, vowels = {}, {}
for _, token in ipairs(tokenize(mark_implied_length(standard_diacritics(text)))) do
local canonical = canonicalize(token)
if not match(canonical, m_data.consonant) then
local vowel, dia = match(canonical, aiu_diacritic)
if vowel and (dia == "" or not match(dia, lengthDiacritic)) then
insert(output, noTag and token or tag(token))
-- Lists the vowel letters that are ambiguous, for categorization purposes.
vowels[lower(vowel)] = true
end
end
end
return output, vowels
end
-- Returns the length of a syllable specified by its position from the end of the word.
function export.length_at(word, syllable)
local tokens = tokenize(word)
if type(word) ~= "string" then
error("First argument of length_at should be a string.")
end
if type(syllable) ~= "number" then
error("Second argument of length_at should be a number.")
end
local syllable_count = 0
for _, token in m_table.reverseIpairs(tokens) do
local length = export.get_length(token)
if length then
syllable_count = syllable_count + 1
if syllable_count == syllable then
return length
end
end
end
if syllable_count < syllable then
error("Length for syllable " .. syllable .. " from the end of the word was not found.")
end
end
local function find_breathing(token)
return match(token, "([" .. ROUGH .. SMOOTH .. "])")
end
local function has_same_breathing_as(token1, token2)
return find_breathing(token1) == find_breathing(token2)
end
-- Make token have the length specified by the string "length".
local function change_length(length, token)
local dia
if length == "long" then
dia = MACRON
elseif length == "short" then
dia = BREVE
end
if dia then
return add(token, dia)
else
return token
end
end
--[[
Take two words, mark implied length on each, then harmonize any macrons and
breves that disagree.
]]
function export.harmonize_length(word1, word2)
word1 = toNFD(word1)
-- Do nothing if there are no vowel letters that could be ambiguous.
if not (find(word1, either_vowel) or find(word2, either_vowel)) then
return word1, word2
end
local tokens1, tokens2 = mark_implied_length(word1, true), mark_implied_length(word2, true)
local strip1, strip2 = shallow_copy(tokenize(export.strip_accent(word1))), shallow_copy(tokenize(export.strip_accent(word2)))
for i, token1 in pairs(tokens1) do
local token2 = tokens2[i]
if strip1[i] == strip2[i] then
if has_same_breathing_as(token1, token2) then
local length1, length2 = export.get_length(token1), export.get_length(token2)
if length1 and length2 and length1 ~= length2 then
if length1 == "either" then
tokens1[i] = change_length(length2, token1)
elseif length2 == "either" then
tokens2[i] = change_length(length1, token2)
end
end
else
break
end
else
break
end
end
local new_word1, new_word2 = concat(tokens1), concat(tokens2)
return new_word1, new_word2
end
--[[
Get weight of nth syllable from end of word. Position defaults to 1, the last
syllable. Returns "heavy" or "light", or nil if syllable is open with an
ambiguous vowel.
]]
function export.get_weight(word, position)
if not if_not_empty(word) then
return nil
end
local tokens = tokenize(word)
if not position then
position = 1
end
local vowel
local vowel_index = 0
-- Find nth vowel from end of word.
for i, token in m_table.reverseIpairs(tokens) do
local length = export.get_length(token)
if length then
vowel_index = vowel_index + 1
if vowel_index == position then
vowel = {index = i, length = length}
break
end
end
end
if not vowel then
return nil
end
if vowel.length == "long" then
return "heavy"
else
-- Count consonants after the vowel.
local consonant_count = 0
for i = vowel.index + 1, #tokens do
if not contains_vowel(tokens[i]) then
consonant_count = consonant_count + 1
else
break
end
end
if consonant_count > 1 then
return "heavy"
elseif vowel.length == "short" then
return "light"
else
return nil
end
end
end
--[[
Add accent mark at position. Position is a number that refers to the nth
vowel from the beginning of the word. Respects the rules of accent.
Examples:
- δημος, 1 => δῆμος
- προτερᾱ, 1 => προτέρᾱ (position changed to 2 because ultima is long)
- μοιρα, 1, true => μοῖρα (circumflex can be added because ultima is
ambiguous)
- χωρᾱ, 1, true => χώρᾱ (circumflex can't be added because ultima
is long)
- τοιουτος, 2 => τοιοῦτος (circumflex because ultima is short)
Arguments:
- word: string (hopefully an Ancient Greek word or stem)
- syllable_position: number (less than the number of monophthongs or diphthongs
in the word)
- options: table
- circumflex boolean (add a circumflex if allowed)
- synaeresis boolean (accent can fall before εω in penult
and ultima: πόλεως)
- short_diphthong boolean (word-final οι, αι count as short)
]]
function export.add_accent(word, syllable_position, options)
local check = _check("add_accent")
check(1, word, "string")
check(2, syllable_position, "number")
check(3, options, "table", true)
word = toNFD(word)
if find(word, tonal_diacritic) then
return word
end
options = options or {}
local tokens = shallow_copy(tokenize(word))
local vowels = export.get_vowel_info(tokens, options.short_diphthong)
local vowel_count = #vowels
-- Convert positions in relation to the beginning of the word
-- to positions in relation to the end of the word.
-- The farthest back that an accent can be placed is 3 (the antepenult),
-- so that is the greatest allowed position.
if syllable_position > 0 then
syllable_position = math.min(3, vowel_count - syllable_position + 1)
-- If the position is in relation to the end of the word and it is greater
-- than the length of the word, then reduce it to the length of the word.
-- This is for practical reasons. Positions in relation to the beginning of
-- the word do not need leeway.
elseif syllable_position < 0 then
syllable_position = math.min(-syllable_position, vowel_count)
end
if syllable_position == 0 then
error("Invalid position value " .. syllable_position .. ".")
elseif syllable_position > vowel_count then
error("The position " .. syllable_position .. " is invalid, because the word has only " .. vowel_count .. " vowels.")
end
-- Apply accent rules to change the accent's position or type.
local accent_mark = options.circumflex and CIRCUMFLEX or ACUTE
local ultima = vowels[1]
-- If synaeresis is selected, a final vowel sequence εω (optionally
-- separated by an undertie) counts as one syllable.
if syllable_position == 3 then
local penult = vowels[2]
if not options.force_antepenult and (ultima.length == "long"
and not (options.synaeresis
and ("Ωω"):find(tokens[ultima.index], 1, true)
and ("Εε"):find(tokens[penult.index], 1, true)
and (ultima.index == penult.index + 1
or ultima.index == penult.index + 2
and tokens[penult.index + 1] == UNDERTIE))) then
syllable_position = 2
else
accent_mark = ACUTE
end
end
if syllable_position == 2 then
if ultima.length == "short" and vowels[2].length == "long" then
accent_mark = CIRCUMFLEX
elseif ultima.length == "long" then
accent_mark = ACUTE
end
end
local vowel = vowels[syllable_position]
if not vowel then
error('No vowel at position ' .. syllable_position ..
' from the end of the word ' .. word .. '.')
end
if vowel.length == "short" then
accent_mark = ACUTE
end
local i = vowel.index
tokens[i] = add(tokens[i], accent_mark)
return concat(tokens)
end
function export.syllables(word, func, number)
local check = _check('syllables')
check(1, word, 'string')
check(2, func, 'string', true)
check(3, number, 'number', true)
if not func then
error('No function specified')
end
local functions = {
eq = function (word, number)
local vowels = 0
for _, token in ipairs(tokenize(word)) do
if contains_vowel(token) then
vowels = vowels + 1
if vowels > number then
return false
end
end
end
if vowels == number then
return true
end
return false
end
}
func = functions[func]
if func then
return func(word, number)
else
error('No function ' .. func)
end
end
return export
ctcoupikea2d7tjrva0fq2qy1leyqwg
မဝ်ဂျူ:la-headword
828
24343
397238
397231
2026-06-20T16:36:37Z
咽頭べさ
33
397238
Scribunto
text/plain
-- TODO: handle "-old" subtypes generally, appending "in Old Latin", where terms have additional OL inflections.
local export = {}
local pos_functions = {}
local string_utilities = "Module:string utilities"
local table_module = "Module:table"
local utilities_module = "Module:utilities"
local concat = table.concat
local form_is_empty = require("Module:la-utilities").form_is_empty
local insert = table.insert
local remove = table.remove
local umatch = mw.ustring.match
local lang = require("Module:languages").getByCode("la")
local NAMESPACE = mw.title.getCurrentTitle().nsText
local PAGENAME = mw.loadData("Module:headword/data").pagename
local legal_gender = {
["m"] = true,
["f"] = true,
["n"] = true,
["?"] = true,
["?!"] = true,
}
local declension_to_english = {
["1"] = "ပထမ",
["2"] = "ဒုတိယ",
["3"] = "တတိယ",
["4"] = "စတုတ္ထ",
["5"] = "ပဉ္စမ",
}
local gender_names = {
["m"] = "ပုလ္လိၚ်",
["f"] = "ဣတ္တိလိၚ်",
["n"] = "နပုလ္လိၚ်",
["?"] = "လိၚ်ဟွံတီကၠး",
["?!"] = "လိၚ်ဟွံပြာကတ်",
}
local function deep_equals(...)
deep_equals = require(table_module).deepEquals
return deep_equals(...)
end
local function get_plaintext(...)
get_plaintext = require(utilities_module).get_plaintext
return get_plaintext(...)
end
local function insert_if_not(...)
insert_if_not = require(table_module).insertIfNot
return insert_if_not(...)
end
local function invert(...)
invert = require(table_module).invert
return invert(...)
end
local function keys_to_list(...)
keys_to_list = require(table_module).keysToList
return keys_to_list(...)
end
local function pattern_escape(...)
pattern_escape = require(string_utilities).pattern_escape
return pattern_escape(...)
end
local function serial_comma_join(...)
serial_comma_join = require(table_module).serialCommaJoin
return serial_comma_join(...)
end
local function split(...)
split = require(string_utilities).split
return split(...)
end
local function ulower(...)
ulower = require(string_utilities).lower
return ulower(...)
end
local function format(array, concatenater)
if #array == 0 then
return ""
end
local concatenated = concat(array, concatenater)
if concatenated == "" then
return ""
elseif concatenated:sub(-1) == "'" then
concatenated = concatenated .. " "
end
return "; ''" .. concatenated .. "''"
end
local function glossary_link(anchor, text)
text = text or anchor
return "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#" .. anchor .. "|" .. text .. "]]"
end
local function make_link(page, display, face, accel)
return require("Module:links").full_link({term = page, alt = display, lang = lang, accel = accel}, face)
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iargs = require("Module:parameters").process(frame.args, {
[1] = {required = true},
["def"] = true,
["suff_type"] = true,
})
local args = frame:getParent().args
local poscat = iargs[1]
local def = iargs.def
local suff_type = iargs.suff_type
local postype = nil
if suff_type then
postype = poscat .. '-' .. suff_type
else
postype = poscat
end
local data = {lang = lang, categories = {}, heads = {}, genders = {}, inflections = {}}
local infl_classes = {}
local title = {}
local postscript = {}
if poscat == "အဆက်လက္ကရဴ" then
-- insert_if_not(data.categories, "Latin " .. suff_type .. "-forming suffixes")
end
if pos_functions[postype] then
local new_poscat = pos_functions[postype](def, args, data, infl_classes, title, postscript)
if new_poscat then
poscat = new_poscat
end
end
data.pos_category = poscat
postscript = concat(postscript, ", ")
return
require("Module:headword").full_headword(data)
.. format(infl_classes, "/")
.. format(title, ", ")
.. (postscript ~= "" and " (" .. postscript .. ")" or "")
end
local function process_num_type(numtype, categories)
if numtype == "card" then
-- insert_if_not(categories, "Latin cardinal numbers")
elseif numtype == "ord" then
-- insert_if_not(categories, "Latin ordinal numbers")
elseif numtype == "frac" then
-- insert_if_not(categories, "Latin fractional numbers")
elseif numtype == "dist" then
-- insert_if_not(categories, "Latin distributive numbers")
elseif numtype == "mul" then
-- insert_if_not(categories, "Latin multiplicative numbers")
elseif numtype == "coll" then
-- insert_if_not(categories, "Latin collective numbers")
elseif numtype then
error("Unrecognized numeral type '" .. numtype .. "'")
end
end
local function normalize_derivation(deriv, anchor, text)
if not deriv then
return nil
end
local deriv1 = deriv[1]
if not deriv1 or deriv1 == "-" then
return deriv1
end
deriv.label = glossary_link(anchor, text)
return deriv
end
local function derivation(data, decldata, arg, anchor, text)
local der = normalize_derivation(decldata[arg], anchor, text)
if der and der ~= "-" then
insert(data.inflections, der)
end
end
local function nouns(pos, def, args, data, infl_classes, title)
local is_num = pos == "ဂၞန်သၚ်္ချာ"
local is_pn = false
if pos == "နာမ်မကိတ်ညဳ" then
is_pn = true
pos = "နာမ်"
end
local decldata = require("Module:la-nominal").do_generate_noun_forms(args, pos, "headword", def, is_num)
local lemma = decldata.overriding_lemma
-- TODO: modify the headword line if the slot isn't the expected one.
if #lemma == 0 then
for slot in require("Module:la-nominal").iter_potential_noun_lemma_slots() do
local potential_lemma = decldata.forms["linked_" .. slot]
if not form_is_empty(potential_lemma) then
if decldata.unattested[slot] then
potential_lemma = "*" .. potential_lemma
end
lemma = potential_lemma
break
end
end
end
data.heads = lemma
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = decldata.id
local genders = decldata.overriding_genders
if #genders == 0 then
if decldata.gender then
genders = {ulower(decldata.gender)}
elseif not is_num then
error("No gender explicitly specified in headword template using g=, and can't infer gender from lemma spec")
end
end
local categories = data.categories
if is_num then
process_num_type(decldata.num_type, categories)
end
if decldata.indecl then
insert(data.inflections, {label = glossary_link("ခလံက်ခနက်")})
insert_if_not(categories, decldata.pos .. "လပ်တေန်နကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်")
for _, g in ipairs(genders) do
local gender = g:match("^(.[\128-\191]*)%-[sp]$")
if not gender then
gender = g
end
if not legal_gender[gender] then
error("Gender “" .. gender .. "” is not a valid Latin gender.")
end
insert(data.genders, g)
insert_if_not(categories, decldata.pos .. gender_names[gender] .. "လပ်တေန်နကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်")
end
else
local is_irreg = false
local is_indecl = false
local is_decl = false
local has_multiple_decls = false
local has_multiple_variants = false
-- flatten declension specs
local decls = {}
for _, g in ipairs(genders) do
if not legal_gender[g] then
error("Gender “" .. g .. "” is not a valid Latin gender.")
elseif decldata.num == "pl" then
g = g .. "-p"
elseif decldata.num == "sg" then
g = g .. "-s"
end
insert(data.genders, g)
end
local function process_decl(decl_list, props)
local headword_decl = props.headword_decl
-- skip adjectival declensions
if headword_decl:match("+$") then
return
elseif props.decl == "irreg" then
is_irreg = true
headword_decl = headword_decl:match("^irreg/(.*)$") or headword_decl
local irreg_decls = split(headword_decl, ",")
if #irreg_decls > 1 then
has_multiple_decls = true
end
for _, d in ipairs(irreg_decls) do
if d == "indecl" or d == "0" then
is_indecl = true
else
is_decl = true
end
insert_if_not(decl_list, d)
end
else
if headword_decl == "indecl" or headword_decl == "0" then
is_indecl = true
else
is_decl = true
end
insert_if_not(decl_list, headword_decl)
end
end
for _, props in ipairs(decldata.propses) do
if props.headword_decl then
process_decl(decls, props)
else
local alternant_decls = {}
for _, alternant in ipairs(props) do
for _, single_props in ipairs(alternant) do
process_decl(alternant_decls, single_props)
end
end
if #alternant_decls > 1 then
has_multiple_decls = true
elseif #decls > 1 then
has_multiple_variants = true
end
for _, d in ipairs(alternant_decls) do
insert_if_not(decls, d)
end
end
end
if is_indecl and is_decl then
has_multiple_decls = true
end
if has_multiple_decls then
-- insert_if_not(categories, "Latin " .. decldata.pos .. " with multiple declensions")
end
if has_multiple_variants then
-- insert_if_not(categories, "Latin " .. decldata.pos .. " with multiple variants of a single declension")
end
if is_irreg then
insert(title, glossary_link("ခလံက်ခနက်"))
insert_if_not(categories, decldata.pos .. "အတိုၚ်ပကတိဟွံသေၚ်နကဵုဘာသာလပ်တေန်ဂမၠိုၚ်")
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. gender_names[g] .. "အတိုၚ်ပကတိဟွံသေၚ်နကဵုဘာသာလပ်တေန်ဂမၠိုၚ်")
end
end
if is_indecl then
if is_decl then
insert(title, glossary_link("ကၞိက်ဟွံမာန်"))
else
insert(data.inflections, {label = glossary_link("ကၞိက်ဟွံမာန်")})
end
insert_if_not(categories, decldata.pos .. "လပ်တေန်နကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်")
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. gender_names[g] .. "လပ်တေန်နကဵုပါ်ပါဲထောံဟွံမာန်ဂမၠိုၚ်")
end
end
if #decls > 1 then
insert(title, "variously declined")
end
for _, decl in ipairs(decls) do
if not (decl == "0" or decl == "indecl" or decl == "sgpl" or decl == "irreg") then
local decl_class = declension_to_english[decl]
if not decl_class then
error("Internal error: declension '" .. decl .. "' not recognized")
end
insert(title, "[[Appendix:လပ်တေန်မလဟုတ်စှ်ေအလန်" .. decl_class .. "|မလဟုတ်စှ်ေအလန်" .. decl_class .. "]]")
insert_if_not(categories, decldata.pos .. "လပ်တေန်မလဟုတ်စှ်ေအလန်" .. decl_class)
for _, g in ipairs(genders) do
insert_if_not(categories, decldata.pos .. gender_names[g] .. "လပ်တေန်ပ္ဍဲဆေၚ်စပ်ကဵုမလဟုတ်စှ်ေအလန်" .. decl_class)
end
end
end
local lemma_num = decldata.num == "pl" and "pl" or "sg"
if NAMESPACE == "ဗီုပြၚ်သိုၚ်တၟိ" then
-- For reconstructed nouns:
if data.genders[1] == 'n' and lemma_num == 'sg' then
-- singular neuter nouns give a plural
local pl = decldata.forms["nom_pl"]
if pl and pl ~= "" and #pl > 0 then
pl.label = "ကိုန်ဗဟုဝစ်"
insert(data.inflections, pl)
end
else
-- all others give an oblique
local obl = decldata.forms["acc_" .. lemma_num]
if obl and obl ~= "" and #obl > 0 then
obl.label = "oblique"
insert(data.inflections, obl)
end
end
else
local gen = decldata.forms["gen_" .. lemma_num]
if (decldata.unattested["gen_" .. lemma_num]) then
gen[1] = '*' .. gen[1]
data.nolink = true
end
if gen and gen ~= "" and gen ~= "—" and #gen > 0 then
if is_decl then
-- Skip displaying the genitive for nouns that are only
-- indeclinable. But we do display it for nouns like Abrahām
-- and Ādām that can be either indeclinable or declined.
gen.label = "ဗဳဇဂကူ"
insert(data.inflections, gen)
end
else
insert(data.inflections, {label = "ဗဳဇဂကူဟွံမွဲ"})
insert_if_not(categories, decldata.pos .. "လပ်တေန်မနွံကဵုဂကူဗဳဇကိုန်ဨကဝုစ်ဟွံသေၚ်ဂမၠိုၚ်")
end
end
end
derivation(data, decldata, "m", "ပုလ္လိၚ်")
derivation(data, decldata, "f", "ဣတ္တိလိၚ်")
derivation(data, decldata, "n", "နပုလ္လိၚ်")
derivation(data, decldata, "adj", "ဆေၚ်စပ်ကဵုဆက်ဆောံ", "နာမဝိသေသနဆေၚ်စပ်ကဵုဆက်ဆောံ")
derivation(data, decldata, "dim", "မလဟုတ်စှ်ေ")
derivation(data, decldata, "aug", "မဇၞော်မောဝ်တိုန်")
for _, cat in ipairs(decldata.categories) do
insert_if_not(categories, cat)
end
for _, cat in ipairs(decldata.cat) do
insert_if_not(categories, cat .. "လပ်တေန်ဂမၠိုၚ်")
end
return is_pn and decldata.pos == "နာမ်" and "နာမ်မကိတ်ညဳ" or decldata.pos
end
pos_functions["နာမ်"] = function(def, args, data, infl_classes, title)
return nouns("နာမ်", def, args, data, infl_classes, title)
end
pos_functions["နာမ်မကိတ်ညဳ"] = function(def, args, data, infl_classes, title)
return nouns("နာမ်မကိတ်ညဳ", def, args, data, infl_classes, title)
end
pos_functions["နာမ်အဆက်လက္ကရဴ"] = function(def, args, data, infl_classes, title)
return nouns("အဆက်လက္ကရဴ", def, args, data, infl_classes, title)
end
pos_functions["နာမ်ဂၞန်သၚ်္ချာ"] = function(def, args, data, infl_classes, title)
return nouns("ဂၞန်သၚ်္ချာ", def, args, data, infl_classes, title)
end
function export.verb_title(title, typeinfo, lemma_forms)
local conj = typeinfo.conj
local irreg_processing = typeinfo.irreg
local subtypes = typeinfo.subtypes
local first_lemma = ""
if #lemma_forms > 0 then
first_lemma = require("Module:links").remove_links(lemma_forms[1])
end
if conj == "1st" then
insert(title, "[[:en:Appendix:Latin first conjugation|ကြိယာအပြံၚ်အလှာဲအလန်ပထမ]]")
elseif conj == "2nd" then
insert(title, "[[:en:Appendix:Latin second conjugation|ကြိယာအပြံၚ်အလှာဲအလန်ဒုတိယ]]")
elseif conj == "3rd" then
insert(title, "[[:en:Appendix:Latin third conjugation|ကြိယာအပြံၚ်အလှာဲအလန်တတိယ]]")
elseif conj == "3rd-io" then
insert(title, ("[[:en:Appendix:Latin third conjugation|ကြိယာအပြံၚ်အလှာဲအလန်တတိယ (အပြံၚ်အလှာဲ%s)]]"):format(make_link(nil, "-iō", "term")))
elseif conj == "3rd/4th" then
insert(title, ("[[:en:Appendix:Latin third conjugation|တတိယ (အပြံၚ်အလှာဲ%s)]] / [[:en:Appendix:Latin fourth conjugation|ကြိယာအပြံၚ်အလှာဲအလန်စတုတ္ထ]]"):format(make_link(nil, "-iō", "term")))
elseif conj == "4th" then
insert(title, "[[:en:Appendix:Latin fourth conjugation|ကြိယာအပြံၚ်အလှာဲအလန်စတုတ္ထ]]")
elseif conj == "irreg" then -- sum
insert(title, "[[:en:Appendix:Latin irregular verbs|ကြိယာအပြံၚ်အလှာဲအလန်ခလံက်ခနက်]]")
end
if subtypes.highlydef then -- āiō, inquam
insert(title, "[[defective verb#အၚ်္ဂလိက်|ဟွံစှ်ေကဵုဗီုပြၚ်]]မသၠုၚ်တဴ")
end
if subtypes.suppl then -- sum, volō
insert(title, "[[suppletive#အၚ်္ဂလိက်|သဒ္ဒာ]]")
end
if subtypes["3only"] then -- decet
insert(title, "ပါဲနူ[[third person#အၚ်္ဂလိက်|ပူဂဵုတတိယ]]")
elseif subtypes.impers then -- decet, advesperāscit (also nopass)
insert(title, "[[impersonal verb#အၚ်္ဂလိက်|ဟၟဲကဵုပစ္စဲ]]")
end
if subtypes.depon then -- dēmōlior, calvor (also noperf)
insert(title, "[[deponent#အၚ်္ဂလိက်|ညးမဒစဵုဒစ]]")
end
if subtypes.perfaspres then -- meminī, ōdī
insert(title, "no [[present tense#အၚ်္ဂလိက်|ပစ္စုပ္ပန်]]ဟွံမွဲ")
-- If semidepon is set, only the active forms are affected.
local voice = subtypes.semidepon and "[[active voice#အၚ်္ဂလိက်|ပရေက်]]" or ""
insert(title, ("[[perfect tense#အၚ်္ဂလိက်|ဗီုပြၚ်မက္ဍိုပ်ပေၚ်]] %sမနွံကဵု [[present tense#အၚ်္ဂလိက်|ပစ္စုပ္ပန်]]အဓိပ္ပာဲ %s"):format(voice, voice))
-- Clarify that deponency can only apply to the perfect.
if subtypes.semidepon then -- ōdī
insert(title, "[[deponent#အၚ်္ဂလိက်|ညးမဟီုကဵုသ္ကေဝ်က္တောဝ်]]ပ္ဍဲဆေၚ်စပ်ကဵု[[perfect tense#အၚ်္ဂလိက်|ဗီုပြၚ်မက္ဍိုပ်ပေၚ်]]")
end
if subtypes.optsemidepon then
insert(title, "[[deponent#အၚ်္ဂလိက်|ညးမဒစဵုဒစ]]ပ္ဍဲဆေၚ်စပ်ကဵု[[perfect tense#အၚ်္ဂလိက်|မဟွံက္ဍိုက်ပေၚ်]]")
end
else
if subtypes.semidepon then -- fīdō, gaudeō
insert(title, "[[semi-deponent#အၚ်္ဂလိက်|သၚ်္ကေတ-မွဲကရေက်]]")
end
if subtypes.optsemidepon then -- audeō, placeō, soleō, pudeō
insert(title, "[[semi-deponent#အၚ်္ဂလိက်|သၚ်္ကေတ-မွဲကရေက်]]တဴရဴအတိုၚ်ပၟိက်")
end
end
if subtypes.imponly then -- cedo, apage
insert(title, "ပါဲနူ-[[imperative mood#အၚ်္ဂလိက်|ဟွံက္ဍိုပ်ပေၚ်]]")
end
if subtypes.nopass then -- coacēscō
insert(title, "[[passive voice#အၚ်္ဂလိက်|ဟွံတဝ်စၞေဟ်]]ဟွံသေၚ်")
end
local stems = {}
if subtypes.nopres then -- coepī; perfaspres already handles this above
insert(stems, "[[present tense#အၚ်္ဂလိက်|ပစ္စုပ္ပန်]]")
end
if subtypes.noperf then
insert(stems, "[[perfect tense#အၚ်္ဂလိက်|ဟွံက္ဍိုက်ပေၚ်]]")
end
if subtypes.nosup or subtypes.supfutractvonly then
insert(stems, "[[supine#အၚ်္ဂလိက်|ဂၠဝ်]]")
end
if #stems > 0 then
local extra = subtypes.supfutractvonly and "ပါဲကၠေံပ္ဍဲဆေၚ်စပ်ကဵု[[participle#အၚ်္ဂလိက်|မကၠောန်စွံလဝ်]][[active voice#အၚ်္ဂလိက်|မစိုပ်တရဴ]][[future tense#အၚ်္ဂလိက်|အနာဂတ်]]"
insert(title, ("no %s stem%s%s"):format(serial_comma_join(stems, {conj = "or"}), #stems > 1 and "s" or "", extra or ""))
end
if subtypes.nofutr then -- soleō
insert(title, "[[future tense#အၚ်္ဂလိက်|အနာဂတ်]]ဟွံသေၚ်")
end
if subtypes.pass3only then -- praefundō
insert(title, "ပါဲနူ-[[third person#အၚ်္ဂလိက်|ပူဂဵုတတိယ]]ပ္ဍဲဆေၚ်စပ်ကဵု[[passive voice#အၚ်္ဂလိက်|ဟွံတဝ်စၞေဟ်]]")
elseif subtypes.passimpers then -- abambulō
local msg = "[[impersonal verb#အၚ်္ဂလိက်|ဟွဲမွဲကဵုပစ္စဲပူဂဵု]]ပ္ဍဲဆေၚ်စပ်ကဵု[[passive voice#အၚ်္ဂလိက်|ဟွံတဝ်စၞေဟ်]]"
if subtypes.passimpersold then -- possum
msg = msg .. " ပ္ဍဲ[[Old Latin|လပ်တေန်တြေံ]]"
end
insert(title, msg)
end
if subtypes.noimp then -- volō
insert(title, "[[imperative mood#အၚ်္ဂလိက်|မက္ဍိုပ်ပေၚ်]]ဟွံသေၚ်")
end
if irreg_processing and umatch(first_lemma, "d[īū]cō$") then -- dīcō
insert(title, "[[:en:Appendix:Latin irregular verbs|ခလံက်ခနက်]]ဂၠေံဂၠေံ[[imperative mood#အၚ်္ဂလိက်|မက္ဍိုပ်ပေၚ်]]")
end
if subtypes.nofutractvptc and not subtypes.nosup then -- fīō
insert(title, "[[participle#အၚ်္ဂလိက်|မကၠောန်စွံလဝ်]][[active voice#အၚ်္ဂလိက်|စိုပ်တရဴ]][[future tense#အၚ်္ဂလိက်|အနာဂတ်]]ဟွံသေၚ်")
end
if not (subtypes.nopres or subtypes.perfaspres or subtypes.imponly) then
if subtypes.noinf then -- inquam
insert(title, "[[infinitive#အၚ်္ဂလိက်|မသ္ကာတ်မြဟ်]]ဟွံသေၚ်")
end
if subtypes.noger then -- libet
insert(title, "[[gerund#အၚ်္ဂလိက်|နာမ်လက္ခဏာ]]ဟွံသေၚ်")
end
end
if subtypes.shorta then -- dō
insert(title, ("[[:en:Appendix:Latin irregular verbs|ခလံက်ခနက်]]ဂၠေံဂၠေံ %s ပ္ဍဲဗီုပြၚ်မဂၠိုၚ်လတုန်"):format(make_link(nil, "ă", "term")))
end
if irreg_processing then
if first_lemma:match("edō$") then -- edō
insert(title, "ဗီုပြၚ်[[:en:Appendix:Latin irregular verbs|ခလံက်ခနက်]]မရုဲစှ်ေကေတ်")
elseif first_lemma:match("fīō$") then -- fīō
insert(title, "[[:en:Appendix:Latin irregular verbs|ခလံက်ခနက်]]မဂၠိၚ်" .. make_link(nil, "ī", "term"))
end
end
end
pos_functions["ကြိယာ"] = function(def, args, data, infl_classes, title)
local m_la_verb = require("Module:la-verb")
local def1, def2
if def then
def1, def2 = def:match("^(.-):(.*)$")
end
local conjdata, typeinfo = m_la_verb.make_data(args, true, def1, def2)
local lemma_forms = conjdata.overriding_lemma
if not lemma_forms or #lemma_forms == 0 then
lemma_forms = m_la_verb.get_lemma_forms(conjdata, true)
end
data.heads = lemma_forms
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-verb}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = conjdata.id
local perf_only = false
local function insert_inflection(infl, label)
infl.label = label
insert(data.inflections, infl)
end
local inf = m_la_verb.get_valid_forms(conjdata.forms["pres_actv_inf"])
if #inf > 0 then
insert_inflection(inf, "စၞးကြိယာပစ္စုပ္ပန်")
else
inf = m_la_verb.get_valid_forms(conjdata.forms["perf_actv_inf"])
if #inf > 0 then
perf_only = true
insert_inflection(inf, "စၞးကြိယာမဍိုက်ပေၚ်")
end
end
if not perf_only then
local perf = m_la_verb.get_valid_forms(conjdata.forms["1s_perf_actv_indc"])
if #perf == 0 then
perf = m_la_verb.get_valid_forms(conjdata.forms["3s_perf_actv_indc"])
end
if #perf > 0 then
insert_inflection(perf, "မဍိုက်ပေၚ်စိုပ်တရဴ")
end
end
local subtypes = typeinfo.subtypes
if not (subtypes.depon or subtypes.semidepon) then
local sup = m_la_verb.get_valid_forms(conjdata.forms["acc_sup"])
if #sup > 0 then
insert_inflection(sup, "ဂၠဝ်")
else
local fap = m_la_verb.get_valid_forms(conjdata.forms["futr_actv_ptc"])
if #fap > 0 then
insert_inflection(fap, "လုပ်ကၠောန်စွံလဝ်အနာဂတ်မစိုပ်တရဴ")
end
end
end
export.verb_title(title, typeinfo, lemma_forms)
end
pos_functions["ကြိယာအဆက်လက္ကရဴ"] = pos_functions["ကြိယာ"]
local function attested_form(decldata, index)
local form
if (decldata.unattested[index]) then
form = { { term = '*' .. decldata.forms[index][1], nolink = true } }
else
form = decldata.forms[index]
end
return form
end
local function degree_derivations(comp, sup, data)
local inflections = data.inflections
if not (comp or sup) then
return
elseif (not comp or comp == "-") and (not sup or sup == "-") then
insert(inflections, {label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#comparative|ပတုပ်ရံၚ်]]ဟွံမာန်"})
insert_if_not(data.categories, "ကြိယာဝိသေသနလပ်တေန်မတော်ဟွံဂွံဂမၠိုၚ်")
return
elseif comp == "-" then
insert(inflections, {label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#comparative|ပတုပ်ရံၚ်]]ဟွံသေၚ်"})
elseif comp then
insert(inflections, comp)
end
if sup == "-" then
insert(inflections, {label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#superlative|သဒ္ဒာ]]ဟွံသေၚ်"})
elseif sup then
insert(inflections, sup)
end
end
local function adjectives(pos, def, args, data, infl_classes)
local is_num = pos == "ဂၞန်သၚ်္ချာ"
local decldata = require("Module:la-nominal").do_generate_adj_forms(args, pos, "headword", nil, def)
local lemma = decldata.overriding_lemma
-- TODO: modify the headword line if the slot isn't the expected one.
if #lemma == 0 then
for slot in require("Module:la-nominal").iter_potential_adj_lemma_slots() do
local potential_lemma = decldata.forms["linked_" .. slot]
if not form_is_empty(potential_lemma) then
if decldata.unattested[slot] then
potential_lemma = "*" .. potential_lemma
end
lemma = potential_lemma
break
end
end
end
data.heads = lemma
-- Since we always set data.heads to the lemma and specification of the lemma is mandatory in {{la-noun}}, there aren't
-- really any redundant heads.
data.no_redundant_head_cat = true
data.id = decldata.id
local categories = data.categories
if is_num then
process_num_type(decldata.num_type, categories)
end
if decldata.num == "pl" then
insert_if_not(categories, decldata.pos .. "လပ်တေန်ပါဲနူကိုန်ဗဟုဝစ်ဂမၠိုၚ်")
end
if decldata.indecl then
insert(data.inflections, {label = glossary_link("ပြံၚ်လှာဲဟွံမာန်")})
if decldata.pos == "လုပ်ကၠောန်စွံလဝ်" then
local lemma1 = lemma[1]
if lemma1:sub(-4) == "ndum" then
insert_if_not(categories, "လုပ်ကၠောန်စွံလဝ်နကဵုဟွံတဝ်စၞေဟ်အနာဂတ်လပ်တေန်ဂမၠိုၚ်")
elseif lemma1:match("um$") then
insert_if_not(categories, "လုပ်ကၠောန်စွံလဝ်နကဵုမဍိုက်ပေၚ်လပ်တေန်ဂမၠိုၚ်")
end
end
else
local lemma_num = decldata.num == "pl" and "pl" or "sg"
local masc = decldata.forms["nom_" .. lemma_num .. "_m"]
local fem = attested_form(decldata, "nom_" .. lemma_num .. "_f")
local neut = attested_form(decldata, "nom_" .. lemma_num .. "_n")
local gen = attested_form(decldata, "gen_" .. lemma_num .. "_m")
local acc = attested_form(decldata, "acc_" .. lemma_num .. "_m")
if decldata.pos == "လုပ်ကၠောန်စွံလဝ်" then
local masc1 = masc[1]
if masc1:sub(-5) == "ūrus" then
insert_if_not(categories, "လပ်တေန်လုပ်ကၠောန်စွံလဝ်နကဵုအနာဂတ်မစိုပ်တရဴဂမၠိုၚ်")
elseif masc1:sub(-4) == "ndus" then
-- FIXME, should rename to "Latin gerundives")
insert_if_not(categories, "လုပ်ကၠောန်စွံလဝ်နကဵုမဍိုက်ပေၚ်တဴအနာဂတ်လပ်တေန်ဂမၠိုၚ်")
else
local masc1_final2 = masc1:sub(-2)
if masc1_final2 == "us" then
insert_if_not(categories, "လုပ်ကၠောန်စွံလဝ်နကဵုမဍိုက်ပေၚ်လပ်တေန်ဂမၠိုၚ်")
elseif masc1_final2 == "ns" then
insert_if_not(categories, "လုပ်ကၠောန်စွံလဝ်ပစ္စုပ္ပန်လပ်တေန်ဂမၠိုၚ်")
else
error("Unrecognized participle ending: " .. masc1)
end
end
end
-- We display the inflections in three different ways to mimic the
-- old way of doing things:
--
-- 1. If masc and fem are different, show masc, fem and neut.
-- 2. Otherwise, if masc and neut are different, show masc and neut.
-- 3. Otherwise, show masc nominative and masc genitive.
if not form_is_empty(fem) and not deep_equals(masc, fem) then
fem.label = "ဣတ္တိလိၚ်"
insert(data.inflections, fem)
if not form_is_empty(neut) then
neut.label = "နပုလ္လိၚ်"
insert(data.inflections, neut)
end
elseif not form_is_empty(neut) and not deep_equals(masc, neut) then
neut.label = "နပုလ္လိၚ်"
insert(data.inflections, neut)
elseif not form_is_empty(gen) then
gen.label = "ဗဳဂဇကူ"
insert(data.inflections, gen)
elseif not form_is_empty(acc) then
acc.label = "ကမ္မကာရက"
insert(data.inflections, acc)
end
insert(infl_classes, decldata.title)
end
local comp = normalize_derivation(decldata.comp, "ပတုပ်ရံၚ်")
local sup = normalize_derivation(decldata.sup, "သဒ္ဒာ")
degree_derivations(comp, sup, data)
derivation(data, decldata, "adv", "ကြိယာဝိသေသန")
for _, cat in ipairs(decldata.categories) do
insert_if_not(categories, cat)
end
for _, cat in ipairs(decldata.cat) do
insert_if_not(categories, cat .. "လပ်တေန်ဂမၠိုၚ်")
end
return decldata.pos
end
pos_functions["နာမဝိသေသန"] = function(def, args, data, infl_classes, title)
return adjectives("နာမဝိသေသန", def, args, data, infl_classes, title)
end
pos_functions["လုပ်ကၠောန်စွံလဝ်"] = function(def, args, data, infl_classes, title)
return adjectives("လုပ်ကၠောန်စွံလဝ်", def, args, data, infl_classes, title)
end
pos_functions["ဖျေံလဝ်သန္နိဋ္ဌာန်"] = function(def, args, data, infl_classes, title)
return adjectives("ဖျေံလဝ်သန္နိဋ္ဌာန်", def, args, data, infl_classes, title)
end
pos_functions["သဗ္ဗနာမ်"] = function(def, args, data, infl_classes, title)
return adjectives("သဗ္ဗနာမ်", def, args, data, infl_classes, title)
end
pos_functions["နာမဝိသေသနအဆက်လက္ကရဴ"] = function(def, args, data, infl_classes, title)
return adjectives("အဆက်လက္ကရဴ", def, args, data, infl_classes, title)
end
pos_functions["ဂၞန်သၚ်္ချာနာမဝိသေသန"] = function(def, args, data, infl_classes, title)
return adjectives("ဂၞန်သၚ်္ချာ", def, args, data, infl_classes, title)
end
pos_functions["ကြိယာဝိသေသန"] = function(def, args, data)
local sublist = {sublist = "/"}
args = require("Module:parameters").process(args, {
[1] = {alias_of = "head", list = false},
[2] = {alias_of = "တုဲဒှ်"},
[3] = {alias_of = "ညိည"},
["head"] = {list = true, required = true},
["တုဲဒှ်"] = sublist,
["ညိည"] = sublist,
["adj"] = sublist,
["id"] = true,
})
data.heads = args.head
data.no_redundant_head_cat = true -- since head= is required
data.id = args.id
local comp, sup = args.comp, args.sup
local irreg = false
if comp then
if comp[1] == "-" then
comp = "-"
elseif comp[1] == nil then
comp = nil
else
comp.label = glossary_link("ပတုပ်ရံၚ်")
comp = args.comp
irreg = true
end
end
if sup then
if sup[1] == "-" then
sup = "-"
elseif sup[1] == nil then
sup = nil
else
sup.label = glossary_link("သဒ္ဒာ")
sup = args.sup
irreg = true
end
end
local categories = data.categories
if irreg then
insert_if_not(categories, "ကြိယာဝိသေသနလပ်တေန်မဗၠေတ်မံၚ်နကဵုအတိုၚ်ပကတိဂမၠိုၚ်")
end
if not (comp or sup) then
local default_comp = {label = glossary_link("ပတုပ်ရံၚ်")}
local default_sup = {label = glossary_link("သဒ္ဒာ")}
for _, head in ipairs(args.head) do
local stem = nil
for _, suff in ipairs{"iter", "nter", "ter", "er", "iē", "ē", "rā", "im", "ō"} do
stem = head:match("(.*)" .. pattern_escape(suff) .. "$")
comp_suff, sup_suff = "ius", "issimē"
if stem ~= nil then
if suff == "nter" then
stem = stem .. "nt"
elseif suff == "rā" then
comp_suff = "er" .. comp_suff
sup_suff = "imē"
end
insert(default_comp, stem .. comp_suff)
insert(default_sup, stem .. sup_suff)
break
end
end
if not stem then
error("Unrecognized adverb type, recognized types are “-ē”, “-er”, “-ter”, “-iter”, “-im”, or “-ō”, “-ra” or specify irregular forms or “-” if incomparable.")
end
end
comp = comp or default_comp
sup = sup or default_sup
end
degree_derivations(comp, sup, data)
derivation(data, args, "adj", "နာမဝိသေသန")
end
pos_functions["ကြိယာဝိသေသနအဆက်လက္ကရဴ"] = pos_functions["ကြိယာဝိသေသန"]
local function get_forms(forms)
if #forms == 0 then
return nil
end
local i, attested = 1, false
while true do
local form = forms[i]
if form == nil then
return forms, attested
elseif form == "-" then
remove(forms, i)
else
if not (attested or get_plaintext(form):sub(1, 1) == "*") then
attested = true
end
i = i + 1
end
end
end
local function degree(pos, deg, pos_func, other_pos, other_pos_label, other_deg, other_deg_label, args, data, infl_classes)
local list = {list = true}
args = require("Module:parameters").process(args, {
[1] = {alias_of = "head", list = false},
["head"] = list,
["positive"] = list,
[other_pos] = {sublist = "/"},
[other_deg] = list,
["id"] = true,
})
data.no_redundant_head_cat = #args.head == 0
-- Set default manually so we can tell whether the user specified head=.
if #args.head == 0 then
args.head = {PAGENAME}
end
data.heads = args.head
data.id = args.id
insert(data.inflections, {label = deg})
if pos_func then
pos_func(args, data, infl_classes)
end
local positive, positive_attested = get_forms(args.positive)
if positive then
if not positive_attested then
insert(data.categories, pos .. "လပ်တေန်ပါဲနူ" .. deg .. "ဂမၠိုၚ်")
end
if #positive > 0 then
args.positive.label = "မချိုတ်ပၠိုတ်"
insert(data.inflections, args.positive)
else
insert(data.inflections, {label = "ဗီုပြၚ်မချိုတ်ပၠိုတ်ဟွံသေၚ်"})
end
end
local other = get_forms(args[other_deg])
if other then
if #other > 0 then
args[other_deg].label = other_deg_label
insert(data.inflections, args[other_deg])
else
insert(data.inflections, {label = "ဗီုပြၚ်" .. other_deg_label .. "ဟွံသေၚ်"})
end
end
derivation(data, args, other_pos, other_pos_label)
-- If a lemma, return the primary part of speech ("adjectives" or
-- "adverbs"), so that the term is categorized in "Latin adjectives" or
-- "Latin adverbs". Otherwise, return nothing, so that the term goes in the
-- relevant non-lemma category (e.g. "Latin comparative adjectives"), and
-- into "Latin non-lemma forms".
if positive and not positive_attested then
return pos
end
end
local function comp_adj(args, data, infl_classes)
insert(infl_classes, "[[Appendix:လပ်တေန်မလဟုတ်စှ်ေအလန်တတိယ|မလဟုတ်စှ်ေအလန်တတိယ]]")
local n = {label = "neuter"}
for _, head in ipairs(args.head) do
local neuter = head:gsub("or$", "us")
insert(n, neuter)
end
insert(data.inflections, n)
end
pos_functions["နာမဝိသေသနပတုပ်ရံၚ်"] = function(def, args, data, infl_classes, title)
return degree("နာမဝိသေသန", "ပတုပ်ရံၚ်", comp_adj, "adv", "ကြိယာဝိသေသန", "ညိည", "သဒ္ဒာ", args, data, infl_classes)
end
pos_functions["ကြိယာဝိသေသနပတုပ်ရံၚ်"] = function(def, args, data, infl_classes, title)
return degree("ကြိယာဝိသေသန", "ပတုပ်ရံၚ်", nil, "adj", "နာမဝိသေသန", "ညိည", "သဒ္ဒာ", args, data, infl_classes)
end
local function sup_adj(args, data, infl_classes)
insert(infl_classes, "[[Appendix:လပ်တေန်မလဟုတ်စှ်ေအလန်ပဌမ|ပဌမ]]")
insert(infl_classes, "[[Appendix:လပ်တေန်မလဟုတ်စှ်ေအလန်ဒုတိယ|မလဟုတ်စှ်ေအလန်ဒုတိယ]]")
local f, n = {label = "ဣတ္တိလိၚ်"}, {label = "နပုလ္လိၚ်"}
for _, head in ipairs(args.head) do
local stem = head:gsub("us$", "")
insert(f, stem .. "a")
insert(n, stem .. "um")
end
insert(data.inflections, f)
insert(data.inflections, n)
end
pos_functions["သဒ္ဒာနာမဝိသေသန"] = function(def, args, data, infl_classes, title)
return degree("နာမဝိသေသန", "သဒ္ဒာ", sup_adj, "adv", "ကြိယာဝိသေသန", "တုဲဒှ်", "ပတုပ်ရံၚ်", args, data, infl_classes)
end
pos_functions["သဒ္ဒာကြိယာဝိသေသန"] = function(def, args, data, infl_classes, title)
return degree("ကြိယာဝိသေသန", "သဒ္ဒာ", nil, "adj", "နာမဝိသေသန", "တုဲဒှ်", "ပတုပ်ရံၚ်", args, data, infl_classes)
end
local function adpositions(pos, def, args, data, infl_classes, title, postscript)
local cases = invert(require("Module:la-utilities").cases)
args = require("Module:parameters").process(args, {
[1] = {alias_of = "head", list = false},
[2] = {list = true, set = keys_to_list(cases)},
["head"] = {list = true, required = true},
["id"] = true,
})
-- Case names are supplied in numbered arguments, optionally preceded by
-- headwords.
cases = args[2]
for i = 1, #cases do
for j = i + 1, #cases do
if cases[i] == cases[j] then
error("Duplicate case")
end
end
local case = cases[i]
local appendix_link = glossary_link(case)
if i == 1 then
appendix_link = "+ " .. appendix_link
end
insert(postscript, appendix_link)
insert_if_not(data.categories, pos .. case .. "လပ်တေန်ဂမၠိုၚ်")
end
data.heads = args.head
data.no_redundant_head_cat = true -- since head= is required
data.id = args.id
end
pos_functions["ဝိဘတ်"] = function(...)
return adpositions("ဝိဘတ်", ...)
end
pos_functions["ကဆံၚ်အကာဲအရာ"] = function(...)
return adpositions("ကဆံၚ်အကာဲအရာ", ...)
end
pos_functions["gerunds"] = function(def, args, data)
args = require("Module:parameters").process(args, {
[1] = {required = true, default = "labōrandum"}, -- headword
[2] = true, -- gerundive
})
data.heads = {args[1]}
data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
insert(data.inflections, {label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#accusative|ဝေါဟာဂကန်ဖျန်]]"})
local stem = args[1]:match("^(.*)um$")
if not stem then
error("Unrecognized gerund ending: " .. stem)
end
if args[2] == "-" then
insert(data.inflections, {label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#gerundive|ဟိုၚ်ပိုၚ်ကၠုၚ်နူဂဝ်]]ဟွံမွဲ"})
else
insert(data.inflections, {[1] = args[2] or stem .. "ရပ်စပ်", label = "[[အဆက်လက္ကရဴ:မသောၚ်ကၠးဝေါဟာ#gerundive|ဟိုၚ်ပိုၚ်ကၠုၚ်နူဂဝ်]]"})
end
end
local function non_lemma_forms(def, args, data)
args = require("Module:parameters").process(args, {
[1] = {required = true, default = def}, -- headword or cases
["head"] = {list = true, require_index = true},
["g"] = {list = true},
["id"] = true,
})
local heads = {args[1]}
for _, head in ipairs(args.head) do
insert(heads, head)
end
data.heads = heads
data.no_redundant_head_cat = true -- since 1= is required and goes into data.heads
data.genders = args.g
data.id = args.id
end
pos_functions["ဗီုပြၚ်နာမ်"] = non_lemma_forms
pos_functions["ဗီုပြၚ်နာမ်မကိတ်ညဳ"] = non_lemma_forms
pos_functions["ဗီုပြၚ်သဗ္ဗနာမ်"] = non_lemma_forms
pos_functions["ဗီုပြၚ်ကြိယာ"] = non_lemma_forms
pos_functions["gerund forms"] = non_lemma_forms
pos_functions["ဗီုပြၚ်နာမဝိသေသန"] = non_lemma_forms
pos_functions["ဗီုပြၚ်လုပ်ကၠောန်စွံလဝ်"] = non_lemma_forms
pos_functions["ဗီုပြၚ်ဖျေံလဝ်သန္နိဋ္ဌာန်"] = non_lemma_forms
pos_functions["ဗီုပြၚ်ဂၞန်သၚ်္ချာ"] = non_lemma_forms
pos_functions["ဗီုပြၚ်အဆက်လက္ကရဴ"] = non_lemma_forms
return export
9o04xneyi0qeno8yq3toc1wd7tdoskp
မဝ်ဂျူ:grc-decl
828
26035
397283
136540
2026-06-21T08:30:12Z
咽頭べさ
33
397283
Scribunto
text/plain
local export = {}
local module_path = 'Module:grc-decl'
local m_grc_decl_table = require(module_path .. '/table')
local m_grc_decl_decl = require(module_path .. '/decl')
local m_params = mw.loadData(module_path .. "/params")
local m_table = require('Module:table')
local usub = mw.ustring.sub
local ufind = mw.ustring.find
local decompose = mw.ustring.toNFD
local shared = require('Module:grc-decl/shared')
local quote, track = shared.quote, shared.track
local function handle_unrecognized_args(unrecognized_args, adjective)
-- Next returns nil if table is empty.
if next(unrecognized_args) then
local template_name = adjective and 'grc-adecl' or 'grc-decl'
local track = track(template_name)
track("unrecognized args")
local unrecognized_list = m_table.keysToList(unrecognized_args)
local agreement = #unrecognized_list > 1 and "s" or ""
mw.addWarning("unrecognized argument" .. agreement .. " in " ..
require("Module:string/nowiki")("{{" .. template_name .. "}}") .. ": " ..
table.concat(unrecognized_list, ", ") ..
"; see Module:grc-decl/params for a full list of recognized args")
end
end
local function swap_args(args, suffix)
--This function has undefined behavior if both <arg> and <arg><suffix> are
--specified; use e.g. <arg>1 and <arg>2 instead.
local args_ = args
args = {}
for code, value in pairs(args_) do
if type(code) == 'number' then
args[code] = value
else
-- Removes suffix from the end of string keys.
args[code:gsub(suffix .. '$', '')] = value
end
end
end
local function interpret_form(args, form_param, is_adjective)
if type(form_param) ~= 'string' then
return {}, {}, nil, nil
end
local no_article = form_param:find('X') and true or false
if no_article and is_adjective then
error('Adjectives cannot have articles. Remove ' .. quote('X') ..
' option in the ' .. quote('form') .. ' parameter.')
end
-- Convert sing, dual, plur to S, D, P.
-- Remove other lowercase letters. This removes "con" and "open".
local number_codes = { sing = true, dual = true, plur = true }
local contracted, comparative, like_adjective
local new_form = form_param:gsub('((%l)%l+)', function(wholematch, initial)
if wholematch == 'con' then
contracted = true
elseif wholematch == 'open' then
contracted = false
elseif wholematch == 'comp' then
comparative = true
elseif wholematch == 'adj' or wholematch == 'adjective' then
like_adjective = true
elseif number_codes[wholematch] then
return initial:upper()
end
return ''
end)
--[[
Returns tables containing all genders and numbers.
For instance, for nouns that are variably masculine or feminine:
args.gender { "M", "F", ["M"] = true, ["F"] = true }
args.number { "S", "D", "P", ["S"] = true, ["D"] = true, ["P"] = true }
Not sure if the sequential entries are needed.
]]
-- Find contiguous gender abbreviations.
local genders = new_form:match("[MFN]+")
if is_adjective and genders then
error("Adjectives cannot have gender specified in the form parameter.")
end
-- Find number abbreviations.
-- If no number, assume all numbers will be displayed.
-- Koine and Byzantine have no dual.
local numbers = new_form:gsub('[^SDP]+', '')
if numbers == '' then
local dial = args.dial
numbers = (dial == 'koi' or dial == 'byz') and 'SP' or 'SDP'
end
if genders then
genders = mw.text.split(genders, "")
for i, gender in ipairs(genders) do
if gender == "" then
genders[i] = nil
else
genders[gender] = true
end
end
if genders.N and ( genders.M or genders.F ) then
error("A noun cannot be neuter and another gender at the same time.")
end
else
genders = {}
end
if numbers then
numbers = mw.text.split(numbers, "")
for i, number in ipairs(numbers) do
if number == "" then
numbers[i] = nil
else
numbers[number] = true
end
end
if numbers.S and numbers.D and numbers.P then
numbers.F = true
end
else
numbers = {}
end
return genders, numbers, no_article, contracted, comparative, is_adjective or like_adjective
end
-- Canonicalize specially-handled dialect codes.
-- TODO: use a table and cover all dialects
local function handle_dialect(dialect)
if dialect == "Homeric" then
dialect = "hom"
elseif dialect == "Attic" then
dialect = "att"
elseif dialect == "Epic" then
dialect = "epi"
elseif dialect == "Ionic" then
dialect = "ion"
elseif dialect == "Koine" then
dialect = "koi"
elseif dialect == "Byzantine" then
dialect = "byz"
elseif dialect == "gkm" then
dialect = "byz"
end
if dialect == "hom" then
dialect = "epi"
end
return dialect
end
local function handle_unmarked_length(arg1, arg2, adjective)
local old_arg1, old_arg2 = arg1, arg2
if arg2 then
local m_accent = require("Module:grc-accent")
local m_utilities = require("Module:grc-utilities")
local standard_diacritics = m_utilities.standardDiacritics
local reorder_diacritics = m_utilities.reorderDiacritics
if arg1 == 'irreg' or arg1 == 'indecl' then
arg2 = m_accent.mark_implied_length(
reorder_diacritics(standard_diacritics(arg2)))
else
arg1, arg2 = m_accent.harmonize_length(
reorder_diacritics(standard_diacritics(arg1)),
reorder_diacritics(standard_diacritics(arg2)))
end
end
local track = track(adjective and 'grc-adecl' or 'grc-decl')
--[=[
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/length marked on arg1]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/length marked on arg2]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/length marked on arg1]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/length marked on arg2]]
]=]
if old_arg1 and arg1 ~= decompose(old_arg1) then
track('length marked on arg1')
end
if old_arg2 and arg2 ~= decompose(old_arg2) then
track('length marked on arg2')
end
return arg1, arg2
end
local function get_args(args, is_adjective, function_name)
-- Have to process args[1] before 'irreg' or 'indecl' is checked for.
local arg1 = mw.text.trim(args[1])
if arg1 == '' then arg1 = nil end
local irreg = arg1 == 'irreg'
local indecl = arg1 == 'indecl'
local form_param = args.form
-- [[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/empty comp or super]]
if is_adjective and args.deg and not (args.deg == 'comp' or args.deg == 'super') then
error('Adjective degree ' .. quote(args.deg) .. ' not recognized.')
end
local dialect_code
local params = m_params[(irreg and 'irreg_' or '') ..
(irreg and form_param and form_param:find('N') and 'N_' or '') ..
(is_adjective and 'adj_' or 'noun_') ..
'params']
local args, unrecognized_args = require('Module:parameters').process(args, params, true, "grc-decl", function_name)
handle_unrecognized_args(unrecognized_args, is_adjective)
form_param, dialect_code = args.form, args.dial
args.maxindex = m_table.length(params)
if irreg then
require('Module:debug').track('grc-decl/irreg')
end
if is_adjective then
args.adjective = true
args.atable = {}
if args.hp then
track('grc-adecl', 'hp')
end
end
args[1], args[2] = handle_unmarked_length(args[1], args[2], is_adjective)
local arg2 = args[2]
args.dial = handle_dialect(dialect_code)
args.gender, args.number, args.no_article, args.contracted, args.comparative, args.like_adjective = interpret_form(args, form_param, is_adjective)
if args.comparative then
if (arg2 or args.dial ~= 'att' or not arg1:find("ον$")) then
error("|form=comp is only meant for Attic third-declension comparatives with a stem in " .. quote("-ον") .. ".")
end
if args.deg then
error('|form=comp not needed when |deg=comp is set.')
end
end
if args.deg == 'comp' then
args.comparative = true
elseif args.deg == 'super' then
args.superlative = true
end
args.indeclinable, args.irregular = indecl, irreg
args.categories = {}
local track = track(is_adjective and 'grc-adecl' or 'grc-decl')
if ((arg1 or '') .. (arg2 or '')):find('˘') then
track('manual-breve')
end
if args.titleapp then
track('titleapp')
end
for _, v in ipairs({ 'titleapp', 'titleapp1', 'titleapp2' }) do
if args[v] then
args[v] = mw.text.split(args[v], '%s*[/,]%s*')
else
args[v] = {}
end
end
for _, v in ipairs({ 'notes', 'notes1', 'notes2' }) do
if args[v] then
args['user_' .. v] = args[v] --convert 'notes' to 'user_notes'
args[v] = {}
else
args[v] = {}
end
end
args.form_cache = {}
return args
end
--[=[
-- This function is an entry point for testing noun functionality only
-- ]=]
function export.test_decl(frame)
local args = get_args(frame, false, "test_decl")
m_grc_decl_decl.get_decl(args)
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
return args
end
-- These conditions should be mutually exclusive so that we don't need two
-- separate functions.
local function uncontracted_condition(dialect, contracted)
return dialect == 'ion' or dialect == 'epi'
or not (contracted == true or dialect == 'att')
end
local function contracted_condition(dialect, contracted)
return not (dialect == 'ion' or dialect == 'epi' or contracted == false)
end
function export.decl(frame)
local args = get_args(frame:getParent().args, false, "decl")
m_grc_decl_decl.get_decl(args)
if args.root:sub(1, 1) == '-' and not args.form:find('[MFN]') then
args.no_article = true
end
if args.decl_type:find('2nd') and not args.decl_type:find('N') and not args.form:find('[MFN]') then
table.insert(args.categories, 'Ancient Greek second-declension nouns without gender specified')
end
if args.decl_type:find('κλῆς') or ufind(args.decl_type, '[ᾰε]σ') then
local out = {}
if uncontracted_condition(args.dial, args.contracted) then
args.titleapp = {}
swap_args(args, 1)
table.insert(args.titleapp, 'uncontracted')
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
table.insert(out, m_grc_decl_table.make_table(args))
end
if contracted_condition(args.dial, args.contracted) then
args.titleapp = {}
swap_args(args, 2)
table.insert(args.titleapp, '[[Appendix:Ancient Greek contraction|contracted]]')
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
table.insert(out, m_grc_decl_table.make_table(args))
end
return table.concat(out, '\n')
else
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
return m_grc_decl_table.make_table(args)
end
end
--[=[
-- This function is an entry point for testing adjective functionality only
-- ]=]
function export.test_adecl(frame)
local args = get_args(frame, true, "test_adecl")
m_grc_decl_decl.get_decl_adj(args)
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
return args
end
function export.adecl(frame)
local args = get_args(frame:getParent().args, true, "adecl")
m_grc_decl_decl.get_decl_adj(args)
if m_grc_decl_decl.adjinflections_con[args.decl_type] then
local out = {}
if uncontracted_condition(args.dial, args.contracted) then
args.titleapp, args.notes, args.categories = {}, {}, {}
swap_args(args, 1)
table.insert(args.titleapp, 'uncontracted')
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
table.insert(out, m_grc_decl_table.make_table_adj(args))
end
if contracted_condition(args.dial, args.contracted) then
args.titleapp, args.notes, args.categories = {}, {}, {}
swap_args(args, 2)
table.insert(args.titleapp, '[[Appendix:Ancient Greek contraction|contracted]]')
args.act = m_grc_decl_decl.adjinflections_con[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections_con[args.decl_type])
table.insert(out, m_grc_decl_table.make_table_adj(args))
end
return table.concat(out, '\n')
else
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
return m_grc_decl_table.make_table_adj(args)
end
end
local function tag(text)
local lang = require("Module:languages").getByCode("grc")
return require("Module:script utilities").tag_text(text, lang)
end
function export.show_noun_forms(frame)
local args = get_args(frame.args[1] and frame.args or frame:getParent().args, false, "show_noun_forms")
m_grc_decl_decl.get_decl(args)
local success, message = pcall(m_grc_decl_decl.make_decl, args, args.decl_type, args.root)
if not success then
return 'Declension generation failed for ' .. args[1] .. (args[2] and ', ' .. args[2] or '') .. ': ' ..
message
end
-- mw.logObject(args)
local inflections = args.ctable
local cases = { "N", "A", "V", "G", "D" }
local numbers = { "S", "D", "P" }
local out = { "\n* " .. tag(args[1]) .. ", " .. tag(args[2]) }
for _, number in ipairs(numbers) do
table.insert(out, "\n** ")
local number_forms = {}
for _, case in ipairs(cases) do
local code = case .. number
local form = inflections[code]
if form then
table.insert(number_forms, tag(form))
end
end
number_forms = table.concat(number_forms, ", ")
table.insert(out, number_forms)
end
return table.concat(out)
end
function export.show_adj_forms(frame)
local args = get_args(frame.args[1] and frame.args or frame:getParent().args, true, "show_adj_forms")
m_grc_decl_decl.get_decl_adj(args)
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
-- mw.logObject(args)
local function print(key, value)
return key .. " = " .. "'" .. value .. "', "
end
local inflections = args.atable
local genders = { "M", "F", "N" }
local numbers = { "S", "D", "P" }
local cases = { "N", "A", "V", "G", "D" }
local out = {}
table.insert(out, "{ '" .. args[1] .. "'")
if args[2] then
table.insert(out, ", '" .. args[2] .. "'")
end
table.insert(out, " },\n{")
for _, gender in pairs(genders) do
table.insert(out, "\n\t")
for _, number in pairs(numbers) do
for _, case in pairs(cases) do
local code = gender .. case .. number
local form = inflections[code]
if form then
table.insert(out, print(code, form))
end
end
end
end
table.insert(out, "\n\t")
local forms = { "adv", "comp", "super" }
for _, form in pairs(forms) do
if inflections[form] then
table.insert(out, print(form, inflections[form]))
end
end
table.insert(out, "\n},")
return frame:extensionTag("source", table.concat(out), {lang = "lua"})
end
return export
pgmtulonmtrk4bjk13v9giru070hedw
397298
397283
2026-06-21T09:36:17Z
咽頭べさ
33
397298
Scribunto
text/plain
local export = {}
local module_path = 'Module:grc-decl'
local m_grc_decl_table = require(module_path .. '/table')
local m_grc_decl_decl = require(module_path .. '/decl')
local m_params = mw.loadData(module_path .. "/params")
local m_table = require('Module:table')
local usub = mw.ustring.sub
local ufind = mw.ustring.find
local decompose = mw.ustring.toNFD
local shared = require('Module:grc-decl/shared')
local quote, track = shared.quote, shared.track
local function handle_unrecognized_args(unrecognized_args, adjective)
-- Next returns nil if table is empty.
if next(unrecognized_args) then
local template_name = adjective and 'grc-adecl' or 'grc-decl'
local track = track(template_name)
track("unrecognized args")
local unrecognized_list = m_table.keysToList(unrecognized_args)
local agreement = #unrecognized_list > 1 and "s" or ""
mw.addWarning("unrecognized argument" .. agreement .. " in " ..
require("Module:string/nowiki")("{{" .. template_name .. "}}") .. ": " ..
table.concat(unrecognized_list, ", ") ..
"; see Module:grc-decl/params for a full list of recognized args")
end
end
local function swap_args(args, suffix)
--This function has undefined behavior if both <arg> and <arg><suffix> are
--specified; use e.g. <arg>1 and <arg>2 instead.
local args_ = args
args = {}
for code, value in pairs(args_) do
if type(code) == 'number' then
args[code] = value
else
-- Removes suffix from the end of string keys.
args[code:gsub(suffix .. '$', '')] = value
end
end
end
local function interpret_form(args, form_param, is_adjective)
if type(form_param) ~= 'string' then
return {}, {}, nil, nil
end
local no_article = form_param:find('X') and true or false
if no_article and is_adjective then
error('Adjectives cannot have articles. Remove ' .. quote('X') ..
' option in the ' .. quote('form') .. ' parameter.')
end
-- Convert sing, dual, plur to S, D, P.
-- Remove other lowercase letters. This removes "con" and "open".
local number_codes = { sing = true, dual = true, plur = true }
local contracted, comparative, like_adjective
local new_form = form_param:gsub('((%l)%l+)', function(wholematch, initial)
if wholematch == 'con' then
contracted = true
elseif wholematch == 'open' then
contracted = false
elseif wholematch == 'comp' then
comparative = true
elseif wholematch == 'adj' or wholematch == 'နာမဝိသေသန' then
like_adjective = true
elseif number_codes[wholematch] then
return initial:upper()
end
return ''
end)
--[[
Returns tables containing all genders and numbers.
For instance, for nouns that are variably masculine or feminine:
args.gender { "M", "F", ["M"] = true, ["F"] = true }
args.number { "S", "D", "P", ["S"] = true, ["D"] = true, ["P"] = true }
Not sure if the sequential entries are needed.
]]
-- Find contiguous gender abbreviations.
local genders = new_form:match("[MFN]+")
if is_adjective and genders then
error("Adjectives cannot have gender specified in the form parameter.")
end
-- Find number abbreviations.
-- If no number, assume all numbers will be displayed.
-- Koine and Byzantine have no dual.
local numbers = new_form:gsub('[^SDP]+', '')
if numbers == '' then
local dial = args.dial
numbers = (dial == 'koi' or dial == 'byz') and 'SP' or 'SDP'
end
if genders then
genders = mw.text.split(genders, "")
for i, gender in ipairs(genders) do
if gender == "" then
genders[i] = nil
else
genders[gender] = true
end
end
if genders.N and ( genders.M or genders.F ) then
error("A noun cannot be neuter and another gender at the same time.")
end
else
genders = {}
end
if numbers then
numbers = mw.text.split(numbers, "")
for i, number in ipairs(numbers) do
if number == "" then
numbers[i] = nil
else
numbers[number] = true
end
end
if numbers.S and numbers.D and numbers.P then
numbers.F = true
end
else
numbers = {}
end
return genders, numbers, no_article, contracted, comparative, is_adjective or like_adjective
end
-- Canonicalize specially-handled dialect codes.
-- TODO: use a table and cover all dialects
local function handle_dialect(dialect)
if dialect == "Homeric" then
dialect = "hom"
elseif dialect == "Attic" then
dialect = "att"
elseif dialect == "Epic" then
dialect = "epi"
elseif dialect == "Ionic" then
dialect = "ion"
elseif dialect == "Koine" then
dialect = "koi"
elseif dialect == "Byzantine" then
dialect = "byz"
elseif dialect == "gkm" then
dialect = "byz"
end
if dialect == "hom" then
dialect = "epi"
end
return dialect
end
local function handle_unmarked_length(arg1, arg2, adjective)
local old_arg1, old_arg2 = arg1, arg2
if arg2 then
local m_accent = require("Module:grc-accent")
local m_utilities = require("Module:grc-utilities")
local standard_diacritics = m_utilities.standardDiacritics
local reorder_diacritics = m_utilities.reorderDiacritics
if arg1 == 'irreg' or arg1 == 'indecl' then
arg2 = m_accent.mark_implied_length(
reorder_diacritics(standard_diacritics(arg2)))
else
arg1, arg2 = m_accent.harmonize_length(
reorder_diacritics(standard_diacritics(arg1)),
reorder_diacritics(standard_diacritics(arg2)))
end
end
local track = track(adjective and 'grc-adecl' or 'grc-decl')
--[=[
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/length marked on arg1]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/length marked on arg2]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/length marked on arg1]]
[[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/length marked on arg2]]
]=]
if old_arg1 and arg1 ~= decompose(old_arg1) then
track('length marked on arg1')
end
if old_arg2 and arg2 ~= decompose(old_arg2) then
track('length marked on arg2')
end
return arg1, arg2
end
local function get_args(args, is_adjective, function_name)
-- Have to process args[1] before 'irreg' or 'indecl' is checked for.
local arg1 = mw.text.trim(args[1])
if arg1 == '' then arg1 = nil end
local irreg = arg1 == 'irreg'
local indecl = arg1 == 'indecl'
local form_param = args.form
-- [[Special:WhatLinksHere/Wiktionary:Tracking/grc-adecl/empty comp or super]]
if is_adjective and args.deg and not (args.deg == 'comp' or args.deg == 'super') then
error('Adjective degree ' .. quote(args.deg) .. ' not recognized.')
end
local dialect_code
local params = m_params[(irreg and 'irreg_' or '') ..
(irreg and form_param and form_param:find('N') and 'N_' or '') ..
(is_adjective and 'adj_' or 'noun_') ..
'params']
local args, unrecognized_args = require('Module:parameters').process(args, params, true, "grc-decl", function_name)
handle_unrecognized_args(unrecognized_args, is_adjective)
form_param, dialect_code = args.form, args.dial
args.maxindex = m_table.length(params)
if irreg then
require('Module:debug').track('grc-decl/irreg')
end
if is_adjective then
args.adjective = true
args.atable = {}
if args.hp then
track('grc-adecl', 'hp')
end
end
args[1], args[2] = handle_unmarked_length(args[1], args[2], is_adjective)
local arg2 = args[2]
args.dial = handle_dialect(dialect_code)
args.gender, args.number, args.no_article, args.contracted, args.comparative, args.like_adjective = interpret_form(args, form_param, is_adjective)
if args.comparative then
if (arg2 or args.dial ~= 'att' or not arg1:find("ον$")) then
error("|form=comp is only meant for Attic third-declension comparatives with a stem in " .. quote("-ον") .. ".")
end
if args.deg then
error('|form=comp not needed when |deg=comp is set.')
end
end
if args.deg == 'comp' then
args.comparative = true
elseif args.deg == 'super' then
args.superlative = true
end
args.indeclinable, args.irregular = indecl, irreg
args.categories = {}
local track = track(is_adjective and 'grc-adecl' or 'grc-decl')
if ((arg1 or '') .. (arg2 or '')):find('˘') then
track('manual-breve')
end
if args.titleapp then
track('titleapp')
end
for _, v in ipairs({ 'titleapp', 'titleapp1', 'titleapp2' }) do
if args[v] then
args[v] = mw.text.split(args[v], '%s*[/,]%s*')
else
args[v] = {}
end
end
for _, v in ipairs({ 'notes', 'notes1', 'notes2' }) do
if args[v] then
args['user_' .. v] = args[v] --convert 'notes' to 'user_notes'
args[v] = {}
else
args[v] = {}
end
end
args.form_cache = {}
return args
end
--[=[
-- This function is an entry point for testing noun functionality only
-- ]=]
function export.test_decl(frame)
local args = get_args(frame, false, "test_decl")
m_grc_decl_decl.get_decl(args)
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
return args
end
-- These conditions should be mutually exclusive so that we don't need two
-- separate functions.
local function uncontracted_condition(dialect, contracted)
return dialect == 'ion' or dialect == 'epi'
or not (contracted == true or dialect == 'att')
end
local function contracted_condition(dialect, contracted)
return not (dialect == 'ion' or dialect == 'epi' or contracted == false)
end
function export.decl(frame)
local args = get_args(frame:getParent().args, false, "decl")
m_grc_decl_decl.get_decl(args)
if args.root:sub(1, 1) == '-' and not args.form:find('[MFN]') then
args.no_article = true
end
if args.decl_type:find('2nd') and not args.decl_type:find('N') and not args.form:find('[MFN]') then
-- table.insert(args.categories, 'Ancient Greek second-declension nouns without gender specified')
end
if args.decl_type:find('κλῆς') or ufind(args.decl_type, '[ᾰε]σ') then
local out = {}
if uncontracted_condition(args.dial, args.contracted) then
args.titleapp = {}
swap_args(args, 1)
table.insert(args.titleapp, 'uncontracted')
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
table.insert(out, m_grc_decl_table.make_table(args))
end
if contracted_condition(args.dial, args.contracted) then
args.titleapp = {}
swap_args(args, 2)
table.insert(args.titleapp, '[[:en:Appendix:Ancient Greek contraction|မချုက်လဝ်ကသုက်]]')
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
table.insert(out, m_grc_decl_table.make_table(args))
end
return table.concat(out, '\n')
else
m_grc_decl_decl.make_decl(args, args.decl_type, args.root)
args.article = m_grc_decl_decl.infl_art(args)
return m_grc_decl_table.make_table(args)
end
end
--[=[
-- This function is an entry point for testing adjective functionality only
-- ]=]
function export.test_adecl(frame)
local args = get_args(frame, true, "test_adecl")
m_grc_decl_decl.get_decl_adj(args)
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
return args
end
function export.adecl(frame)
local args = get_args(frame:getParent().args, true, "adecl")
m_grc_decl_decl.get_decl_adj(args)
if m_grc_decl_decl.adjinflections_con[args.decl_type] then
local out = {}
if uncontracted_condition(args.dial, args.contracted) then
args.titleapp, args.notes, args.categories = {}, {}, {}
swap_args(args, 1)
table.insert(args.titleapp, 'uncontracted')
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
table.insert(out, m_grc_decl_table.make_table_adj(args))
end
if contracted_condition(args.dial, args.contracted) then
args.titleapp, args.notes, args.categories = {}, {}, {}
swap_args(args, 2)
table.insert(args.titleapp, '[[:en:Appendix:Ancient Greek contraction|မချုက်လဝ်ကသုက်]]')
args.act = m_grc_decl_decl.adjinflections_con[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections_con[args.decl_type])
table.insert(out, m_grc_decl_table.make_table_adj(args))
end
return table.concat(out, '\n')
else
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
return m_grc_decl_table.make_table_adj(args)
end
end
local function tag(text)
local lang = require("Module:languages").getByCode("grc")
return require("Module:script utilities").tag_text(text, lang)
end
function export.show_noun_forms(frame)
local args = get_args(frame.args[1] and frame.args or frame:getParent().args, false, "show_noun_forms")
m_grc_decl_decl.get_decl(args)
local success, message = pcall(m_grc_decl_decl.make_decl, args, args.decl_type, args.root)
if not success then
return 'Declension generation failed for ' .. args[1] .. (args[2] and ', ' .. args[2] or '') .. ': ' ..
message
end
-- mw.logObject(args)
local inflections = args.ctable
local cases = { "N", "A", "V", "G", "D" }
local numbers = { "S", "D", "P" }
local out = { "\n* " .. tag(args[1]) .. ", " .. tag(args[2]) }
for _, number in ipairs(numbers) do
table.insert(out, "\n** ")
local number_forms = {}
for _, case in ipairs(cases) do
local code = case .. number
local form = inflections[code]
if form then
table.insert(number_forms, tag(form))
end
end
number_forms = table.concat(number_forms, ", ")
table.insert(out, number_forms)
end
return table.concat(out)
end
function export.show_adj_forms(frame)
local args = get_args(frame.args[1] and frame.args or frame:getParent().args, true, "show_adj_forms")
m_grc_decl_decl.get_decl_adj(args)
args.act = m_grc_decl_decl.adjinflections[args.decl_type]
m_grc_decl_decl.make_decl_adj(args, m_grc_decl_decl.adjinflections[args.decl_type])
-- mw.logObject(args)
local function print(key, value)
return key .. " = " .. "'" .. value .. "', "
end
local inflections = args.atable
local genders = { "M", "F", "N" }
local numbers = { "S", "D", "P" }
local cases = { "N", "A", "V", "G", "D" }
local out = {}
table.insert(out, "{ '" .. args[1] .. "'")
if args[2] then
table.insert(out, ", '" .. args[2] .. "'")
end
table.insert(out, " },\n{")
for _, gender in pairs(genders) do
table.insert(out, "\n\t")
for _, number in pairs(numbers) do
for _, case in pairs(cases) do
local code = gender .. case .. number
local form = inflections[code]
if form then
table.insert(out, print(code, form))
end
end
end
end
table.insert(out, "\n\t")
local forms = { "adv", "comp", "super" }
for _, form in pairs(forms) do
if inflections[form] then
table.insert(out, print(form, inflections[form]))
end
end
table.insert(out, "\n},")
return frame:extensionTag("source", table.concat(out), {lang = "lua"})
end
return export
1adhz7mx9rirm83d9letl6kdspacdlz
မဝ်ဂျူ:grc-decl/decl
828
26043
397290
136541
2026-06-21T08:43:32Z
咽頭べさ
33
397290
Scribunto
text/plain
local module_path = 'Module:grc-decl/decl'
local m_classes = mw.loadData(module_path .. '/classes')
local m_paradigms = mw.loadData(module_path .. '/staticdata/paradigms')
local m_dialect_groups = mw.loadData(module_path .. '/staticdata/dialects')
local m_decl_data = require(module_path .. '/data')
local m_accent = require('Module:grc-accent')
local concat = table.concat
local insert = table.insert
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local ulen = mw.ustring.len
local umatch = mw.ustring.match
local usub = mw.ustring.sub
local export = {
inflections = m_decl_data.inflections,
adjinflections = m_decl_data.adjinflections,
adjinflections_con = m_decl_data.adjinflections_con,
}
local function quote(text)
return "“" .. text .. "”"
end
local function get_accent_info(form)
-- Get position of accent (nth vowel from beginning of word).
local accent = {}
local is_suffix = form:sub(1, 1) == '-'
accent.position, accent.type = m_accent.detect_accent(form)
-- Position: position of accent from beginning of word (number) or nil.
-- Accent: accent name (string) or nil.
-- Form must have an accent, unless it is a suffix.
if not is_suffix and not next(accent) then
error('No accent detected on ' .. quote(form) ..
'. Please add an accent by copying this template and placing ' ..
quote('/') .. ' for acute or ' .. quote('~') ..
' for circumflex after the vowel that should be accented: {{subst:chars|grc|' .. form .. '}}.')
end
-- Accent term as proxy for distinguishing between oxytone and perispomenon.
accent.term = m_accent.get_accent_term(form)
return accent, is_suffix
end
local form_redirects = {
AS = 'NS', VS = 'NS',
DD = 'GD', AD = 'ND', VD = 'ND',
AP = 'NP', VP = 'NP',
}
local form_metatable = {
__index = function (self, form_code)
if type(form_code) ~= 'string' then return nil end
if form_redirects[form_code] then
return self[form_redirects[form_code]]
elseif form_redirects[form_code:sub(2)] then
return self[form_code:sub(1, 1) .. form_redirects[form_code:sub(2)]]
-- If this is a neuter form but not in the nominative case,
-- use the corresponding masculine form.
elseif form_code:match('N[^N].') then
return self['M' .. form_code:sub(2)]
end
end,
}
local function add_redirects(form_table)
return setmetatable(form_table, form_metatable)
end
local function add_forms(args)
if not args.irregular then
--add stem to forms
local function add_stem(forms)
return forms:gsub('%$', args.stem)
end
-- args.suffix indicates that this is a paradigm for an unaccented suffix,
-- such as [[-εια]].
if args.indeclinable then
for k in pairs(args.ctable) do
if k:match('[NGDAV][SDP]') then -- only format case-number forms
args.ctable[k] = args[2]
end
end
elseif args.suffix and not next(args.accent) then
for k, v in pairs(args.ctable) do
if k:match('[NGDAV][SDP]') then -- only format case-number forms
args.ctable[k] = add_stem(v)
end
end
else
-- If the term is not a suffix and no accent was detected, then
-- get_accent_info above must throw an error,
-- or else there will be an uncaught error here.
local add_circumflex = args.accent.type == 'circumflex'
local recessive = -3
-- Force recessive accent in the Lesbian dialect.
local accent_position = args.dial == 'les' and recessive
or args.accent.position
-- Circumflex on monosyllabic DS and AS in consonant-stem third-
-- declension nouns: for example, Τρῷ and Τρῶ, DS and AS of Τρώς.
local DS_AS = args.accent_alternating == true
-- Added by "kles" function: for example, Περίκλεις.
local VS = args.recessive_VS and recessive
local synaeresis = args.synaeresis
local add_accent = m_accent.add_accent
local function add_accent_to_forms(forms, code)
return forms:gsub('[^/]+', function(form)
return add_accent(form,
code == 'VS' and VS or accent_position,
{
synaeresis = synaeresis,
circumflex = (code == 'DS' or code == 'AS') and DS_AS or add_circumflex,
short_diphthong = true,
force_antepenult = args.force_antepenult,
}
)
end)
end
for k, v in pairs(args.ctable) do
if k:match('[NGDAV][SDP]') then -- only format case-number forms
args.ctable[k] = add_accent_to_forms(add_stem(v), k)
end
end
end
end
end
local gender_codes = { 'M', 'F', 'N' }
local case_codes = { 'N', 'G', 'D', 'A', 'V' }
local number_codes = { 'S', 'D', 'P' }
local function handle_noun_overrides(form_table, override_table)
for _, case in ipairs(case_codes) do
for _, number in ipairs(number_codes) do
local key = case .. number
if override_table[key] then
require('Module:debug').track('grc-decl/form-override')
end
form_table[key] = override_table[key] or form_table[key]
end
end
end
local function handle_adjective_overrides(form_table, override_table)
for _, gender in ipairs(gender_codes) do
for _, case in ipairs(case_codes) do
for _, number in ipairs(number_codes) do
local key = gender .. case .. number
if override_table[key] then
require('Module:debug').track('grc-adecl/form-override')
end
form_table[key] = override_table[key] or form_table[key]
end
end
end
end
--[=[
Gets stem-ending combinations from [[Module:grc-decl/decl/data]]
and [[Module:grc-decl/decl/staticdata]]. Called a single time to get forms
of a noun, and two or three times by make_decl_adj for each of the genders
of an adjective.
]=]
function export.make_decl(args, decl, root, is_adjective)
if not export.inflections[decl] then
error('Inflection type ' .. quote(decl) .. ' not found in [[' .. module_path .. "/data]].")
end
if args.adjective and args.irregular then
error('Irregular adjectives are not handled by make_decl.')
end
if not root then
error('No root for ' .. args[1] .. '.')
end
args.stem = root
export.inflections[decl](args)
args.gender[1] = args.gender[1] or args.ctable['g']
args.declheader = args.declheader or args.ctable['decl']
add_forms(args)
if not is_adjective then
handle_noun_overrides(args.ctable, args)
end
add_redirects(args.ctable)
end
-- String (comparative ending), function (input: root; output: comparative),
-- false (the declension has no comparative form), or nil (use the if-statements
-- to determine a comparative form).
local decl_to_comp = {
['1&3-ᾰν'] = 'ᾰ́ντερος',
['1&3-εν'] = 'έντερος',
['1&3-εσσ'] = 'έστερος', -- hopefully this is general?
['1&3-εσσ-con'] = 'ήστερος',
['1&3-ups-ε'] = 'ῠ́τερος',
['1&3-ups-ει'] = 'ῠ́τερος',
['3rd-cons'] = function(root)
local last2 = usub(root, -2)
if last2 == 'ον' then
return root .. 'έστερος'
elseif last2 == 'εσ' then
return root:gsub('εσ$', 'έστερος')
else
return false
end
end,
['1&3-οτ'] = false,
['3rd-εσ'] = 'έστερος',
['3rd-εσ-open'] = 'έστερος',
['1&2-alp-con'] = 'εώτερος', -- I assume—though I can't find examples
['1&2-eta-con'] = 'εώτερος',
['3rd-pure-υ'] = 'ῠ́τερος',
}
local function retrieve_comp(root, decl_type)
local data = decl_to_comp[decl_type]
if not data then
return data
elseif type(data) == 'string' then
return root .. data
elseif type(data) == 'function' then
return data(root)
else
error('Data for ' .. decl_type .. ' is invalid.')
end
end
-- Constructs an adverb, comparative, and superlative.
function export.make_acs(args)
-- input:
-- strings
local root, decl_type = args.root, args.decl_type
-- tables
local accent, atable = args.accent, args.atable
-- output:
local comp = retrieve_comp(root, decl_type)
local super, adv
if comp == nil then
local alpha_nonultima = decl_type == '1&2-alp' and
accent.term ~= 'oxytone' and
accent.term ~= 'perispomenon'
local last3 = usub(root, -3)
if alpha_nonultima and last3 == 'τερ' then
comp = nil
adv = atable['NNS']
-- ?
-- comp = nil
elseif alpha_nonultima and last3 == 'τᾰτ' then
super = nil
adv = atable['NNP']
-- ?
-- super = nil
elseif decl_type:find('ντ') then
comp = nil -- participles
super = nil
elseif (m_accent.get_weight(root, 1) == "light" or decl_type:match('att$')) then
comp = root .. 'ώτερος'
else
comp = root .. 'ότερος'
end
end
atable.adv = adv
-- Actually neuter accusative singular. This is correct for -τερος and
-- for μείζων; also for all comparatives in -ων?
or args.comparative and atable.NNS
-- actually neuter accusative plural
or args.superlative and atable.NNP
or atable.MGP and atable.MGP:gsub('ν$', 'ς'):gsub('ν<', 'ς<')
atable.comp = comp
atable.super = super or comp and comp:gsub('ερος$', 'ᾰτος')
-- Remove comparative and superlative if adjective is a comparative or superlative.
-- Parameters that trigger this condition are |deg=comp, |deg=super, and the
-- deprecated |form=comp.
if args.comparative or args.superlative then
atable.comp, atable.super = nil, nil
end
for _, form in ipairs { 'adv', 'comp', 'super' } do
if args[form] == "-" then
atable[form] = nil
elseif args[form] then
atable[form] = args[form]
end
end
end
--[[
noun_table contains case-number forms.
adjective_table will contain gender-case-number forms.
override_table contains gender-case-number forms that will override the
forms in noun_table.
]]
local function transfer_forms_to_adjective_table(adjective_table, noun_table, gender_code)
for case_and_number_code, form in pairs(noun_table) do
adjective_table[gender_code .. case_and_number_code] = form
end
end
--[=[
Interprets the table for the adjective's inflection type
in [[Module:grc-decl/decl/staticdata]].
]=]
function export.make_decl_adj(args, ct)
if args.irregular then
return export.inflections['irreg-adj'](args)
end
--[[
Two possibilities, with the indices of the table of endings
and the stem augmentation that they use:
- masculine–feminine (1, a1), neuter (2, a2)
- masculine (1, a1), feminine (2, a2), neuter (3, a3 else a1)
]]
-- Masculine or masculine and feminine forms.
export.make_decl(args, ct[1], args.root .. (ct.a1 or ''), true)
transfer_forms_to_adjective_table(args.atable, args.ctable, 'M')
-- Feminine or neuter forms.
if ct[2] then
export.make_decl(args, ct[2], args.fstem or (args.root .. (ct.a2 or '')), true)
transfer_forms_to_adjective_table(args.atable, args.ctable, 'F')
end
export.make_decl(args, ct[3], args.root .. (ct.a3 or ct.a1 or ''), true)
transfer_forms_to_adjective_table(args.atable, args.ctable, 'N')
add_redirects(args.atable)
args.ctable = nil
export.make_acs(args)
handle_adjective_overrides(args.atable, args)
args.adeclheader = ct.adeclheader or 'လဟုတ်စှ်ေ'
end
-- This function requires NFC forms for [[Module:grc-decl/decl/classes]],
-- but NFD forms for [[Module:grc-decl/decl/data]].
function export.get_decl(args)
if args.indeclinable then
if not args[2] then error("Specify the indeclinable form in the 2nd parameter.") end
args.decl_type, args.root = 'indecl', ''
return
elseif args.irregular then
if args.gender[1] == "N" then
args.decl_type, args.root = 'irregN', ''
else
args.decl_type, args.root = 'irreg', ''
end
return
elseif not (args[1] and args[2]) then
error("Use the 1st and 2nd parameters for the nominative and genitive singular.")
end
local infl_info = m_classes.infl_info.noun
args[1] = toNFC(args[1])
args[2] = toNFC(args[2])
local arg1, arg2 = args[1], args[2]
local nom_without_accent = toNFC(m_accent.strip_tone(arg1))
local gen_without_accent = toNFC(m_accent.strip_tone(arg2))
local nominative_matches, decl_type, root = {}
for i = -infl_info.longest_nominative_ending, -1 do
local nominative_ending = usub(nom_without_accent, i)
local decl_types_by_genitive_ending = infl_info[nominative_ending]
-- If decl_types_by_genitive_ending is a string, then it is the key of
-- another table in infl_info, a nominative ending with a macron or
-- breve (ι → ῐ).
if type(decl_types_by_genitive_ending) == "string" then
decl_types_by_genitive_ending = infl_info[decl_types_by_genitive_ending]
end
if decl_types_by_genitive_ending then
insert(nominative_matches, decl_types_by_genitive_ending)
root = usub(nom_without_accent, 1, -1 - ulen(nominative_ending))
for j = -6, -1 do
local genitive_ending = usub(gen_without_accent, j)
local name = decl_types_by_genitive_ending[genitive_ending]
if name then
decl_type = name
break
end
end
if decl_type then
break
end
end
end
args.accent, args.suffix = get_accent_info(arg1)
if decl_type and root then
if args.contracted == 'false' and not decl_type:find('open') then
decl_type = decl_type .. '-open'
end
args.decl_type, args.root = decl_type, toNFD(root)
return
elseif gen_without_accent:match('ος$') then
local root = toNFD(usub(gen_without_accent, 1, -3))
if (
args.gender[1] == "N" or (
not (args.gender[1] == "M" and args.gender[2] == "F") and
umatch(root, "α" .. mw.loadData('Module:grc-utilities/data').length.mandatory .. "τ$")
)
) then
args.decl_type, args.root = '3rd-N-cons', root
else
args.decl_type, args.root = '3rd-cons', root
end
return
end
if nominative_matches[1] then
local m_table = require 'Module:table'
local grc = require 'Module:languages'.getByCode 'grc'
local make_sort_key = require("Module:memoize")(function (term)
return (grc:makeSortKey(term))
end)
if nominative_matches[2] then
local new_nominative_matches = {}
for _, matches in ipairs(nominative_matches) do
for k, v in pairs(matches) do
new_nominative_matches[k] = v
end
end
nominative_matches = new_nominative_matches
else
nominative_matches = nominative_matches[1]
end
local gens = require 'Module:fun'.map(
function (gen)
return quote("-" .. gen)
end,
m_table.keysToList(
nominative_matches,
function (gen1, gen2)
local sort_key1, sort_key2 =
make_sort_key(gen1), make_sort_key(gen2)
if sort_key1 == sort_key2 then
return gen1 < gen2
else
return sort_key1 < sort_key2
end
end))
local agreement
if #gens > 1 then
agreement = { "Declensions were", "s ", " do" }
else
agreement = { "A declension was", " ", " does" }
end
gens = concat(gens, ", ")
error(agreement[1] .. " found that matched the ending of the nominative form " .. quote(arg1) ..
", but the genitive ending" .. agreement[2] .. gens ..
agreement[3] .. " not match the genitive form " .. quote(arg2) .. ".")
else
for nom, gens in pairs(m_classes.ambig_forms) do
if arg1:match(nom .. "$") then
for gen, _ in pairs(gens) do
if arg2:match(gen .. "$") then
error("No declension found for nominative " .. quote(arg1) .. " and genitive " .. quote(arg2) ..
". There are two declensions with nominative " .. quote("-" .. nom) ..
" and genitive " .. quote("-" .. gen) ..
". To indicate which one you mean, mark the vowel length of the endings with a macron or breve.")
end
end
end
end
error("Can’t find a declension type for nominative " .. quote(arg1) .. " and genitive " .. quote(arg2) .. ".")
end
end
-- This function requires NFC forms for [[Module:grc-decl/decl/classes]],
-- but NFD forms for [[Module:grc-decl/decl/data]].
function export.get_decl_adj(args)
if args.irregular then
args.decl_type, args.root = 'irreg', ''
return
elseif not args[1] then
error('Use the 1st and 2nd parameters for the masculine and the ' ..
'feminine or neuter nominative singular, or the first parameter ' ..
' alone for the 3rd declension stem.')
end
args[1] = toNFC(args[1])
if args[2] then
args[2] = toNFC(args[2])
end
local arg1, arg2 = args[1], args[2]
local mstrip = toNFC(m_accent.strip_tone(arg1))
local fstrip
if arg2 then
fstrip = toNFC(m_accent.strip_tone(arg2))
else
args.accent, args.suffix = get_accent_info(arg1)
args.decl_type, args.root = '3rd-cons', toNFD(mstrip)
return
end
local infl_info = m_classes.infl_info.adj
-- See if last three or two characters of masc have an entry.
local masc, decl
for i = -infl_info.longest_masculine_ending, -2 do
local ending = usub(mstrip, i)
local data = infl_info[ending]
if data then
masc = ending
decl = data
break
end
end
-- Allows redirecting, so that macrons or breves can be omitted for instance.
if type(decl) == "string" then
decl = infl_info[decl]
end
if decl then
-- Look for a feminine ending that matches the end of the feminine form.
local fem, name
for feminine, decl_name in pairs(decl) do
if fstrip:match(feminine .. '$') then
fem = feminine
name = decl_name:gsub("%d$", "")
break
end
end
if fem then
args.accent, args.suffix = get_accent_info(arg1)
-- The only indication that λέγων, λέγουσᾰ (stem λεγοντ-) and
-- ποιῶν, ποιοῦσᾰ (stem ποιουντ-) have different stems is the
-- accentuation of the masculine form.
if name == '1&3-οντ' and args.accent.term == 'perispomenon' then
name = '1&3-οντ-con'
end
if not export.adjinflections[name] then
error('Inflection recognition failed. Function for generated inflection code ' ..
quote(name) .. ' not found in [[' .. module_path .. "/data]].")
end
args.decl_type, args.root = name, toNFD(mstrip:gsub(masc .. "$", ""))
return
else
-- No declension type found.
local fems = {}
local is_neuter = false
for fem in pairs(decl) do
if fem == "ον" then
is_neuter = true
end
insert(fems, quote("-" .. fem))
end
fems = concat(fems, ", ")
local agreement = { "A declension was", " ", " does" }
if #fems > 1 then
agreement = { "Declensions were", "s ", " do" }
end
error(agreement[1] .. " found that matched the ending of the masculine " .. quote(arg1) ..
", but the corresponding feminine" .. (is_neuter and " and neuter" or "") .. " ending" .. agreement[2] .. fems ..
agreement[3] .. " not match the feminine " .. quote(arg2) .. ".")
end
end
error("Can’t find a declension type for masculine " .. quote(arg1) .. " and feminine or neuter " .. quote(arg2) .. ".")
end
--[[
Returns a table containing the inflected forms of the article,
to be placed before each inflected noun form.
]]
function export.infl_art(args)
if args.dial == 'epi' or args.adjective or args.no_article then
return {}
end
local art = {}
local arttable
if args.gender[1] then
arttable = m_paradigms.art_att[args.gender[1]]
else
error('Gender not specified.')
end
for code, suffix in pairs(arttable) do
if (args.gender[1] == "M" and args.gender[2] == "F") and
m_paradigms.art_att.M[code] ~= m_paradigms.art_att.F[code] then
art[code] = m_paradigms.art_att.M[code] .. ' / ' .. m_paradigms.art_att.F[code]
else
art[code] = suffix
end
end
if args.gender[1] == 'F' then
if m_dialect_groups['nonIA'][args.dial] then
art['NS'] = 'ᾱ̔' -- 104.1-4
art['GS'] = 'τᾶς'
art['DS'] = 'τᾷ'
art['AS'] = 'τᾱ̀ν'
end
if args.dial == 'the' or args.dial == 'les' then
art['DS'] = 'τᾶ' -- 39
elseif args.dial == 'boi' or args.dial == 'ara' or args.dial == 'ele' then
art['DS'] = 'ται' -- 104.3
end
if m_dialect_groups['nonIA'][args.dial] then
art['GP'] = 'τᾶν' -- 104.6
end
if args.dial == 'ato' then
art['DP'] = 'τῆσῐ(ν)' -- 104.7
elseif args.dial == 'ion' then
art['DP'] = 'τῇσῐ(ν)' -- 104.7
end
if m_dialect_groups['buck78'][args.dial] then
art['AP'] = 'τᾰ̀ς' -- 104.8
elseif args.dial == 'kre' or args.dial == 'arg' then
art['AP'] = 'τὰνς'
elseif args.dial == 'les' then
art['AP'] = 'ταῖς'
elseif args.dial == 'ele' then
art['AP'] = 'ταὶρ'
end
if args.dial == 'kre' or args.dial == 'les' or args.dial == 'kyp' then
art['NS'] = 'ᾱ̓' -- 57
art['NP'] = 'αἰ'
elseif args.dial == 'ele' then
art['NS'] = 'ᾱ̓'
art['NP'] = 'ταὶ'
elseif args.dial == 'boi' then
art['NP'] = 'τὴ' -- 104.5
elseif m_dialect_groups['west'][args.dial] then --boeotian is covered above
art['NP'] = 'ταὶ'
end
elseif args.gender[1] == 'M' or args.gender[1] == 'N' then
if args.dial == 'the' then
art['GS'] = 'τοῖ' -- 106.1
art['DS'] = 'τοῦ' -- 23
art['ND'] = 'τοὺ'
art['GP'] = 'τοῦν'
end
if args.dial == 'les' then
art['DS'] = 'τῶ' -- 106.2
elseif args.dial == 'boi' or args.dial == 'ara' or args.dial == 'ele' or args.dial == 'eub' then
art['DS'] = 'τοῖ' -- 106.2
end
if args.dial == 'ato' or args.dial == 'ion' then
art['DP'] = 'τοῖσῐ(ν)' -- 106.4
end
if args.gender[1] == 'M' then
if m_dialect_groups['buck78'][args.dial] then
art['AP'] = 'τὸς' -- 106.5
elseif args.dial == 'kre' or args.dial == 'arg' then
art['AP'] = 'τὸνς'
elseif args.dial == 'les' then
art['AP'] = 'τοῖς'
elseif args.dial == 'ele' then
art['AP'] = 'τοὶρ'
elseif m_dialect_groups['severe'][args.dial] or args.dial == 'boi' then
art['AP'] = 'τὼς'
end
if args.dial == 'kre' or args.dial == 'les' or args.dial == 'kyp' then
art['NS'] = 'ὀ' -- 57
art['NP'] = 'οἰ'
elseif args.dial == 'ele' then
art['NS'] = 'ὀ'
art['NP'] = 'τοὶ'
elseif m_dialect_groups['west'][args.dial] or args.dial == 'boi' then
art['NP'] = 'τοὶ'
end
end
if args.dial == 'ele' then
art['GD'] = 'τοίοις'
-- elseif args.dial == 'ara' then
-- art['GD'] = 'τοιυν'
end
end
return art
end
local lang = require("Module:languages").getByCode("grc")
local function tag(text)
return require("Module:script utilities").tag_text("-" .. text, lang)
end
local function print_detection_table(detection_table, labels, noun)
local out = require('Module:array')()
local function sort(item1, item2)
-- Put 'longest_nominative_ending' and 'longest_masculine_ending' first.
local item1_longest = item1:match('^longest')
if item1_longest or item2:match('^longest') then
return item1_longest ~= nil
end
local sort1, sort2 = (lang:makeSortKey(item1)), (lang:makeSortKey(item2))
local decomp_length1, decomp_length2 = ulen(toNFD(item1)), ulen(toNFD(item2))
if sort1 == sort2 then
-- Sort ᾱ or ᾰ before α.
if decomp_length1 > decomp_length2 then
return true
else
return false
end
else
return sort1 < sort2
end
end
for key1, value1 in require("Module:table").sortedPairs(detection_table, sort) do
if key1:match('^longest') then
out:insert('* ' .. key1:gsub('_', ' ') .. ': ' .. value1 .. ' characters')
else
insert(out, "\n* " .. labels[1] .. " " .. tag(key1))
if type(value1) == "string" then
out:insert(" → " .. tag(value1))
elseif type(value1) == "table" then
for key2, value2 in require("Module:table").sortedPairs(value1, sort) do
-- mw.log(len(key1), len(key2))
out:insert("\n** " ..
(noun and labels[2] or key2 == "ον" and "နပုလ္လိၚ်" or "ဣတ္တိလိၚ်") ..
" " .. tag(key2) .. ": <code>" .. value2 .. "</code>")
if noun then
out:insert(" (<code>" .. (m_classes.conversion[value2] or "?") .. "</code>)")
end
end
end
end
end
return out:concat()
end
function export.show_noun_categories(frame)
return print_detection_table(m_classes.infl_info.noun, { "မဒုၚ်ယၟု", "ဗဳဇဂကူ" }, true)
end
function export.show_adj_categories(frame)
return print_detection_table(m_classes.infl_info.adj, { "ပုလ္လိၚ်", "ဣတ္တိလိၚ် ဝါ နပုလ္လိၚ်" })
end
return export
9irgtu3avtb4anmsaf0ic4tl7xdtz5j
မဝ်ဂျူ:grc-decl/decl/data
828
26045
397288
136539
2026-06-21T08:38:16Z
咽頭べさ
33
397288
Scribunto
text/plain
local module_path = 'Module:grc-decl/decl'
local m_decl_static_data = mw.loadData(module_path .. '/classes')
local m_paradigms = mw.loadData(module_path .. '/staticdata/paradigms')
local m_dialect_groups = mw.loadData(module_path .. '/staticdata/dialects')
local m_accent = require('Module:grc-accent')
local m_links = require('Module:links')
local m_str_utils = require("Module:string utilities")
local check_type = require('libraryUtil').checkType
local grc = require('Module:languages').getByCode('grc')
local codepoint = m_str_utils.codepoint
local deep_copy = require('Module:table').deepCopy
local syllables = m_accent.syllables
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local umatch = m_str_utils.match
local usub = m_str_utils.sub
local grc_utilities_data
local function get_grc_utilities_data()
grc_utilities_data, get_grc_utilities_data = mw.loadData('Module:grc-utilities/data'), nil
return grc_utilities_data
end
local export = {
inflections = {},
adjinflections = m_decl_static_data.adjinflections,
adjinflections_con = m_decl_static_data.adjinflections_con,
}
local function ine(var)
if var == '' then
return nil
else
return var
end
end
local function quote(text)
return '“' .. text .. '”'
end
local function mention(alt)
return m_links.full_link({ alt = alt, lang = grc }, 'term')
end
local dental_lookup = {
['δ'] = '*-δς',
['θ'] = '*-θς',
['τ'] = '*-τς',
}
-- Return one of the three options, or an error message.
-- suffix is true if args[1] does not contain an accent mark and begins in a hyphen.
local function accent_switch(accent_term, if_oxytone, if_perispomenon, otherwise, error_message, unaccented_suffix)
local value
-- accent_term can be nil if this is a paradigm for an unaccented_suffix.
check_type('accent_term', 1, accent_term, 'string', unaccented_suffix)
if accent_term == 'oxytone' then
value = if_oxytone
elseif accent_term == 'perispomenon' then
value = if_perispomenon
else
value = otherwise
end
return value or error_message and error(error_message)
end
local function uncontracted_error(contracted, dialect, nom_ending)
if contracted == false and
(dialect == 'att' or dialect == 'koi' or dialect == 'byz') then
--[[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/uncontracted error]]
require('Module:debug').track('grc-decl/uncontracted error')
mw.log('In the Attic, Koine, or Byzantine dialects, nouns in ' ..
quote(nom_ending) .. ' are contracted. Remove ' ..
quote('con') .. ' from the ' ..
quote('form') .. ' parameter or change the dialect.')
end
end
local function nonrecessive_error(accent_term, error_message)
if accent_term == 'oxytone' or accent_term == 'perispomenon' then
error(error_message)
end
end
local function some(t, func)
for _, item in ipairs(t) do
if func(item) then
return true
end
end
return false
end
-- FIXME: use ... to handle an arbitrary number of dialects
local function dial_condition(actual_dialect, dialect1, dialect2)
if not actual_dialect then
return false
end
if type(dialect1) == "string" then
return actual_dialect == dialect1 or
dialect2 and actual_dialect == dialect2 or
m_dialect_groups[dialect1] and m_dialect_groups[dialect1][actual_dialect]
elseif type(dialect1) == "table" then
return some(dialect1, function(dialect)
return dial_condition(actual_dialect, dialect)
end)
end
end
local function dial_form_multi(args, forms, dialects)
local actual_dialect = args.dial
if not actual_dialect then
return
end
local ctable = args.ctable
-- Forms is an array of tables containing individual forms in
-- the same dialect or dialects:
-- { <case–number>, <form> }
-- Dialects is a sequence of strings or tables:
-- "<dialect code>"
-- or
-- { "<dialect code 1>", "<dialect code 2>", ... }
if dialects then
if dial_condition(actual_dialect, dialects) then
for _, form in ipairs(forms) do
if type(form[2]) == 'string' then
ctable[form[1]] = form[2]
end
end
end
-- Forms is a sequence of tables:
-- { <case–number>, <form>, <dialect code> }
-- or
-- { <case–number>, <form>, { <dialect code 1>, <dialect code 2>, ... } }
elseif type(forms) == 'table' then
for _, form_data in ipairs(forms) do
if dial_condition(actual_dialect, form_data[3]) and type(form_data[2]) == 'string' then
ctable[form_data[1]] = form_data[2]
end
end
end
end
-- FIXME: use ... to handle an arbitrary number of dialects
local function dial_form(args, f, suffix, dialect1, dialect2)
if dial_condition(args.dial, dialect1, dialect2) then
args.ctable[f] = suffix
end
end
-- Should Aeolic be moved here?
local function dial_forms_first(args)
dial_form_multi(args, {
{ 'GS', '$ᾱς/$ᾱῠ̈', 'ara' },
{ 'DS', '$η', 'boi' }, -- 104.3
{ 'DS', '$αι', { 'ara', 'ele' } },
{ 'DS', '$ᾱ', { 'the', 'les' } },
{ 'GD', '$αιῐ̈ν', 'epi' },
{ 'GD', '$αιῠ̈ν', 'ark' },
{ 'GD', '$ην', 'boi' },
{ 'GD', '$αιαις/$αιαιρ', 'ele' },
{ 'NP', '$η', 'boi' },
{ 'GP', '$ᾱ́ων/$έων/$ῶν', 'epi' }, -- 104.6
{ 'GP', '$έων/$ῶν', 'ion' },
{ 'GP', '$ᾶν', 'nonIA' },
{ 'GP', '$ᾱ́ων/$ᾶν', 'lyr' },
{ 'GP', '$ᾱ́ων', 'boi' },
{ 'DP', '$ῃσῐ(ν)/$ῃς/$αις', 'epi' }, -- 104.7
{ 'DP', '$ῃσῐ(ν)', 'ion' },
{ 'DP', '$ᾱσῐ(ν)/$ᾳσῐ(ν)', 'ato' },
{ 'DP', '$αις/$αισῐ(ν)', 'lyr' },
{ 'DP', '$ης', 'boi' },
{ 'DP', '$ᾳσῐ/$αισῐ', 'les' },
{ 'AP', '$ᾰς', 'buck78' }, -- 104.8
{ 'AP', '$ᾱ̆ς', 'lyr' },
{ 'AP', '$ᾰ(ν)ς', { 'kre', 'arg' } },
{ 'AP', '$αις', 'les' },
{ 'AP', '$ᾰς/$αις/$αιρ', 'ele' },
})
end
local function dial_forms_first_oxy(args)
dial_form_multi(args, {
{ 'GS', '$ᾶς/$ᾶῠ̈', 'ara' },
{ 'DS', '$ῆ', 'boi' }, -- 104.3
{ 'DS', '$αῖ', { 'ara', 'ele' } },
{ 'DS', '$ᾱ', 'les' }, -- recessive
{ 'DS', '$ᾶ', 'the' },
{ 'GD', '$αῖῐ̈ν', 'epi' },
{ 'GD', '$αῖῠ̈ν', 'ark' },
{ 'GD', '$ῆν', 'boi' },
{ 'GD', '$αίαις/$αίαιρ', 'ele' },
{ 'NP', '$ή', 'boi' },
{ 'GP', '$ᾱ́ων/$έων/$ῶν', 'epi' }, -- 104.6
{ 'GP', '$έων/$ῶν', 'ion' },
{ 'GP', '$ᾶν', 'nonIA' },
{ 'GP', '$ᾱ́ων/$ᾶν', 'lyr' },
{ 'GP', '$ᾱ́ων', 'boi' },
{ 'DP', '$ῇσῐ(ν)/$ῇς/$αῖς', 'epi' }, -- 104.7
{ 'DP', '$ῇσῐ(ν)', 'ion' },
{ 'DP', '$ᾶσῐ(ν)/$ᾷσῐ(ν)', 'ato' },
{ 'DP', '$αῖς/$αῖσῐ(ν)', 'lyr' },
{ 'DP', '$ῆς', 'boi' },
{ 'DP', '$ᾳσῐ/$αισῐ', 'les' }, -- recessive
{ 'AP', '$ᾰ́ς', 'buck78' }, -- 104.8
{ 'AP', '$ᾱ̆́ς', 'lyr' },
{ 'AP', '$ᾰ́(ν)ς', { 'kre', 'arg' } },
{ 'AP', '$αις', 'les' }, -- recessive
{ 'AP', '$ᾰ́ς/$αίς/$αίρ', 'ele' },
})
end
export.inflections['1st-alp'] = function(args)
local suffix = accent_switch(args.accent.term, '', '_con', '_pax', nil, args.suffix)
args.ctable = deep_copy(m_paradigms['alp' .. suffix])
if args.accent.term == 'oxytone' then
dial_forms_first_oxy(args)
else
if args.like_adjective then
args.ctable['GP'] = '$ων'
end
if args.accent.term ~= 'perispomenon' then
dial_forms_first(args)
end
end
end
--[=[
Only difference from "1st-alp-pax" and "1st-eta-pax" is that because of the "-prx",
[[Module:grc-decl/decl]] doesn't shift the accent to the end of the stem
in all forms. Used only in 1st-and-2nd-declension adjectives.
]=]
-- export.inflections['1st-alp-prx'] = export.inflections['1st-alp-pax']
-- export.inflections['1st-eta-prx'] = export.inflections['1st-eta-pax']
export.inflections['1st-eta'] = function(args)
local suffix = accent_switch(args.accent.term, '', '_con', '_pax', nil, args.suffix)
args.ctable = deep_copy(m_paradigms['eta' .. suffix])
if args.accent.term == 'oxytone' then
-- Assuming this applies for perispomenon as well as oxytone.
dial_forms_first_oxy(args)
dial_form_multi(args, {
{ 'DP', '$ῆσῐ(ν)/$ῇσῐ(ν)', 'ato' },
})
elseif args.accent.term ~= 'perispomenon' then
if args.like_adjective then
args.ctable['GP'] = '$ων'
end
dial_forms_first(args)
dial_form_multi(args, {
{ 'DP', '$ησῐ(ν)/$ῃσῐ(ν)', 'ato' },
})
end
end
-- Always recessive, except in adjectives or derivatives of them.
local function short_alpha(code)
return function(args)
if code == 'als' then
-- Ionic and Epic have eta, not alpha, in all forms except the
-- nominative and accusative singular.
if args.dial == 'ion' or args.dial == 'epi' then
short_alpha('ets')(args)
return
end
elseif code ~= 'ets' then
error('Invalid code ' .. tostring(code))
end
local accent_on_ultima = args.like_adjective and '_prx' or nil
local suffix = accent_switch(args.accent.term,
accent_on_ultima, accent_on_ultima, '_prx',
'First-declension feminine nouns with nominative singular in ' ..
'short alpha must have recessive accent.', args.suffix)
args.ctable = deep_copy(m_paradigms[code .. suffix])
dial_forms_first(args)
if code == 'ets' then
dial_form(args, 'DP', '$ησῐ(ν)/$ῃσῐ(ν)', 'ato')
end
end
end
export.inflections['1st-als'] = short_alpha('als')
export.inflections['1st-ets'] = short_alpha('ets')
export.inflections['1st-M-alp'] = function(args)
local suffix = accent_switch(args.accent.term, nil, '_con', '_pax',
'Oxytone masculine first declension not supported.', args.suffix)
args.ctable = deep_copy(m_paradigms['M_alp' .. suffix])
if args.accent.term ~= 'perispomenon' then
dial_forms_first(args)
dial_form_multi(args, {
{ 'GS', '$ᾱο/$εω/$ω', 'epi' },
{ 'GS', '$εω/$ω', 'ion' },
{ 'GS', '$ᾱ', 'nonIA' },
{ 'GS', '$ᾱ(ο)', 'lyr' },
{ 'GS', '$ᾱο', 'boi' },
{ 'GS', '$ᾱῠ̈', 'ark' },
{ 'GS', '$ᾱ(ῠ̈)', 'kyp' },
{ 'GS', '$ᾱ(ς)', { 'meg', 'northwest' } }, -- 105.2
})
end
end
export.inflections['1st-M-eta'] = function(args)
local suffix = accent_switch(args.accent.term, '', '_con', '_pax', nil, args.suffix)
args.ctable = deep_copy(m_paradigms['M_eta' .. suffix])
-- [[ἰδιώτης]], genitive singular ἰδιώτεω, not *ἰδιωτέω,
-- at least in Herodotus 1.123.
if args.dial == 'ion' or args.dial == 'epi' then
args.synaeresis = true
end
if args.accent.term == 'oxytone' then
dial_forms_first_oxy(args)
dial_form_multi(args, {
{ 'GS', '$ᾶο/$έω/$ῶ', 'epi' },
{ 'GS', '$έω/$ῶ', 'ion' },
{ 'GS', '$ᾶ', 'nonIA' },
{ 'GS', '$ᾶ(ο)', 'lyr' },
{ 'GS', '$ᾶο', 'boi' },
{ 'GS', '$ᾶῠ̈', 'ark' },
{ 'GS', '$ᾶ(ῠ̈)', 'kyp' },
{ 'GS', '$ᾶ(ς)', { 'meg', 'northwest' } }, -- 105.2
{ 'DP', '$ῆσῐ(ν)/$ῇσῐ(ν)', 'ato' },
})
elseif args.accent.term ~= 'perispomenon' then
dial_forms_first(args)
dial_form_multi(args, {
{ 'GS', '$ᾱο/$εω/$ω', 'epi' },
{ 'GS', '$εω/$ω', 'ion' },
{ 'GS', '$ᾱ', 'nonIA' },
{ 'GS', '$ᾱ(ο)', 'lyr' },
{ 'GS', '$ᾱο', 'boi' },
{ 'GS', '$ᾱῠ̈', 'ark' },
{ 'GS', '$ᾱ(ῠ̈)', 'kyp' },
{ 'GS', '$ᾱ(ς)', { 'meg', 'northwest' } }, -- 105.2
{ 'DP', '$ησῐ(ν)/$ῃσῐ(ν)', 'ato' },
})
end
if args['voc'] == 'α' or usub(args.stem, -1) == 'τ' then
args.ctable['VS'] = '$ᾰ'
end
end
local function dial_forms_second(args, neuter)
mw.log(mw.dumpObject(neuter))
dial_form_multi(args, {
{ 'GS', '$οιο/$ου', 'epi' }, -- 106.1
{ 'GS', '$οι(ο)', 'the' },
{ 'GS', '$ω', { 'lyr', 'severe', 'boi' } },
{ 'GS', '$ω(ν)', 'kyp' },
{ 'DS', '$ω', 'les' }, -- 106.2
{ 'DS', '$ου', 'the' },
{ 'DS', '$οι', { 'ele', 'boi', 'ara', 'eub' } },
{ 'GD', '$οιῐ̈ν', 'epi' }, -- 106.6
{ 'GD', '$οιῠ̈ν', 'ark' },
{ 'GD', '$οιοις/$οιοιρ', 'ele' },
{ 'GP', '$ουν', 'the' },
{ 'DP', '$οισῐ(ν)/$οις', 'epi' }, -- 106.4
{ 'DP', '$οισῐ(ν)', { 'ato', 'ion' } },
{ 'DP', '$οις/$οισῐ(ν)', 'lyr' },
{ 'DP', '$οισῐ(ν)', 'les' },
})
if not neuter then
dial_form_multi(args, {
{ 'ND', '$ου', 'the' }, -- 23
{ 'AP', '$ως', { 'lyr', 'severe' } }, -- 106.5
{ 'AP', '$ος', 'buck78' },
{ 'AP', '$ο(ν)ς', { 'kre', 'arg' } },
{ 'AP', '$οις', 'les' },
{ 'AP', '$ος/$οις/$οιρ', 'ele' },
})
end
end
local function dial_forms_second_oxy(args, neuter)
mw.log(mw.dumpObject(neuter))
dial_form_multi(args, {
{ 'GS', '$οῖο/$οῦ', 'epi' }, -- 106.1
{ 'GS', '$οῖ(ο)', 'the' },
{ 'GS', '$ῶ', { 'lyr', 'severe', 'boi' } },
{ 'GS', '$ῶ(ν)', 'kyp' },
{ 'DS', '$ω', 'les' }, -- 106.2; les is recessive
{ 'DS', '$οῦ', 'the' },
{ 'DS', '$οῖ', { 'ele', 'boi', 'ara', 'eub' } },
{ 'GD', '$οῖῐ̈ν', 'epi' }, -- 106.6
{ 'GD', '$οῖῠ̈ν', 'ark' },
{ 'GD', '$οίοις/$οίοιρ', 'ele' },
{ 'GP', '$οῦν', 'the' },
{ 'DP', '$οῖσῐ(ν)/$οῖς', 'epi' }, -- 106.4
{ 'DP', '$οῖσῐ(ν)', { 'ato', 'ion' } },
{ 'DP', '$οῖς/$οῖσῐ(ν)', 'lyr' },
{ 'DP', '$οισῐ(ν)', 'les' }, -- recessive
})
if not neuter then
dial_form_multi(args, {
{ 'ND', '$ού', 'the' }, -- 23
{ 'AP', '$ώς', { 'lyr', 'severe' } }, -- 106.5
{ 'AP', '$ός', 'buck78' },
{ 'AP', '$ό(ν)ς', { 'kre', 'arg' } },
{ 'AP', '$οις', 'les' }, -- recessive
{ 'AP', '$ός/$οίς/$οίρ', 'ele' },
})
end
end
-- For nouns like λόγος and ἔργον.
local function second_basic(gender_code)
return function(args)
local suffix = accent_switch(args.accent.term, '', nil, '_prx',
'Perispomenon basic second-declension nouns not supported.', args.suffix)
args.ctable = deep_copy(m_paradigms['second' .. (gender_code or '') .. suffix])
if args.accent.term == 'oxytone' then
dial_forms_second_oxy(args, gender_code == '_N')
else
dial_forms_second(args, gender_code == '_N')
end
end
end
export.inflections['2nd'] = second_basic()
export.inflections['2nd-N'] = second_basic('_N')
local function second_contracted(gender_code)
return function(args)
local suffix = accent_switch(args.accent.term, nil, '', '_pax',
'Oxytone contracted second-declension nouns are not supported.', args.suffix)
if gender_code == '_N' and suffix == '_pax' then
error('Paroxytone contracted neuter second-declension nouns are not supported')
end
args.ctable = deep_copy(m_paradigms['second' .. (gender_code or '') .. '_con' .. suffix])
end
end
export.inflections['2nd-con'] = second_contracted()
export.inflections['2nd-N-con'] = second_contracted('_N', true)
local function second_Attic(gender)
return function(args)
local suffix = accent_switch(args.accent.term, '', '_con', '_prx', nil, args.suffix)
if gender == '_N' and suffix == '_con' then
error('Perispomenon Attic declension neuter nouns are not supported.')
end
args.force_antepenult = true
args.ctable = deep_copy(m_paradigms['second' .. (gender or '') .. '_att' .. suffix])
end
end
export.inflections['2nd-att'] = second_Attic()
export.inflections['2nd-N-att'] = second_Attic('_N')
--[[
In order:
- vowel before ντ at end of stem, or declension category
- masculine nominative singular ending
- neuter nominative singular ending
- segment preceding ῐ in dative plural
]]
local nt = {
['ο'] = { 'ων', 'ον', 'ουσ' }, -- ἔχων (ἔχω)
['1&3-ουντ'] = { 'ους', 'ον', 'ουσ' }, -- δούς (δίδωμι)
['ου'] = { 'ων', 'ουν', 'ουσ' }, -- ποιῶν (ποιέω), δηλῶν (δηλόω)
['ε'] = { 'εις', 'εν', 'εισ' }, -- θείς (τίθημι), ἀχθείς (ἄγω)
['η'] = { 'ης', 'ην', 'ῃσ' }, -- φωνῆς ()
['ω'] = { 'ων', 'ων', 'ωσ' }, -- ζῶν (ζάω)
}
-- Get nominative singular and dative plural (minus ῐ(ν)) for ντ-stems.
local function handle_nt(base, decl_type, gender, is_neuter, adjective, arg1, arg2)
local m_data, NS, DP = grc_utilities_data or get_grc_utilities_data()
base = toNFD(base)
-- Here we must match α, ε, η, ι, ο, υ, ω, or ου (with any number of
-- diacritics) followed by ντ.
local whole_match, vowel, diacritic = umatch(base, '((ου)(' .. m_data.combining_diacritic .. '*)ντ)$')
if whole_match == nil then
whole_match, vowel, diacritic = umatch(base, '(([αεηιουω])(' .. m_data.combining_diacritic .. '*)ντ)$')
end
if not whole_match then
error('Something is wrong with the stem ' .. base .. '.')
end
local nom_base = base:gsub(whole_match, '')
-- Declension type has priority over vowel because δούς (δοντ-) and
-- λαβών (λαβόντ-) have the same stem vowel, but different masculine
-- nominative singulars.
local data = nt[decl_type] or nt[vowel]
if data then
if adjective then
NS = nom_base .. (is_neuter and data[2] or data[1])
end
DP = nom_base .. data[3]
elseif umatch(diacritic, "^" .. m_data.length.optional .. "$") then
if vowel then
local intermediate_base, macron = nom_base .. vowel, m_data.diacritics.macron
DP = intermediate_base .. macron .. 'σ'
if adjective then
if is_neuter then
NS = intermediate_base .. diacritic .. 'ν'
else
NS = intermediate_base .. macron .. 'ς'
end
end
else
error('Failed to generate nominative singular and dative plural for ' ..
quote(arg1) .. ', ' .. quote(arg2) .. '.')
end
else
error('Invalid diacritic ' ..
(type(diacritic) == 'string' and string.format("U+%X", codepoint(diacritic)) or tostring(diacritic)) ..
') in the stem ' .. base .. '.')
end
if not (adjective or gender[1]) then
gender[1] = 'M'
gender.M = true
end
return NS, DP
end
local finals = {
['β'] = 'ψ',
['γ'] = 'ξ',
['κ'] = 'ξ',
['κτ'] = 'ξ',
['π'] = 'ψ',
['πτ'] = 'ψ',
['ϙ'] = 'ξ',
['φ'] = 'ψ',
['χ'] = 'ξ',
--[[
['τ'] = ,
['δ'] = ,
['θ'] = ,
--]]
}
local function new_gender(gender)
return { gender, [gender] = true }
end
-- is_neuter: boolean
-- accent_alternating: boolean
local function third_nom(args, is_neuter, accent_alternating)
-- strings
local arg1, arg2, base = args[1], args[2], toNFC(args.stem)
local ctable = args.ctable
-- output
local NS, DS, AS, DP = ctable.NS, ctable.DS, ctable.AS, ctable.DP
-- boolean
local adjective = args.like_adjective
-- tables
local gender, notes = args.gender, args.notes
--[[
local notes = {
labial = 'Nominative singular ' ..
mention('-ψ') ..
(('φβ'):find(last1) and ' is a neutralization of ' or ' is a respelling of ') ..
mention(last1) ..
' + the nominative singular suffix ' ..
mention('-ς') .. '.',
velar_dental = 'Nominative singular ' ..
mention('-ξ') ..
' is a neutralization of ' ..
mention(last2) ..
' + the nominative singular suffix ' ..
mention('-ς') .. '.',
'Nominative singular ' ..
mention('-ξ') ..
(umatch('χγ', last1) and ' is a neutralization of ' or ' is a respelling of ') ..
mention(last1) ..
' + the nominative singular suffix ' ..
mention('-ς') .. '.'
}
--]]
local identifying_ending = umatch(base, '[κνπ]τ$') or usub(base, -1)
local NS_ending = finals[identifying_ending]
if NS_ending then
NS = base:gsub(identifying_ending .. "$", NS_ending)
DP = NS
end
if not (NS or DP) then
local decl_type = args.decl_type
local nom_base = usub(base, 1, -2)
if identifying_ending == 'ντ' then
-- May also add gender.
NS, DP = handle_nt(base, decl_type, gender, is_neuter, adjective, arg1, arg2)
elseif ('τδθ'):find(identifying_ending) then
DP = nom_base .. 'σ'
if not (adjective or gender[1]) then
if base:match("τητ$") or umatch(base, "[δθ]$") then
gender = new_gender('F')
elseif umatch(base, "[ηω]τ$") then
gender = new_gender('M')
elseif umatch(toNFD(base), "α" .. (grc_utilities_data or get_grc_utilities_data()).length.mandatory .. "τ$") then
gender = new_gender('N')
end
end
local final_ot = base:match("οτ$")
if final_ot and not is_neuter then
NS = base:gsub('οτ$', 'ως')
elseif is_neuter and not final_ot then
NS = nom_base
else
NS = nom_base .. 'ς'
end
if arg1:find('ς$') then
table.insert(notes,
'Nominative singular ' .. mention('-ς') ..
' arose by reduction of the original cluster ' ..
mention(dental_lookup[identifying_ending]) .. '.')
end
elseif ('ϝϳλρν'):find(identifying_ending) then
if usub(base, -1) ~= 'ν' then
DP = base .. 'σ'
else
DP = nom_base .. 'σ'
end
if is_neuter then
NS = base
else
local vowel = usub(base, -2, -2)
if vowel == 'ε' then
NS = usub(base, 1, -3) .. 'η' .. identifying_ending
elseif vowel == 'ο' then
NS = usub(base, 1, -3) .. 'ω' .. identifying_ending
elseif vowel == 'ῑ' then --ῥίς etc.
NS = nom_base .. 'ς'
elseif (vowel == 'ᾰ' and gender[1] ~= 'N') then
NS = usub(base, 1, -3) .. 'ᾱς'
else
NS = base
end
end
if not gender[1] then
if umatch(base, '[γδ]ον$') then
gender[1] = 'F'
elseif umatch(toNFD(base), "α" .. (grc_utilities_data or get_grc_utilities_data()).length.optional .. "ρ$") then
gender[1] = 'N'
else
gender[1] = 'M'
end
end
elseif identifying_ending == 'σ' then
DP = base
if is_neuter and not adjective then
NS = nom_base .. 'ς'
else
NS = usub(base, 1, -3) .. 'ης'
end
elseif identifying_ending == 'ω' then
-- m_paradigms.lp_prx.NS is nil. Is the condition correct?
if NS == m_paradigms.lp_prx.NS then
DS = nom_base .. 'ῳ/$ῐ̈'
AS = '$/$ᾰ'
else
DS = '$ῐ̈́'
AS = '$/$ᾰ́'
end
DP = nom_base .. 'ωσ'
NS = nom_base .. 'ως'
gender[1] = gender[1] or 'M'
else
error('Stem does not end in a consonant: ' .. base)
end
end
-- This overrides any assignment done above. Better to improve the code
-- above or prevent it from assigning NS.
if not adjective then
NS = arg1
end
if DP then
if accent_alternating then
DP = DP .. 'ῐ́(ν)'
else
DP = DP .. 'ῐ(ν)'
end
end
ctable.DS, ctable.AS = DS, AS
ctable.NS, ctable.DP = NS, DP
args.gender = gender
end
local function dial_forms_third(args)
if not args.ctable.DP then
require('Module:debug').track('grc-decl/no dative plural')
mw.log("no DP: " .. args[1] .. ", " .. args[2])
end
dial_form_multi(args, {
{ 'GD', '$οιῐ̈ν' },
{ 'DP', (args.ctable['DP'] and (args.ctable['DP'] .. '/') or '') .. '$εσῐ(ν)/$εσσῐ(ν)' },
},
'epi')
dial_form_multi(args, {
{ 'AS', '$ᾰν', 'kyp' },
{ 'GD', '$οιῠ̈ν', 'ark' },
{ 'DP', '$εσσῐ(ν)', 'dor' },
{ 'DP', '$εσσῐ(ν)', { 'les', 'the' } },
{ 'DP', '$εσσῐ(ν)', 'boi' },
{ 'DP', '$οις', { 'lok', 'ele' } },
{ 'AP', '$ες', 'ark' },
{ 'AP', '$ες/$ερ', 'ele' },
{ 'AP', '$ᾰ(ν)ς', { 'kre', 'arg' } },
})
end
local function dial_forms_third_oxy(args)
dial_form_multi(args, {
{ 'GD', '$οῖῐ̈ν' },
{ 'DP', (args.ctable['DP'] and (args.ctable['DP'] .. '/') or '') .. '$εσῐ(ν)/$εσσῐ(ν)' },
},
'epi')
dial_form_multi(args, {
{ 'AS', '$ᾰν', 'kyp' },
{ 'GD', '$οῖῠ̈ν', 'ark' },
{ 'DP', '$εσσῐ(ν)', 'dor' },
{ 'DP', '$εσσῐ(ν)', { 'les', 'the' } },
{ 'DP', '$εσσῐ(ν)', 'boi' },
{ 'DP', '$οῖς', { 'lok', 'ele' } },
{ 'AP', '$ες', 'ark' },
{ 'AP', '$ες/$ερ', 'ele' },
{ 'AP', '$ᾰ(ν)ς', { 'kre', 'arg' } },
})
end
-- For instance, [[μείζων]].
local function third_comparative(args, neuter)
local short_stem, count = args.stem:gsub('ον$', '')
if count ~= 1 then
error('Stem failure.')
end
if neuter then
dial_form(args, 'NP', '$ᾰ/' .. short_stem .. 'ω', 'att')
else
dial_form_multi(args, {
{ 'AS', '$ᾰ/' .. short_stem .. 'ω'},
{ 'NP', '$ες/' .. short_stem .. 'ους' },
{ 'AP', '$ᾰς/' .. short_stem .. 'ους' },
}, 'att')
end
end
-- These nouns are monosyllabic, but unlike most they do not accent the ending
-- of the genitive–dative dual and genitive plural: παίδων, not *παιδῶν.
local monosyllabic_exceptions = require("Module:table/listToSet"){"δᾴς", "δμώς", "ἦρ", "θώς", "κῆρ", "οὖς", "παῖς", "Τρώς", "φῶς"}
-- Other exceptions: contracted forms like ἔαρος > ἦρος (not *ἠρός).
-- The source for this is Smyth § 252.
local function third(neuter)
return function (args)
local decl_type = args.decl_type
if decl_type:find('ντ$') and syllables(args[1], 'eq', 1) then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/grc-decl/monosyllabic nt]]
require('Module:debug').track('grc-decl/monosyllabic nt')
end
-- This tracks monosyllabic nouns or adjectives that have alternating accent
-- position. Masculine and neuter participles (with stems in -ντ) and
-- suffixes do not.
local accent_alternating = not (args.suffix or args.stem:find('ντ$')) and syllables(args[1], 'eq', 1)
args.accent_alternating = accent_alternating
local accent_on_ultima = accent_alternating and '' or '_prx'
local suffix = accent_switch(args.accent.term, accent_on_ultima, accent_on_ultima, '_prx', nil, args.suffix)
args.ctable = deep_copy(m_paradigms[(neuter and 'N_' or '') .. 'lp' .. suffix])
if not (args.NS and args.DP) then
third_nom(args, neuter, accent_alternating)
end
if args.comparative then
third_comparative(args, neuter)
end
if not neuter then
local stem = toNFC(args.stem)
if umatch(stem, "ῐ̈?[δτ]$") or umatch(stem, "ῑ̈?θ$") then
local i_stem = usub(stem, 1, -2)
if args.accent.term ~= 'oxytone' then
local n_stem = i_stem .. 'ν'
dial_form(args, 'AS', n_stem, 'att')
dial_form(args, 'AS', n_stem .. "/$ᾰ", { 'koi', 'ion', 'epi' } )
end
args.ctable['VS'] = args['VS'] or i_stem
elseif usub(stem, -2) == 'ντ' and (not args.like_adjective or decl_type == '1&3-εσσ' or decl_type == '1&3-εσσ-con' or decl_type == '3rd-cons') then
args.ctable['VS'] = args['VS'] or usub(stem, 1, -2)
elseif args.accent.term ~= 'oxytone' and args.accent.term ~= 'perispomenon' and umatch(stem, '[ρν]$') then
args.ctable['VS'] = args['VS'] or stem
-- What's an example of this?
elseif usub(stem, -1) == 'ε' then
args.ctable['VS'] = args['VS'] or stem .. 'ς'
end
if args.accent.term == 'perispomenon' then
args.ctable['NS'] = args[1]
end
end
if accent_alternating then
dial_forms_third_oxy(args)
if monosyllabic_exceptions[toNFC(args[1])] then
-- Remove accent marks: that is, make the form be accented on the
-- stem.
args.ctable.GD = m_accent.strip_tone(args.ctable.GD)
args.ctable.GP = m_accent.strip_tone(args.ctable.GP)
end
else
dial_forms_third(args)
end
end
end
export.inflections['3rd-cons'] = third(false)
export.inflections['3rd-N-cons'] = third(true)
local function dial_forms_es(args, neuter)
dial_form_multi(args, {
{ 'GS', '$εος', 'nonIA' },
{ 'GS', '$ῐος', 'buck9' },
{ 'GS', '$εος/$ευς', { 'ion', 'epi' } },
{ 'DS', '$εῐ̈/$ει', { 'ion', 'epi' } },
{ 'ND', '$εε/$ει', { 'ion', 'epi' } },
{ 'GD', '$έοιν', { 'nonIA', 'ion' } },
{ 'GD', '$έοιῐ̈ν', 'epi' },
{ 'GD', '$έοιῠ̈ν', 'ark' },
{ 'GD', '$ῐ́οιν', 'buck9' },
{ 'GP', '$εων', { 'nonIA', 'ion', 'epi' } },
{ 'GP', '$ῐων', 'buck9' },
{ 'DP', '$εσῐ(ν)/$εσσῐ(ν)/$έεσσῐ(ν)', 'epi' }
})
if neuter then
dial_form_multi(args, {
{ 'NP', '$εᾰ', { 'nonIA', 'ion', 'epi' } },
})
else
dial_form_multi(args, {
{ 'AS', '$εᾰ', { 'nonIA', 'ion', 'epi' } },
{ 'AS', '$ῐᾰ', 'buck9' },
{ 'NP', '$εες/$εις', { 'nonIA', 'ion', 'epi' } },
{ 'AP', '$εᾰς', { 'nonIA', 'ion', 'epi' } },
{ 'AP', '$ῐᾰς', 'buck9' },
})
end
end
local function dial_forms_es_oxy(args, neuter)
dial_form_multi(args, {
{ 'GS', '$έος', 'nonIA' },
{ 'GS', '$ῐ́ος', 'buck9' },
{ 'GS', '$έος/$εῦς', { 'ion', 'epi' } },
{ 'DS', '$έῐ̈/$εῖ', { 'ion', 'epi' } },
{ 'ND', '$έε/$εῖ', { 'ion', 'epi' } },
{ 'GD', '$έοιν', { 'nonIA', 'ion' } },
{ 'GD', '$εοῖῐ̈ν', 'epi' },
{ 'GD', '$εοῖῠ̈ν', 'ark' },
{ 'GD', '$ῐ́οιν', 'buck9' },
{ 'GP', '$έων', { 'nonIA', 'ion', 'epi' } },
{ 'GP', '$ῐ́ων', 'buck9' },
{ 'DP', '$έσῐ(ν)/$έσσῐ(ν)/$έεσσῐ(ν)', 'epi' }
})
if neuter then
dial_form_multi(args, {
{ 'NP', '$έᾰ', { 'nonIA', 'ion', 'epi' } },
})
else
dial_form_multi(args, {
{ 'AS', '$έᾰ', { 'nonIA', 'ion', 'epi' } },
{ 'AS', '$ῐ́ᾰ', 'buck9' },
{ 'NP', '$έες/$εῖς', { 'nonIA', 'ion', 'epi' } },
{ 'AP', '$έᾰς', { 'nonIA', 'ion', 'epi' } },
{ 'AP', '$ῐ́ᾰς', 'buck9' },
})
end
end
-- Adjectives with these endings have persistent accent (Smyth 292c):
-- εὐώδης, εὐῶδες.
local persistent_es = {
['ώδης'] = true,
['ώλης'] = true,
['ώρης'] = true,
['ήρης'] = true,
}
-- How to deal with τριήρων, not *τριηρῶν (Smyth 264)?
local function es_adj(gender_code, open)
return function(args)
uncontracted_error(args.contracted or not open, args.dial, '-ης')
local suffix = accent_switch(args.accent.term, '', nil, '_prx',
'Perispomenon third-declension forms in -ης not supported.', args.suffix)
args.ctable = deep_copy(m_paradigms[(gender_code or '') .. 'es_adj' ..
suffix .. (open and '_open' or '')])
-- Most adjectives of this type have recessive accent. Set accent to
-- antepenult.
if not args.suffix and not persistent_es[toNFC(usub(args[1], -4))] then
args.accent.position = -3
end
if args.accent.term == 'oxytone' then
dial_forms_es_oxy(args, gender_code == 'N_')
else
dial_forms_es(args, gender_code == 'N_')
end
if gender_code ~= 'N_' then
dial_form(args, 'NS', '$εῖς', 'boi', 'the')
end
end
end
export.inflections['3rd-εσ'] = es_adj()
export.inflections['3rd-N-εσ'] = es_adj('N_')
export.inflections['3rd-εσ-open'] = es_adj(nil, true)
export.inflections['3rd-N-εσ-open'] = es_adj('N_', true)
local function _os(gender_code, open)
return function(args)
uncontracted_error(args.contracted or not open, args.dial, '-ως')
local suffix = accent_switch(args.accent.term, '', nil, '_prx', nil, args.suffix)
args.ctable = deep_copy(m_paradigms[(gender_code or '') .. 'os' ..
suffix .. (open and '_open' or '')])
end
end
export.inflections['3rd-οσ'] = _os()
export.inflections['3rd-N-οσ'] = _os('N_')
export.inflections['3rd-οσ-open'] = _os(nil, true)
export.inflections['3rd-N-οσ-open'] = _os('N_', true)
local function neuter_os(open)
return function(args)
nonrecessive_error(args.accent.term,
'Third-declension neuter nouns in -ος must be accented recessively')
uncontracted_error(args.contracted or not open, args.dial, '-ος')
args.ctable = deep_copy(m_paradigms['N_es_prx' .. (open and '_open' or '')])
dial_forms_es(args, true)
end
end
export.inflections['3rd-N-ος'] = neuter_os()
export.inflections['3rd-N-ος-open'] = neuter_os(true)
local function neuter_as(open)
return function(args)
nonrecessive_error(args.accent.term,
'Third-declension neuter nouns in -ας must be accented recessively')
uncontracted_error(args.contracted or not open, args.dial, '-ᾰς')
args.ctable = deep_copy(m_paradigms['N_as_prx' .. (open and '_open' or '')])
end
end
export.inflections['3rd-N-ᾰσ'] = neuter_as()
export.inflections['3rd-N-ᾰσ-open'] = neuter_as(true)
local function kles(open)
return function(args)
local dialect = args.dial
uncontracted_error(args.contracted or not open, dialect, '-κλης')
if dialect == 'ion' or dialect == 'epi' then
open = true
end
args.ctable = deep_copy(m_paradigms['kles' .. (open and '_open' or '')])
args.number = { 'S', S = true }
args.recessive_VS = true
if open then
dial_form_multi(args, {
{ 'GS', '$κλῆος/$κλέος' },
{ 'DS', '$κλῆῐ̈/$κλέῐ̈' },
{ 'AS', '$κλῆᾰ/$κλέᾱ' },
},
{'ion', 'epi' })
else
dial_form_multi(args, {
{ 'GS', '$κλέος', 'nonIA' },
{ 'GS', '$κλεῖος', 'boi' },
})
end
end
end
export.inflections['3rd-κλῆς'] = kles()
export.inflections['3rd-κλῆς-open'] = kles(true)
local function dial_forms_weak_iu(args, neuter)
dial_form_multi(args, {
{ 'GS', '$έος', { 'ion', 'epi' } },
{ 'DS', '$εῖ', { 'att', 'koi' } },
{ 'DS', '$έῐ̈/$εῖ', { 'ion', 'epi' } },
{ 'ND', '$εῖ', 'att' },
{ 'ND', '$έε/$εῖ', { 'ion', 'epi' } },
{ 'GD', '$έοιῐ̈ν', 'epi' },
{ 'GD', '$έοιῠ̈ν', 'ark' },
{ 'DP', '$έσῐ(ν)/$έσσῐ(ν)/$έεσσῐ(ν)', 'epi' },
{ 'DP', '$έεσσῐ(ν)', 'dor' }}
)
if not neuter then
dial_form_multi(args, {
{ 'NP', '$εῖς', 'att' },
{ 'NP', '$εῖς/$έες', 'koi' },
{ 'NP', '$έες/$εῖς', { 'ion', 'epi' } },
{ 'AP', '$εῖς', { 'att', 'koi' } },
})
end
end
local function dial_forms_weak_iu_prx(args, neuter)
dial_form_multi(args, {
{ 'GS', '$εος', { 'ion', 'epi' } },
{ 'DS', '$ει', { 'att', 'koi' } },
{ 'DS', '$εῐ̈/$ει', { 'ion', 'epi' } },
{ 'ND', '$ει', 'att' },
{ 'ND', '$εε/$ει', { 'ion', 'epi' } },
{ 'GD', '$έοιῐ̈ν', 'epi' },
{ 'GD', '$έοιῠ̈ν', 'ark' },
{ 'DP', '$εσῐ(ν)/$εσσῐ(ν)/$έεσσῐ(ν)', 'epi' },
{ 'DP', '$έεσσῐ(ν)', 'dor' }
})
if neuter then
dial_form_multi(args, {
{ 'NP', '$η/$εᾰ', 'att' },
})
else
dial_form_multi(args, {
{ 'NP', '$εις', 'att' },
{ 'NP', '$εις/$εες', 'koi' },
{ 'NP', '$εες/$εις', { 'ion', 'epi' } },
{ 'AP', '$εις', { 'att', 'koi' } },
})
end
end
local function weak_iu (vowel, gender, adj_decl)
return function(args)
local suffix = accent_switch(args.accent.term, '', nil, '_prx', nil, args.suffix)
args.ctable = deep_copy(m_paradigms[(gender or '') .. 'weak_' .. vowel .. (adj_decl and '_adj' or '') .. suffix])
if not args.like_adjective then
args.synaeresis = true
end
local neuter = gender == 'N_'
if args.accent.term == 'oxytone' then
dial_forms_weak_iu(args, neuter)
else
dial_forms_weak_iu_prx(args, neuter)
end
end
end
export.inflections['3rd-weak-ι'] = weak_iu('i')
export.inflections['3rd-N-weak-ι'] = weak_iu('i', 'N_')
export.inflections['3rd-weak-ι-adj'] = weak_iu('i', nil, true)
export.inflections['3rd-N-weak-ι-adj'] = weak_iu('i', 'N_', true)
export.inflections['3rd-weak-υ'] = weak_iu('u')
export.inflections['3rd-N-weak-υ'] = weak_iu('u', 'N_')
export.inflections['3rd-weak-υ-adj'] = weak_iu('u', nil, true)
export.inflections['3rd-N-weak-υ-adj'] = weak_iu('u', 'N_', true)
export.inflections['3rd-pure-ι'] = function(args)
nonrecessive_error("Nouns in -ῐς cannot be accented on the ultima")
args.ctable = deep_copy(m_paradigms.pure_i_prx)
dial_form_multi(args, {
{ 'GS', '$ῐος/$ηος' },
{ 'DS', '$ῐῐ̈/$ῑ/$ηῐ̈/$ει' },
{ 'GD', '$ῐ́οιῐ̈ν' },
{ 'NP', '$ῐες/$ηες' },
{ 'DP', '$ῐσῐ(ν)/$ῐσσῐ(ν)/$ῐ́εσσῐ(ν)' },
{ 'AP', '$ῐᾰς/$ηᾰς/$ῑς' },
},
'epi')
dial_form_multi(args, {
{ 'GD', '$ῐ́οιῠ̈ν', 'ark' },
{ 'DP', '$ῐ́εσσῐ(ν)', 'dor' },
})
end
export.inflections['3rd-N-pure-ι-prx'] = function(args)
args.ctable = deep_copy(m_paradigms.N_pure_i_prx)
end
export.inflections['3rd-N-pure-ι-pax'] = export.inflections['3rd-N-pure-ι-prx']
local function dial_forms_u_oxy_or_con(args, neuter)
dial_form_multi(args, {
{ 'DS', '$ῠ́ῐ̈/$υῖ', { 'att', 'ion', 'epi' } },
{ 'ND', '$ῠ́ε/$ῦ', 'att' },
{ 'GD', '$ῠ́οιῐ̈ν', 'epi' },
{ 'GD', '$ῠ́οιῠ̈ν', 'ark' },
{ 'DP', '$ῠ́σῐ(ν)/$ῠ́σσῐ(ν)/$ῠ́εσσῐ(ν)', 'epi' },
{ 'DP', '$ῠ́εσσῐ(ν)', 'dor' },
})
if not neuter then
dial_form_multi(args, {
{ 'NP', '$ῠ́ες/$ῦς', 'att' },
{ 'AP', '$ῦς/$ῠ́ᾰς', 'att', 'koi' },
{ 'AP', '$ῠ́ᾰς/$ῦς', { 'ion', 'epi' } },
})
end
end
local function dial_forms_u_prx(args, neuter)
dial_form_multi(args, {
{ 'DS', '$ῠῐ̈/$υι', { 'att', 'koi', 'ion', 'epi' } },
{ 'ND', '$ῠε/$ῡ', 'att' },
{ 'GD', '$ῠ́οιῐ̈ν', 'epi' },
{ 'GD', '$ῠ́οιῠ̈ν', 'ark' },
{ 'DP', '$ῠσῐ(ν)/$ῠσσῐ(ν)/$ῠ́εσσῐ(ν)', 'epi' },
{ 'DP', '$ῠ́εσσῐ(ν)', 'dor' },
})
if not neuter then
dial_form_multi(args, {
{ 'NP', '$ῠες/$ῡς', 'att' },
{ 'AP', '$ῡς/$ῠᾰς', 'att', 'koi' },
{ 'AP', '$ῠᾰς/$ῡς', { 'ion', 'epi' } },
})
end
end
local function dial_forms_u_mono(args)
dial_form_multi(args, {
{ 'DS', '$ῠῐ̈́/$υί', { 'att', 'ion', 'epi' } },
{ 'GD', '$ῠοῖῐ̈ν', 'epi' },
{ 'GD', '$ῠοῖῠ̈ν', 'ark' },
{ 'DP', '$ῠσῐ́(ν)/$ῠσσῐ́(ν)/$ῠ́εσσῐ(ν)', 'epi' },
})
end
local function pure_u_short(gender_code)
return function(args)
local suffix = accent_switch(args.accent.term, '', nil, '_prx', nil, args.suffix)
args.ctable = deep_copy(m_paradigms[(gender_code or '') .. 'pure_u' .. suffix])
local neuter = gender_code == 'N_'
if args.accent.term == 'oxytone' then
dial_forms_u_oxy_or_con(args, neuter)
elseif args.accent.term ~= 'perispomenon' then
dial_forms_u_prx(args, neuter)
end
end
end
export.inflections['3rd-pure-υ'] = pure_u_short()
export.inflections['3rd-N-pure-υ'] = pure_u_short('N_')
-- TODO: add optional long ῡ in Epic oblique forms.
local function pure_u_long(gender_code)
return function(args)
local accent = args.accent.term
local suffix = accent_switch(accent, '', '_con', '_prx', nil, args.suffix)
local mono = syllables(args[1], 'eq', 1)
args.ctable = deep_copy(m_paradigms[(gender_code or '') .. 'pure_u_long' .. suffix .. (mono and '_mono' or '')])
local neuter = gender_code == 'N_'
if accent == 'oxytone' or accent == 'perispomenon' then
dial_forms_u_oxy_or_con(args, neuter)
else
dial_forms_u_prx(args, neuter)
end
if mono then
dial_forms_u_mono(args)
end
end
end
export.inflections['3rd-pure-υ-long'] = pure_u_long()
export.inflections['3rd-N-pure-υ-long'] = pure_u_long('N_')
local function third_eus(contracted)
return function(args)
-- Maybe only Attic actually?
local dialect = args.dial
if contracted and not (dialect == 'att' or dialect == 'koi' or dialect == 'byz') then
error('Only Attic, Koine, or Byzantine Greek have contracted declined forms for nouns in -ευς.')
end
if dialect == 'kyp' or dialect == 'boi' then
args.ctable = deep_copy(m_paradigms.eus_hwos)
elseif dialect == 'les' or dialect == 'epi' then
args.ctable = deep_copy(m_paradigms.eus_hos)
dial_form_multi(args, {
{ 'GS', '$ῆος/$έος' },
{ 'DS', '$ῆῐ̈/$έῐ̈/$εῖ' },
{ 'AS', '$ῆᾰ/$έᾰ' },
{ 'ND', '$ῆε/$ῆ/$έε/$εῖ' },
{ 'GD', '$ήοιῐ̈ν/$έοιῐ̈ν' },
{ 'NP', '$ῆες/$ῆς/$έες/$εῖς' },
{ 'GP', '$ήων/$έων' },
{ 'DP', '$εῦσῐ(ν)/$ήεσσῐ(ν)' },
{ 'AP', '$ῆᾰς/$έᾰς' },
},
'epi')
elseif dialect == 'the' or dialect == 'ele' then
args.ctable = deep_copy(m_paradigms.eus_eios)
else
if contracted then
args.ctable = deep_copy(m_paradigms.eus_con)
table.insert(args.titleapp, '[[Appendix:Ancient Greek contraction|contracted]]')
else
args.ctable = deep_copy(m_paradigms.eus)
end
dial_form_multi(args, {
{ 'NS', '$ής', 'ara' },
{ 'GS', '$έος', { 'nonIA', 'ion' } },
{ 'DS', '$εῖ', 'att' },
{ 'DS', '$έῐ̈/$εῖ', 'ion' },
{ 'AS', '$έᾰ/$ῆ', 'ion' },
{ 'AS', '$έᾰ', 'nonIA' },
{ 'AS', '$ήν', 'ara' },
{ 'AS', '$ῆ', { 'doric', 'del' } },
{ 'AS', '$έᾰ', { 'lok', 'kre' } },
{ 'GD', '$έοιῠ̈ν', 'ark' },
{ 'NP', '$έες/$εῖς', 'ion' },
{ 'NP', '$εῖς', 'nonIA' },
{ 'NP', '$ῆς', { 'koa', 'lak' } },
{ 'NP', '$ῆς', 'ara' },
{ 'NP', '$έες', 'kre' },
{ 'NP', '$εῖς', 'late' },
{ 'DP', '$έεσσῐ(ν)', 'dor' }, -- this is somewhat conjectured
{ 'AP', '$έᾰς', { 'nonIA', 'ion' } },
})
--[[
Contraction only for nouns with vowel before -ευς.
]]
if umatch(args.stem, '[αεηιουω]' .. (grc_utilities_data or get_grc_utilities_data()).length.optional .. '$') then
dial_form_multi(args, {
{ 'GS', '$έως/$ῶς' },
{ 'AS', '$έᾱ/$ᾶ' },
{ 'GP', '$έων/$ῶν' },
{ 'AP', '$έᾱς/$ᾶς' },
},
'att')
table.insert(args.notes, 'The first form is uncontracted, the second [[Appendix:Ancient Greek contraction|contracted]].')
elseif contracted then
error('Forms with a stem ending in ' ..
require('Module:grc-utilities').tag(usub(args.stem, -1)) ..
' do not have contracted forms.')
end
end
end
end
export.inflections['3rd-ευς'] = third_eus(false)
export.inflections['3rd-ευς-con'] = third_eus(true)
export.inflections['3rd-οι'] = function(args)
args.ctable = deep_copy(m_paradigms.oi)
dial_form_multi(args, {
{ 'GS', '$ῶς', 'sever' },
{ 'AS', '$οῦν', 'ion' },
})
end
local function get_param_code(number)
if number.F then
return 'full'
end
local param_code = (number.S and 'S' or '') .. (number.D and 'D' or '') .. (number.P and 'P' or '')
if param_code == '' then
error('Could not decide which table of forms to use.')
end
return param_code
end
-- irregular masculine or feminine nouns
export.inflections['irreg'] = function(args)
local params = m_decl_static_data.irregular.noun.masculine_feminine
if args.gender.N then
return export.inflections['irregN'](args)
end
local number = args.number
local param_code = get_param_code(number)
local forms = params[param_code]
args.declheader = 'irreg'
local ctable = {}
local found_forms = false
for i = 2, args.maxindex do
local code = forms[i]
local arg1 = ine(args[i])
if code then
local arg2 = ine(args[code])
if arg1 and arg2 then
error('Two forms specified for ' .. code .. ': ' .. arg1 .. ' and ' .. arg2 '.')
end
local number_code = code:sub(2, 2)
if arg1 or arg2 then
if number[number_code] then
found_forms = true
else
error('The number ' .. number_code .. ' is not specified in the form parameter.')
end
end
ctable[code] = arg1 or arg2
elseif arg1 then
local abbr = {
S = 'singular',
D = 'dual',
P = 'plural',
}
local numbers = mw.text.listToText(require('Module:fun').map(function(code)
return abbr[code] or code
end,
number
))
local singular = not number[2]
error('Parameter ' .. i .. ' has been given, but only ' .. #forms ..
' parameters are needed because the number' .. (singular and '' or 's') ..
' specified in the form parameter ' .. (singular and 'is ' or 'are ') ..
numbers .. '.')
end
end
if not found_forms then
error('No displayable forms found.')
end
args.ctable = ctable
end
-- irregular neuter nouns
export.inflections['irregN'] = function(args) --neuter irregular nouns
local params = m_decl_static_data.irregular.noun.neuter
local number = args.number
local param_code = get_param_code(number)
local forms = params[param_code]
local ctable = {}
for i = 2, args.maxindex do
local code = forms[i]
local arg1 = args[i]
if code then
local arg2 = args[code]
if arg1 and arg2 then
error('Two forms given for form ' .. code .. ': ' .. arg1 ..
' in parameter ' .. i .. ' and ' .. arg2 ..
' in parameter ' .. code ..
'. Choose one or put both in the same parameter separated by slashes.')
end
ctable[code] = arg1 or arg2
elseif arg1 then
error('Parameter ' .. i .. ', ' .. arg1 .. ', does not have a case and number assigned to it.')
end
end
for form, source in pairs(forms.redirects) do
ctable[form] = args[form] or ctable[source]
end
args.ctable = ctable
end
-- irregular adjectives
export.inflections['irreg-adj'] = function(args)
local params = m_decl_static_data.irregular.adjective
local number = args.number
local param_code = get_param_code(number)
local forms = params[param_code]
local atable = {}
for i = 2, args.maxindex do
local code = forms[i]
local arg1 = ine(args[i])
if code then
local arg2 = ine(args[code])
if arg1 and arg2 then
error('Two forms given for form ' .. code .. ': ' .. arg1 ..
' in parameter ' .. i .. ' and ' .. arg2 ..
' in parameter ' .. code ..
'. Choose one or put both in the same parameter separated by slashes.')
end
atable[code] = arg1 or arg2
else
if arg1 then
error('No gender, case, and number assigned to parameter ' ..
i .. ': ' .. tostring(arg1) .. '. Only ' ..
#forms .. ' parameters are needed.')
end
end
end
for form, source in pairs(forms.redirects) do
atable[form] = args[form] or atable[source]
end
if number.D then
for target_case, source_case in pairs { A = 'N', V = 'N', D = 'G' } do
for _, gender in ipairs { 'M', 'F', 'N' } do
local target = gender .. target_case .. 'D'
atable[target] = args[target] or atable[target] or atable[gender .. source_case .. 'D']
target = gender .. 'VP'
atable[target] = args[target] or atable[target] or atable[gender .. 'NP']
end
end
end
args.atable = atable
end
export.inflections['indecl'] = function(args)
args.ctable = deep_copy(m_paradigms.indecl)
args.stem = { args[2] }
end
return export
7wmncxf1r3g4uzhnfawsf6titxl3rn6
မဝ်ဂျူ:grc-decl/params
828
26048
397285
36653
2026-06-21T08:32:34Z
咽頭べさ
33
397285
Scribunto
text/plain
local m_table = require("Module:table")
local deep_copy = m_table.deepCopy
local genders = { 'M', 'F', 'N' }
local cases = { 'N', 'G', 'D', 'A', 'V' }
local numbers = { 'S', 'D', 'P' }
local noun_params = {
[1] = {},
[2] = {},
dial = { default = 'att' },
form = { default = 'full' },
voc = {}, -- if "α", means that first-declension masculine has vocative in -ᾰ
notes = {},
note = { alias_of = "notes" },
['notes1'] = {},
['notes2'] = {},
titleapp = {},
['titleapp1'] = {},
['titleapp2'] = {},
}
for _, c in ipairs(cases) do
for _, n in ipairs(numbers) do
noun_params[c .. n] = {}
noun_params[c .. n .. 1] = {}
noun_params[c .. n .. 2] = {}
end
end
local irreg_noun_params, irreg_N_noun_params = deep_copy(noun_params), deep_copy(noun_params)
for i = 3, 9 do
irreg_N_noun_params[i] = {}
end
for i = 3, 12 do
irreg_noun_params[i] = {}
end
local adj_params = {
[1] = {},
[2] = {},
dial = { default = 'att' },
form = { default = '' },
notes = {},
['notes1'] = {},
['notes2'] = {},
titleapp = {},
['titleapp1'] = {},
['titleapp2'] = {},
title = {},
adv = {},
['adv1'] = {},
['adv2'] = {},
deg = {},
comp = {},
['comp1'] = {},
['comp2'] = {},
super = {},
['super1'] = {},
['super2'] = {},
hp = { type = "boolean" },
}
for _, g in ipairs(genders) do
for _, c in ipairs(cases) do
for _, n in ipairs(numbers) do
adj_params[g .. c .. n] = {}
adj_params[g .. c .. n .. 1] = {}
adj_params[g .. c .. n .. 2] = {}
end
end
end
local irreg_adj_params = deep_copy(adj_params)
for i = 3, 25 do
irreg_adj_params[i] = {}
end
return {
noun_params = noun_params,
irreg_noun_params = irreg_noun_params,
irreg_N_noun_params = irreg_N_noun_params,
adj_params = adj_params,
irreg_adj_params = irreg_adj_params,
}
bg0yx72cznplalct2777jo778aji5v9
မဝ်ဂျူ:grc-decl/style.css
828
26049
397282
36654
2026-06-21T08:24:06Z
咽頭べさ
33
397282
sanitized-css
text/css
.grc-decl.NavFrame { /* adjoining classes are intentional */
clear: both;
width: 100%; /* changeable */
}
.grc-decl .NavHead {
text-align: center;
cursor: pointer;
}
.grc-decl .NavContent {
display: block;
}
.grc-decl table {
width: 100%;
border-collapse: collapse;
background: var(--wikt-palette-grey-4,#A9A9A9);
color: var(--wikt-palette-black,#000000);
text-align: center;
}
.grc-decl table, .grc-decl th, .grc-decl td {
border: 1px solid var(--wikt-palette-grey-4,darkgray);
}
.grc-decl .divider {
width: 0.5%;
}
.grc-decl .case-number-header, .grc-decl .derived-forms-header,
.grc-decl .case-header, .grc-decl .number-header, .grc-decl .gender-header,
.grc-decl .notes-header, .grc-decl .derived-forms-header,
.grc-decl .derived-form-name-header {
font-style: italic;
}
.grc-decl .case-number-header, .grc-decl .case-gender-header,
.grc-decl .derived-forms-header {
background: var(--wikt-palette-dulllightblue,#B0C4DE);
}
.grc-decl .case-number-header {
width: 16%; /* changeable */
}
.grc-decl .number-header {
width: 28%; /* changeable */
}
.grc-decl .case-header, .grc-decl .number-header, .grc-decl .gender-header,
.grc-decl .notes-header, .grc-decl .derived-form-name-header {
background: var(--wikt-palette-grey-3,#C0C0C0);
}
.grc-adecl .number-header {
background: var(--wikt-palette-grey-2,#CECECE);
}
.grc-decl .form {
background: var(--wikt-palette-grey-1,#F5F5F5);
}
.grc-decl .notes {
background: var(--wikt-palette-grey-1,#F5F5F5);
text-align: left;
font-size: 90%;
}
.grc-decl .tr {
color: var(--wikt-palette-grey-8,#888888);
}
aorxzvmdtfp9auqebpc670rg8mbm0nq
မဝ်ဂျူ:grc-decl/table
828
26050
397281
36655
2026-06-21T08:22:56Z
咽頭べさ
33
397281
Scribunto
text/plain
local path = 'Module:grc-decl'
local headers = mw.loadData(path .. '/decl/classes').headers
local concat = table.concat
local ugsub = mw.ustring.gsub
local Array = require 'Module:array'
local function split(...)
split = require('Module:string utilities').split
return split(...)
end
local function trim(...)
trim = require('Module:string utilities').trim
return trim(...)
end
-- Commas or slashes in the cell for a particular form are converted to this.
local form_separator = ' / '
local export = {}
-- displayed in cell that has no form in it
local empty_cell = '—'
local nonAttic_note = 'Dialects other than Attic are not well attested. ' ..
'Some forms may be based on conjecture. Use with caution.'
local Attic_note = 'This table gives Attic inflectional endings. ' ..
'For declension in other dialects, see [[Appendix:Ancient Greek dialectal declension]].'
local case_names = { 'Nominative', 'Genitive', 'Dative', 'Accusative', 'Vocative' }
local function is_empty(str)
return not str or str == '' or str == '-' or str == '—'
end
-- Use the fields in a table to fill out template parameter syntax in a string.
local function fill_params(str, mapping)
str = str:gsub('{{{([^}]+)}}}',
function(key)
return mapping[key] or error("Parameter " .. key .. " not found.")
end)
return str
end
local lang = require('Module:languages').getByCode('grc')
local full_link = require('Module:links').full_link
local function entry_link(term, accel)
term = ugsub(term, 'σ%f[%s%z]', 'ς') --just in case
return full_link({ lang = lang, term = term, tr = '-', accel = accel }, nil, false)
end
-- Creates a callable table that saves previous transliterations.
-- Helpful because most paradigms have some syncretic forms; particularly useful for neuter forms.
local transliterate = require("Module:memoize")(require('Module:grc-translit').tr)
local tag_translit = require('Module:script utilities').tag_translit
local function format_translit(Greek_text)
return tag_translit(transliterate(Greek_text), lang, 'default')
end
local function get_label_display(dialect)
return require("Module:labels").get_label_info { label = dialect, lang = lang, nocat = true}.label
end
local function get_stylesheet()
return require("Module:TemplateStyles")("Module:grc-decl/style.css")
end
local function make_number_table(number_arg)
local numbers = {}
for _, number in ipairs{ { 'S', 'Singular' }, { 'D', 'Dual' }, { 'P', 'Plural' } } do
if number_arg[number[1]] then
table.insert(numbers, number[2])
end
end
return numbers
end
local function link(alt, sep, accel)
if alt == '-' then
return '-'
end
if alt:find('%b()') then
local no_paren_content, with_paren_content = alt:gsub('%b()', ''), alt:gsub('[()]', '')
-- This expands πᾶσῐ(ν) to πᾶσῐ / πᾶσῐν so that both terms can be found
-- in searches.
return entry_link(no_paren_content, accel) .. sep .. entry_link(with_paren_content, accel)
else
return entry_link(alt, accel)
end
end
local function get_header(code, irregular, indeclinable)
if not code then
if irregular then
return 'Irregular declension'
elseif indeclinable then
return 'လဟုတ်စှ်ေ'
else
return "??"
end
elseif #code > 5 then
mw.log('grc-decl/header not code')
return code
else
return headers[code] or
error('No header for the code ' .. code .. '.')
end
end
-- Case abbreviations used by {{inflection of}}.
local inflection_of_case_abbreviations = {
N = 'nom', G = 'gen', D = 'dat', A = 'acc', V = 'voc'
}
local function link_form(args, form_code, istitle)
local form_table = args.adjective and args.atable or args.ctable
local forms = form_table[form_code]
if is_empty(forms) then
return empty_cell
end
local accel_prefix
if args.adjective then
-- Generate acceleration information ([[WT:ACCEL]]) for declined forms
-- and for the comparative and superlative forms.
if form_code:find('^%u+$') then
local gender, case, number = form_code:match('^(.)(.)(.)$')
gender, number = gender:lower(), number:lower()
case = inflection_of_case_abbreviations[case]
or error("Case " .. case .. " not recognized.")
-- If feminine nominative singular is absent, masculine and feminine
-- are probably the same?
local gender_codes = gender == 'm' and not args.atable.FNS and gender .. '//f'
or gender
accel_prefix = gender_codes .. '|' .. case .. '|' .. number
if args.comparative then
accel_prefix = accel_prefix .. '|ပတဝ်ပတုပ်ရံၚ်'
elseif args.superlative then
accel_prefix = accel_prefix .. '|သဒ္ဒာ'
end
elseif form_code == "comp" then
accel_prefix = 'comparative'
elseif form_code == "super" then
accel_prefix = 'superlative'
end
else
local case, number = form_code:match('^(.)(.)$')
number = number:lower()
case = inflection_of_case_abbreviations[case]
or error("Case '" .. tostring(case) .. "' not found.")
accel_prefix = case .. '|' .. number
end
-- Add suffix, and make sure any macrons and breves are included in the
-- non-lemma entry.
local accel
if accel_prefix then
local origin
if args.decl_type == "irreg" or args.decl_type == "indecl" then
origin = args[2]
else
for _, number in ipairs {'S', 'D', 'P'} do
if args.number[number] then
local code = 'N' .. number
if args.adjective then
code = 'M' .. code
end
origin = args[code] or form_table[code] or args[1]
break
end
end
end
origin = origin or args[1] -- just in case
accel = {form = accel_prefix, lemma = origin}
end
--[[
An Ancient Greek word character optionally preceded by a hyphen or
followed by a sequence of word characters or parentheses.
Matches -ᾰ́ς, σοῖσι(ν), as well as cases with parentheses.
]]
local sep = "<br>"
if istitle or not args.adjective then
sep = form_separator
end
forms = split(forms, '%s*[/,]%s*')
-- Don't add acceleration to links in the title, as it causes the
-- specified parsing order to be overridden.
if istitle then
accel = nil
end
local linked_forms = {}
for i, form in ipairs(forms) do
linked_forms[i] = link(trim(form), sep, accel)
end
linked_forms = concat(linked_forms, sep)
-- concat article
local articles
if not args.adjective and form_code:sub(1, 1) ~= 'V' then
articles = args.article[form_code]
if articles then
articles = split(articles, '%s*[/,]%s*')
local linked_articles = {}
for i, article in ipairs(articles) do
linked_articles[i] = link(trim(article), form_separator)
end
linked_forms = concat(linked_articles, form_separator) .. " " .. linked_forms
end
end
if istitle then
return linked_forms
elseif articles then
articles = concat(articles, form_separator) .. " "
else
articles = ""
end
return linked_forms .. "<br>" .. format_translit(articles .. concat(forms, sep))
end
local function make_title(args)
local title = Array()
title:insert(get_header(args.declheader, args.irregular, args.indeclinable) .. ' of ')
-- Display the nominative and genitive form for the first number that has
-- forms.
for _, number_code in ipairs{ 'S', 'D', 'P' } do
if args.number[number_code] then
title:insert(link_form(args, 'N' .. number_code, true) .. '; '
.. link_form(args, 'G' .. number_code, true))
break
end
end
if args.dial then
table.insert(args.titleapp, get_label_display(args.dial))
end
if args.titleapp[1] then
title:insert(' (' .. concat(args.titleapp, ', ') .. ')')
end
return title:concat()
end
local case_header =
[[
|-
! class="case-header" | {{{case_name}}}
]]
local noun_form_cell =
[[
| class="form" data-accel-col="{{{col}}}" | {{{form}}}
]]
local adj_form_cell =
[[
| class="form" data-accel-col="{{{col}}}" colspan="{{{colspan}}}" | {{{form}}}
]]
local function make_rows(args, nums)
local rows = Array()
if not args.adjective then
case_header = case_header
noun_form_cell = noun_form_cell
end
for _, case_name in ipairs(case_names) do
rows:insert((case_header:gsub("{{{case_name}}}", case_name)))
local case_abbr = case_name:sub(1, 1)
for i, number in ipairs(nums) do
rows:insert(fill_params(noun_form_cell, {
form = link_form(args, case_abbr .. number:sub(1, 1)),
col = i,
}))
end
end
return rows:concat()
end
local notes_template =
[[
|-
! class="notes-header" | စၟတ်သမ္တီ:
| {{{extra_cell}}}class="notes" colspan="13" | <div class="use-with-mention">{{{notes}}}</div>
]]
local function make_notes(args)
args.notes = Array(args.notes)
if args.dial ~= 'koi' and args.dial ~= 'byz' then
args.notes:insert(1, args.dial == 'att' and Attic_note or nonAttic_note)
end
if args.user_notes then -- add user notes
args.notes:insert(args.user_notes)
end
if args.debug then
args.notes:insert(args.debug)
end
if next(args.notes) == nil then
return ""
end
return fill_params(notes_template, {
extra_cell = args.adjective and '\n| ' or '',
notes = args.notes
:map(function (note) return "\n* " .. note end):concat(),
})
end
local number_header =
[[
! class="number-header" | {{{number}}}
]]
local noun_table_top =
[=[
<div class="NavFrame grc-decl">
<div class="NavHead">{{{title}}}</div>
<div class="NavContent">
{| class="inflection-table inflection-table-grc"
! class="case-number-header" | ကိစ္စ / #
]=]
function export.make_table(args)
local nums = make_number_table(args.number)
if not args.adjective then
noun_table_top = noun_table_top
number_header = number_header
end
-- This can be simplified.
-- Percents have to be escaped (otherwise, strangely, a null character is
-- inserted).
local output = Array(
(noun_table_top
:gsub('{{{title}}}', make_title(args))))
for _, number in ipairs(nums) do
output:insert((number_header:gsub('{{{number}}}', number)))
end
output:insert(make_rows(args, nums))
output:insert(make_notes(args))
output:insert('|}</div></div>')
if args.categories[1] and mw.title.getCurrentTitle().nsText == '' then
output:insert(require('Module:utilities').format_categories(args.categories, lang))
end
return output:concat() .. get_stylesheet()
end
local function make_title_adj(args, genders)
if args.title then
return args.title
else
local title = Array()
title:insert(get_header(args.adeclheader, args.irregular, args.indeclinable) .. ' of ')
for _, number in ipairs{ 'S', 'D', 'P' } do
if args.number[number] then
local gender_forms = {}
for _, gender in ipairs(genders) do
table.insert(gender_forms, link_form(args, gender .. 'N' .. number, true))
end
title:insert(concat(gender_forms, '; '))
break
end
end
if args.dial then
table.insert(args.titleapp, get_label_display(args.dial))
end
if args.titleapp[1] then
title:insert(' (' .. concat(args.titleapp, ', ') .. ')')
end
return title:concat()
end
end
local function make_rows_adj(args, nums, genders)
local rows = Array()
local twopt = args.act and args.act[2] == nil
for _, case_name in ipairs(case_names) do
rows:insert((case_header:gsub('{{{case_name}}}', case_name)))
for i, number in ipairs(nums) do
rows:insert('|\n')
local case_number = case_name:sub(1, 1) .. number:sub(1, 1)
for j, gender in ipairs(genders) do
rows:insert(fill_params(adj_form_cell, {
col = (i - 1) * 3 + j,
colspan = twopt and gender == 'M' and '2' or '1',
form = link_form(args, gender .. case_number),
}))
end
end
end
return rows:concat()
end
-- Add the part of the table containing the adverb and the comparative and
-- superlative forms, if applicable.
local function make_acs_adj(args, nums)
-- This should only apply to pronouns. I think.
-- If all of adverb, comparative, and superlative are absent, don't display
-- the "derived forms" part of the table at all.
if #nums < 3 or require 'Module:fun'.all(
function (form_code)
return is_empty(args.atable[form_code])
end,
{ 'adv', 'comp', 'super' }) then
return ''
end
args.atable.adv = args.atable.adv
args.atable.comp = args.atable.comp
args.atable.super = args.atable.super
local fill = {
colspan = '3',
adv = link_form(args, 'adv'),
comp = link_form(args, 'comp'),
super = link_form(args, 'super'),
}
local acs_section = [=[
|-
! class="derived-forms-header" rowspan="2" | ဗီုပြၚ်မဂွံလဝ်အာဲကၟာဲ
|
! class="derived-form-name-header" colspan={{{colspan}}} | ကြိယာဝိသေသန
|
! class="derived-form-name-header" colspan={{{colspan}}} | ပတဝ်ပတုပ်ရံၚ်
|
! class="derived-form-name-header" colspan={{{colspan}}} | သဒ္ဒာ
|-
|
| class="form" colspan={{{colspan}}} | {{{adv}}}
|
| class="form" colspan={{{colspan}}} | {{{comp}}}
|
| class="form" colspan={{{colspan}}} | {{{super}}}
]=]
return fill_params(acs_section, fill)
end
local adj_table_top =
[=[
<div class="NavFrame grc-decl grc-adecl">
<div class="NavHead">{{{title}}}</div>
<div class="NavContent">
{| class="inflection-table inflection-table-grc"
! class="number-header" | ဂၞန်
]=]
function export.make_table_adj(args)
local nums = make_number_table(args.number)
local threept = not(args.act and args.act[2] == nil)
local genders = threept and { 'M', 'F', 'N' } or { 'M', 'N' }
local number_header =
[=[
! class="divider" |
! class="number-header" colspan=3 | {{{number}}}
]=]
local gender_headers =
[=[
|
! class="gender-header" | ပုလ္လိၚ်
! class="gender-header" | ဣတ္တိလိၚ်
! class="gender-header" | နပုလ္လိၚ်
]=]
local output = Array(
(adj_table_top:gsub('{{{title}}}', make_title_adj(args, genders)))
)
for _, number in ipairs(nums) do
output:insert((number_header:gsub('{{{number}}}', number)))
end
output:insert([=[|-
! class="case-gender-header" | ကိစ္စ/လိၚ်
]=])
for _, _ in ipairs(nums) do
output:insert(gender_headers)
end
output:insert(make_rows_adj(args, nums, genders))
output:insert(make_acs_adj(args, nums))
output:insert(make_notes(args))
output:insert('|}</div></div>')
if args.categories[1] and mw.title.getCurrentTitle().nsText == '' then
output:insert(require('Module:utilities').format_categories(args.categories, lang))
end
return output:concat() .. get_stylesheet()
end
return export
b95fny3e99g9x445u35b2rjlemgucyj
397296
397281
2026-06-21T09:27:33Z
咽頭べさ
33
397296
Scribunto
text/plain
local path = 'Module:grc-decl'
local headers = mw.loadData(path .. '/decl/classes').headers
local concat = table.concat
local ugsub = mw.ustring.gsub
local Array = require 'Module:array'
local function split(...)
split = require('Module:string utilities').split
return split(...)
end
local function trim(...)
trim = require('Module:string utilities').trim
return trim(...)
end
-- Commas or slashes in the cell for a particular form are converted to this.
local form_separator = ' / '
local export = {}
-- displayed in cell that has no form in it
local empty_cell = '—'
local nonAttic_note = 'အရေဝ်အခြာမဟီုဂးတၞဟ်ကံကၠတ်အတေံမဟီုဂးလဝ်သဒှ်ဍာံဗွဲမဂၠိုၚ်ဟွံသေၚ်။ ' ..
'ဗီုပြၚ်လ္ၚဵုမဂၠိုၚ်ကဵုမဒှ်တံသ္ဇိုၚ်လ္တူသမ္ဗန္ဓ။ မရပ်စပ်မၞုံကဵုဂလာန်မကဵုသတိ။'
local Attic_note = 'မဒုၚ်ဖျေံထောံစရၚ်အၚ်တဏအ်ဝွံချပ်ဗ္စာရဏာပရေၚ်ကံကၠတ်ပွမတုဲဒှ်လဝ်ရ။' ..
'သွက်မလဟုတ်စှ်ေပ္ဍဲအရေဝ်အခြာမဟီုဂးတၞဟ်၊ ဗီုရံၚ် [[:en:Appendix:Ancient Greek dialectal declension]]'
local case_names = { 'မဒုၚ်ယၟု', 'ဗဳဇဂကူ', 'ပြကမ္မကာရက', 'ကမ္မကာရက', 'ပရေၚ်ဂယိုၚ်လမျီု' }
local function is_empty(str)
return not str or str == '' or str == '-' or str == '—'
end
-- Use the fields in a table to fill out template parameter syntax in a string.
local function fill_params(str, mapping)
str = str:gsub('{{{([^}]+)}}}',
function(key)
return mapping[key] or error("Parameter " .. key .. " not found.")
end)
return str
end
local lang = require('Module:languages').getByCode('grc')
local full_link = require('Module:links').full_link
local function entry_link(term, accel)
term = ugsub(term, 'σ%f[%s%z]', 'ς') --just in case
return full_link({ lang = lang, term = term, tr = '-', accel = accel }, nil, false)
end
-- Creates a callable table that saves previous transliterations.
-- Helpful because most paradigms have some syncretic forms; particularly useful for neuter forms.
local transliterate = require("Module:memoize")(require('Module:grc-translit').tr)
local tag_translit = require('Module:script utilities').tag_translit
local function format_translit(Greek_text)
return tag_translit(transliterate(Greek_text), lang, 'default')
end
local function get_label_display(dialect)
return require("Module:labels").get_label_info { label = dialect, lang = lang, nocat = true}.label
end
local function get_stylesheet()
return require("Module:TemplateStyles")("Module:grc-decl/style.css")
end
local function make_number_table(number_arg)
local numbers = {}
for _, number in ipairs{ { 'S', 'ကိုန်ဨကဝုစ်' }, { 'D', 'ၜါလ္ပာ်' }, { 'P', 'ကိုန်ဗဟုဝစ်' } } do
if number_arg[number[1]] then
table.insert(numbers, number[2])
end
end
return numbers
end
local function link(alt, sep, accel)
if alt == '-' then
return '-'
end
if alt:find('%b()') then
local no_paren_content, with_paren_content = alt:gsub('%b()', ''), alt:gsub('[()]', '')
-- This expands πᾶσῐ(ν) to πᾶσῐ / πᾶσῐν so that both terms can be found
-- in searches.
return entry_link(no_paren_content, accel) .. sep .. entry_link(with_paren_content, accel)
else
return entry_link(alt, accel)
end
end
local function get_header(code, irregular, indeclinable)
if not code then
if irregular then
return 'လဟုတ်စှ်ေခလံက်ခနက်'
elseif indeclinable then
return 'လဟုတ်စှ်ေ'
else
return "??"
end
elseif #code > 5 then
mw.log('grc-decl/header not code')
return code
else
return headers[code] or
error('No header for the code ' .. code .. '.')
end
end
-- Case abbreviations used by {{inflection of}}.
local inflection_of_case_abbreviations = {
N = 'nom', G = 'gen', D = 'dat', A = 'acc', V = 'voc'
}
local function link_form(args, form_code, istitle)
local form_table = args.adjective and args.atable or args.ctable
local forms = form_table[form_code]
if is_empty(forms) then
return empty_cell
end
local accel_prefix
if args.adjective then
-- Generate acceleration information ([[WT:ACCEL]]) for declined forms
-- and for the comparative and superlative forms.
if form_code:find('^%u+$') then
local gender, case, number = form_code:match('^(.)(.)(.)$')
gender, number = gender:lower(), number:lower()
case = inflection_of_case_abbreviations[case]
or error("Case " .. case .. " not recognized.")
-- If feminine nominative singular is absent, masculine and feminine
-- are probably the same?
local gender_codes = gender == 'm' and not args.atable.FNS and gender .. '//f'
or gender
accel_prefix = gender_codes .. '|' .. case .. '|' .. number
if args.comparative then
accel_prefix = accel_prefix .. '|ပတဝ်ပတုပ်ရံၚ်'
elseif args.superlative then
accel_prefix = accel_prefix .. '|သဒ္ဒာ'
end
elseif form_code == "comp" then
accel_prefix = 'ပတဝ်ပတုပ်ရံၚ်'
elseif form_code == "super" then
accel_prefix = 'သဒ္ဒာ'
end
else
local case, number = form_code:match('^(.)(.)$')
number = number:lower()
case = inflection_of_case_abbreviations[case]
or error("Case '" .. tostring(case) .. "' not found.")
accel_prefix = case .. '|' .. number
end
-- Add suffix, and make sure any macrons and breves are included in the
-- non-lemma entry.
local accel
if accel_prefix then
local origin
if args.decl_type == "irreg" or args.decl_type == "indecl" then
origin = args[2]
else
for _, number in ipairs {'S', 'D', 'P'} do
if args.number[number] then
local code = 'N' .. number
if args.adjective then
code = 'M' .. code
end
origin = args[code] or form_table[code] or args[1]
break
end
end
end
origin = origin or args[1] -- just in case
accel = {form = accel_prefix, lemma = origin}
end
--[[
An Ancient Greek word character optionally preceded by a hyphen or
followed by a sequence of word characters or parentheses.
Matches -ᾰ́ς, σοῖσι(ν), as well as cases with parentheses.
]]
local sep = "<br>"
if istitle or not args.adjective then
sep = form_separator
end
forms = split(forms, '%s*[/,]%s*')
-- Don't add acceleration to links in the title, as it causes the
-- specified parsing order to be overridden.
if istitle then
accel = nil
end
local linked_forms = {}
for i, form in ipairs(forms) do
linked_forms[i] = link(trim(form), sep, accel)
end
linked_forms = concat(linked_forms, sep)
-- concat article
local articles
if not args.adjective and form_code:sub(1, 1) ~= 'V' then
articles = args.article[form_code]
if articles then
articles = split(articles, '%s*[/,]%s*')
local linked_articles = {}
for i, article in ipairs(articles) do
linked_articles[i] = link(trim(article), form_separator)
end
linked_forms = concat(linked_articles, form_separator) .. " " .. linked_forms
end
end
if istitle then
return linked_forms
elseif articles then
articles = concat(articles, form_separator) .. " "
else
articles = ""
end
return linked_forms .. "<br>" .. format_translit(articles .. concat(forms, sep))
end
local function make_title(args)
local title = Array()
title:insert(get_header(args.declheader, args.irregular, args.indeclinable) .. ' of ')
-- Display the nominative and genitive form for the first number that has
-- forms.
for _, number_code in ipairs{ 'S', 'D', 'P' } do
if args.number[number_code] then
title:insert(link_form(args, 'N' .. number_code, true) .. '; '
.. link_form(args, 'G' .. number_code, true))
break
end
end
if args.dial then
table.insert(args.titleapp, get_label_display(args.dial))
end
if args.titleapp[1] then
title:insert(' (' .. concat(args.titleapp, ', ') .. ')')
end
return title:concat()
end
local case_header =
[[
|-
! class="case-header" | {{{case_name}}}
]]
local noun_form_cell =
[[
| class="form" data-accel-col="{{{col}}}" | {{{form}}}
]]
local adj_form_cell =
[[
| class="form" data-accel-col="{{{col}}}" colspan="{{{colspan}}}" | {{{form}}}
]]
local function make_rows(args, nums)
local rows = Array()
if not args.adjective then
case_header = case_header
noun_form_cell = noun_form_cell
end
for _, case_name in ipairs(case_names) do
rows:insert((case_header:gsub("{{{case_name}}}", case_name)))
local case_abbr = case_name:sub(1, 1)
for i, number in ipairs(nums) do
rows:insert(fill_params(noun_form_cell, {
form = link_form(args, case_abbr .. number:sub(1, 1)),
col = i,
}))
end
end
return rows:concat()
end
local notes_template =
[[
|-
! class="notes-header" | စၟတ်သမ္တီ:
| {{{extra_cell}}}class="notes" colspan="13" | <div class="use-with-mention">{{{notes}}}</div>
]]
local function make_notes(args)
args.notes = Array(args.notes)
if args.dial ~= 'koi' and args.dial ~= 'byz' then
args.notes:insert(1, args.dial == 'att' and Attic_note or nonAttic_note)
end
if args.user_notes then -- add user notes
args.notes:insert(args.user_notes)
end
if args.debug then
args.notes:insert(args.debug)
end
if next(args.notes) == nil then
return ""
end
return fill_params(notes_template, {
extra_cell = args.adjective and '\n| ' or '',
notes = args.notes
:map(function (note) return "\n* " .. note end):concat(),
})
end
local number_header =
[[
! class="number-header" | {{{number}}}
]]
local noun_table_top =
[=[
<div class="NavFrame grc-decl">
<div class="NavHead">{{{title}}}</div>
<div class="NavContent">
{| class="inflection-table inflection-table-grc"
! class="case-number-header" | ကိစ္စ / #
]=]
function export.make_table(args)
local nums = make_number_table(args.number)
if not args.adjective then
noun_table_top = noun_table_top
number_header = number_header
end
-- This can be simplified.
-- Percents have to be escaped (otherwise, strangely, a null character is
-- inserted).
local output = Array(
(noun_table_top
:gsub('{{{title}}}', make_title(args))))
for _, number in ipairs(nums) do
output:insert((number_header:gsub('{{{number}}}', number)))
end
output:insert(make_rows(args, nums))
output:insert(make_notes(args))
output:insert('|}</div></div>')
if args.categories[1] and mw.title.getCurrentTitle().nsText == '' then
output:insert(require('Module:utilities').format_categories(args.categories, lang))
end
return output:concat() .. get_stylesheet()
end
local function make_title_adj(args, genders)
if args.title then
return args.title
else
local title = Array()
title:insert(get_header(args.adeclheader, args.irregular, args.indeclinable) .. ' of ')
for _, number in ipairs{ 'S', 'D', 'P' } do
if args.number[number] then
local gender_forms = {}
for _, gender in ipairs(genders) do
table.insert(gender_forms, link_form(args, gender .. 'N' .. number, true))
end
title:insert(concat(gender_forms, '; '))
break
end
end
if args.dial then
table.insert(args.titleapp, get_label_display(args.dial))
end
if args.titleapp[1] then
title:insert(' (' .. concat(args.titleapp, ', ') .. ')')
end
return title:concat()
end
end
local function make_rows_adj(args, nums, genders)
local rows = Array()
local twopt = args.act and args.act[2] == nil
for _, case_name in ipairs(case_names) do
rows:insert((case_header:gsub('{{{case_name}}}', case_name)))
for i, number in ipairs(nums) do
rows:insert('|\n')
local case_number = case_name:sub(1, 1) .. number:sub(1, 1)
for j, gender in ipairs(genders) do
rows:insert(fill_params(adj_form_cell, {
col = (i - 1) * 3 + j,
colspan = twopt and gender == 'M' and '2' or '1',
form = link_form(args, gender .. case_number),
}))
end
end
end
return rows:concat()
end
-- Add the part of the table containing the adverb and the comparative and
-- superlative forms, if applicable.
local function make_acs_adj(args, nums)
-- This should only apply to pronouns. I think.
-- If all of adverb, comparative, and superlative are absent, don't display
-- the "derived forms" part of the table at all.
if #nums < 3 or require 'Module:fun'.all(
function (form_code)
return is_empty(args.atable[form_code])
end,
{ 'adv', 'comp', 'super' }) then
return ''
end
args.atable.adv = args.atable.adv
args.atable.comp = args.atable.comp
args.atable.super = args.atable.super
local fill = {
colspan = '3',
adv = link_form(args, 'adv'),
comp = link_form(args, 'comp'),
super = link_form(args, 'super'),
}
local acs_section = [=[
|-
! class="derived-forms-header" rowspan="2" | ဗီုပြၚ်မဂွံလဝ်အာဲကၟာဲ
|
! class="derived-form-name-header" colspan={{{colspan}}} | ကြိယာဝိသေသန
|
! class="derived-form-name-header" colspan={{{colspan}}} | ပတဝ်ပတုပ်ရံၚ်
|
! class="derived-form-name-header" colspan={{{colspan}}} | သဒ္ဒာ
|-
|
| class="form" colspan={{{colspan}}} | {{{adv}}}
|
| class="form" colspan={{{colspan}}} | {{{comp}}}
|
| class="form" colspan={{{colspan}}} | {{{super}}}
]=]
return fill_params(acs_section, fill)
end
local adj_table_top =
[=[
<div class="NavFrame grc-decl grc-adecl">
<div class="NavHead">{{{title}}}</div>
<div class="NavContent">
{| class="inflection-table inflection-table-grc"
! class="number-header" | ဂၞန်
]=]
function export.make_table_adj(args)
local nums = make_number_table(args.number)
local threept = not(args.act and args.act[2] == nil)
local genders = threept and { 'M', 'F', 'N' } or { 'M', 'N' }
local number_header =
[=[
! class="divider" |
! class="number-header" colspan=3 | {{{number}}}
]=]
local gender_headers =
[=[
|
! class="gender-header" | ပုလ္လိၚ်
! class="gender-header" | ဣတ္တိလိၚ်
! class="gender-header" | နပုလ္လိၚ်
]=]
local output = Array(
(adj_table_top:gsub('{{{title}}}', make_title_adj(args, genders)))
)
for _, number in ipairs(nums) do
output:insert((number_header:gsub('{{{number}}}', number)))
end
output:insert([=[|-
! class="case-gender-header" | ကိစ္စ/လိၚ်
]=])
for _, _ in ipairs(nums) do
output:insert(gender_headers)
end
output:insert(make_rows_adj(args, nums, genders))
output:insert(make_acs_adj(args, nums))
output:insert(make_notes(args))
output:insert('|}</div></div>')
if args.categories[1] and mw.title.getCurrentTitle().nsText == '' then
output:insert(require('Module:utilities').format_categories(args.categories, lang))
end
return output:concat() .. get_stylesheet()
end
return export
sua4b6wy7511gsrmzzj7m7e7t36huzw
ကဏ္ဍ:ဝေါဟာအၚ်္ဂလိက်မၞုံကဵုဒုၚ်စသိုၚ်အရီုမဟွံဂတာပ်ခေတ်
14
52080
397268
275835
2026-06-20T19:12:34Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:ဝေါဟာအၚ်္ဂလိက် မနွံကဵုဒုၚ်စသိုၚ်အရီုမဟွံဂတာပ်ခေတ်]] ဇရေင် [[ကဏ္ဍ:ဝေါဟာအၚ်္ဂလိက်မၞုံကဵုဒုၚ်စသိုၚ်အရီုမဟွံဂတာပ်ခေတ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်
275835
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်]]
cgthbuhht2vx8a42gqbqvafhhdb35kh
မဝ်ဂျူ:grc-utilities/templates
828
52675
397307
69037
2026-06-21T10:03:11Z
咽頭べさ
33
397307
Scribunto
text/plain
local export = {}
local m_table = require('Module:table')
local m_utils = require('Module:grc-utilities')
local m_data = require('Module:grc-utilities/data')
local tag = m_utils.tag
local link = m_utils.link
local tokenize = m_utils.tokenize
local diacritic = m_data.diacritic
local U = mw.ustring.char
local toNFD = mw.ustring.toNFD
local gsub = mw.ustring.gsub
local dottedCircle = U(0x25CC)
export.addDottedCircle = require("Module:Unicode data").add_dotted_circle
function export.printTokens(frame)
text = frame.args[1]
local token_format = '<span class="Polyt" style="background-color: var(--wikt-palette-grey-2,#E9E9E9);>%s</span>'
local spacing = {
["\n"] = "¶",
["\r"] = "¶",
[" "] = " ",
}
if text then
local tokens = m_table.shallowCopy(tokenize(text))
for i, token in pairs(tokens) do
tokens[i] = token_format:format(string.gsub(token, "%s", spacing))
end
return "|-\n| " .. tag(text) .. " || " .. tag(table.concat(tokens, ", "))
else
error("Provide text to tokenize in first parameter.")
end
end
function export.printDiacritics(frame)
local functionToPrint = frame.args[1] or error('Specify a function in the first parameter.')
local term = frame.args[2] or error('Add text in the second parameter.')
local result = m_utils[functionToPrint](term)
-- Show diacritics above or below a dotted circle.
content = {
term = tag(term),
term_decomposition = tag(export.addDottedCircle(toNFD(term))),
result = tag(result),
result_decomposition = tag(export.addDottedCircle(result)),
}
local output = [[ term (term_decomposition) → result (result_decomposition)]]
local function addContent(item)
return content[item] or ""
end
return (output:gsub("[%a_]+", addContent))
end
function export.decompose(frame)
local params = {
[1] = {},
["link"] = { type = "boolean" },
}
args = require("Module:parameters").process(frame.args, params)
local text = args[1]
text = toNFD(text)
local link = args.link
local composed
if link then
composed = link(text, nil, nil, "-")
else
composed = tag(text)
end
local decomposed = export.addDottedCircle(text)
if link then
local result = {}
for seat, letter in gmatch(decomposed, "(" .. dottedCircle .. "?)(.)") do
local link
if letter then
link = linkNoTag(letter, seat .. letter)
end
table.insert(result, link)
end
decomposed = table.concat(result)
end
decomposed = tag(decomposed)
return composed .. " (" .. decomposed .. ")"
end
function export.tokenize(frame)
local map = require("Module:fun").map
local token_format = '<span class="Polyt" style="background-color: var(--wikt-palette-lightergrey,#EFEFEF);>%s</span>'
local spacing = {
["\n"] = "¶",
["\r"] = "¶",
[" "] = " ",
}
local _tokenize = tokenize
local function tokenize(word, ...)
return _tokenize(word)
end
local function print_tokens(tokens)
if type(tokens) == "string" then
return tokens
end
local output = {}
for i, token in ipairs(tokens) do
output[i] = string.format(token_format, string.gsub(token, "%s", spacing))
end
return table.concat(output, " ")
end
return table.concat(map(print_tokens, map(tokenize, frame.args)), "<br>")
end
return export
b9z9ex8m90uhqsixcrkxldxlb7c9icx
မဝ်ဂျူ:accel/grc
828
111871
397301
142857
2026-06-21T09:51:45Z
咽頭べさ
33
397301
Scribunto
text/plain
-- To do: add dialect labels, at least for non-Attic dialects.
-- Ideally, dialectal lemmas and non-lemma forms should be in different
-- categories, but no infrastructure for that exists yet.
-- Fix acceleration of second-declension adjectives: feminine is missing.
-- [[Special:Diff/50392096]]
local function chars(content) return "{{subst:chars|grc|" .. content .. "}}" end
local function accent_recessively(form)
local m_accent = require "Module:grc-accent"
return m_accent.add_accent(m_accent.strip_tone(form), -3)
end
local function get_participle_information(masculine)
local decl, feminine, neuter
if masculine:find("ος$") then
decl = "1&2"
feminine = accent_recessively(masculine:gsub("ος$", "η"))
neuter = masculine:gsub("ς$", "ν")
else
decl = "1&3"
local m_utilities_data = require "Module:grc-utilities/data"
-- Warning! This pattern will not work if there's a vowel before the
-- participle ending, as in τεθνεώς, perfect active participle of
-- θνῄσκω.
local ending = mw.ustring.match(mw.ustring.toNFD(masculine),
m_utilities_data.vowel .. "[^" ..
m_utilities_data.vowels .. "]+$")
if ending then
local m_accent = require "Module:grc-accent"
ending = m_accent.strip_tone(ending)
local accent_pos, accent_type = m_accent.detect_accent(masculine)
if ending == "ων" then -- recessive, oxytone, properispomenon
local stem = mw.ustring.gsub(mw.ustring.toNFD(masculine),
"ω[" ..
m_utilities_data.diacritics
.acute ..
m_utilities_data.diacritics
.circum .. "]?ν$", "")
feminine = stem .. "ουσᾰ"
if accent_type == "circumflex" then
-- τῑμῶν, τῑμῶσᾰ, τῑμῶν
neuter = target
else
-- λέγων, λέγουσα, λέγον
-- λαβών, λαβοῦσᾰ, λαβόν
neuter = stem .. "ον"
end
elseif ending == "ᾱς" then -- recessive except in athematic verbs
stem = mw.ustring.gsub(mw.ustring.toNFD(masculine),
"α" ..
m_utilities_data.diacritics.macron ..
m_utilities_data.diacritics.acute ..
"?ς", "")
feminine = stem .. "ᾱσᾰ"
neuter = stem .. "ᾰν"
-- Aorist passive or athematic; always oxytone?
elseif ending == "εις" then
stem = masculine:gsub("είς", "")
feminine = stem .. "εῖσᾰ"
neuter = stem .. "έν"
elseif ending == "ως" then -- Perfect active; always oxytone?
stem = masculine:gsub("ώς", "")
feminine = stem .. "υῖᾰ"
neuter = stem .. "ός"
-- Present active, δεικνῡ́ς and such
elseif ending == "ῡς" then
stem = masculine:gsub("ῡ́ς", "")
feminine = stem .. "ῦσᾰ"
neuter = stem .. "ῠ́ν"
end
if feminine and neuter then
feminine, neuter = m_accent.add_accent(feminine, accent_pos),
m_accent.add_accent(neuter, accent_pos)
end
end
end
return decl, feminine, neuter
end
-- Determine lemma (masculine nominative singular form)
local function get_participle_lemma(feminine_or_neuter)
local lemma
if mw.ustring.find(feminine_or_neuter, "μ[εέ]ν[ηο]ν?$") then
local stem = mw.ustring.match(feminine_or_neuter,
"^(.+μ[εέ]ν)[ηο]ν?$")
lemma = accent_recessively(stem .. "ος")
else
local m_utilities_data = require "Module:grc-utilities/data"
local stem, ending = mw.ustring.match(mw.ustring.toNFD(
feminine_or_neuter),
"^(.-)([αεουω][ιυ]?" ..
m_utilities_data.diacritic ..
"*[σςν]?α?" ..
m_utilities_data.diacritics
.breve .. "?)$")
ending = mw.ustring.toNFC(ending)
-- [αεοω][ιυ]?[accents][σςν]?ᾰ??
if ending == "εῖσᾰ" or ending == "έν" then
lemma = stem .. "είς"
elseif ending == "ῶσᾰ" or ending == "ῶν" then
lemma = stem .. "ῶν"
elseif ending == "ᾶσᾰ" then
lemma = stem .. "ᾱ́ς"
-- Need to distinguish contracted present-tense verbs
-- from second aorists! δούς can maybe be neglected.
elseif ending == "οῦσᾰ" or ending == "όν" then
lemma = stem .. "ών"
elseif ending == "ουσᾰ" or ending == "ον" then
lemma = stem .. "ων"
elseif ending == "υῖᾰ" or ending == "ός" then
lemma = stem .. "ώς"
elseif ending == "ῦσᾰ" or ending == "ῠ́ν" then
lemma = stem .. "ῡ́ς"
end
end
return lemma
end
return {
generate = function(params, entry)
local target = (params.target ~= params.target_pagename and "|" ..
params.target or "")
entry.head = "{{grc-" .. params.pos .. " form" .. target .. "}}"
-- Comparatives and superlatives don't use {{grc-adjective form}}, but
-- rather the lemma templates ({{grc-adj-1&2}}, {{grc-adj-3rd}}) with the
-- parameter |deg=comp or |deg=super, because they have inflected forms
-- (neuter if they are in the third declension, or feminine and neuter if
-- they are in the first and second declension).
if params.form == "comparative" or params.form == "superlative" then
local decl, stem, feminine, neuter
-- Comparatives and superlatives always have recessive accent.
if params.target_pagename:find("ος$") then
decl = "1&2"
stem = params.target:gsub("ος$", "")
-- Feminine could have ᾱ or η. Add default based on ειρ rule.
-- This will often be incorrect for dialects without the ᾱ-to-η
-- shift, like Doric and Aeolic.
feminine = accent_recessively(stem ..
(mw.ustring
.find(stem, "[ειρ]$") and
"ᾱ" or "η"))
neuter = params.target:gsub("ς$", "ν")
elseif params.target_pagename:find("ων$") then
decl = "3rd"
stem = params.target:gsub("ων$", "")
-- Add ending -ον and accent recessively.
-- This will not generate the correct accent if a macron was omitted
-- in the masculine form.
neuter = accent_recessively(params.target:gsub("ων$", "ον"))
else
error(
"Could not determine declension for the " .. params.form ..
" adjective " .. params.target .. ".")
end
local degree_abbrev = params.form == "ပတဝ်ပတုပ်ရံၚ်" and "comp" or
"super"
entry.head = "{{grc-adj-" .. decl .. target
-- Place feminine and neuter forms in {{chars}} so that editor can easily
-- correct any errors before saving.
if feminine then
entry.head = entry.head .. "|" .. chars(feminine)
end
entry.head = entry.head .. "|" .. chars(neuter) .. "|deg=" ..
degree_abbrev .. "}}"
entry.declension = "{{grc-adecl|" ..
(decl == "3rd" and neuter or params.target ..
"|" .. feminine) .. "|deg=" ..
degree_abbrev .. "}}"
-- Inflected forms of a comparative or superlative.
else
local last_code = params.form:match("|(%l+)$")
if last_code == "comparative" or last_code == "သဒ္ဒာ" then
local degree_abbrev = last_code == "ပတဝ်ပတုပ်ရံၚ်" and "comp" or
"super"
entry.head = "{{grc-" .. params.pos .. " form" .. target ..
"|deg=" .. degree_abbrev .. "}}"
-- Remove |comparative or |superlative from {{inflection of}}
entry.def = entry.def:gsub("|" .. last_code, "")
end
end
if params.pos == "ကြိယာ" then
if params.form:find "%f[^%z|]part%f[%z|]" then -- participle
entry.pos_header = "လုပ်ကၠောန်စွံလဝ်"
local gender = params.form:match "%f[^%z|][mfn]%f[%z|]"
if gender == "m" then -- masculine (lemma)
local decl, feminine, neuter =
get_participle_information(params.target)
entry.head = "{{grc-part-" .. decl .. target .. "|" ..
(feminine or chars "") .. "|" ..
(neuter or chars "") .. "}}"
entry.declension = "{{grc-adecl|" .. params.target .. "|" ..
(feminine or chars "") .. "}}"
-- Remove gender from inflection-of template, as the masculine
-- is a pseudo-lemma.
entry.def = entry.def:gsub("%f[^%z|]m|", "")
elseif gender == "f" or gender == "n" then
local lemma = get_participle_lemma(params.target)
if lemma then
entry.head = "{{grc-participle form" .. target .. "}}"
entry.def = "{{inflection of|grc|" .. lemma .. "||" ..
gender .. "|nom|s" .. "}}"
end
end
end
end
entry.pronunc = "{{grc-IPA" .. target .. "}}"
end
}
q9z1cptbo6uxouf5suh4ufhays63978
ထာမ်ပလိက်:ety
10
116283
397252
149946
2026-06-20T17:42:22Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:etymon]] ဇရေင် [[ထာမ်ပလိက်:ety]]
149946
wikitext
text/x-wiki
<includeonly>{{#invoke:etymon|main}}</includeonly><noinclude>{{documentation}}</noinclude>
5t3xwy26hk5cfvmzk7ny2oqnf3fvdz7
မဝ်ဂျူ:etymon
828
116284
397257
379478
2026-06-20T17:59:57Z
咽頭べさ
33
397257
Scribunto
text/plain
--[=[
This module implements the {{etymon}} template for structured etymology data on Wiktionary.
It enables the creation of etymology trees and text by parsing etymon chains,
scraping linked pages for their own {{etymon}} data, and recursively building a tree
of derivational relationships.
Authors:
- Original implementation: [[User:Ioaxxere]]
- Full refactor (September 2025): [[User:Fenakhay]] ([[Special:Diff/86717746]])
Modules:
- [[Module:etymon]]: main module handling parsing, validation, tree building, and page scraping
- [[Module:etymon/data]]: keyword definitions, configuration, and status constants
- [[Module:etymon/tree]]: etymology tree rendering
- [[Module:etymon/text]]: etymology text generation
- [[Module:etymon/categories]]: category generation logic
- [[Module:etymon/tracking]]: tracking
]=]
local export = {}
local __state = {
cached_etymon_args = {},
cached_etymon_pages = {},
cached_descendants_checks = {},
senseid_parent_etymon = {},
available_etymon_ids = {},
single_etymons = {},
entry_title = nil,
entry_lang_code = nil,
current_page_has_inline_etymology = false,
current_page_has_redundant_etymology = false,
used_idless_etymon = false,
toplevel_has_inline_etymology = false,
toplevel_redundant_etymology = false,
toplevel_idless_etymon = false,
has_mismatched_id = false,
linked_page_multiple_etymons_idless = false,
linked_page_partial_etymology_sections = false,
partial_etymology_targets = {},
skip_partial_etymology_category = false,
max_depth_reached = 0,
total_nodes = 0,
language_count = {},
toplevel_keyword_stats = {},
id_stats = nil,
warnings = {},
}
local function reset_invocation_state()
__state.current_page_has_inline_etymology = false
__state.current_page_has_redundant_etymology = false
__state.used_idless_etymon = false
__state.toplevel_has_inline_etymology = false
__state.toplevel_redundant_etymology = false
__state.toplevel_idless_etymon = false
__state.has_mismatched_id = false
__state.linked_page_multiple_etymons_idless = false
__state.linked_page_partial_etymology_sections = false
__state.max_depth_reached = 0
__state.total_nodes = 0
__state.language_count = {}
__state.toplevel_keyword_stats = {}
__state.warnings = {}
end
local M = require("Module:module loader").init({
require = {
data = "Module:etymon/data",
tree = "Module:etymon/tree",
text = "Module:etymon/text",
categories = "Module:etymon/categories",
tracking = "Module:etymon/tracking",
descendants = "Module:etymon/descendants",
anchors = "Module:anchors",
etydate = "Module:etydate",
etymology = "Module:etymology",
families = "Module:families",
languages = "Module:languages",
languages_errorgetby = "Module:languages/errorGetBy",
links = "Module:links",
pages = "Module:pages",
parameters = "Module:parameters",
string_utilities = "Module:string utilities",
template_parser = "Module:template parser",
utilities = "Module:utilities",
debug = "Module:debug",
en_utilities = "Module:en-utilities",
parse_utilities = "Module:parse utilities",
references = "Module:references",
template_styles = "Module:TemplateStyles",
script_utilities = "Module:script utilities",
JSON = "Module:JSON",
yesno = "Module:yesno",
},
loadData = {
headword_data = "Module:headword/data",
parameters_data = "Module:parameters/data",
text_allowed = "Module:etymon/data/text_allowed",
},
})
local Util = {}
function Util.format_error(message, preview_only)
if preview_only and not M.pages.is_preview() then
return nil
end
return '<span class="error">' .. message .. '</span>'
end
function Util.add_warning(message, preview_only)
local formatted = Util.format_error(message, preview_only)
if formatted then
table.insert(__state.warnings, formatted)
end
end
function Util.is_text_param_allowed_for_lang(lang)
if not lang or type(lang) ~= "table" then
return false
end
local types = lang.getTypes and lang:getTypes()
if types and types.family then
local code = lang.getCode and lang:getCode()
return code and M.text_allowed.families[code] == true
end
local full_code = lang.getFullCode and lang:getFullCode()
if full_code and M.text_allowed.langs[full_code] then
return true
end
if lang.inFamily then
for family_code in pairs(M.text_allowed.families) do
if lang:inFamily(family_code) then
return true
end
end
end
return false
end
function Util.get_lang(code, no_error)
if no_error then
return M.languages.getByCode(code, nil, true)
end
return M.languages.getByCode(code, nil, true) or M.languages_errorgetby.code(code, true, true)
end
-- Match a term language against a text=:lang stop target (supports etymology-only codes).
function Util.lang_matches_stop_code(term_lang, stop_code)
if not term_lang or not stop_code or stop_code == "" then
return false
end
local stop_lang = Util.get_lang(stop_code, true)
if not stop_lang then
return false
end
if term_lang:getCode() == stop_lang:getCode() then
return true
end
if stop_lang:getFullCode() == stop_lang:getCode() then
return term_lang:getFullCode() == stop_lang:getCode()
end
return false
end
function Util.get_family(code)
return M.families.getByCode(code)
end
function Util.get_lang_exception(lang)
-- Families have no language-specific exceptions
if lang.getTypes and lang:getTypes().family then
return nil
end
local code = lang:getCode()
local lang_exceptions = M.data.config.lang_exceptions
if lang_exceptions[code] then
return lang_exceptions[code]
end
for norm_code, exc in pairs(lang_exceptions) do
if exc.normalize_to and code == exc.normalize_to then
return exc
end
if exc.normalize_from_families then
local should_normalize = false
for _, family in ipairs(exc.normalize_from_families) do
if lang:inFamily(family) then
should_normalize = true
break
end
end
if should_normalize and exc.normalize_exclude_families then
for _, family in ipairs(exc.normalize_exclude_families) do
if lang:inFamily(family) then
should_normalize = false
break
end
end
end
if should_normalize then
local ret = {}
for k, v in pairs(exc) do
ret[k] = v
end
ret.suppress_tr = nil
return ret
end
end
end
return nil
end
function Util.get_norm_lang(lang)
local exc = Util.get_lang_exception(lang)
if exc and exc.normalize_to then
return M.languages.getByCode(exc.normalize_to)
end
return lang
end
function Util.resolve_context_lang(lang, node_args)
if type(node_args) ~= "table" then return lang end
if node_args.status == M.data.STATUS.INLINE then return lang end
if not (lang.hasType and lang:hasType("etymology-only")) then return lang end
local full = lang.getFull and lang:getFull()
if not full or full:getCode() == lang:getCode() then return lang end
if full.hasAncestor and full:hasAncestor(lang) then return lang end
return full
end
-- Add default values for boolean modifiers (e.g., <unc> becomes <unc:1>)
-- This is needed because Module:parse utilities expects boolean modifiers to have explicit values
function Util.add_boolean_defaults(str, param_mods)
local result = str
for name, spec in pairs(param_mods) do
if spec.type == "boolean" then
-- Replace <name> with <name:1> (but not <name:...> which already has a value)
result = result:gsub("<" .. name .. ">", "<" .. name .. ":1>")
end
end
return result
end
local REQUEST_TEMPLATE_PARAM_MODS = {
rfe = {
nocat = { type = "boolean" },
sort = {},
y = {},
m = {},
fragment = {},
section = {},
box = { type = "boolean" },
noes = { type = "boolean" },
},
etystub = {
nocat = { type = "boolean" },
sort = {},
nocap = { type = "boolean" },
nodot = { type = "boolean" },
},
}
function Util.expand_request_template(frame, template_name, param_value, lang_code)
local param_mods = REQUEST_TEMPLATE_PARAM_MODS[template_name]
local with_defaults = Util.add_boolean_defaults(param_value, param_mods)
local parsed = M.parse_utilities.parse_inline_modifiers(with_defaults, {
param_mods = param_mods,
generate_obj = function(text)
if M.yesno(text, false) then
return { is_boolean = true }
end
return { text = text }
end,
})
local template_args = { [1] = lang_code }
for name in pairs(param_mods) do
template_args[name] = parsed[name]
end
if not parsed.is_boolean then
template_args[2] = parsed.text
end
return " " .. frame:expandTemplate({
title = template_name,
args = template_args,
})
end
-- Centralized term formatting: handles suppress_term (-), unknown_term (empty/+), and regular terms
function Util.format_term(term, is_toplevel, opts)
opts = opts or {}
-- suppress_term (-) returns nil
if term.suppress_term then
return nil
end
local lang = term.lang
local exc = Util.get_lang_exception(lang)
if is_toplevel then
local display_text = term.alt or term.title or ""
local sc = term.sc or lang:findBestScript(display_text)
local bold_text = tostring(mw.html.create("strong")
:addClass("selflink")
:wikitext(display_text))
return M.script_utilities.tag_text(bold_text, lang, sc, "term")
end
local link_params = { lang = lang }
link_params.term = not term.unknown_term and term.title or nil
link_params.alt = term.alt
link_params.id = (not term.unknown_term and term.id and term.id ~= "") and term.id or nil
if not (exc and exc.suppress_tr) then
link_params.tr = term.tr
link_params.ts = term.ts
else
link_params.suppress_tr = true
end
link_params.lit = (opts.lit ~= "suppress") and term.lit or nil
if opts.gloss ~= "suppress" then
link_params.gloss = term.t
end
if term.g and term.g ~= "" then
local genders = M.string_utilities.split(term.g, ",")
for i = 1, #genders do
genders[i] = M.string_utilities.trim(genders[i])
end
link_params.genders = genders
end
if opts.pos ~= "suppress" then
link_params.pos = term.pos
link_params.ng = term.ng
end
if exc and exc.suppress_tr then
link_params.lit = nil
end
local show_qualifiers
if opts.tree_ql ~= "suppress" then
if term.q then
link_params.q = term.q
end
if term.qq then
link_params.qq = term.qq
end
if term.l then
link_params.l = term.l
end
if term.ll then
link_params.ll = term.ll
end
show_qualifiers = term.q or term.qq or term.l or term.ll
end
return M.links.full_link(link_params, "term", nil, show_qualifiers and true or nil)
end
local __is_content_page_cached
function Util.is_content_page()
if __is_content_page_cached == nil then
__is_content_page_cached = M.pages.is_content_page(mw.title.getCurrentTitle())
end
return __is_content_page_cached
end
local __page_data_cached
function Util.get_page_data()
if not __page_data_cached then
__page_data_cached = M.headword_data.page
end
return __page_data_cached
end
-- Extract base keyword from param (without modifiers)
local function get_keyword_base(param)
if type(param) ~= "string" then return nil end
local base = param:match("^:?([^<]+)") or param:gsub("^:", "")
return base
end
local function is_keyword(param, allow_colon_less)
if type(param) ~= "string" then return false end
local keywords = M.data.keywords
if param:sub(1, 1) == ":" then
local base = get_keyword_base(param)
return keywords[base] ~= nil
end
if allow_colon_less then
local base = get_keyword_base(param)
return keywords[base] ~= nil
end
return false
end
local function get_keyword(param, allow_colon_less)
if type(param) ~= "string" then return nil end
local keywords = M.data.keywords
if param:sub(1, 1) == ":" then
return get_keyword_base(param)
end
if allow_colon_less then
local base = get_keyword_base(param)
if keywords[base] then
return base
end
end
return nil
end
local function normalize_keyword(keyword)
if keyword:sub(1, 1) == ":" then
return keyword
end
return ":" .. keyword
end
-- Resolve keyword (possibly an alias) to its canonical form. Used only at input boundaries
local function get_canonical_keyword(keyword)
if not keyword then return keyword end
return M.data.keyword_canonical[keyword] or keyword
end
local function is_affix_group_keyword(keyword)
local config = keyword and M.data.keywords[keyword]
return config and config.affix_categories or false
end
local function reject_removed_surf_keyword(param)
local base = get_keyword_base(param)
if base == "surf" then
error("The `:surf` keyword has been removed. Use `<surf>` on a formation keyword instead (e.g. `:af<surf>`, `:bor<surf>`).")
end
end
local function copy_keyword_info(source)
local copy = {}
for k, v in pairs(source) do
copy[k] = v
end
return copy
end
local function lowercase_glossary_display(text)
return text:gsub("(%[%[Appendix:Glossary#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function surf_should_keep_formation_phrase(base)
if not base.phrase then
return false
end
if base.glossary then
return true
end
return not (base.phrase == "from" and (base.text == "From" or base.text == "from"))
end
-- Runtime overrides when <surf> is present on a keyword.
local function get_effective_keyword_info(keyword, modifiers)
local base = M.data.keywords[keyword]
if not base or not modifiers or not modifiers.surf then
return base
end
local effective = copy_keyword_info(base)
local surf_text = "By [[Appendix:Glossary#surface_analysis|surface analysis]],"
local surf_phrase = "by surface analysis,"
effective.new_sentence = true
effective.invisible = "tree"
if surf_should_keep_formation_phrase(base) then
effective.phrase = surf_phrase .. " " .. base.phrase
if base.text then
effective.text = surf_text .. " " .. lowercase_glossary_display(base.text)
else
effective.text = surf_text .. " " .. base.phrase
end
else
effective.text = surf_text
effective.phrase = surf_phrase
end
return effective
end
-- Build text/phrase for nominalization with <g:code> (uses data module for codes only).
local function get_nominalization_label_for_g(code)
if not code or code == "" then return nil end
local codes = M.data.nominalization_g_codes
local adj = codes[code]
if not adj and #code == 2 then
local gender_adj = codes[code:sub(1, 1)]
local number_adj = codes[code:sub(2, 2)]
if gender_adj and number_adj then
adj = gender_adj .. " " .. number_adj
end
end
if not adj then return nil end
local text = adj:gsub("^%l", function(c) return string.upper(c) end) .. " [[Appendix:Glossary#nominalization|nominalization]] of"
local phrase = M.en_utilities.add_indefinite_article(adj .. " [[Appendix:Glossary#nominalization|nominalization]] of", false)
return { text = text, phrase = phrase }
end
local EtymonParser = {}
-- Keyword modifier definitions
EtymonParser.keyword_param_mods = {
unc = { type = "boolean" },
ref = {},
text = { restrict = { keywords = { "from", "derived" } } },
lit = { restrict = { affix_group = true } },
conj = {}, -- conjunction for alternatives: "and", "or", "and/or", etc.
g = { restrict = { keywords = { "nominalization" } } },
surf = { type = "boolean" },
senseid = { restrict = { keywords = { "semantic loan" } } },
}
-- Term modifier definitions
EtymonParser.etymon_param_mods = {
id = {},
t = {},
tr = {},
ts = {},
q = {},
qq = {},
l = {},
ll = {},
pos = {},
ng = {},
alt = {},
g = {},
ety = {},
lit = {},
unc = { type = "boolean" },
ref = {},
aftype = { restrict = { affix_group = true } },
postype = {},
bor = { type = "boolean", restrict = { affix_group = true } },
slbor = { type = "boolean", restrict = { affix_group = true } },
lbor = { type = "boolean", restrict = { affix_group = true } },
}
local function get_clean_param_mods(param_mods)
local clean = {}
for mod_name, mod_def in pairs(param_mods) do
clean[mod_name] = {}
for key, value in pairs(mod_def) do
if key ~= "restrict" then
clean[mod_name][key] = value
end
end
end
return clean
end
function EtymonParser.check_modifier_restrictions(modifiers, current_keyword, param_mods)
for mod_name, mod_value in pairs(modifiers) do
-- Only check restrictions if the modifier has a non-false/nil value
if mod_value then
local mod_def = param_mods[mod_name]
if mod_def and mod_def.restrict then
if mod_def.restrict.affix_group then
if not is_affix_group_keyword(current_keyword) then
local mod_display = mod_value == true and "<" .. mod_name .. ">" or "<" .. mod_name .. ":" .. tostring(mod_value) .. ">"
error("The modifier `" .. mod_display .. "` is only allowed for affix-group keywords (e.g. `:af`, `:blend`, `:univ`).")
end
elseif mod_def.restrict.keywords then
local allowed_keywords = mod_def.restrict.keywords
local is_allowed = false
for _, allowed_keyword in ipairs(allowed_keywords) do
if current_keyword == allowed_keyword then
is_allowed = true
break
end
end
if not is_allowed then
local keyword_list = {}
for _, kw in ipairs(allowed_keywords) do
table.insert(keyword_list, ":" .. kw)
end
local keyword_str = table.concat(keyword_list, #keyword_list == 2 and " or " or ", ")
if #keyword_list > 2 then
-- Replace last comma with "or"
keyword_str = keyword_str:gsub(", ([^,]+)$", " or %1")
end
local mod_display = mod_value == true and "<" .. mod_name .. ">" or "<" .. mod_name .. ":" .. tostring(mod_value) .. ">"
error("The modifier `" .. mod_display .. "` is only allowed for the keyword" .. (#keyword_list > 1 and "s " or " ") .. keyword_str .. ".")
end
end
end
end
end
end
local TERM_RULE_DISALLOW = {
suppress = { field = "suppress_term", label = "suppressed" },
unknown = { field = "unknown_term", label = "unknown" },
family = { field = "is_family", label = "family" },
}
function EtymonParser.check_etymon_limits(count, limits, label, opts)
if not limits then
return
end
opts = opts or {}
local min_etymons = limits.min_etymons
if min_etymons == nil and not opts.skip_default_min then
min_etymons = 1
end
if min_etymons and count < min_etymons then
if min_etymons > 1 then
error("Detected " .. label .. " group with fewer than " .. min_etymons .. " etymons.")
else
error("Detected " .. label .. " with no etymons.")
end
end
if limits.max_etymons and count > limits.max_etymons then
local unit = (limits.max_etymons == 1) and "etymon" or "etymons"
error("Detected " .. label .. " with more than " .. limits.max_etymons .. " " .. unit .. ".")
end
end
function EtymonParser.check_term_rules(etymon_data, entry_lang, rules, label)
label = label or "term"
if rules and rules.disallow then
local disallowed = {}
for _, typ in ipairs(rules.disallow) do
local spec = TERM_RULE_DISALLOW[typ]
if spec and etymon_data[spec.field] then
table.insert(disallowed, spec.label)
end
end
if #disallowed > 0 then
error(label .. " does not support " ..
mw.text.listToText(disallowed, "or") .. " etymons.")
end
end
if etymon_data.is_family then
if rules and rules.family == "disallowed" then
error(label .. " does not support family codes" .. (rules.family_suffix or "."))
elseif not etymon_data.suppress_term then
error("Family codes require suppressed term (use family:-).")
end
end
if rules then
if rules.require_term and (not etymon_data.term or etymon_data.term == "") then
error(label .. " requires a term for each listed form.")
end
if rules.entry_lang then
if Util.get_norm_lang(etymon_data.lang):getFullCode() ~=
Util.get_norm_lang(entry_lang):getFullCode() then
error(label .. " terms must be in the entry language (" ..
entry_lang:getFullCode() .. "), got '" .. etymon_data.lang:getFullCode() .. "'.")
end
end
if rules.ancestor_check then
M.etymology.check_ancestor(entry_lang, etymon_data.lang)
end
elseif etymon_data.is_family and not etymon_data.suppress_term then
error("Family codes require suppressed term (use family:-).")
end
end
function EtymonParser.check_keyword_term(etymon_data, entry_lang, keyword)
local config = M.data.keywords[keyword]
EtymonParser.check_term_rules(etymon_data, entry_lang, config and config.term_rules, "`:" .. keyword .. "`")
end
function EtymonParser.check_supplement_term(etymon_data, entry_lang, supplement_type)
local config = M.data.supplements[supplement_type]
EtymonParser.check_term_rules(etymon_data, entry_lang, config and config.term_rules, "|" .. supplement_type .. "=")
end
-- Parse keyword with modifiers (e.g., ":bor<unc>" or ":bor<ref:{{R:example}}>")
function EtymonParser.parse_keyword_modifiers(param)
if type(param) ~= "string" then return nil, {} end
local base_keyword = get_keyword_base(param)
if not base_keyword then return nil, {} end
local canonical_keyword = get_canonical_keyword(base_keyword)
-- Check if there are any modifiers
if not param:find("<", 1, true) then
return canonical_keyword, {}
end
-- Parse modifiers using the same mechanism as etymon parsing
local rest_with_defaults = Util.add_boolean_defaults(param, EtymonParser.keyword_param_mods)
local function generate_obj(ignored)
return {}
end
local parsed = M.parse_utilities.parse_inline_modifiers(rest_with_defaults:gsub("^:?[^<]+", ""),
{ param_mods = get_clean_param_mods(EtymonParser.keyword_param_mods), generate_obj = generate_obj })
local modifiers = {
unc = parsed.unc or false,
ref = parsed.ref,
text = parsed.text,
lit = parsed.lit,
conj = parsed.conj,
g = parsed.g,
surf = parsed.surf or false,
senseid = parsed.senseid,
}
-- Validate modifiers against restrictions
EtymonParser.check_modifier_restrictions(modifiers, canonical_keyword, EtymonParser.keyword_param_mods)
return canonical_keyword, modifiers
end
local function normalize_keyword_param(keyword_with_mods)
local trimmed = M.string_utilities.trim(keyword_with_mods)
reject_removed_surf_keyword(trimmed:match("^:") and trimmed or (":" .. trimmed))
local base = get_keyword_base(trimmed)
if not base or not M.data.keywords[base] then
error("Invalid keyword '" .. trimmed .. "' in inline etymology")
end
local canonical_base = get_canonical_keyword(base)
local without_colon = trimmed:gsub("^:", "")
local mods_part = without_colon:sub(#base + 1)
local kw_param = normalize_keyword(canonical_base .. mods_part)
EtymonParser.parse_keyword_modifiers(kw_param)
return kw_param
end
local function get_keyword_mod_names()
local names = {}
for mod_name in pairs(EtymonParser.keyword_param_mods) do
names[mod_name] = true
end
return names
end
local function parse_inline_ety_run(ety_string)
local body = ety_string or ""
if body == "" then
error("Empty inline etymology")
end
local keyword_mod_names = get_keyword_mod_names()
local pos = 1
local len = #body
local function parse_err(msg)
error(msg .. " in inline etymology: '" .. body .. "'")
end
local function peek_double()
return body:sub(pos, pos + 1) == "<<"
end
local function mod_name_from_unwrapped(unwrapped)
return unwrapped:match("^<([^:>]+)")
end
local function is_keyword_mod(unwrapped)
local name = mod_name_from_unwrapped(unwrapped)
return name and keyword_mod_names[name] or false
end
local function read_double_bracket()
if not peek_double() then
return nil
end
local start = pos
pos = pos + 2
while pos <= len - 1 do
if body:sub(pos, pos + 1) == ">>" then
local token = body:sub(start, pos + 1)
pos = pos + 2
return token, token:sub(2, -2)
end
pos = pos + 1
end
parse_err("Unmatched <<")
end
local function read_angle_cell()
if body:sub(pos, pos) ~= "<" or peek_double() then
return nil
end
local open = pos
pos = pos + 1
local depth = 1
local i = pos
while i <= len do
local ch = body:sub(i, i)
if ch == "<" then
depth = depth + 1
elseif ch == ">" then
depth = depth - 1
if depth == 0 then
local inner = body:sub(open + 1, i - 1)
pos = i + 1
return inner
end
end
i = i + 1
end
parse_err("Unmatched <")
end
local function read_bare_run()
local start = pos
while pos <= len and body:sub(pos, pos) ~= "<" do
pos = pos + 1
end
return body:sub(start, pos - 1)
end
local function absorb_double_keyword_mods(keyword_str)
while peek_double() do
local saved = pos
local _, unwrapped = read_double_bracket()
if is_keyword_mod(unwrapped) then
keyword_str = keyword_str .. unwrapped
else
pos = saved
break
end
end
return keyword_str
end
local kw_start = pos
while pos <= len and body:sub(pos, pos) ~= "<" do
pos = pos + 1
end
local keyword = body:sub(kw_start, pos - 1)
if keyword:match("^%s*$") then
parse_err("Missing keyword")
end
keyword = absorb_double_keyword_mods(keyword)
local cells = {}
while pos <= len do
if peek_double() then
local _, unwrapped = read_double_bracket()
if is_keyword_mod(unwrapped) then
parse_err("Unexpected keyword modifier " .. unwrapped .. " outside of a keyword")
end
table.insert(cells, "+" .. unwrapped)
elseif body:sub(pos, pos) == "<" then
local inner = read_angle_cell()
if inner ~= "" then
table.insert(cells, inner)
end
else
local bare = read_bare_run()
if bare ~= "" then
if bare:sub(1, 1) ~= ":" then
parse_err("Unexpected bare text '" .. bare .. "' (use :keyword for nested keywords in inline etymology)")
end
if not is_keyword(bare, true) then
parse_err("Invalid keyword '" .. bare .. "' in inline etymology")
end
table.insert(cells, absorb_double_keyword_mods(bare))
end
end
end
return {
keyword = keyword,
cells = cells,
}
end
function EtymonParser.inline_ety_to_pipe(ety_string)
local run = parse_inline_ety_run(ety_string)
if not run.keyword or run.keyword:match("^%s*$") then
return "|"
end
local pipe_parts = { normalize_keyword_param(M.string_utilities.trim(run.keyword)) }
for _, segment in ipairs(run.cells) do
if is_keyword(segment, true) then
table.insert(pipe_parts, normalize_keyword_param(segment))
else
table.insert(pipe_parts, segment)
end
end
return "|" .. table.concat(pipe_parts, "|") .. "|"
end
function EtymonParser.pipe_to_inline_ety(pipe_string)
local cells = {}
for cell in pipe_string:gmatch("([^|]+)") do
if cell ~= "" then
table.insert(cells, cell)
end
end
if #cells == 0 then
return ""
end
local inline_parts = {}
for index, cell in ipairs(cells) do
local base = get_keyword_base(cell)
if base and M.data.keywords[base] then
local without_colon = cell:gsub("^:", "")
local kw_base, mods = without_colon:match("^([^<]+)(.*)$")
local inline_kw = (kw_base or without_colon) .. (mods or ""):gsub("<([^>]+)>", "<<%1>>")
if index > 1 then
inline_kw = ":" .. inline_kw
end
table.insert(inline_parts, inline_kw)
elseif cell:sub(1, 1) == "+" then
local mod = cell:sub(2)
if mod:match("^<.->$") then
mod = mod:sub(2, -2)
end
table.insert(inline_parts, "<<" .. mod .. ">>")
else
table.insert(inline_parts, "<" .. cell .. ">")
end
end
return table.concat(inline_parts, "")
end
function EtymonParser.parse_inline_ety(ety_string, context_lang)
local run = parse_inline_ety_run(ety_string)
local keyword = M.string_utilities.trim(run.keyword)
reject_removed_surf_keyword(":" .. keyword)
if not is_keyword(keyword, true) then
error("Invalid keyword '" .. keyword .. "' in inline etymology <ety:" .. keyword .. "...>")
end
local args = { context_lang:getCode(), normalize_keyword_param(keyword) }
for _, segment in ipairs(run.cells) do
if is_keyword(segment, true) then
table.insert(args, normalize_keyword_param(segment))
else
table.insert(args, segment)
end
end
return args
end
function EtymonParser.parse_etymon(param, context_lang)
if is_keyword(param) then
return nil
end
if type(param) ~= "string" then
return nil
end
local lang, rest
local is_family = false
local before_bracket = param:match("^([^<]*)") or param
local lang_code, rest_match = before_bracket:match("^([a-zA-Z][a-zA-Z0-9._-]*):(.*)$")
if lang_code then
local potential_lang = Util.get_lang(lang_code, true)
if potential_lang then
lang = potential_lang
rest = param:sub(#lang_code + 2)
else
local potential_family = Util.get_family(lang_code)
if potential_family then
lang = potential_family
rest = param:sub(#lang_code + 2)
is_family = true
else
lang = context_lang
rest = param
end
end
else
lang = context_lang
rest = param
end
M.tracking.track_term(rest)
if rest == "" or rest == "+" then
return {
lang = lang,
term = nil,
unknown_term = true,
is_family = is_family,
}
end
if rest == "-" then
return {
lang = lang,
term = nil,
suppress_term = true,
is_family = is_family,
}
end
if not rest:find("<", 1, true) then
return {
lang = lang,
term = M.string_utilities.trim(rest),
is_family = is_family,
}
end
local term_text = rest:match("^([^<]*)") or ""
local is_unknown = (term_text == "" or term_text == "+")
local is_suppress = (term_text == "-")
local function generate_obj(ignored_term)
return { term = (is_unknown or is_suppress) and nil or M.string_utilities.trim(term_text) }
end
local rest_with_defaults = Util.add_boolean_defaults(rest, EtymonParser.etymon_param_mods)
local parsed_obj = M.parse_utilities.parse_inline_modifiers(rest_with_defaults,
{ param_mods = get_clean_param_mods(EtymonParser.etymon_param_mods), generate_obj = generate_obj })
if parsed_obj.id and parsed_obj.id:match("^!") then
parsed_obj.id = parsed_obj.id:sub(2)
parsed_obj.override = true
end
parsed_obj.lang = lang
parsed_obj.is_family = is_family
if is_unknown then
parsed_obj.unknown_term = true
elseif is_suppress then
parsed_obj.suppress_term = true
end
return parsed_obj
end
function EtymonParser.validate(lang, args, id, title, pos, starts_with_lang_code)
-- id is now optional, so only validate if provided
if id then
if mw.ustring.len(id) < 2 then
error("The `id` parameter must have at least two characters.")
end
if id == title or id == Util.get_page_data().pagename then
error("The `id` parameter must not be the same as the page title.")
end
end
local valid_pos = { prefix = true, suffix = true, interfix = true, infix = true, root = true, word = true }
if pos and not valid_pos[pos] then
error("Unknown value provided for `pos`. Valid values: " .. table.concat(require("Module:table").keysToList(valid_pos), ", ") .. ".")
end
local current_keyword = "from"
local current_keyword_explicit = false
local keyword_etymons = {}
local keywords = M.data.keywords
local function checkKeyword()
local config = keywords[current_keyword]
if current_keyword == "from" and not current_keyword_explicit and #keyword_etymons == 0 then
keyword_etymons = {}
return
end
EtymonParser.check_etymon_limits(#keyword_etymons, config, "`:" .. current_keyword .. "`")
keyword_etymons = {}
end
local start_index = starts_with_lang_code and 2 or 1
for i = start_index, #args do
local param = args[i]
if type(param) ~= "string" then
elseif param:sub(1, 1) == ":" and not is_keyword(param) then
reject_removed_surf_keyword(param)
error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?")
elseif is_keyword(param) then
checkKeyword()
current_keyword = get_canonical_keyword(get_keyword(param))
current_keyword_explicit = true
else
local etymon_data = EtymonParser.parse_etymon(param, lang)
if etymon_data then
table.insert(keyword_etymons, param)
EtymonParser.check_keyword_term(etymon_data, lang, current_keyword)
-- Check modifier restrictions
EtymonParser.check_modifier_restrictions(etymon_data, current_keyword, EtymonParser.etymon_param_mods)
-- postype must be "root" or "word"
local VALID_POSTYPES = { root = true, word = true }
if etymon_data.postype and not VALID_POSTYPES[etymon_data.postype] then
error("Invalid <postype:" .. etymon_data.postype .. ">; must be \"root\" or \"word\".")
end
if etymon_data.ety then
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
EtymonParser.validate(etymon_data.lang, inline_args, nil, nil, nil, true)
end
else
table.insert(keyword_etymons, param)
end
end
end
checkKeyword()
end
local DataRetriever = {}
local function format_etymon_id_hint(id_data, idx)
local id = type(id_data) == "table" and id_data.id or id_data
local pos = type(id_data) == "table" and id_data.pos
if id and id ~= "" and id ~= "*" then
return '"' .. id .. '"'
end
if pos and pos ~= "" then
return "unnamed (|pos=" .. pos .. "|)"
end
return "etymon #" .. idx .. " (no |id= on page)"
end
local function etymon_target_page_link(page, norm_lang)
return M.links.full_link({
term = page,
lang = norm_lang,
no_generate_forms = true,
}, "term")
end
-- Summarize {{etymon}} id slots on a linked page for preview warnings.
local function summarize_available_etymon_ids(ids)
local id_list = {}
local all_idless = true
local target_has_idless = false
local any_pos = false
for i, id_data in ipairs(ids) do
local id = type(id_data) == "table" and id_data.id or id_data
local pos = type(id_data) == "table" and id_data.pos
if id and id ~= "" and id ~= "*" then
all_idless = false
else
target_has_idless = true
end
if pos and pos ~= "" then
any_pos = true
end
table.insert(id_list, format_etymon_id_hint(id_data, i))
end
return {
id_list = id_list,
all_idless = all_idless,
target_has_idless = target_has_idless,
any_pos = any_pos,
count = #ids,
options_text = mw.text.listToText(id_list),
}
end
local function ambiguous_etymon_suggestion(page_link, summary)
if summary.all_idless then
if summary.any_pos then
return " None set `|id=` yet; add a unique `|id=` to each on " .. page_link
.. ", then `<id:identifier>` after the term here. Section order / hints: "
.. summary.options_text .. "."
end
return " None set `|id=` yet; add a unique `|id=` to each {{etymon}} in that section from top to bottom, then `<id:identifier>` after the term here (same value as `|id=`)."
end
return " Specify which one with `<id:identifier>` after the term. Options: " .. summary.options_text .. "."
end
local function warn_ambiguous_etymon_link(page, norm_lang, ids, is_toplevel)
local page_link = etymon_target_page_link(page, norm_lang)
local summary = summarize_available_etymon_ids(ids)
if is_toplevel and summary.target_has_idless then
__state.linked_page_multiple_etymons_idless = true
end
local lang_name = norm_lang:getCanonicalName()
local lead = "Etymology link to " .. page_link .. " is ambiguous (" .. summary.count
.. " {{etymon}} templates for " .. lang_name .. ")."
Util.add_warning(lead .. ambiguous_etymon_suggestion(page_link, summary), true)
end
local function is_mismatched_explicit_id(base_key, cached_args, parent_etymon)
return cached_args == M.data.STATUS.MISSING and not parent_etymon
and #(__state.available_etymon_ids[base_key] or {}) > 0
end
local function maybe_flag_partial_etymology_reference(base_key, etymon_data, cached_args, is_toplevel)
if not is_toplevel or __state.skip_partial_etymology_category then
return
end
if not __state.partial_etymology_targets[base_key] then
return
end
if etymon_data.id and type(cached_args) == "table" then
return
end
__state.linked_page_partial_etymology_sections = true
end
local function is_nonlemma_etymon_template(template_args)
return template_args and M.yesno(template_args.nl, false)
end
local function warn_mismatched_explicit_id(page, norm_lang, base_key, etymon_id)
local page_link = etymon_target_page_link(page, norm_lang)
local summary = summarize_available_etymon_ids(__state.available_etymon_ids[base_key] or {})
local lang_name = norm_lang:getCanonicalName()
local lead = "Etymology link to " .. page_link .. " uses `<id:" .. etymon_id
.. ">`, but no {{etymon}} on that page has `|id=" .. etymon_id .. "|` for " .. lang_name .. "."
Util.add_warning(lead .. " Valid IDs: " .. summary.options_text .. ".", true)
end
-- Given an etymon data, scrape its page and cache the result in the global state object.
function DataRetriever.cache_page_etymons(etymon_page, etymon_title, key, etymon_lang, etymon_id, redirected_from, descendants_is_toplevel)
local content = etymon_title:getContent()
if not content then
__state.cached_etymon_args[key] = M.data.STATUS.REDLINK
return
end
-- Check if the linked page is a redirect. If it is, the template parsing
-- code below will be effectively skipped, and `scrape_page` will be called
-- again on the redirect target (see the bottom of this function)
local lang_section_for_descendants = nil
local redirect_target = etymon_title.redirect_target
if not redirect_target then
content = M.pages.get_section(content, etymon_lang:getFullName(), 2)
if not content then
__state.cached_etymon_args[key] = M.data.STATUS.MISSING
return
end
lang_section_for_descendants = content
end
local etymon_lang_code = etymon_lang:getFullCode()
local lang_page_key = etymon_lang_code .. ":" .. etymon_page
local found_templates_for_lang = {}
local found_ids = {}
local get_node_class = M.template_parser.class_else_type
-- Look for all {{etymon}} templates within the page content using the template parser
-- This way the same page is never parsed more than once
-- Build a map from senseids to their parent etymonids.
local active_etymon_args = nil
local etymology_section_count = 0
local etymology_sections_with_etymon = 0
local current_etymology_has_etymon = false
local current_etymology_has_nonlemma = false
local function finalize_current_etymology_section()
if etymology_section_count == 0 then
return
end
if current_etymology_has_etymon or current_etymology_has_nonlemma then
etymology_sections_with_etymon = etymology_sections_with_etymon + 1
end
current_etymology_has_etymon = false
current_etymology_has_nonlemma = false
end
for node in M.template_parser.parse(content):iterate_nodes() do
local node_class = get_node_class(node)
if node_class == "heading" then
-- A new L2 or etymology section acts as a barrier: an {{etymon}} usage
-- used previously cannot be the parent of any subsequent senseids.
-- Note that we don't have to check for L2s due to the usage of `M.pages.get_section` above.
if node:get_name():find("^နိရုတ်") then
finalize_current_etymology_section()
etymology_section_count = etymology_section_count + 1
active_etymon_args = nil
end
elseif node_class == "ထာမ်ပလိက်" then
local template_name = node:get_name()
if template_name == "etymon" then
local template_args = node:get_arguments()
-- Check if this etymon is for our language
if template_args[1] == etymon_lang_code then
if is_nonlemma_etymon_template(template_args) then
if etymology_section_count > 0 then
current_etymology_has_nonlemma = true
end
else
if etymology_section_count > 0 then
current_etymology_has_etymon = true
end
table.insert(found_templates_for_lang, template_args)
if template_args.id then
local etymon_key = lang_page_key .. ":" .. template_args.id
__state.cached_etymon_args[etymon_key] = template_args
__state.cached_etymon_pages[etymon_key] = tostring(etymon_page)
table.insert(found_ids, template_args.id)
active_etymon_args = template_args
else
-- Store idless etymon with default key
local etymon_key = lang_page_key .. ":*"
__state.cached_etymon_args[etymon_key] = template_args
__state.cached_etymon_pages[etymon_key] = tostring(etymon_page)
table.insert(found_ids, "*")
active_etymon_args = template_args
end
end
end
elseif active_etymon_args and template_name == "senseid" then
local template_args = node:get_arguments()
-- This should always be true for proper usages of {{senseid}}.
if template_args[1] == etymon_lang_code and template_args[2] then
local sense_id_key = lang_page_key .. ":" .. template_args[2]
__state.senseid_parent_etymon[sense_id_key] = active_etymon_args
__state.cached_etymon_pages[sense_id_key] = tostring(etymon_page)
end
end
end
end
finalize_current_etymology_section()
if lang_section_for_descendants
and etymology_section_count > 1
and etymology_sections_with_etymon > 0
and etymology_sections_with_etymon < etymology_section_count
then
__state.partial_etymology_targets[lang_page_key] = true
end
if descendants_is_toplevel and lang_section_for_descendants and #found_templates_for_lang > 0 then
M.descendants.cache_page_checks({
lang_section = lang_section_for_descendants,
etymon_lang_code = etymon_lang_code,
found_templates_for_lang = found_templates_for_lang,
entry_title = __state.entry_title,
entry_lang_code = __state.entry_lang_code,
entry_lang = __state.entry_lang_code and Util.get_lang(__state.entry_lang_code, true) or nil,
cached_descendants_checks = __state.cached_descendants_checks,
lang_page_key = lang_page_key,
redirected_from = redirected_from,
})
end
local id_data_list = {}
for _, args in ipairs(found_templates_for_lang) do
local id = args.id or "*"
table.insert(id_data_list, { id = id, pos = args.pos })
end
__state.available_etymon_ids[lang_page_key] = id_data_list
if #found_templates_for_lang == 1 then
__state.single_etymons[lang_page_key] = found_templates_for_lang[1]
end
if redirected_from and __state.available_etymon_ids[lang_page_key] then
__state.available_etymon_ids[redirected_from] = __state.available_etymon_ids[redirected_from] or {}
for _, id_data in ipairs(__state.available_etymon_ids[lang_page_key]) do
table.insert(__state.available_etymon_ids[redirected_from], id_data)
end
end
if __state.cached_etymon_args[key] ~= nil or __state.senseid_parent_etymon[key] ~= nil then
-- All done!
return
elseif redirect_target and not redirected_from then
-- Try scraping the redirect.
etymon_page = redirect_target.prefixedText
DataRetriever.cache_page_etymons(etymon_page, redirect_target, lang_page_key .. ":" .. etymon_id, etymon_lang, etymon_id, lang_page_key, descendants_is_toplevel)
__state.cached_etymon_args[key] = __state.cached_etymon_args[etymon_lang_code .. ":" .. etymon_page .. ":" .. etymon_id]
else
__state.cached_etymon_args[key] = M.data.STATUS.MISSING
end
end
local function has_linkable_term(etymon_data)
if etymon_data.is_family or etymon_data.suppress_term or etymon_data.unknown_term then
return false
end
local term = etymon_data.term
if term == nil or term == "" then
return false
end
return M.string_utilities.trim(term) ~= ""
end
local function record_term_id_tracking(etymon_data)
if not has_linkable_term(etymon_data) then
return
end
local term_page = M.links.get_link_page(etymon_data.term, etymon_data.lang)
M.tracking.record_term_id_usage(__state.id_stats, etymon_data, term_page)
end
-- Given an etymon object, scrape its page (if necessary) and return its own etymon arguments as well as the page name.
function DataRetriever.get_etymon_args(etymon_data, is_toplevel)
if not has_linkable_term(etymon_data) then
return M.data.STATUS.MISSING, nil, nil, nil
end
local page = M.links.get_link_page(etymon_data.term, etymon_data.lang)
local norm_lang = Util.get_norm_lang(etymon_data.lang)
local base_key = norm_lang:getFullCode() .. ":" .. page
if etymon_data.id then
local key = base_key .. ":" .. etymon_data.id
local cached_args = __state.cached_etymon_args[key] or __state.senseid_parent_etymon[key]
if cached_args == nil then
local title = mw.title.new(page)
if not title then error('Invalid page title "' .. page .. '" encountered.') end
DataRetriever.cache_page_etymons(page, title, key, norm_lang, etymon_data.id, nil, is_toplevel)
end
cached_args = __state.cached_etymon_args[key] or __state.senseid_parent_etymon[key] -- refresh
-- Get etymon_id from parent if this was resolved via senseid
local parent_etymon = __state.senseid_parent_etymon[key]
local resolved_etymon_id = parent_etymon and parent_etymon.id
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = {
explicit_id = etymon_data.id,
parent_etymon = parent_etymon,
},
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, key, norm_lang, etymon_data.id, nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = {
explicit_id = etymon_data.id,
parent_etymon = parent_etymon,
},
})
end
end
local mismatched_id = is_mismatched_explicit_id(base_key, cached_args, parent_etymon)
if mismatched_id and is_toplevel then
__state.has_mismatched_id = true
M.tracking.record_mismatched_id_usage(__state.id_stats, norm_lang, page, etymon_data.id)
warn_mismatched_explicit_id(page, norm_lang, base_key, etymon_data.id)
end
maybe_flag_partial_etymology_reference(base_key, etymon_data, cached_args, is_toplevel)
return cached_args, __state.cached_etymon_pages[key], resolved_etymon_id, descendants_check
else
__state.used_idless_etymon = true
if is_toplevel then
__state.toplevel_idless_etymon = true
end
if __state.available_etymon_ids[base_key] == nil then
local title = mw.title.new(page)
if not title then error('Invalid page title "' .. page .. '" encountered.') end
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, is_toplevel)
end
local ids = __state.available_etymon_ids[base_key] or {}
local count = #ids
-- Try to filter by postype if available and we have multiple candidates
if count > 1 and etymon_data.postype then
local matching_ids = {}
for _, id_data in ipairs(ids) do
if id_data.pos == etymon_data.postype then
table.insert(matching_ids, id_data)
end
end
if #matching_ids == 1 then
local matched_id = matching_ids[1].id
local matched_key = base_key .. ":" .. matched_id
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "postype")
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = { id = matched_id },
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = { id = matched_id },
})
end
end
local matched_args = __state.cached_etymon_args[matched_key]
maybe_flag_partial_etymology_reference(base_key, etymon_data, matched_args, is_toplevel)
return matched_args, __state.cached_etymon_pages[matched_key], nil, descendants_check
end
end
if count == 1 then
local only_id_data = ids[1]
local only_id = (type(only_id_data) == "table" and only_id_data.id) or only_id_data or "*"
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "single")
local descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = is_toplevel,
base_key = base_key,
lookup = { id_data = only_id_data },
})
if is_toplevel and descendants_check == nil then
local title = mw.title.new(page)
if title then
DataRetriever.cache_page_etymons(page, title, base_key .. ":*", norm_lang, "*", nil, true)
descendants_check = M.descendants.get_lookup_check({
cached_descendants_checks = __state.cached_descendants_checks,
is_toplevel = true,
base_key = base_key,
lookup = { id_data = only_id_data },
})
end
end
local single_args = __state.single_etymons[base_key]
maybe_flag_partial_etymology_reference(base_key, etymon_data, single_args, is_toplevel)
return single_args, __state.cached_etymon_pages[base_key .. ":" .. only_id], nil, descendants_check
elseif count > 1 then
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "ambiguous")
warn_ambiguous_etymon_link(page, norm_lang, ids, is_toplevel)
maybe_flag_partial_etymology_reference(base_key, etymon_data, M.data.STATUS.AMBIGUOUS, is_toplevel)
return M.data.STATUS.AMBIGUOUS, nil, nil, nil
else
M.tracking.record_idless_resolution(__state.id_stats, norm_lang, page, "missing")
maybe_flag_partial_etymology_reference(base_key, etymon_data, M.data.STATUS.MISSING, is_toplevel)
return M.data.STATUS.MISSING, nil, nil, nil
end
end
end
local function keyword_invisible_in_tree(keyword_info)
if not keyword_info then
return false
end
local inv = keyword_info.invisible
return inv == "all" or inv == true or inv == "tree"
end
-- True when the node has at least one top-level child container visible in the tree.
local function node_has_visible_tree_children(node)
for _, container in ipairs(node.children or {}) do
if not keyword_invisible_in_tree(container.keyword_info) then
return true
end
end
return false
end
-- Count visible term nodes in the tree.
local function get_visible_tree_depth(node, skip_child_rendering)
local max_depth = 1
if skip_child_rendering or not node then
return max_depth
end
for _, container in ipairs(node.children or {}) do
local keyword_info = container.keyword_info
if not keyword_invisible_in_tree(keyword_info) then
local skip_grandchildren = keyword_info and keyword_info.no_child_categories
for _, term in ipairs(container.terms or {}) do
if term.is_duplicate then
if term.original_has_children then
max_depth = math.max(max_depth, 2)
end
else
max_depth = math.max(max_depth, 1 + get_visible_tree_depth(term, skip_grandchildren))
end
end
end
end
return max_depth
end
local function as_param_list(val)
if val == nil then
return {}
end
if type(val) == "table" then
return val
end
if type(val) == "string" and val ~= "" then
return { val }
end
return {}
end
local TreeBuilder = {}
local function parse_etymon_references(refs_text)
if not refs_text or refs_text == "" then
return ""
end
return M.references.parse_references(refs_text)
end
local function parse_tree_references(node)
if node.ref then
node.parsed_ref = parse_etymon_references(node.ref)
end
if node.children then
for _, container in ipairs(node.children) do
if container.terms then
for _, term in ipairs(container.terms) do
parse_tree_references(term)
end
end
end
end
if node.supplements then
for _, supplement in ipairs(node.supplements) do
if supplement.terms then
for _, term in ipairs(supplement.terms) do
parse_tree_references(term)
end
end
end
end
end
-- Build a unique key for deduplication in the seen table
function TreeBuilder.build_key(lang, title, args)
local norm_lang_code = Util.get_norm_lang(lang):getFullCode()
local is_table = type(args) == "table"
local id = (is_table and args.id) or ""
if title then
return norm_lang_code .. ":" .. M.links.get_link_page(title, lang) .. ":" .. id
end
if is_table and args.status == M.data.STATUS.INLINE then
local content_parts = {}
for i = 1, #args do
content_parts[i] = tostring(args[i])
end
return norm_lang_code .. ":*:" .. id .. "\0" .. table.concat(content_parts, "\0")
end
return norm_lang_code .. ":*:" .. id
end
-- Copy parsed etymon modifiers onto a tree/supplement term node.
function TreeBuilder.apply_etymon_fields(term, etymon_data)
term.id = etymon_data.id
term.t = etymon_data.t
term.tr = etymon_data.tr
term.ts = etymon_data.ts
term.alt = etymon_data.alt
term.g = etymon_data.g
term.pos = etymon_data.pos
term.ng = etymon_data.ng
term.ref = etymon_data.ref
term.is_uncertain = etymon_data.unc
term.lit = etymon_data.lit
term.q = etymon_data.q
term.qq = etymon_data.qq
term.l = etymon_data.l
term.ll = etymon_data.ll
term.suppress_term = etymon_data.suppress_term
term.unknown_term = etymon_data.unknown_term
term.is_family = etymon_data.is_family
term.override = etymon_data.override
term.aftype = etymon_data.aftype
term.postype = etymon_data.postype
term.bor = etymon_data.bor
term.lbor = etymon_data.lbor
term.slbor = etymon_data.slbor
end
function TreeBuilder.build_supplement_term(etymon_data, entry_lang, supplement_type)
EtymonParser.check_supplement_term(etymon_data, entry_lang, supplement_type)
local term = {
lang = etymon_data.lang,
title = etymon_data.term,
children = {},
status = M.data.STATUS.OK,
}
TreeBuilder.apply_etymon_fields(term, etymon_data)
return term
end
function TreeBuilder.build_supplement_terms(entry_lang, supplement_type, param_value)
local terms = {}
for _, term_param in ipairs(as_param_list(param_value)) do
if type(term_param) == "string" and term_param ~= "" then
local etymon_data = EtymonParser.parse_etymon(term_param, entry_lang)
if etymon_data then
table.insert(terms, TreeBuilder.build_supplement_term(etymon_data, entry_lang, supplement_type))
end
end
end
return terms
end
-- Attach a |param= supplement defined in etymon_data.supplements (e.g. doublet=).
function TreeBuilder.append_term_supplement(data_tree, entry_lang, supplement_type, param_value)
local config = M.data.supplements[supplement_type]
if not config then
error("Unknown supplement '" .. tostring(supplement_type) .. "'.")
end
local terms = TreeBuilder.build_supplement_terms(entry_lang, supplement_type, param_value)
if #terms == 0 then
return
end
data_tree.supplements = data_tree.supplements or {}
table.insert(data_tree.supplements, {
type = supplement_type,
config = config,
terms = terms,
})
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, supplement_type, entry_lang, entry_lang, true)
end
function TreeBuilder.build(lang, title, args, seen, depth, stop_recursion)
seen = seen or {}
depth = depth or 0
local is_toplevel = (depth == 0)
if depth > __state.max_depth_reached then
__state.max_depth_reached = depth
end
__state.total_nodes = __state.total_nodes + 1
local lang_code = lang:getCode()
__state.language_count[lang_code] = (__state.language_count[lang_code] or 0) + 1
local current_id = (type(args) == "table" and args.id) or ""
local key = TreeBuilder.build_key(lang, title, args)
local node = { lang = lang, title = title, id = current_id, args = args, children = {}, status = M.data.STATUS.OK }
if type(args) ~= "table" or seen[key] then
node.status = args or M.data.STATUS.MISSING
-- Mark as duplicate if we've seen this node before
if seen[key] then
node.is_duplicate = true
node.duplicate_key = key
local original_node = seen[key]
if type(original_node) == "table" and original_node.children and #original_node.children > 0 then
node.original_has_children = true
end
end
return node
end
node.status = args.status or M.data.STATUS.OK
seen[key] = node
-- If stop_recursion is set, skip parsing children but check for visible children
if stop_recursion then
local keywords = M.data.keywords
local has_visible_children = false
for i = 2, #args do
local param = args[i]
if type(param) == "string" then
local keyword_base = get_keyword_base(param)
if keyword_base and keywords[keyword_base] then
local _, kw_modifiers = EtymonParser.parse_keyword_modifiers(param:sub(1, 1) == ":" and param or (":" .. param))
if not keyword_invisible_in_tree(get_effective_keyword_info(keyword_base, kw_modifiers)) then
has_visible_children = true
break
end
elseif param:sub(1, 1) ~= ":" then
-- It's a term (not a keyword), so there are visible children
has_visible_children = true
break
end
end
end
node.has_visible_children = has_visible_children
return node
end
-- Parse args into keyword containers
local current_keyword = "နူဝေါဟာ "
local current_keyword_modifiers = {}
local current_container = nil
local function ensure_container()
if not current_container or current_container.keyword ~= current_keyword then
local keyword_info = get_effective_keyword_info(current_keyword, current_keyword_modifiers)
current_container = {
keyword = current_keyword,
keyword_info = keyword_info,
keyword_modifiers = current_keyword_modifiers,
terms = {},
}
table.insert(node.children, current_container)
-- Override keyword text/phrase for nominalization with <g:code>
if current_keyword_modifiers.g and current_keyword == "nominalization" then
local labels = get_nominalization_label_for_g(current_keyword_modifiers.g)
if not labels then
local codes = {}
for c in pairs(M.data.nominalization_g_codes) do table.insert(codes, c) end
table.sort(codes)
error("Invalid <g:" .. tostring(current_keyword_modifiers.g) .. ">. Supported codes for nominalization: " .. table.concat(codes, ", "))
end
current_container.keyword_info = copy_keyword_info(keyword_info)
current_container.keyword_info.text = labels.text
current_container.keyword_info.phrase = labels.phrase
end
end
return current_container
end
local parse_context_lang = Util.resolve_context_lang(lang, args)
for i = 2, #args do
local param = args[i]
if is_keyword(param) then
local keyword, modifiers = EtymonParser.parse_keyword_modifiers(param)
if not keyword then
error("Invalid keyword '" .. param .. "'.")
end
current_keyword = keyword
current_keyword_modifiers = modifiers
current_container = nil -- Force new container for new keyword
elseif type(param) == "string" and param:sub(1, 1) == ":" then
reject_removed_surf_keyword(param)
error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?")
elseif type(param) == "string" then
local etymon_data = EtymonParser.parse_etymon(param, parse_context_lang)
if etymon_data then
-- Track keyword usage at top level
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, current_keyword, lang, etymon_data.lang, is_toplevel)
local term_node = {}
local container
-- Handle suppress_term (-) and unknown_term (empty or +) directly
if etymon_data.suppress_term or etymon_data.unknown_term then
container = ensure_container()
if etymon_data.ety then
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
inline_args.id = etymon_data.id
inline_args.status = M.data.STATUS.INLINE
term_node = TreeBuilder.build(etymon_data.lang, nil, inline_args, seen, depth + 1)
else
term_node = {
lang = etymon_data.lang,
children = {},
status = M.data.STATUS.OK,
}
end
TreeBuilder.apply_etymon_fields(term_node, etymon_data)
else
-- Regular term: fetch arguments from page
record_term_id_tracking(etymon_data)
local etymon_args, page_of, resolved_etymon_id, descendants_check =
DataRetriever.get_etymon_args(etymon_data, is_toplevel)
-- Check for <ety> inline parameter doesn't override the scraped arguments, unless the latter are missing
if etymon_data.ety then
if etymon_args == M.data.STATUS.REDLINK or etymon_args == M.data.STATUS.MISSING then
__state.current_page_has_inline_etymology = true
if is_toplevel then
__state.toplevel_has_inline_etymology = true
end
local inline_args = EtymonParser.parse_inline_ety(etymon_data.ety, etymon_data.lang)
-- Track inline ety keywords too
local inline_keyword = get_keyword(inline_args[2], true)
if inline_keyword and #inline_args >= 3 then
local inline_etymon = EtymonParser.parse_etymon(inline_args[3], etymon_data.lang)
if inline_etymon then
M.tracking.record_keyword_usage(__state.toplevel_keyword_stats, inline_keyword, etymon_data.lang, inline_etymon.lang, is_toplevel)
end
end
inline_args.id = etymon_data.id
inline_args.status = M.data.STATUS.INLINE
etymon_args = inline_args
term_node.page_of = __state.cached_etymon_pages[key] -- term node is on the same page as the parent
else
-- Scraped arguments exist, <ety> is redundant and ignored
__state.current_page_has_redundant_etymology = true
if is_toplevel then
__state.toplevel_redundant_etymology = true
end
end
end
-- Ensure container exists before checking keyword info
container = ensure_container()
-- Check if current keyword has no_child_categories - if so, stop recursion
local keyword_info = container.keyword_info
local should_stop_recursion = (stop_recursion or (keyword_info and keyword_info.no_child_categories))
term_node = TreeBuilder.build(etymon_data.lang, etymon_data.term, etymon_args, seen, depth + 1, should_stop_recursion)
term_node.target_key = Util.get_norm_lang(etymon_data.lang):getFullCode() ..
":" .. M.links.get_link_page(etymon_data.term, etymon_data.lang)
term_node.etymon_id = resolved_etymon_id -- The actual etymon id when resolved via senseid
term_node.page_of = page_of
TreeBuilder.apply_etymon_fields(term_node, etymon_data)
term_node.missing_descendants_header, term_node.missing_descendants_entry =
M.descendants.get_term_sync_flags(current_keyword, term_node.status, descendants_check)
end
table.insert(container.terms, term_node)
end
end
end
return node
end
-- Convert etymology tree to JSON-serializable table
local function tree_to_json(node)
local obj = {
term = node.title,
lang = node.lang:getCode(),
lang_name = node.lang:getCanonicalName(),
id = (node.id and node.id ~= "") and node.id or nil,
status = node.status,
is_uncertain = node.is_uncertain or nil,
is_duplicate = node.is_duplicate or nil,
gloss = node.t,
transliteration = node.tr,
transcription = node.ts,
alt = node.alt,
g = node.g,
pos = node.pos,
ng = node.ng,
children = {},
}
for _, container in ipairs(node.children or {}) do
local keyword_info = container.keyword_info
if keyword_info then
local container_obj = {
keyword = container.keyword,
keyword_label = keyword_info.text,
keyword_abbrev = keyword_info.abbrev,
is_group = keyword_info.is_group or nil,
is_invisible = keyword_info.invisible or nil,
is_uncertain = (container.keyword_modifiers and container.keyword_modifiers.unc) or nil,
terms = {},
}
for _, term in ipairs(container.terms or {}) do
table.insert(container_obj.terms, tree_to_json(term))
end
table.insert(obj.children, container_obj)
end
end
return obj
end
-- Build and return the etymology data tree for a given term.
function export.get_tree(lang, title, args, options)
options = options or {}
__state.entry_title = title
__state.entry_lang_code = lang:getCode()
__state.id_stats = M.tracking.new_id_stats()
__state.skip_partial_etymology_category = options.skip_partial_etymology_category == true
if options.validate then
EtymonParser.validate(lang, args, options.id, title, options.pos, false)
end
local lang_code = lang:getCode()
local start_index = (args[1] == lang_code) and 2 or 1
local tree_args = { [1] = lang_code, id = options.id or args.id }
for i = start_index, #args do
table.insert(tree_args, args[i])
end
__state.cached_etymon_args[lang_code .. ":" .. title .. ":" .. (tree_args.id or "")] = tree_args
local ety_data_tree = TreeBuilder.build(lang, title, tree_args)
parse_tree_references(ety_data_tree)
if options.json then
return M.JSON.toJSON(tree_to_json(ety_data_tree))
end
return ety_data_tree
end
-- Given a language code, page name and optionally the id= parameter,
-- render the tree and only the etymology tree for the relevant page.
-- Fetches and parses the corresponding {{etymon}} from the requested page,
-- and any further pages needed to render the tree.
-- Parameters can be passed either through the #invoke or as
-- template parameters *through* an #invoke.
function export.render_tree_for_etymon_on_page(frame)
local frame_args = frame.args
local parent_args = frame:getParent().args
local langcode = frame_args[1] or parent_args[1]
local pagename = frame_args[2] or parent_args[2]
local id = frame_args["id"] or parent_args["id"]
local display_title = frame_args["title"] or parent_args["title"]
local parsed_title = mw.title.new(pagename, 0)
local title
if parsed_title.namespace == 0 then
title = M.pages.safe_page_name(parsed_title)
elseif parsed_title.namespace == 118 then
title = "*" .. M.pages.safe_page_name(parsed_title)
else
error("Unsupported namespace for render_tree_for_etymon_on_page: " .. parsed_title.namespace)
end
local lang = Util.get_lang(langcode)
-- Construct etymon_data for DataRetriever.get_args.
local etymon_data = {
lang = lang,
term = title,
id = id
}
local args, pagename = DataRetriever.get_etymon_args(etymon_data, true)
if args == M.data.STATUS.MISSING then
error("The etymon template was not found (language " ..
langcode ..
", title '" ..
title ..
"'" ..
(id and ", ID '" .. id .. "'" or ", no ID given") .. "). Page contents may have changed in the interim.")
end
local tree_title = display_title or title
if lang:stripDiacritics(M.links.remove_links(tree_title)) ~= lang:stripDiacritics(M.links.remove_links(title)) then
M.tracking.track_title_pagename_mismatch(lang)
end
reset_invocation_state()
local ety_data_tree = export.get_tree(lang, tree_title, args, {
validate = true,
id = id,
})
local output = {}
table.insert(output, M.template_styles("Module:etymon/styles.css"))
table.insert(output, M.tree.render({
data_tree = ety_data_tree,
format_term_func = function(term, is_toplevel)
return Util.format_term(term, is_toplevel, {
gloss = "suppress",
pos = "suppress",
lit = "suppress",
tree_ql = "suppress",
})
end,
}))
return table.concat(output)
end
function export.main(frame)
local parent_args = frame:getParent().args
local args = M.parameters.process(parent_args, M.parameters_data.etymon)
local lang = args[1]
local etymon_args = args[2]
local id = args.id
local title = args.title
local text = args.text
local tree = args.tree
local etydate = args.etydate
local doublet = args.doublet
local rfe = args.rfe
local etystub = args.etystub
local is_nonlemma = M.yesno(args.nl, false)
local page_data = Util.get_page_data()
if not title then
title = page_data.pagename
if page_data.namespace == "ဗီုပြၚ်သိုၚ်တၟိ" then title = "*" .. title end
end
local entry_pagename = page_data.pagename
if page_data.namespace == "ဗီုပြၚ်သိုၚ်တၟိ" then
entry_pagename = "*" .. entry_pagename
end
if lang:stripDiacritics(M.links.remove_links(title)) ~= lang:stripDiacritics(M.links.remove_links(entry_pagename)) then
M.tracking.track_title_pagename_mismatch(lang)
end
local current_L2 = M.pages.get_current_L2()
if current_L2 then
local norm_lang = Util.get_norm_lang(lang)
local norm_name = norm_lang:getCanonicalName()
if current_L2 ~= norm_name then
local lang_desc = lang:getCode() .. " (" .. lang:getCanonicalName() .. ")"
if norm_lang:getCode() ~= lang:getCode() then
lang_desc = lang_desc .. ", normalized to " .. norm_lang:getCode() .. " (" .. norm_name .. ")"
end
error("Language '" .. lang_desc .. "' does not match the L2 header (" .. current_L2 .. ").")
end
end
reset_invocation_state()
local ety_data_tree = export.get_tree(lang, title, etymon_args, {
validate = true,
pos = args.pos,
id = id,
json = args.json,
skip_partial_etymology_category = is_nonlemma,
})
if args.json then
return ety_data_tree
end
local output = {}
local text_allowlist_mode = M.text_allowed.default_mode or "off"
if text and text_allowlist_mode ~= "off" and not Util.is_text_param_allowed_for_lang(lang) then
local msg = "Etymology texts (parameter <code>text=</code>) are not allowed for " .. lang:getFullName() ..
"; see [[Template:etymon#Text allowlist|Template:etymon § Text allowlist]] for the list of languages that may use the <code>text=</code> parameter."
if text_allowlist_mode == "error" then
error(msg)
else
Util.add_warning(msg, true)
end
end
local lang_exc = Util.get_lang_exception(lang)
if lang_exc and lang_exc.disallow then
local disallow = lang_exc.disallow
local error_text = " for " .. lang:getFullName()
if disallow.ref then
error_text = error_text .. "; see " .. disallow.ref
else
error_text = error_text .. "."
end
if tree and disallow.tree then
error("Etymology trees are not allowed" .. error_text)
end
if text and disallow.text then
error("Etymology texts are not allowed" .. error_text)
end
end
if etydate then
local etydate_param_mods = {
ref = { list = true, type = "references", allow_holes = true },
refn = { list = true, allow_holes = true },
nocap = { type = "boolean" },
}
local function generate_etydate_obj(etydate_text)
local etydate_specs = {}
for spec in etydate_text:gmatch("[^,]+") do
table.insert(etydate_specs, mw.text.trim(spec))
end
return { [1] = etydate_specs }
end
local parsed_etydate = M.parse_utilities.parse_inline_modifiers(etydate, { param_mods = etydate_param_mods, generate_obj = generate_etydate_obj })
local etydate_args = {
[1] = parsed_etydate[1],
nocap = parsed_etydate.nocap or false,
}
ety_data_tree.supplements = ety_data_tree.supplements or {}
table.insert(ety_data_tree.supplements, {
type = "etydate",
etydate_text = M.etydate.format_etydate(etydate_args, { omit_refs = true }),
etydate_refs = (parsed_etydate.ref and #parsed_etydate.ref > 0) and parsed_etydate.ref or nil,
})
end
TreeBuilder.append_term_supplement(ety_data_tree, lang, "doublet", doublet)
if ety_data_tree.supplements then
parse_tree_references(ety_data_tree)
end
local has_visible_children = node_has_visible_tree_children(ety_data_tree)
-- Suppress trees for multiword entries and one-step chains
local visible_tree_depth = get_visible_tree_depth(ety_data_tree)
local is_trivial_tree = visible_tree_depth <= 2
local is_multiword = title:find("%s") ~= nil or title:find("_") ~= nil
if tree and (is_multiword or is_trivial_tree) then
tree = false
end
if tree then
table.insert(output, M.template_styles("Module:etymon/styles.css"))
table.insert(output, M.tree.render({
data_tree = ety_data_tree,
format_term_func = function(term, is_toplevel)
return Util.format_term(term, is_toplevel, {
gloss = "suppress",
pos = "suppress",
lit = "suppress",
tree_ql = "suppress",
})
end,
}))
end
local tree_disallowed = lang_exc and lang_exc.disallow and lang_exc.disallow.tree
local ety_tree_json = M.JSON.toJSON(tree_to_json(ety_data_tree))
local anchor = M.anchors.etymonid(lang, id, {
no_tree = args.notree,
title = title,
empty_tree = (not has_visible_children) or tree_disallowed,
ety_tree_json = ety_tree_json,
})
table.insert(output, anchor)
local text_stop_lang_missing = nil
if text then
local max_depth, stop_at_blue_link, stop_at_lang, stop_at_lang_or_bluelink
if text == "++" then
max_depth, stop_at_blue_link = false, false
elseif text == "+" then
max_depth, stop_at_blue_link = 1, false
elseif text == "*" then
max_depth, stop_at_blue_link = false, true
elseif text:match("^:[^*]+%*$") then
-- Stop at a specific language OR first bluelink after it, e.g., ":ota*"
-- If the target language is a redlink, continue to the first bluelink
local lang_code = text:match("^:([^*]+)%*$")
if lang_code and lang_code ~= "" then
local lang_obj = Util.get_lang(lang_code, true)
if lang_obj then
stop_at_lang_or_bluelink = lang_code
else
Util.add_warning('Invalid language code "' .. lang_code .. '" in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false
end
else
Util.add_warning('Empty language code in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false
end
elseif text:sub(1, 1) == ":" then
-- Stop at a specific language, e.g., ":ar" stops at first Arabic term
local lang_code = text:sub(2)
if lang_code ~= "" then
-- Validate the language code
local lang_obj = Util.get_lang(lang_code, true)
if lang_obj then
stop_at_lang = lang_code
else
Util.add_warning('Invalid language code "' .. lang_code .. '" in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false -- default to ++
end
else
Util.add_warning('Empty language code in text parameter. Showing full chain instead.')
max_depth, stop_at_blue_link = false, false -- default to ++
end
else
local num = tonumber(text)
if num and num >= 1 then
max_depth, stop_at_blue_link = num, false
else
error('Invalid text value "' ..
text .. '". Valid values are: "++" (full chain), "+" (first step only), "*" (until first blue link), a number (max steps), ":lang" (stop at language), or ":lang*" (stop at language or first bluelink if redlink)')
end
end
local text_output, text_render_meta = M.text.render({
data_tree = ety_data_tree,
format_term_func = Util.format_term,
lang_matches_stop_code = Util.lang_matches_stop_code,
max_depth = max_depth,
stop_at_blue_link = stop_at_blue_link,
curr_page = page_data.pagename,
nodot = args.nodot,
dot = args.dot,
stop_at_lang = stop_at_lang,
stop_at_lang_or_bluelink = stop_at_lang_or_bluelink,
})
table.insert(output, text_output)
if stop_at_lang and text_render_meta and not text_render_meta.stop_lang_reached then
M.tracking.track_text_stop_lang_missing(lang, stop_at_lang)
text_stop_lang_missing = stop_at_lang
end
end
if rfe then
table.insert(output, Util.expand_request_template(frame, "rfe", rfe, lang:getCode()))
end
if etystub then
table.insert(output, Util.expand_request_template(frame, "etystub", etystub, lang:getCode()))
end
if is_nonlemma then
table.insert(output, " " .. frame:expandTemplate({
title = "nonlemma",
args = {},
}))
end
local categories = {}
if Util.is_content_page() then
M.tracking.track_tree_metrics({
max_depth_reached = __state.max_depth_reached,
total_nodes = __state.total_nodes,
language_count = __state.language_count,
lang = lang,
})
categories = M.categories.build({
data_tree = ety_data_tree,
page_lang = lang,
available_etymon_ids = __state.available_etymon_ids,
senseid_parent_etymon = __state.senseid_parent_etymon,
get_norm_lang_func = Util.get_norm_lang,
lang_exc = lang_exc,
suppress_categories = lang_exc and lang_exc.suppress_categories,
nocat = args.nocat,
tree = tree,
text = text,
exnihilo = args.exnihilo,
toplevel_has_inline_etymology = __state.toplevel_has_inline_etymology,
toplevel_redundant_etymology = __state.toplevel_redundant_etymology,
toplevel_idless_etymon = __state.toplevel_idless_etymon,
has_mismatched_id = __state.has_mismatched_id,
linked_page_multiple_etymons_idless = __state.linked_page_multiple_etymons_idless,
linked_page_partial_etymology_sections = __state.linked_page_partial_etymology_sections,
text_stop_lang_missing = text_stop_lang_missing,
})
M.tracking.track_keywords(__state.toplevel_keyword_stats, lang)
M.tracking.track_page_id(lang, id)
M.tracking.track_ids(__state.id_stats, lang)
end
if #categories > 0 then
table.insert(output, M.categories.format(categories, lang))
end
if __state.warnings then
for i, warning in ipairs(__state.warnings) do
table.insert(output, (i == 1 and "\n" or "") .. warning .. "\n")
end
end
return table.concat(output)
end
return export
t2bhoc32es00qgf8b14srh30fkwyrte
မဝ်ဂျူ:etymon/styles.css
828
116285
397256
379474
2026-06-20T17:49:01Z
咽頭べさ
33
397256
sanitized-css
text/css
/* Main container */
.etytree {
width: max-content;
max-width: 100%;
overflow: hidden;
box-sizing: border-box;
}
.etytree .NavHead {
background: var(--wikt-palette-lightergrey);
}
.etytree .NavHead > div {
width: 25em;
}
.etytree .NavContent {
overflow: auto;
}
.etytree-body {
display: flex;
flex-direction: column;
align-items: center;
padding: 0.5em;
margin: auto;
width: fit-content;
}
.etytree-branch-group {
display: flex;
column-gap: 0.5em;
align-items: end;
position: relative;
}
.etytree-branch {
display: flex;
flex-direction: column;
align-items: center;
}
/* Term blocks */
.etytree-block {
position: relative;
padding: 5px 10px;
border: 1px solid var(--wikt-palette-lightgrey);
border-radius: 4px;
background: var(--wikt-palette-beige);
text-align: center;
}
/* Termless keyword blocks (invisible wrapper for positioning) */
.etytree-termless-block {
height: 0 !important;
padding: 0 !important;
border: none !important;
background: transparent !important;
margin: 0 !important;
overflow: visible;
}
.etytree-block.etytree-duplicate {
border: 1px dashed var(--wikt-palette-grey);
}
.etytree-term {
display: inline-block;
}
/* Vertical connectors */
.etytree-connector-vertical,
.etytree-connector-vertical-short {
border-right: 2px solid var(--wikt-palette-grey);
position: relative;
transform: translateX(1px);
}
.etytree-connector-vertical { height: 20px; }
.etytree-connector-vertical-short { height: 10px; }
.etytree-connector-dotted {
border-left: 2px dotted var(--wikt-palette-grey);
height: 20px;
display: block;
margin-left: 50%;
}
/* Branch connectors */
.etytree-branch-left,
.etytree-branch-right {
height: 10px;
width: calc(50% + 0.25em);
border-bottom: 2px solid var(--wikt-palette-grey);
}
.etytree-branch-left {
border-left: 2px solid var(--wikt-palette-grey);
border-bottom-left-radius: 4px;
transform: translateX(50%);
}
.etytree-branch-right {
border-right: 2px solid var(--wikt-palette-grey);
border-bottom-right-radius: 4px;
transform: translateX(-50%);
}
.etytree-branch-mid {
border-bottom: 2px solid var(--wikt-palette-grey);
width: calc(100% + 0.5em);
}
/* Duplicate connector (L-shaped with arrow) */
.etytree-duplicate-connector {
display: flex;
justify-content: center;
height: 20px;
}
.etytree-duplicate-connector > div {
position: relative;
width: 60px;
height: 100%;
}
.etytree-duplicate-connector .etytree-dup-right {
position: absolute;
right: 0;
top: 50%;
bottom: 0;
border-left: 2px dotted var(--wikt-palette-grey);
}
.etytree-duplicate-connector .etytree-dup-horiz {
position: absolute;
left: 0;
right: 0;
top: 50%;
border-top: 2px dotted var(--wikt-palette-grey);
}
.etytree-duplicate-connector .etytree-dup-left {
position: absolute;
left: 0;
top: 0;
bottom: 50%;
border-left: 2px dotted var(--wikt-palette-grey);
}
.etytree-duplicate-connector .etytree-dup-arrow {
position: absolute;
left: -5px;
top: -5px;
font-size: 10px;
color: var(--wikt-palette-grey);
}
/* Label containers */
.etytree-label-container {
z-index: 1;
position: absolute;
transform: translate(-50%);
top: calc(100% + 5px);
left: 50%;
line-height: 10px;
overflow: visible;
}
.etytree-group-label {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 2;
height: 10px;
line-height: 10px;
}
/* Labels */
.etytree-label abbr {
font-size: 12px;
font-style: italic;
color: var(--wikt-palette-black);
background: var(--wikt-palette-cyan);
border-radius: 2px;
text-decoration: none;
}
/* Uncertainty marker */
.etytree-unc {
font-size: 10px;
font-weight: bold;
padding: 1px 2px;
background: var(--wikt-palette-pink);
border-radius: 2px;
text-decoration: none;
}
.etytree-label + .etytree-unc {
position: absolute;
left: calc(100% + 3px);
}
/* Final marker (for termless keywords) */
.etytree-final {
font-size: 10px;
font-weight: bold;
padding: 1px 2px;
background: var(--wikt-palette-grey) !important;
color: var(--wikt-palette-white) !important;
border-radius: 2px;
text-decoration: none;
display: inline-block;
line-height: 1;
}
.etytree-label-container .etytree-final {
position: absolute;
left: 50%;
top: -12px;
transform: translateX(-50%);
z-index: 3;
margin-left: 0;
}
aehq4sw2oq2ax3mx1z3wi8t42l828gq
မဝ်ဂျူ:grc-utilities/data/doc
828
213222
397309
293165
2026-06-21T10:07:18Z
咽頭べさ
33
397309
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူဒေတာဂရေတ်တြေံဂမၠိုၚ်|utilities]]
</includeonly>
m7enkg7fafwrb4adb794zxu3r3cwyyy
ကဏ္ဍ:မဝ်ဂျူဒေတာဂရေတ်တြေံဂမၠိုၚ်
14
213223
397294
293166
2026-06-21T08:49:41Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ကဏ္ဍ:မဝ်ဂျူစရၚ်ဘာသာဂရေတ်တြေံဂမၠိုၚ်]] ဇရေင် [[ကဏ္ဍ:မဝ်ဂျူဒေတာဂရေတ်တြေံဂမၠိုၚ်]] သီုကဵု ဟွံဂွံ ဂိုင်စွံလဝ် မကလေင်ပညုင်
293166
wikitext
text/x-wiki
[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်|စ]][[ကဏ္ဍ:မဝ်ဂျူစရၚ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
7srki5oe21urxil8gbf97hx5k5g1uqk
ထာမ်ပလိက်:ety/documentation
10
282288
397254
372240
2026-06-20T17:42:22Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:etymon/documentation]] ဇရေင် [[ထာမ်ပလိက်:ety/documentation]]
372240
wikitext
text/x-wiki
{{documentation subpage}}
{{uses lua|etymon|etymon/tree|etymon/text|etymon/categories}}
{{uses templatestyles|Module:etymon/styles.css}}
This template may be used in Wiktionary entries to indicate a term's immediate ancestor. Note that generally, an "etymon" can refer to any kind of etymological ancestor, but on this page, "etymon" will be used specifically for an immediate ancestor. For example, the etymon of {{m+|en|nexus}} is {{m+|la|nexus}}, and the etymon of {{m+|la|nexus}} is {{m+|la|nectō}}. Terms can have multiple etymons, so the etymons of {{m+|en|toothbrush}} are both {{m|en|tooth}} and {{m|en|brush}}. Even if the etymology of a term is completely unknown, this template may still be useful.
'''Current features:''' automatic categorization, tree generation, text generation (experimental), reference support.
===Usage===
Suppose that the etymon of {{m+|en|pay}} is set to {{m+|enm|payen}}, and the etymon of ''payen'' is set to {{m+|fro|paiier}}. The template is then able to intelligently connect ''pay'' and ''paiier'', even though they are two steps apart. The template thus reduces duplication across entries by making it unnecessary to manually specify that ''pay'' and ''paiier'' are connected.
When there are multiple etymologies for the same term (homographs), etymology IDs must be specified in the etymon parameters to distinguish between them. Otherwise, there is ambiguity: when we write ''pay'' is from ''paiier'', we really mean ''pay'' in the sense "to give money", not "to cover the bottom of a vessel with tar or pitch" (which has a completely different origin). The only way to ensure that the template is able to traverse these etymological chains without getting confused is to ensure that both senses of ''pay'' are given unique IDs which allow them to be distinguished. This mirrors the practice of the ''OED'', which identifies these two ''pay''s as [https://doi.org/10.1093/OED/1139292520 1139292520] and [https://doi.org/10.1093/OED/4272270366 4272270366], respectively. However, unlike in the ''OED'', the identifier should be a word or short phrase which summarizes the definition of the term rather than a meaningless string of numbers. In the case of ''pay'', the two IDs might be <code>give money</code> and <code>smear</code>.
For terms with only one etymology, no ID is required in the etymon parameters and the template will work with simple etymons like <code>enm:payen</code> or <code>fro:paiier</code>. However, the template's {{para|id}} parameter is always required to identify the current entry's etymology section.
===Parameters===
The template takes the following parameters:
; {{para|1|req=1}}
: The language code of the current entry.
; {{para|id|req=1}}
: The etymology ID. This parameter also creates an anchor to the current section. For example, if the template at {{m+|en|father|id=male parent}} is {{tl|1=etymon|2=en|3=id=male parent}}, this etymology section is directly linked to by [[father#English: male parent]]. The ID must have at least two characters and must not be the same as the page title.
; {{para|title}}
: This parameter manually overrides the current page title. For example, if an etymology tree is created at {{m+|la|pōnō}} (located at [[pono]]) it is necessary to specify {{para|title|pōnō}} to ensure that the macrons are displayed.
; {{para|pos}}
: Indicates the part of speech of the current entry, which allows descendants to intelligently categorize themselves. Current allowed values are: <code>prefix</code>, <code>suffix</code>, <code>interfix</code>, <code>infix</code>, <code>root</code>.
; {{para|exnihilo}}
: If set to anything, adds the entry to the category <code>[[:Category:Terms coined ex nihilo by language|<language> terms coined ex nihilo]]</code>.
; {{para|tree}}
: If set to anything, displays an etymology tree.
; {{para|text}} ['''EXPERIMENTAL''']
: If set to anything, displays some text describing the etymology. The text modes are: <code>+</code> (single step), <code>++</code> (all steps), and <code>*</code> (to the nearest blue link).
; {{para|2}}, {{para|3}}, ...
: These are the etymon parameters. Each etymon parameter can be either an ''etymon'' or a ''derivation keyword''. There can be any number of etymon parameters.
====Etymons====
Etymons must be written using the following format: <code>languagecode:term<id:identifier><ref:reference></code>. For example: <code>en:pay<id:give money></code> represents {{m+|en|pay}} (etymology 1). As a shortcut, it is possible to omit the language code (i.e., just writing <code>pay<id:give money></code>). In this case, the template will assume that the language is the same as the one set in {{para|1}}. Note that if a given word lacks a page entry, the ID <code>?</code> may be passed in to avoid throwing an invalid ID error.
The ID is not mandatory - simple etymons can be written as just <code>languagecode:term</code> (e.g., <code>en:father</code>) or <code>term</code> (e.g., <code>father</code> when the language matches parameter 1). However, if there are multiple etymologies for the same term, an ID must be specified to distinguish between them.
Additional inline modifiers can be used:
* <code><id:identifier></code> - specifies the etymology ID
* <code><t:gloss></code> - provides gloss
* <code><tr:transliteration></code> - provides transliteration
* <code><ts:transcription></code> - provides transcription
* <code><alt:alternative display></code> - alternative display text
* <code><ety:inline etymology></code> - inline etymology for redlinks
* <code><unc></code> - When set (i.e. <code><unc></code>), marks the corresponding step or element as uncertain. Note that discredited, dubious, or speculative etymologies should not be added to the template at all
* <code><ref:reference text></code> - adds references (see References section)
====Derivation keywords====
Each derivation keyword applies to all the etymons that follow it. Derivation keywords must be prefixed with a colon (:). A derivation keyword is reset by another derivation keyword. For example, <code>|:inh|etymon1|etymon2|:bor|etymon3|etymon4</code> means that a term is inherited from both etymon1 and etymon2 and also borrowed from both etymon3 and etymon4.
* ''':from''': (default) unspecified derivation type within a language. Corresponds with {{tl|from}}, as well as a wide variety of miscellaneous derivations including {{tl|clipping}}, {{tl|deverbal}}, {{tl|back-formation}}, and others.
* ''':der''': short for "derived". Used when a term is borrowed from another language, but may have been altered in some way. Corresponds with {{tl|derived}}.
* ''':bor''': short for "borrowed". Used when a term is borrowed from another language directly. Corresponds with {{tl|borrowed}}.
* ''':lbor''': short for "learned borrowing". Used when a term is borrowed from another language directly, but done intentionally rather than through normal language contact. Correponds to {{tl|learned borrowing}}.
* ''':slbor''': short for "semi-learned borrowing". Used for a learned borrowing which is reshaped somewhat. Corresponds with {{tl|semi-learned borrowing}}.
* ''':obor''': short for "orthographic borrowing". Used for {{lg|orthographic borrowing|orthographic borrowings}}. Corresponds with {{tl|orthographic borrowing}}.
* ''':ubor''': short for "unadapted borrowing". Used for direct borrowings that retain original orthography. Corresponds with {{tl|unadapted borrowing}}.
* ''':inh''': short for "inherited". Used when a term comes directly from the parent language unchanged. Corresponds with {{tl|inherited}}.
* ''':calque''': used for {{lg|calque|calques}}. Corresponds with {{tl|calque}}.
* ''':sl''': used for {{lg|semantic loan|semantic loans}}. Corresponds with {{tl|semantic loan}}.
* ''':af''': short for "affix". Used for compounds, affixation, and any other template where a "+" is involved. The keywords :af and :afeq are unique in that the order matters: <code>|:af|etymon1|etymon2</code> means etymon1 + etymon2, while <code>|:af|etymon2|etymon1</code> means etymon2 + etymon1, which would be an entirely different word. Corresponds with {{tl|affix}}, {{tl|compound}}, and others.
* ''':blend''': used for {{lg|blend|blends}}. Corresponds with {{tl|blend}}.
* ''':bf''': short for "back-formation". Used for {{lg|back-formation|back-formations}}. Corresponds with {{tl|back-formation}}.
* ''':translit''': short for "transliteration". Used when a term is transliterated from another script. Corresponds with {{tl|transliteration}}.
* ''':vrd''': short for "vṛddhi derivative". Used for Sanskrit vṛddhi derivatives.
* ''':aphetic''': used for {{lg|aphesis|aphetic forms}}. Corresponds with {{tl|aphetic form}}.
* ''':afeq''': short for "equivalent affix". For example, {{m+|en|childhood}} is from {{m+|enm|childhode}}, but is equivalent to {{af|en|child|-hood}}. Any etymons associated with this parameter are ignored entirely, besides categorization. Corresponds with {{tl|affix}}, {{tl|compound}}, and others.
* ''':influence''': used when a term is influenced in some way by another. For example, the modern meaning of {{m+|en|discomfit}} is influenced by the unrelated word {{m|en|discomfort}}. This does not correspond with any existing template.
Using a keyword not on this list will produce an error.
====References====
References can be added to etymons using inline modifiers with the syntax <code><ref:reference text></code>. Multiple references can be separated by <code> !!! </code> (with spaces around the exclamation marks). References support the same syntax as other Wiktionary reference templates, including named references and groups (see [[Module:references]]). References are only displayed when {{para|text}} is set and only on the same entry they are defined, not on any descendants.
Examples:
* <code>la:verbum<ref:{{†temp|R:L&S}}></code> - single reference
** Equivalent to <code><nowiki><ref>{{R:L&S}}</ref></nowiki></code>
* <code>la:verbum<ref:{{†temp|R:L&S}}<<name:LS>> !!! {{†temp|R:Gaffiot}}></code> - multiple references with naming
** Equivalent to <code><nowiki><ref name="LS">{{R:L&S}}</ref><ref>{{R:Gaffiot}}</ref></nowiki></code>
* <code>la:verbum<ref:<<name:LS>>></code> - reference to previously named reference
** Equivalent to <code><nowiki><ref name="LS"/></nowiki></code>
* <code>la:verbum<ref:{{†temp|R:L&S}}<<name:LS>><<group:etymology>>></code> - named reference with group
** Equivalent to <code><nowiki><ref name="LS" group="etymology">{{R:L&S}}</ref></nowiki></code>
====Trees====
If the parameter {{para|tree|1}} is set, an etymology tree is inserted.
Per an April 2024 vote, each language community decides when it is appropriate to show a tree on a particular entry.<ref>[[Wiktionary:Votes/2024-04/Allowing etymology trees on entries]]</ref> Additionally, trees should not be displayed for clear open compounds like {{m|en|United States of America}}.<ref>{{section link|Wiktionary:Beer parlour/2024/June#Use of etymology trees made with Template:etymon in the entries for multi-word terms}}</ref>
===Examples===
<code>{{temp|etymon|en|id=male parent|:inh|enm:fader<id:father>}}</code> (on {{m+|en|father|id=male parent}})
This means: ''father'' is inherited from Middle English ''fader''.
<code>{{temp|etymon|ine-pro|id=father|:af|*peh₂-<id:protect><unc>|*-tḗr<id:agent noun><unc>}}</code> (on {{m+|ine-pro|*ph₂tḗr|id=father}})
This means: ''*ph₂tḗr'' might come from ''*peh₂'' + ''*-tḗr''. In this case, the etymons are associated with the derivation keyword ":af". Note that since the language is not specified for either etymon, the template assumes that the two etymons are <code>ine-pro</code> (Proto-Indo-European).
<code>{{temp|etymon|pl|id=floor|podłożyć<id:put>}}</code> (on {{m+|pl|podłoga|id=floor}})
This means: ''podłoga'' comes from Polish ''podłożyć''. Currently, there is no keyword specifically designating a deverbal. This may be changed in the future.
<code>{{temp|etymon|en|id=bundle of flowers|:bor|fr:bouquet<id:bundle><ref:<nowiki>{{R:TLFi}}</nowiki>>|text=1}}</code>
This means: ''bouquet'' is borrowed from French ''bouquet'', with a reference to the TLFi dictionary. The reference will appear after the period in the generated text: "Borrowed from French ''bouquet''.<sup>[1]</sup>"
See [[Template:etymon/testcases]] for test cases and more examples of use.
===Categorization===
The template generates various categories depending on how it is used, including the ones within:
* [[:Category:Entries referencing etymons with invalid IDs by language]]
* [[:Category:Entries with etymology trees by language]]
* [[:Category:Entries with etymology texts by language]]
* [[:Category:Pages with inline etymon for redlinks]]
* [[:Category:Pages with redundant inline etymon]]
* [[:Category:Pages using etymon with no ID]]
as well as various standard etymology categories (e.g. [[:Category:English terms borrowed back into English]]) depending on what entries exist in the tree.
===References===
{{reflist}}
----
===TemplateData===
{{TemplateData header}}
<templatedata>
{
"description": "This template may be used indicate a term's immediate ancestor(s).",
"params": {
"1": {
"label": "Language",
"description": "The language of the current entry.",
"type": "string",
"required": true,
"suggested": true,
"example": "en"
},
"2": {
"label": "Etymon parameter #1",
"description": "The first etymon parameter. Typically for derivation keyword.",
"type": "string",
"example": ":der, alternatively - enm:fader<id:father>"
},
"3": {
"label": "Etymon parameter #2",
"description": "The second etymon parameter.",
"type": "string"
},
"4": {
"label": "Etymon parameter #3",
"description": "The third etymon parameter.",
"type": "string"
},
"5": {
"label": "Etymon parameter #4",
"description": "The fourth etymon parameter.",
"type": "string"
},
"6": {
"label": "Etymon parameter #5",
"description": "The fifth etymon parameter.",
"type": "string"
},
"7": {
"label": "Etymon parameter #6",
"description": "The sixth etymon parameter.",
"type": "string"
},
"8": {
"label": "Etymon parameter #7",
"description": "The seventh etymon parameter.",
"type": "string"
},
"9": {
"label": "Etymon parameter #8",
"description": "The eighth etymon parameter.",
"type": "string"
},
"id": {
"label": "Etymology ID",
"description": "The ID of the current etymology section.",
"type": "string",
"required": true,
"suggested": true,
"example": "male parent"
},
"title": {
"label": "Title",
"description": "The title of the current entry (if different from the page title)",
"type": "string",
"example": "father"
},
"tree": {
"label": "Tree",
"description": "Set this to \"1\" to display a tree.",
"type": "string",
"example": "1"
},
"text": {
"label": "Text",
"description": "Automatically generates some text (experimental, see documentation).",
"type": "string",
"example": "1"
}
},
"paramOrder": [
"1",
"id",
"title",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"tree",
"text"
],
"format": "inline"
}
</templatedata>
<includeonly>
[[ကဏ္ဍ:ထာမ်ပလိက်နိရုတ်ဂမၠိုၚ်]]
</includeonly>
33nvwl1y7xlpa8y5c22jbs6asx9i5vu
abicio
0
296076
397251
397220
2026-06-20T17:40:54Z
咽頭べさ
33
397251
wikitext
text/x-wiki
==လပ်တေန်==
===ပွံၚ်နဲတၞဟ်===
* {{alt|la|abiiciō|abjiciō}}
===နိရုတ်===
{{ety|la|title=abiciō|:af|ab-<t:from, down or away from>|iaciō<t:throw, hurl>|text=+|tree=1}}
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abiciō|eccl=0}}
* {{la-IPA|abjiciō}}
===ကြိယာ===
{{la-verb|3|abiciō|abiēc|abiect}}
# သကဵုကၠဟ် ဝါ ထဝေၚ်ကၠဟ်ဖျေံထောံ ဝါ ဒၞာဲဇမ္ၚောဲတေံ၊ ထဝေၚ် ဝါ ကၠဟ်ထောံဇမ္ၚောဲမ္ၚောဲ ဝါ လ္ပာ်သ္ကဲ။
# သကဵုကေတ်တိုန်၊ ဗိုတ်ကၠဟ်ထောံ၊ ဗလးထောံဇကုသၟး၊ ထဝေၚ်ထောံ။
# သကဵုပ္ဍဵုဒလိုက်ထောံ၊ ဖျေံထောံကဆံၚ်၊ တရဳကၠေံ၊ ဖျဝ်ဖျေံ၊ ဒဗိုတ်ဖျေံထောံ။
# သကဵုထပိုတ်ထောံ၊ ဇၞးကေတ်။
# သကဵုသွံၚုဟ်မးတန်တန်၊ မဖျေံထောံၚုဟ်ဂၠိုၚ်လောန်အာ၊ ပၠေၚ်ထောံ၊ ဖျဝ်ဖျေံထောံကဆံၚ်၊ အထေၚ်ဍောတ်သွတ်။
# သကဵုဇကုမကၠဟ်ထောံလ္တူဆေၚ်စပ်ကဵုဖျေံသ္ဇိုၚ်၊ ဇကုမကၠဟ်ထောံဇမ္ၚောဲမ္ၚောဲ၊ မဖျေံထောံကဆံၚ်ဇကု၊ မကေတ်တိုန်အပ္ဍဲဗလးကၠဟ်ထောံပရေၚ်တၚ်ရန်တၟံ။
# သကဵုဗလးတၟာတ်ထောံအမှု၊ ထပိုတ်၊ လှောဝ်ဒဗိုတ်၊ လဗိုတ်၊ ကၠဟ်။
====သမ္ဗန္ဓ====
{{la-conj|3|abiciō|abiēc|abiect}}
===မဒုၚ်လွဳစ===
* {{desc|en|abject}}
* {{desc|it|abiettare}}
* {{desc|pt|abjetar}}
* {{desc|es|abyectar}}
agrt9v0hkcqvd9elo4nexkaubwks6dn
abiicio
0
296089
397239
2026-06-20T16:41:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA|abiiciō}} ===ကြိယာ=== {{head|la|ကြိယာ}} # {{alternative form of|la|abiciō}}"
397239
wikitext
text/x-wiki
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abiiciō}}
===ကြိယာ===
{{head|la|ကြိယာ}}
# {{alternative form of|la|abiciō}}
0qs57mleahq0zxgflw8ty1rvjek5cea
abiectum
0
296090
397240
2026-06-20T16:45:45Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာ=== {{head|la|participle form}} # {{inflection of|la|abiectus||nom|n|s}}"
397240
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာ===
{{head|la|participle form}}
# {{inflection of|la|abiectus||nom|n|s}}
lrxn8vxjfvzak5oo2e38shix7jiiono
abiectus
0
296091
397241
2026-06-20T17:11:51Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ပွံၚ်နဲတၞဟ်=== * {{alter|la|abjectus}} ===ကြိယာ=== {{la-part|abiectus|comp=abiectior|sup=abiectissimus|adv=abiectē}} # ကၠဟ်ဂမၠိုၚ် ဝါ ဒဗိုတ်လ္ပာ်သ္ကဲ၊ စှ်ေ ဝါ ဇမ္ၚောဲ၊ ပွမၞုံဒှ်လဗိုတ်ထောံဇမ္ၚောဲမ္ၚောဲ။ #..."
397241
wikitext
text/x-wiki
==လပ်တေန်==
===ပွံၚ်နဲတၞဟ်===
* {{alter|la|abjectus}}
===ကြိယာ===
{{la-part|abiectus|comp=abiectior|sup=abiectissimus|adv=abiectē}}
# ကၠဟ်ဂမၠိုၚ် ဝါ ဒဗိုတ်လ္ပာ်သ္ကဲ၊ စှ်ေ ဝါ ဇမ္ၚောဲ၊ ပွမၞုံဒှ်လဗိုတ်ထောံဇမ္ၚောဲမ္ၚောဲ။
# မကေတ်တိုန်၊ လဗိုတ်ကၠဟ်ထောံ၊ ဖျေံထောံလဝ်ကဆံၚ်၊ ပွမၞုံဒှ်ပရေၚ်ထွံကၠေံထောံလဝ်။
# ပရေၚ်ထပိုတ်ထောံလဝ်၊ မၞုံဒှ်ပရေၚ်ထပိုတ်ထောံလဝ်။
# ဖျဝ်၊ မသဝ်ပ္ဍဲကဆံၚ်၊ ထ္ၜုဲထောံလဝ်၊ မဂၠုက်ဗွဲအသၟဝ်။
#: {{syn|la|modicus|dēmissus}}
# အယုတ်၊ မကၠိပပ်။
====လဟုတ်စှ်ေ====
{{la-adecl|abiectus}}
===မဒုၚ်လွဳစ===
* {{desc|it|abietto|abbietto}}
* {{desc|fr|abject}}
** {{desc|nb|abjekt|bor=1}}
* {{desc|nb|abjekt|bor=1}}
4gn4lmkmynh8jv873qn4gqqwfgjb95u
abiecta
0
296092
397242
2026-06-20T17:13:18Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာ=== {{head|la|participle form}} # {{inflection of|la|abiectus||nom//voc|f|s|;|nom//acc//nom|n|p}} ===ကြိယာ=== {{head|la|participle form|head=abiectā}} # {{inflection of|la|abiectus||abl|f|s}}"
397242
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာ===
{{head|la|participle form}}
# {{inflection of|la|abiectus||nom//voc|f|s|;|nom//acc//nom|n|p}}
===ကြိယာ===
{{head|la|participle form|head=abiectā}}
# {{inflection of|la|abiectus||abl|f|s}}
il98uujn2dj2lggtn19dmtx6fhjhd44
abiectior
0
296093
397243
2026-06-20T17:13:58Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာ=== {{head|la|participle form}} # {{inflection of|la|abiectus||nom//voc|f|s|;|nom//acc//nom|n|p}}"
397243
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာ===
{{head|la|participle form}}
# {{inflection of|la|abiectus||nom//voc|f|s|;|nom//acc//nom|n|p}}
h02bx961unwm4qzonhzk4t1y5bk5h1o
abiectissimus
0
296094
397244
2026-06-20T17:15:32Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA}} ===ကြိယာ=== {{head|la|participle form}} # {{superlative of|la|abiectus}}"
397244
wikitext
text/x-wiki
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA}}
===ကြိယာ===
{{head|la|participle form}}
# {{superlative of|la|abiectus}}
45d4bh1az98341jt96lttb7m4ytdczb
397245
397244
2026-06-20T17:17:12Z
咽頭べさ
33
397245
wikitext
text/x-wiki
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA}}
===ကြိယာ===
{{head|la|participle form}}
# {{superlative of|la|abiectus}}
====လဟုတ်စှ်ေ====
{{la-adecl|abiectissimus}}
nim684hi8xce0mh5w7g3d5dq709rz6v
abiecte
0
296095
397246
2026-06-20T17:25:31Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာဝိသေသန=== {{la-adv|abiectē}} # ပရေၚ်ယုတ်မာ၊ ပရေၚ်စိုတ်ဓာတ်ကဆံၚ်ဍောတ်။ # ပရေၚ်မယျဵုလ္ဂူ၊ ပရေၚ်ကဆံၚ်သဝ်တဴဗွဲ။"
397246
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာဝိသေသန===
{{la-adv|abiectē}}
# ပရေၚ်ယုတ်မာ၊ ပရေၚ်စိုတ်ဓာတ်ကဆံၚ်ဍောတ်။
# ပရေၚ်မယျဵုလ္ဂူ၊ ပရေၚ်ကဆံၚ်သဝ်တဴဗွဲ။
fec6o16fsh3s2q4sogmmidwpqg563tl
abiectius
0
296096
397247
2026-06-20T17:27:02Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာဝိသေသန=== {{la-adv-comp|abiectius}} # {{comparative of|la|abiectē|POS=adverb}}"
397247
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာဝိသေသန===
{{la-adv-comp|abiectius}}
# {{comparative of|la|abiectē|POS=adverb}}
av9q6j1bxsnsuw7dm89xjqmhi0ew84a
abiectissime
0
296097
397248
2026-06-20T17:29:20Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA|abiectissimē}} ===ကြိယာ=== {{head|la|participle form}} # {{inflection of|la|abiectissimus||voc|m|s}} ===ကြိယာဝိသေသန=== {{la-adv-sup|abiectissimē}} # {{superlative of|la|abiectē|POS=adverb}}"
397248
wikitext
text/x-wiki
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abiectissimē}}
===ကြိယာ===
{{head|la|participle form}}
# {{inflection of|la|abiectissimus||voc|m|s}}
===ကြိယာဝိသေသန===
{{la-adv-sup|abiectissimē}}
# {{superlative of|la|abiectē|POS=adverb}}
hd5i0fgam457vrqnf88tpdqbqburqde
abieci
0
296098
397249
2026-06-20T17:36:59Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာ=== {{head|la|verb form|head=abiēcī}} # {{inflection of|la|abiciō||1|s|perf|actv|indc}}"
397249
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာ===
{{head|la|verb form|head=abiēcī}}
# {{inflection of|la|abiciō||1|s|perf|actv|indc}}
t6h3f157pk2uyfzejejtarknxn4qrph
abicere
0
296099
397250
2026-06-20T17:38:21Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ကြိယာ=== {{head|la|verb form}} # {{inflection of|la|abiciō||pres|actv|inf|;|2|s|pres|pasv|imp//ind}}"
397250
wikitext
text/x-wiki
==လပ်တေန်==
===ကြိယာ===
{{head|la|verb form}}
# {{inflection of|la|abiciō||pres|actv|inf|;|2|s|pres|pasv|imp//ind}}
fma2rpr7a88492cy4j4w7eye8vd6i49
ထာမ်ပလိက်:etymon
10
296100
397253
2026-06-20T17:42:22Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:etymon]] ဇရေင် [[ထာမ်ပလိက်:ety]]
397253
wikitext
text/x-wiki
#REDIRECT [[ထာမ်ပလိက်:ety]]
7ny3i9vt2rqlfelblwuatcj4xvr23ob
ထာမ်ပလိက်:etymon/documentation
10
296101
397255
2026-06-20T17:42:23Z
咽頭べさ
33
咽頭べさ ပြံင်ပဆုဲလဝ် မုက်လိက် [[ထာမ်ပလိက်:etymon/documentation]] ဇရေင် [[ထာမ်ပလိက်:ety/documentation]]
397255
wikitext
text/x-wiki
#REDIRECT [[ထာမ်ပလိက်:ety/documentation]]
19x0q3iwimfoj4ekg05ptabk6qde525
abace
0
296102
397258
2026-06-20T18:08:09Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==အဖှာၚ်== ===ပွံၚ်နဲတၞဟ်=== * {{a|aa|Northern dialects}} {{alter|aa|abicé}} ===ဗွဟ်ရမ္သာၚ်=== * {{aa-IPA|abacé}} ===ကြိယာ=== {{aa-verb}} # သၟူမသ၊ သၟူမသအုဲ။ ====သမ္ဗန္ဓ==== {{aa-conj/II|a|ba|c|bá}} ==လပ်တေန်== ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA|abace}} ===နာမ်==..."
397258
wikitext
text/x-wiki
==အဖှာၚ်==
===ပွံၚ်နဲတၞဟ်===
* {{a|aa|Northern dialects}} {{alter|aa|abicé}}
===ဗွဟ်ရမ္သာၚ်===
* {{aa-IPA|abacé}}
===ကြိယာ===
{{aa-verb}}
# သၟူမသ၊ သၟူမသအုဲ။
====သမ္ဗန္ဓ====
{{aa-conj/II|a|ba|c|bá}}
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abace}}
===နာမ်===
{{head|la|noun form|g=m}}
# {{inflection of|la|abacus||voc|s}}
===နာမ်===
{{head|la|noun form|g=m}}
# {{inflection of|la|abax||abl|s}}
==အၚ်္ဂလိက်တြေံ==
===ဗွဟ်ရမ္သာၚ်===
* {{ang-IPA|ābace|pos=verb}}
===ကြိယာ===
{{head|ang|verb form|head=ābace}}
# {{infl of|ang|ābacan||1|s|pres|ind|;|s|pres|sub}}
==ပဝ်လာန်==
===ဗွဟ်ရမ္သာၚ်===
{{pl-pr|a=LL-Q809 (pol)-Olaf-abace.wav}}
===နာမ်===
{{head|pl|noun form|g=f}}
# {{inflection of|pl|abaka||dat//loc|s}}
==ရဝ်မေနဳယျာ==
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|ro|/aˈbat͡ʃe/}}
* {{rhymes|ro|at͡ʃe|s=3}}
* {{hyph|ro|a|bá|ce}}
===နာမ်===
{{head|ro|noun form|g=n-p}}
# {{noun form of|ro|abac||indef|nom//acc//gen//dat|p}}
===နာမ်===
{{head|ro|noun form|g=f-p}}
# {{noun form of|ro|abacă||indef|nom//acc|p|;|indef|gen//dat|s//p|}}
h922b0fkp1qnci019bqd76p0roiw8h5
ကဏ္ဍ:ကာရန်:ရဝ်မေနဳယျာ/at͡ʃe
14
296103
397259
2026-06-20T18:26:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာရဝ်မေနဳယျာ|ရဝ်မေနဳယျာ]] » :..."
397259
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာရဝ်မေနဳယျာ|ရဝ်မေနဳယျာ]] » [[:ကဏ္ဍ:ကာရန်:ရဝ်မေနဳယျာ|ကာရန်ဂမၠိုၚ်]] » -at͡ʃe
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာရဝ်မေနဳယျာ|ရဝ်မေနဳယျာ]]မနွံကာရန် [[ကာရန်:ရဝ်မေနဳယျာ/at͡ʃe|-at͡ʃe]] ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:ရဝ်မေနဳယျာ|at͡ʃe]]
ednvitkls3x25obcbgj8qprpprfxxy7
ကာရန်:ရဝ်မေနဳယျာ/at͡ʃe
106
296104
397260
2026-06-20T18:30:20Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{rhymes nav|ro|a|t͡ʃe}} ==ကာရန်ဂမၠိုၚ်== ===ဝဏ္ဏပိ=== <!--Note: words in this section must be stressed on the PENULTIMATE syllable.--> {{rhyme-top}} * {{l|ro|abace}} {{rhyme-bottom}}"
397260
wikitext
text/x-wiki
{{rhymes nav|ro|a|t͡ʃe}}
==ကာရန်ဂမၠိုၚ်==
===ဝဏ္ဏပိ===
<!--Note: words in this section must be stressed on the PENULTIMATE syllable.-->
{{rhyme-top}}
* {{l|ro|abace}}
{{rhyme-bottom}}
33gvu2om665d52uf4z8wk38b12q1cba
ကဏ္ဍ:ကာရန်:ပဝ်လာန်/at͡sɛ
14
296105
397261
2026-06-20T18:33:31Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာပဝ်လာန်|ပဝ်လာန်]] » :ကဏ္ဍ:ကာ..."
397261
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာပဝ်လာန်|ပဝ်လာန်]] » [[:ကဏ္ဍ:ကာရန်:ပဝ်လာန်|ကာရန်ဂမၠိုၚ်]] » -at͡sɛ
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာပဝ်လာန်|ပဝ်လာန်]]မနွံကာရန် [[ကာရန်:ပဝ်လာန်/at͡sɛ|-at͡sɛ]] ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:ပဝ်လာန်|at͡sɛ]]
hauu8cwe7p4nnldu6wf4ovuqspiary9
ကာရန်:ပဝ်လာန်/at͡sɛ
106
296106
397262
2026-06-20T18:35:50Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{rhymes nav|pl|a|t͡sɛ}} ==ဗွဟ်ရမ္သာၚ်== *{{IPAchar|/-at͡sɛ/}} ==ကာရန်ဂမၠိုၚ်== ===ဝဏ္ဏမွဲ=== ===ဝဏ္ဏၜါ=== ===ဝဏ္ဏပိ=== ===ဝဏ္ဏပန်=== ===ဝဏ္ဏမသုန်=== ===ဝဏ္ဏတရဴ=== ===ဝဏ္ဏထပှ်=== ===ဝဏ္ဏဒ္စာံ=== ===ဝဏ္ဏဒ္စိတ်=== ===ဝဏ..."
397262
wikitext
text/x-wiki
{{rhymes nav|pl|a|t͡sɛ}}
==ဗွဟ်ရမ္သာၚ်==
*{{IPAchar|/-at͡sɛ/}}
==ကာရန်ဂမၠိုၚ်==
===ဝဏ္ဏမွဲ===
===ဝဏ္ဏၜါ===
===ဝဏ္ဏပိ===
===ဝဏ္ဏပန်===
===ဝဏ္ဏမသုန်===
===ဝဏ္ဏတရဴ===
===ဝဏ္ဏထပှ်===
===ဝဏ္ဏဒ္စာံ===
===ဝဏ္ဏဒ္စိတ်===
===ဝဏ္ဏစှ်===
15swuz2leeb30yupyg4ge62m9trw39s
abax
0
296107
397263
2026-06-20T18:47:25Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|Abax|авах}} =={{=en=}}== ===နိရုတ်=== ဝေါဟာကၠုၚ်နူ {{bor|en|grc|ἄβαξ}} ===နာမ်=== {{en-noun|!}} # မစွံလဝ်ပၞော်ဒၞာဲပရေၚ်မခိုဟ်မၞုံကဵုဒၞာဲဂတဵုဍာ်တိတ်တၟံခေတ်တြေံဂမၠိုၚ်။ ==လပ်တေန်== ===ဗွဟ်ရမ္သ..."
397263
wikitext
text/x-wiki
{{also|Abax|авах}}
=={{=en=}}==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{bor|en|grc|ἄβαξ}}
===နာမ်===
{{en-noun|!}}
# မစွံလဝ်ပၞော်ဒၞာဲပရေၚ်မခိုဟ်မၞုံကဵုဒၞာဲဂတဵုဍာ်တိတ်တၟံခေတ်တြေံဂမၠိုၚ်။
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abax}}
===နာမ်===
{{la-noun|abax<3>|g=m}}
# {{alternative form of|la|abacus}}
====လဟုတ်စှ်ေ====
{{la-ndecl|abax<3>}}
r7dbgx62dh7ztjmmqenwpoghzsm19kk
abacis
0
296108
397264
2026-06-20T18:51:56Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==လပ်တေန်== ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA|abacīs}} ===နာမ်=== {{head|la|noun form|head=abacīs|g=m}} # {{inflection of|la|abacus||dat//abl|p}} ===ဗွဟ်ရမ္သာၚ်=== * {{la-IPA|abacis}} ===နာမ်=== {{head|la|noun form|g=m}} # {{inflection of|la|abax||gen|s}}"
397264
wikitext
text/x-wiki
==လပ်တေန်==
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abacīs}}
===နာမ်===
{{head|la|noun form|head=abacīs|g=m}}
# {{inflection of|la|abacus||dat//abl|p}}
===ဗွဟ်ရမ္သာၚ်===
* {{la-IPA|abacis}}
===နာမ်===
{{head|la|noun form|g=m}}
# {{inflection of|la|abax||gen|s}}
2hq8cnkytieqcv94b4fx119cjhzvyed
nominative case
0
296109
397265
2026-06-20T19:03:28Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== {{wikipedia|lang=en}} ===ဗွဟ်ရမ္သာၚ်=== * {{IPA|en|a1=GA|/ˈnɑm(ɪ)nətɪv keɪs/|a2=RP|/ˈnɒm(ɪ)nətɪv keɪs/}} * {{audio|en|LL-Q1860 (eng)-Flame, not lame-nominative case.wav|a=US}} * {{rhymes|en|eɪs|s=5}} ===နာမ်=== {{en-noun}} # ကိစ္စမဒုၚ်ယၟု။ # {{lb|en|grammar}} မဆေၚ်စပ်ကဵုကိစ္စမရပ်စပ်န..."
397265
wikitext
text/x-wiki
=={{=en=}}==
{{wikipedia|lang=en}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|en|a1=GA|/ˈnɑm(ɪ)nətɪv keɪs/|a2=RP|/ˈnɒm(ɪ)nətɪv keɪs/}}
* {{audio|en|LL-Q1860 (eng)-Flame, not lame-nominative case.wav|a=US}}
* {{rhymes|en|eɪs|s=5}}
===နာမ်===
{{en-noun}}
# ကိစ္စမဒုၚ်ယၟု။
# {{lb|en|grammar}} မဆေၚ်စပ်ကဵုကိစ္စမရပ်စပ်နကဵုစၞောန်ထ္ၜးပရေၚ်ဘာသာ—ဝါ စၞး—ဆေၚ်စပ်ကဵုကြိယာမၞုံကဵုတွဵုဒနက်မွဲသာ်။
{{lb|en|obsolete|grammar}} ဆေၚ်စပ်ကဵုပရေၚ်ဘာသာနကဵုကြိယာမွဲသာ်။
9ehw6fz7s52v7m16qttuvrh22u4jbjs
nominative cases
0
296110
397267
2026-06-20T19:11:44Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== ===နာမ်=== {{head|en|noun form}} # {{plural of|en|nominative case}}"
397267
wikitext
text/x-wiki
=={{=en=}}==
===နာမ်===
{{head|en|noun form}}
# {{plural of|en|nominative case}}
4flc1kcshmscbcfw5tix8r3v9u6kwbq
ကဏ္ဍ:ဝေါဟာသဒ္ဒာအၚ်္ဂလိက်ဂမၠိုၚ်
14
296111
397269
2026-06-20T19:13:15Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်]]"
397269
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်]]
cgthbuhht2vx8a42gqbqvafhhdb35kh
ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်/eɪs
14
296112
397270
2026-06-20T19:15:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]] » :ကဏ..."
397270
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]] » [[:ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်|ကာရန်ဂမၠိုၚ်]] » -eɪs
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]]မနွံကာရန် [[ကာရန်:အၚ်္ဂလိက်/eɪs|-eɪs]] ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်|eɪs]]
gnpbiw7cu6iwfw8s4l9vartwoefm82j
ကာရန်:အၚ်္ဂလိက်/eɪs
106
296113
397271
2026-06-20T19:18:07Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{rhymes nav|en|eɪ|s}} ==ဗွဟ်ရမ္သာၚ်== {{enPR|-ās}}, {{IPA|en|/-eɪs/}} ==ကာရန်ဂမၠိုၚ်== ===ဝဏ္ဏမွဲ=== {{rhyme-top}} * {{l|en|ace}} * {{l|en|base}} * {{l|en|bass}} * {{l|en|brace}} * {{l|en|case}} * {{l|en|chase}} * {{l|en|dace}} * {{l|en|dais}} * {{l|en|face}} * {{l|en|grace}} * {{l|en|lace}} * {{l|en|mace}} * {{l|en|Naas}} * {{l|en|pace}} * {{l|en|pl..."
397271
wikitext
text/x-wiki
{{rhymes nav|en|eɪ|s}}
==ဗွဟ်ရမ္သာၚ်==
{{enPR|-ās}}, {{IPA|en|/-eɪs/}}
==ကာရန်ဂမၠိုၚ်==
===ဝဏ္ဏမွဲ===
{{rhyme-top}}
* {{l|en|ace}}
* {{l|en|base}}
* {{l|en|bass}}
* {{l|en|brace}}
* {{l|en|case}}
* {{l|en|chase}}
* {{l|en|dace}}
* {{l|en|dais}}
* {{l|en|face}}
* {{l|en|grace}}
* {{l|en|lace}}
* {{l|en|mace}}
* {{l|en|Naas}}
* {{l|en|pace}}
* {{l|en|place}}
* {{l|en|plaice}}
* {{l|en|race}}
* {{l|en|space}}
* {{l|en|Stace}}
* {{l|en|Thrace}}
* {{l|en|trace}}
* {{l|en|vase}}
{{rhyme-bottom}}
===ဝဏ္ဏၜါ===
<!--Note: words in this section must be stressed on the FINAL syllable.-->
{{rhyme-top}}
* {{l|en|abase}}
* {{l|en|aggrace}}, {{l|en|agrace}}
* {{l|en|apace}}
* {{l|en|belace}}
* {{l|en|debase}}
* {{l|en|deface}}
* {{l|en|discase}}
* {{l|en|disgrace}}
* {{l|en|displace}}
* {{l|en|efface}}
* {{l|en|embase}}, {{l|en|imbase}}
* {{l|en|embrace}}
* {{l|en|emplace}}
* {{l|en|encase}}, {{l|en|incase}}
* {{l|en|enchase}}
* {{l|en|enface}}
* {{l|en|enlace}}, {{l|en|inlace}}
* {{l|en|erase}}
* {{l|en|grimace}}
* {{l|en|homespace}}
* {{l|en|imbase}}<!--same as "embase"-->
* {{l|en|inlace}}<!--same as "enlace"-->
* {{l|en|misgrace}}
* {{l|en|misplace}}
* {{l|en|outpace}}
* {{l|en|outrace}}
* {{l|en|percase}}
* {{l|en|rebrace}}
* {{l|en|reface}}
* {{l|en|replace}}
* {{l|en|retrace}}
* {{l|en|strait-lace}}
* {{l|en|unbrace}}
* {{l|en|uncase}}
* {{l|en|unlace}}
* {{l|en|unplace}}
* {{l|en|untrace}}
{{rhyme-bottom}}
===ဝဏ္ဏပိ===
<!--Note: words in this section must be stressed on the FINAL syllable.-->
{{rhyme-top}}
* {{l|en|happy place}}
* {{l|en|heart of grace}}
* {{l|en|interlace}}
* {{l|en|bouillabaisse}}
{{rhyme-bottom}}
===ဝဏ္ဏပန်===
<!--Note: words in this section must be stressed on the FINAL syllable.-->
{{rhyme-top}}
* [[Havre de Grace]]
{{rhyme-bottom}}
8k50q5l7abps2m0m6qz1xmo48p0zd4u
grammar
0
296114
397272
2026-06-20T19:31:55Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== ===ပွံၚ်နဲတၞဟ်=== * {{alt|en|grammary||archaic}} * {{alt|en|grammer||obsolete}} ===နိရုတ်=== {{root|en|ine-pro|*gerbʰ-}} ဝေါဟာကၠုၚ်နူ {{inh|en|enm|gramere}}၊ နကဵုအဆက်နူ {{der|en|fro|gramaire}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{der|en|la-vul|*grammāria}}၊ နူအဆက်နကဵု {{der|en|la|g..."
397272
wikitext
text/x-wiki
=={{=en=}}==
===ပွံၚ်နဲတၞဟ်===
* {{alt|en|grammary||archaic}}
* {{alt|en|grammer||obsolete}}
===နိရုတ်===
{{root|en|ine-pro|*gerbʰ-}}
ဝေါဟာကၠုၚ်နူ {{inh|en|enm|gramere}}၊ နကဵုအဆက်နူ {{der|en|fro|gramaire}}၊ နကဵုမဆေၚ်စပ်ကဵုနူ {{der|en|la-vul|*grammāria}}၊ နူအဆက်နကဵု {{der|en|la|grammatica}}၊ မဆက်ဆေန်နူ {{der|en|grc|γραμματική}}၊ နူအဆက် {{der|en|ine-pro|*gerbʰ-}}
===ဗွဟ်ရမ္သာၚ်===
* {{IPA|en|/ˈɡɹæm.ə(ɹ)/|a=RP,AU}}
* {{enPR|grăm'ər|a=GA,CA}}, {{IPA|en|/ˈɡɹæm.ɚ/|[ˈɡɹɛəm.ɚ]}}
** {{IPA|en|[ˈɡɹæːm.ɚ]|[ˈɡɹam.ɚ]|a=CA}}
** {{audio|en|en-us-grammar.ogg|a=California}}
* {{rhymes|en|æmə(ɹ)|s=2}}
* {{hyphenation|en|gram|mar}}
===နာမ်===
{{en-noun|~}}
# သဒ္ဒါ၊ ပြကိုဟ်သဒ္ဒါ၊ ဗျာကရိုန်။
===မဒုၚ်လွဳစ===
* {{desc|sm|kalama|bor=1}}
===ကြိယာ===
{{en-verb}}
# သကဵုပွမထံက်ပၚ်တၚ်မဖျေံဆေၚ်စပ်ကဵုသၞောဝ်နကဵုသဒ္ဒါဂမၠိုၚ်၊ သကဵုရပ်စပ်သဒ္ဒါ။
50o0hbd6ow8o5f1n38i0ou6jfkubsho
grammars
0
296115
397273
2026-06-20T19:34:59Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== ===နာမ်=== {{head|en|noun form}} # {{plural of|en|grammar}} ===ကြိယာ=== {{head|en|verb form}} # {{infl of|en|grammar||s-verb-form}}"
397273
wikitext
text/x-wiki
=={{=en=}}==
===နာမ်===
{{head|en|noun form}}
# {{plural of|en|grammar}}
===ကြိယာ===
{{head|en|verb form}}
# {{infl of|en|grammar||s-verb-form}}
06vap9ccquzbyocvx3ya2vl0op4pgxb
grammaring
0
296116
397274
2026-06-20T19:35:53Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== ===ကြိယာ=== {{head|en|verb form}} # {{infl of|en|grammar||ing-form}}"
397274
wikitext
text/x-wiki
=={{=en=}}==
===ကြိယာ===
{{head|en|verb form}}
# {{infl of|en|grammar||ing-form}}
owofir30a5r6thcgqjza44uwso7jk7c
grammared
0
296117
397275
2026-06-20T19:39:23Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "=={{=en=}}== ====နာမဝိသေသန==== {{en-adj|-}} # ပွမပိုၚ်ပြဳလဝ်ဗီုပြၚ်ချိုတ်ချိုတ်ပၠိုတ်ပၠိုတ်ဆေၚ်စပ်ကဵုသဒ္ဒါ။ ===ကြိယာ=== {{head|en|verb form}} # {{infl of|en|grammar||ed-form}}"
397275
wikitext
text/x-wiki
=={{=en=}}==
====နာမဝိသေသန====
{{en-adj|-}}
# ပွမပိုၚ်ပြဳလဝ်ဗီုပြၚ်ချိုတ်ချိုတ်ပၠိုတ်ပၠိုတ်ဆေၚ်စပ်ကဵုသဒ္ဒါ။
===ကြိယာ===
{{head|en|verb form}}
# {{infl of|en|grammar||ed-form}}
r5qlqwyrcg32n2kvejmcqbi98k0qdeh
ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်/æmə(ɹ)
14
296118
397276
2026-06-20T19:41:19Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]] » :ကဏ..."
397276
wikitext
text/x-wiki
[[:ကဏ္ဍ:ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်|ဒၞာဲလုပ်အဝေါၚ်ကဵုပၟိက်]] » [[:ကဏ္ဍ:အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်|အရေဝ်ဘာသာအိုတ်သီုဂမၠိုၚ်]] » [[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]] » [[:ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်|ကာရန်ဂမၠိုၚ်]] » -æmə(ɹ)
:စရၚ်မဆေၚ်စပ်ကဵုဝေါဟာ[[:ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်|အၚ်္ဂလိက်]]မနွံကာရန် [[ကာရန်:အၚ်္ဂလိက်/æmə(ɹ)|-æmə(ɹ)]] ဂမၠိုၚ်။
[[ကဏ္ဍ:ကာရန်:အၚ်္ဂလိက်|æmə(ɹ)]]
0atb9t8fgwttagepcag34rex8mlgwnh
ကာရန်:အၚ်္ဂလိက်/æmə(ɹ)
106
296119
397277
2026-06-20T19:43:39Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{rhymes nav|en|æ|mə(ɹ)}} ==ဗွဟ်ရမ္သာၚ်== {{enPR|-ămə(r)}}, {{IPA|en|/-æmə(r)/}}, /<tt>-{mə(r)</tt>/ ===လိက်သမ္တီ=== #For more rhymes, add ''er'' to some nouns and adjectives at [[Rhymes:အၚ်္ဂလိက်/æm|/-æm/]]. #In [[non-rhotic]] accents, words ending in [[Rhymes:အၚ်္ဂလိက်/æmə|/-æmə/]] are rhymes for words on this page. ==ကာ..."
397277
wikitext
text/x-wiki
{{rhymes nav|en|æ|mə(ɹ)}}
==ဗွဟ်ရမ္သာၚ်==
{{enPR|-ămə(r)}}, {{IPA|en|/-æmə(r)/}}, /<tt>-{mə(r)</tt>/
===လိက်သမ္တီ===
#For more rhymes, add ''er'' to some nouns and adjectives at [[Rhymes:အၚ်္ဂလိက်/æm|/-æm/]].
#In [[non-rhotic]] accents, words ending in [[Rhymes:အၚ်္ဂလိက်/æmə|/-æmə/]] are rhymes for words on this page.
==ကာရန်ဂမၠိုၚ်==
===ဝဏ္ဏမွဲ===
<!--Note: words in this section must be stressed on the PENULTIMATE syllable.-->
<!--Do not add comparatives to this section-->
{{rhyme-top}}
* {{l|en|ammer}}
* {{l|en|bammer}}
* {{l|en|clamor}}, {{l|en|clamour}}
* {{l|en|crammer}}
* {{l|en|dammar}}
* {{l|en|drammer}}
* {{l|en|gammer}}
* {{l|en|glamor}}, {{l|en|glamour}}
* {{l|en|grammar}}<!--not "grammer"-->
* {{l|en|hammer}}
* {{l|en|jammer}}
* {{l|en|lamber}}<!--sic-->
* {{l|en|mammer}}
* {{l|en|rammer}}
* {{l|en|scammer}}
* {{l|en|shammer}}
* {{l|en|slammer}}
* {{l|en|spammer}}
* {{l|en|stammer}}
* {{l|en|stammer}}
* {{l|en|tammar}}
* {{l|en|whammer}}
* {{l|en|yammer}}
* {{l|en|Во}}
{{rhyme-bottom}}
===ဝဏ္ဏၜါ===
<!--Note: words in this section must be stressed on the PENULTIMATE syllable.-->
<!--Do not add comparatives to this section-->
{{rhyme-top}}
* {{l|en|beclamour}}
* {{l|en|beglamour}}
* {{l|en|despammer}}
* {{l|en|enamor}}, {{l|en|enamour}}
* {{l|en|rehammer}}
{{rhyme-bottom}}
===ဝဏ္ဏပိ===
<!--Note: words in this section must be stressed on the PENULTIMATE syllable.-->
<!--Do not add comparatives to this section-->
{{rhyme-top}}
* {{l|en|disenamour}}
* {{l|en|over-clamor}}, {{l|en|over-clamour}}
* {{l|en|re-enamour}}
{{rhyme-bottom}}
4tcp9scxqyjlacrssmo45eaj2aiccp7
ကဏ္ဍ:ဝေါဟာအၚ်္ဂလိက်မဆက်ဆေန်စှ်ေကၠုၚ်နူတံရိုဟ်အိန်ဒဝ်-ယူရဝ်ပဳယာန်-အခိုက်ကၞာနကဵုအဆက်ဝေါဟာ *gerbʰ-
14
296120
397278
2026-06-20T19:46:28Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်]]"
397278
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာအၚ်္ဂလိက်]]
cgthbuhht2vx8a42gqbqvafhhdb35kh
ဗီုပြၚ်သိုၚ်တၟိ:အိန်ဒဝ်-ယူရဝ်ပဳယာန်-အခိုက်ကၞာ/gerbʰ-
118
296121
397279
2026-06-20T19:49:03Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{reconstructed}} ==အိန်ဒဝ်-ယူရဝ်ပဳယာန်-အခိုက်ကၞာ== ===တံရိုဟ်=== {{ine-root}} # သကဵုဂၠတ်။"
397279
wikitext
text/x-wiki
{{reconstructed}}
==အိန်ဒဝ်-ယူရဝ်ပဳယာန်-အခိုက်ကၞာ==
===တံရိုဟ်===
{{ine-root}}
# သကဵုဂၠတ်။
jscec61atut1oddik3dj8a68qhnq3nl
γραμματική
0
296122
397280
2026-06-21T08:14:11Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{also|γραμματικῇ}} ==ဂရေတ်တြေံ== {{root|grc|ine-pro|*gerbʰ-}} ===ဗွဟ်ရမ္သာၚ်=== {{grc-IPA|γρᾰμμᾰτῐκή}} ===နာမ်=== {{grc-noun|γρᾰμμᾰτῐκή|γρᾰμμᾰτῐκῆς|f|first}} # {{non-gloss|အရီုလမျီုလုပ်ကၠုၚ်ဂမၠိုၚ်:}} ## အ္စာဗြဴဆေၚ်စပ်ကဵုကဆံ..."
397280
wikitext
text/x-wiki
{{also|γραμματικῇ}}
==ဂရေတ်တြေံ==
{{root|grc|ine-pro|*gerbʰ-}}
===ဗွဟ်ရမ္သာၚ်===
{{grc-IPA|γρᾰμμᾰτῐκή}}
===နာမ်===
{{grc-noun|γρᾰμμᾰτῐκή|γρᾰμμᾰτῐκῆς|f|first}}
# {{non-gloss|အရီုလမျီုလုပ်ကၠုၚ်ဂမၠိုၚ်:}}
## အ္စာဗြဴဆေၚ်စပ်ကဵုကဆံၚ်ပထမဂမၠိုၚ်။
## မၞိဟ်ဗြဴမွဲဇကုညးမဒဒက်တဴကဵုသၟတ်ဗြဴမကေတ်လဝ်ဌာန်ဒၞာဲမၞုံကဵုလိက်ပတ်ဂှ်ဂမၠိုၚ်၊ တၠပညာသဒ္ဒါ ဝါ ညးမချူလိက်ပါ်ပါဲ။
# {{non-gloss|အရီုမသက္ကုဟၟဲကဵုလမျီုဂမၠိုၚ်:}}
## သဒ္ဒါ။
## မဆေၚ်စပ်ကဵုမဟာဌာနဗ္တောန်ပညာနကဵုမကတ်လ္ၚတ်ပညာ။
## ဗျန်၊ အက္ခရ်၊ ပွမချူ။
====လဟုတ်စှ်ေ====
{{grc-decl|γρᾰμμᾰτῐκή|γρᾰμμᾰτῐκῆς}}
===မဒုၚ်လွဳစ===
* {{desc|el|γραμματική}}
====နာမဝိသေသန====
{{head|grc|adjective form|head=γρᾰμμᾰτῐκή}}
# {{inflection of|grc|γρᾰμμᾰτῐκός||nom|s|f}}
# {{inflection of|grc|γρᾰμμᾰτῐκός||voc|s|f}}
==ဂရေတ်==
===နိရုတ်===
ဝေါဟာကၠုၚ်နူ {{inh|el|grc|γρᾰμμᾰτῐκή}}
===နာမ်===
{{el-noun|f|unc}}
# သဒ္ဒါ။
====လဟုတ်စှ်ေ====
{{el-nF-η-1|γραμματικ}}
====နာမဝိသေသန====
{{head|el|adjf}}
# {{infl of|el|γραμματικός||nom//acc//voc|f|s}}
c4nr8dwizxxgwz76j9uhg1qhxfpa1ej
မဝ်ဂျူ:grc-decl/doc
828
296123
397284
2026-06-21T08:31:26Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "<div style="float: right; margin: 0 0 1em 0.5em; border: 1px solid var(--wikt-palette-grey-7,darkgray); padding: 0.5em;> <inputbox> type=fulltext prefix=Module:grc-decl searchbuttonlabel=Search in modules width=20 </inputbox> </div> This module is the backend to {{temp|grc-decl}} and {{temp|grc-adecl}}. It was created by [[User:ObsequiousNewt|ObsequiousNewt]] and then restructured by [[User:JohnC5|JohnC5]] and User:..."
397284
wikitext
text/x-wiki
<div style="float: right; margin: 0 0 1em 0.5em; border: 1px solid var(--wikt-palette-grey-7,darkgray); padding: 0.5em;>
<inputbox>
type=fulltext
prefix=Module:grc-decl
searchbuttonlabel=Search in modules
width=20
</inputbox>
</div>
This module is the backend to {{temp|grc-decl}} and {{temp|grc-adecl}}. It was created by [[User:ObsequiousNewt|ObsequiousNewt]] and then restructured by [[User:JohnC5|JohnC5]] and [[User:Erutuon|Erutuon]].
==Odds and ends==
The module tracks uses of {{temp|grc-decl}} and {{temp|grc-adecl}} in which parameter 1 does not have an accent mark using the tracking template {{whatlinkshere|tracking=grc-decl/no accent}}. Irregular and indeclinable paradigms are excluded from this check.
The module adds a breve or macron to mark the length of the monophthongs {{m|grc||α, ι, υ}} if they do not bear a macron, breve, circumflex, or iota subscript and the length can be deduced from the rules of accent. Thus, {{temp|grc-decl|ἄστρον|ἄστρου}} generates the same forms as {{temp|grc-decl|ᾰ̓́στρον|ᾰ̓́στρου}}. This is done by the {{code|lua|mark_implied_length}} and {{code|lua|harmonize_length}} functions in [[Module:grc-accent]].
Nominative and genitive, masculine and feminine, or masculine and neuter endings containing the monophthongs {{m|grc||α, ι, υ}} need not be marked with macrons and breves if there is only one declension with the given endings when vowel length is ignored. Thus {{temp|grc-decl|νεανίας|ου}} is fine because the only declension pattern with the endings {{m|grc||-ας, -ου}} is {{m|grc||-ᾱς, -ου}}, but {{temp|grc-decl|αἰτία|ας}} will throw an error, because both {{m|grc||-ᾰ, -ᾱς}} and {{m|grc||-ᾱ, -ᾱς}} are possible. This feature is made possible by [[Module:grc-decl/decl/staticdata]].
==Submodules==
[[Module:grc-decl/decl]] contains functions that determine the declension class, generate the inflected forms, and retrieves the correct forms of the article.
[[Module:grc-decl/table]] generates the table using the inflected forms, the forms of the article (if any){{,}} and the dialect and {{para|titleapp}} parameters.
[[Module:grc-decl/params]] contains the lists of parameters used by {{temp|grc-decl}} and {{temp|grc-adecl}}.
[[Module:grc-decl/decl/data]] contains functions that return the forms of a given declension type, modifying the raw paradigms or the stems as necessary.
[[Module:grc-decl/decl/staticdata]] generates data that is copied to [[Module:grc-decl/decl/classes]] and used to determine the declension class based on the nominative and genitive (for nouns) or the masculine and feminine or neuter (for adjectives).
[[Module:grc-decl/decl/staticdata/paradigms]] contains raw paradigms for declension classes, as well as any variations with a different accent on the ending.
[[Module:grc-decl/decl/staticdata/dialects]] contains data for dialect groups.
==Testcases==
{{also|Appendix:Ancient Greek declension tables}}
{{grc-adecl|ἄ˘ρῐστος|η|deg=super}}
{{grc-decl|irreg|form=M|νόος|νόος|νοΐ|νόᾰ|νόε|-|νόοιν|νόες|νόων|νόσῐ(ν)|νόᾰς|note=Third declension only found in later writers|title={{grc-apdx|3decl|Third declension}} of {{l-self|grc|[[ὁ]] [[νόος]]; [[τοῦ]] [[νόος]]}} ({{grc-att}})}}
{{grc-decl|θόρῠβος|ου|titleapp=foo / bar,bazz}}
{{grc-adecl|ᾰ̓δεής|ᾰ̓δεές|titleapp=foo / bar,bazz}}
{{grc-decl|Περῐκλῆς|Περῐκλέους|form=sing|titleapp=foo / bar,bazz}}
<includeonly>
{{module cat|grc}}
</includeonly>
dwfrtud874tss6cnap3nioolhjsiinx
မဝ်ဂျူ:grc-decl/params/doc
828
296124
397286
2026-06-21T08:33:18Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "This module returns the lists of parameters used by {{temp|grc-decl}} and {{temp|grc-adecl}}. <includeonly> {{module cat|grc}} </includeonly>"
397286
wikitext
text/x-wiki
This module returns the lists of parameters used by {{temp|grc-decl}} and {{temp|grc-adecl}}.
<includeonly>
{{module cat|grc}}
</includeonly>
pwg54rfx52tt8jq4g1gp27cfm0rvs10
ကဏ္ဍ:မဝ်ဂျူပွမပြံၚ်လှာဲဂရေတ်တြေံဂမၠိုၚ်
14
296125
397287
2026-06-21T08:35:07Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:မဝ်ဂျူဗီုအပြံၚ်အလှာဲဝေါဟာဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]"
397287
wikitext
text/x-wiki
[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:မဝ်ဂျူဗီုအပြံၚ်အလှာဲဝေါဟာဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
fvkx9iqa3enftyi5in4etb998c028j4
မဝ်ဂျူ:grc-decl/decl/data/doc
828
296126
397289
2026-06-21T08:39:01Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|grc}} </includeonly>"
397289
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|grc}}
</includeonly>
jjspp8979630ljm9asqtonz1ibyej0n
မဝ်ဂျူ:grc-decl/decl/doc
828
296127
397291
2026-06-21T08:44:37Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "This module contains functions that use the declension information in the submodules [[Module:grc-decl/decl/data|data]] and [[Module:grc-decl/decl/staticdata|staticdata]] to determine the declension type, generate the inflected forms, and add the forms of the definite article. <includeonly> [[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]] </includeonly>"
397291
wikitext
text/x-wiki
This module contains functions that use the declension information in the submodules [[Module:grc-decl/decl/data|data]] and [[Module:grc-decl/decl/staticdata|staticdata]] to determine the declension type, generate the inflected forms, and add the forms of the definite article.
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]]
</includeonly>
h4nkjf0sz44fo0sv6y503av4bl3b9na
မဝ်ဂျူ:grc-decl/decl/staticdata
828
296128
397292
2026-06-21T08:45:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "--[[ Abbreviations and codes used in declension names: - accent - nothing: oxytone - pax: paroxytone - prx: proparoxytone - con: perispomenon - contraction - con: contracted (perispomenon) - open: uncontracted - the characteristics of the ending (historically the stem) - 1st declension - alp: long alpha - eta: eta - als: long alpha, but short alpha in nominative and accusative singular -..."
397292
Scribunto
text/plain
--[[
Abbreviations and codes used in declension names:
- accent
- nothing: oxytone
- pax: paroxytone
- prx: proparoxytone
- con: perispomenon
- contraction
- con: contracted (perispomenon)
- open: uncontracted
- the characteristics of the ending (historically the stem)
- 1st declension
- alp: long alpha
- eta: eta
- als: long alpha, but short alpha in nominative and accusative singular
- als: eta, but short alpha in nominative and accusative singular
- 3rd declension
- pure: begins with ι or υ throughout
- weak: begins with ι or υ alternating with ε or η
]]
local export = {
adjinflections = {},
adjinflections_con = {},
}
local module_path = 'Module:grc-decl/decl/staticdata'
local m_paradigms = mw.loadData(module_path .. "/paradigms")
local ustring = mw.ustring
local U = ustring.char
local sub = ustring.sub
local gsub = ustring.gsub
local toNFC = ustring.toNFC
local toNFD = ustring.toNFD
--[[
Creates a version of an ending with macrons removed, and with macrons or breves switched.
The switching is pointless for endings containing more than one macron or breve:
for instance, ᾱσᾰ becomes ᾰσᾱ.
]]
local function mess_with_length(text)
-- local text = toNFD(text)
local macron = U(0x304)
local breve = U(0x306)
local unmarked_length = gsub(text, "[" .. macron .. breve .. "]", "")
local opposite_length = gsub(
text,
"[" .. macron .. breve .. "]",
{ [macron] = breve, [breve] = macron }
)
return unmarked_length, opposite_length
end
-- Adds a key with macrons or breves removed to the table.
local function add_unmarked_form(list, key, value)
if type(list) ~= "table" then
return list
end
-- key = toNFD(key)
local unmarked_length, opposite_length = mess_with_length(key)
if unmarked_length ~= key and not list[opposite_length] then
list[unmarked_length] = list[unmarked_length] or value
end
list[key] = list[key] or value
return list
end
--[=[
Noun declension categories that [[Module:grc-decl/decl]]
uses to determine the declension category of the nominative and genitive forms
that are supplied to the template.
]=]
local infl_categories = {
['1st-alp'] = m_paradigms.alp_pax,
['1st-eta'] = m_paradigms.eta_pax,
['1st-als'] = m_paradigms.als_prx,
['1st-ets'] = m_paradigms.ets_prx,
['1st-M-alp'] = m_paradigms.M_alp_pax,
['1st-M-alp2'] = m_paradigms.M_alp_con, -- add 2 for unique key
['1st-M-eta'] = m_paradigms.M_eta_pax,
['2nd'] = m_paradigms.second,
['2nd-con'] = m_paradigms.second_con,
['2nd-N'] = m_paradigms.second_N,
['2nd-N-con'] = m_paradigms.second_N_con,
['2nd-att'] = m_paradigms.second_att,
['2nd-N-att'] = m_paradigms.second_N_att_prx,
['3rd-εσ'] = m_paradigms.es_adj,
['3rd-εσ-open'] = m_paradigms.es_adj_prx_open,
['3rd-N-εσ'] = m_paradigms.N_es_adj,
['3rd-N-ος'] = m_paradigms.N_es_prx,
['3rd-N-ος-open'] = m_paradigms.N_es_prx_open,
['3rd-N-ᾰσ'] = m_paradigms.N_as_prx,
['3rd-N-ᾰσ-open'] = m_paradigms.N_as_prx_open,
['3rd-κλῆς'] = m_paradigms.kles,
['3rd-κλῆς-open'] = m_paradigms.kles_open, -- add 2 for unique key
['3rd-weak-ι'] = m_paradigms.weak_i_prx,
['3rd-weak-υ'] = m_paradigms.weak_u,
['3rd-N-weak-ι'] = m_paradigms.N_weak_i_prx,
['3rd-N-weak-υ'] = m_paradigms.N_weak_u,
['3rd-pure-ι'] = m_paradigms.pure_i_prx,
['3rd-N-pure-ι'] = m_paradigms.N_pure_i_prx,
['3rd-pure-υ-long'] = m_paradigms.pure_u_long_prx,
['3rd-pure-υ'] = m_paradigms.pure_u,
['3rd-N-pure-υ'] = m_paradigms.N_pure_u_prx,
['3rd-ευς'] = m_paradigms.eus,
['3rd-ευς-con'] = m_paradigms.eus_con,
['3rd-οι'] = m_paradigms.oi,
}
-- Used by the function that generates the list of declension categories on the documentation page.
export.conversion = {
['1st-alp'] = 'alp_pax',
['1st-eta'] = 'eta_pax',
['1st-als'] = 'als_prx',
['1st-ets'] = 'ets_prx',
['1st-M-alp'] = 'M_alp_pax',
['1st-M-alp2'] = 'M_alp_con',
['1st-M-eta'] = 'M_eta_pax',
['2nd'] = 'second',
['2nd-con'] = 'second_con',
['2nd-N'] = 'second_N',
['2nd-N-con'] = 'second_N_con',
['2nd-att'] = 'second_att',
['2nd-N-att'] = 'second_N_att_prx',
['3rd-εσ'] = 'es_adj',
['3rd-εσ-open'] = 'es_adj_prx_open',
['3rd-N-εσ'] = 'N_es_adj',
['3rd-N-ος'] = 'N_es_prx',
['3rd-N-ος-open'] = 'N_es_prx_open',
['3rd-N-ᾰσ'] = 'N_as_prx',
['3rd-κλῆς'] = 'kles',
['3rd-κλῆς-open'] = 'kles_open',
['3rd-weak-ι'] = 'weak_i_prx',
['3rd-weak-υ'] = 'weak_u',
['3rd-N-weak-ι'] = 'N_weak_i_prx',
['3rd-N-weak-υ'] = 'N_weak_u',
['3rd-pure-ι'] = 'pure_i_prx',
['3rd-N-pure-ι'] = 'N_pure_i_prx',
['3rd-pure-υ-long'] = 'pure_u_long_prx',
['3rd-pure-υ'] = 'pure_u',
['3rd-N-pure-υ'] = 'N_pure_u_prx',
['3rd-ευς'] = 'eus',
['3rd-ευς-con'] = 'eus_con',
['3rd-οι'] = 'oi',
}
infl_info = {}
export.ambig_forms = {}
-- Constructs a table for nouns with the same structure as the one for adjectives.
local strip_tone = require("Module:grc-accent").strip_tone
local longest_nominative_ending = 0
for name, decl in pairs(infl_categories) do
local nom = strip_tone(sub(decl.NS, 2))
local gen = strip_tone(sub(strip_tone(decl.GS), 2))
longest_nominative_ending = math.max(longest_nominative_ending, mw.ustring.len(mw.ustring.toNFC(nom)))
if not infl_info[nom] then
infl_info[nom] = {}
end
if type(infl_info[nom]) == "table" then
if infl_info[nom][gen] then
error('Conflict in noun declensions; two declensions with nominative ' .. nom ..
' and genitive ' .. gen .. '.')
end
name = gsub(name, "%d$", "")
infl_info[nom][gen] = name
end
end
infl_info.longest_nominative_ending = longest_nominative_ending
for nominative, list in pairs(infl_info) do
local unmarked_length, opposite_length = mess_with_length(nominative)
local data_for_opposite
if unmarked_length ~= opposite_length then
data_for_opposite = infl_info[opposite_length] or infl_info[toNFC(opposite_length)]
if not data_for_opposite then
infl_info[unmarked_length] = nominative
end
end
if type(list) == "table" then
local new_list = {}
for gen, name in pairs(list) do
local unmarked_length, opposite_length = mess_with_length(gen)
if unmarked_length ~= gen and not list[opposite_length] then
new_list[unmarked_length] = name
end
new_list[gen] = name
end
list = new_list
local combined_gens = {}
if data_for_opposite and not infl_info[unmarked_length] then
local is_ambig = false
for gen, name in pairs(list) do
combined_gens[gen] = name
end
for gen, name in pairs(data_for_opposite or {}) do
local gen_unmarked_length, gen_opposite_length = mess_with_length(gen)
if list[gen] or list[gen_opposite_length] then
--[[
If there are two declension types with the same nominative
and genitive endings aside from the length of the nominative,
then strip the macron or breve from both forms and record them.
]]
is_ambig = true
end
combined_gens = add_unmarked_form(combined_gens, gen, name)
end
if is_ambig then
--[[
Remove length marks and record all the nominative–genitive pairs
that were found.
]]
local nom = mess_with_length(nominative)
for gen, name in pairs(combined_gens) do
gen = mess_with_length(gen)
export.ambig_forms[nom] = export.ambig_forms[nom] or {}
export.ambig_forms[nom][gen] = true
end
else
infl_info[unmarked_length] = combined_gens
end
end
infl_info[nominative] = list
end
end
local infl_info_adj = {
['ος'] = {
['ᾱ'] = '1&2-alp',
['η'] = '1&2-eta',
['ον'] = '2nd',
},
['ους'] = {
['ᾱ'] = '1&2-alp-con',
['η'] = '1&2-eta-con',
['ουσᾰ'] = '1&3-ουντ',
},
['ῠς'] = { ['ειᾰ'] = '1&3-ups' },
-- ['υς'] = 'ῠς',
['ως'] = {
['υιᾰ'] = '1&3-οτ',
['ων'] = '2nd-att',
},
['ᾱς'] = {
['αινᾰ'] = '1&3-ᾰν',
['ᾱσᾰ'] = '1&3-ᾰντ',
},
['ην'] = { ['εινᾰ'] = '1&3-εν' },
['εις'] = {
['εισᾰ'] = '1&3-εντ',
['εσσᾰ'] = '1&3-εσσ',
},
['ων'] = {
['ουσᾰ'] = '1&3-οντ',
['ωσᾰ'] = '1&3-ωντ',
},
['ῡς'] = { ['ῡσᾰ'] = '1&3-ῠντ' },
['ης'] = { ['ες'] = '3rd-εσ' },
}
export.ambig_forms_adj = {}
--[[
[''] = '',
]]
for masculine, list in pairs(infl_info_adj) do
if type(list) == "table" then
-- Decompose masculine and feminine (or neuter) endings.
local new_fems = {}
local fems_changed = false
for feminine, name in pairs(list) do
new_feminine = toNFD(feminine)
if new_feminine ~= feminine then
fems_changed = true
end
new_fems[new_feminine] = name
end
list = new_fems
new_masculine = toNFD(masculine)
if fems_changed or new_masculine ~= masculine then
-- Delete existing entry
infl_info_adj[masculine] = nil
-- Create decomposed one.
infl_info_adj[new_masculine] = list
end
elseif type(list) == "string" then
if not infl_info_adj[list] then
error(masculine .. ' has been redirected to the form ' .. list .. ', which does not exist.')
end
end
end
local longest_masculine_ending = 0
for masculine, list in pairs(infl_info_adj) do
local unmarked_length, opposite_length = mess_with_length(masculine)
local data_for_opposite
longest_masculine_ending =
math.max(longest_masculine_ending, mw.ustring.len(mw.ustring.toNFC(masculine)))
if unmarked_length ~= opposite_length then
data_for_opposite = infl_info_adj[opposite_length] or infl_info_adj[toNFC(opposite_length)]
if not data_for_opposite then
infl_info_adj[unmarked_length] = masculine
end
end
local new_list = {}
for fem, name in pairs(list) do
local unmarked_length, opposite_length = mess_with_length(fem)
if unmarked_length ~= fem and not list[opposite_length] then
new_list[unmarked_length] = name
end
new_list[fem] = name
end
list = new_list
local combined_fems = {}
if data_for_opposite and not infl_info_adj[unmarked_length] then
for fem, name in pairs(list) do
combined_fems[fem] = name
end
for fem, name in pairs(data_for_opposite or {}) do
if list[fem] then
--[[
If there are declension types with the same masculine and
feminine endings, aside from the length (not currently true),
then strip the macron or breve and log them.
]]
local key = mess_with_length(masculine)
local value = mess_with_length(fem)
export.ambig_forms_adj[key] = value
combined_fems = nil
break
end
combined_fems = add_unmarked_form(combined_fems, fem, name)
end
if combined_fems then
infl_info_adj[unmarked_length] = combined_fems
end
end
infl_info_adj[masculine] = list
end
infl_info_adj.longest_masculine_ending = longest_masculine_ending
--[[
Mapping from adjectival declension codes to the declension type used for the masculine (1),
feminine (2), and neuter (3), along with any suffixes added to the stem in the masculine
and neuter (a1) or feminine (a2).
]]
export.headers = {
['1&2'] = '[[Appendix:Ancient Greek first declension|First]] and [[Appendix:Ancient Greek second declension|second]] declension',
['1&3'] = '[[Appendix:Ancient Greek first declension|First]] and [[Appendix:Ancient Greek third declension|third]] declension',
['2nd'] = '[[Appendix:Ancient Greek second declension|Second declension]]',
['3rd'] = '[[Appendix:Ancient Greek third declension|Third declension]]',
['Attic'] = '[[Appendix:Ancient Greek Attic declension|Attic second declension]]',
['irreg'] = 'Irregular declension',
}
for k, header in pairs(m_paradigms.headers) do
if export.headers[k] then
if export.headers[k] ~= header then
error('Two headers with same name: ' .. export.header[k] .. ', ' .. header .. '.')
end
else
export.headers[k] = header
end
end
--First-and-second-declension adjectives
export.adjinflections['1&2-alp'] = { '2nd', '1st-alp', '2nd-N', adeclheader = '1&2' }
export.adjinflections['1&2-alp-con'] = { '2nd', '1st-alp', '2nd-N', a1 = 'ε', a2 = 'ε', adeclheader = '1&2' } -- avoid collisions
export.adjinflections['1&2-eta'] = { '2nd', '1st-eta', '2nd-N', adeclheader = '1&2' }
export.adjinflections['1&2-eta-con'] = { '2nd', '1st-alp', '2nd-N', a1 = 'ε', a2 = 'ε', adeclheader = '1&2' }
-- First-and-third-declension adjectives
export.adjinflections['1&3-ups'] = { '3rd-weak-υ', '1st-als', '3rd-N-weak-υ', a2 = 'ει', adeclheader = '1&3' }
export.adjinflections['1&3-ᾰν'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ᾰν', a2 = 'αιν', adeclheader = '1&3' }
export.adjinflections['1&3-εν'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εν', a2 = 'ειν', adeclheader = '1&3' }
export.adjinflections['1&3-εσσ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εντ', a2 = 'εσσ', adeclheader = '1&3' }
--[[ Participles (subtype of first-and-third) ]]
export.adjinflections['1&3-ουντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'οντ', a2 = 'ουσ', adeclheader = '1&3' }
-- perfect active:
export.adjinflections['1&3-οτ'] = { '3rd-cons', '1st-als', '3rd-N-cons', a1 = 'οτ', a2 = 'υι', adeclheader = '1&3' }
-- From roots with reflex of *h₁, and in the aorist passive:
export.adjinflections['1&3-εντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εντ', a2 = 'εισ', adeclheader = '1&3' }
-- From roots with reflex of *h₂, and 1st aorist active:
export.adjinflections['1&3-ᾰντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ᾰντ', a2 = 'ᾱσ', adeclheader = '1&3' }
-- From roots with reflex of *h₃, and thematic active:
export.adjinflections['1&3-οντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'οντ', a2 = 'ουσ', adeclheader = '1&3' }
-- έω/όω contract; this category does not appear in infl_info_adj, because it
-- has to be assigned specifically in [[Module:grc-decl/sandbox/decl]], if
-- masculine singular has acute on ultima (is perispomenon):
export.adjinflections['1&3-οντ-con'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ουντ', a2 = 'ουσ', adeclheader = '1&3' }
-- νῡμι active:
export.adjinflections['1&3-ῠντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ῠντ', a2 = 'ῡσ', adeclheader = '1&3' }
-- άω contract:
export.adjinflections['1&3-ωντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ωντ', a2 = 'ωσ', adeclheader = '1&3' }
-- Masculine and feminine identical
export.adjinflections['2nd'] = { '2nd', nil, '2nd-N', adeclheader = '2nd' }
export.adjinflections['2nd-att'] = { '2nd-att', nil, '2nd-N-att', adeclheader = 'Attic' }
export.adjinflections['3rd-cons'] = { '3rd-cons', nil, '3rd-N-cons', adeclheader = '3rd' }
export.adjinflections['3rd-εσ-open'] = { '3rd-εσ-open', nil, '3rd-N-εσ-open', adeclheader = '3rd' }
export.adjinflections['1&2-alp-con'] = { '2nd-con', '1st-alp', '2nd-N-con', adeclheader = '1&2' }
export.adjinflections['1&2-eta-con'] = { '2nd-con', '1st-eta', '2nd-N-con', adeclheader = '1&2' }
export.adjinflections['3rd-εσ'] = { '3rd-εσ', nil, '3rd-N-εσ', adeclheader = '3rd' }
export.adjinflections_con['1&2-alp-con'] = export.adjinflections['1&2-alp-con']
export.adjinflections_con['1&2-eta-con'] = export.adjinflections['1&2-eta-con']
export.adjinflections_con['3rd-εσ'] = export.adjinflections['3rd-εσ']
export.infl_info = {}
export.infl_info.noun = infl_info
export.infl_info.adj = infl_info_adj
export.irregular = {}
export.irregular.noun = {}
export.irregular.noun.masculine_feminine = {
S = { false, 'NS', 'GS', 'DS', 'AS', 'VS' },
D = { false, 'ND', 'GD' },
P = { false, 'NP', 'GP', 'DP', 'AP' },
SD = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'ND', 'GD',
},
SP = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'NP', 'GP', 'DP', 'AP'
},
DP = {
false, 'ND', 'GD',
'NP', 'GP', 'DP', 'AP'
},
full = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'ND', 'GD',
'NP', 'GP', 'DP', 'AP'
},
}
export.irregular.noun.neuter = {
S = { false, 'NS', 'GS', 'DS',
redirects = {
AS = 'NS', VS = 'NS',
},
},
D = { false, 'DS', 'DG' },
P = { false, 'NP', 'GP', 'DP',
redirects = {
AP = 'NP'
},
},
SD = { false, 'NS', 'GS', 'DS', 'ND', 'GD',
redirects = {
AS = 'NS', VS = 'NS'
},
},
SP = { false, 'NS', 'GS', 'DS', 'NP', 'GP', 'DP',
redirects = {
AS = 'NS', VS = 'NS', AP = 'NP'
}
},
DP = { false, 'ND', 'GD', 'NP', 'GP', 'DP',
redirects = {
AP = 'NP',
},
},
full = { false, 'NS', 'GS', 'DS', 'ND', 'GD', 'NP', 'GP', 'DP',
redirects = {
AS = 'NS', VS = 'NS', AP = 'NP'
},
},
}
export.irregular.adjective = {
S = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS',
'NNS',
redirects = { NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS', },
},
D = {
false, 'MND', 'MGD',
'FND', 'FGD',
redirects = { NND = 'MGD', NGD = 'MGD', }
},
P = {
false, 'MNP', 'MGP', 'MDP', 'MAP',
'FNP', 'FGP', 'FDP', 'FAP',
'NNP',
redirects = { NGP = 'MGP', NDP = 'MDP', NAP = 'NNP' },
},
SD = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MND', 'MGD',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FND', 'FGD',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NND = 'MND', NGD = 'MGD',
},
},
SP = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MNP', 'MGP', 'MDP', 'MAP',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FNP', 'FGP', 'FDP', 'FAP',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
DP = {
false, 'MND', 'MGD', 'MNP', 'MGP', 'MDP', 'MAP',
'FND', 'FGD', 'FNP', 'FGP', 'FDP', 'FAP',
'NNP',
redirects = {
NND = 'MND', NGD = 'MGD',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
full = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MND', 'MGD', 'MNP', 'MGP', 'MDP', 'MAP',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FND', 'FGD', 'FNP', 'FGP', 'FDP', 'FAP',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NND = 'MND', NGD = 'MGD',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
}
return export
9psaj0pwkg1msjc95foe737a81ckfxy
397300
397292
2026-06-21T09:48:05Z
咽頭べさ
33
397300
Scribunto
text/plain
--[[
Abbreviations and codes used in declension names:
- accent
- nothing: oxytone
- pax: paroxytone
- prx: proparoxytone
- con: perispomenon
- contraction
- con: contracted (perispomenon)
- open: uncontracted
- the characteristics of the ending (historically the stem)
- 1st declension
- alp: long alpha
- eta: eta
- als: long alpha, but short alpha in nominative and accusative singular
- als: eta, but short alpha in nominative and accusative singular
- 3rd declension
- pure: begins with ι or υ throughout
- weak: begins with ι or υ alternating with ε or η
]]
local export = {
adjinflections = {},
adjinflections_con = {},
}
local module_path = 'Module:grc-decl/decl/staticdata'
local m_paradigms = mw.loadData(module_path .. "/paradigms")
local ustring = mw.ustring
local U = ustring.char
local sub = ustring.sub
local gsub = ustring.gsub
local toNFC = ustring.toNFC
local toNFD = ustring.toNFD
--[[
Creates a version of an ending with macrons removed, and with macrons or breves switched.
The switching is pointless for endings containing more than one macron or breve:
for instance, ᾱσᾰ becomes ᾰσᾱ.
]]
local function mess_with_length(text)
-- local text = toNFD(text)
local macron = U(0x304)
local breve = U(0x306)
local unmarked_length = gsub(text, "[" .. macron .. breve .. "]", "")
local opposite_length = gsub(
text,
"[" .. macron .. breve .. "]",
{ [macron] = breve, [breve] = macron }
)
return unmarked_length, opposite_length
end
-- Adds a key with macrons or breves removed to the table.
local function add_unmarked_form(list, key, value)
if type(list) ~= "table" then
return list
end
-- key = toNFD(key)
local unmarked_length, opposite_length = mess_with_length(key)
if unmarked_length ~= key and not list[opposite_length] then
list[unmarked_length] = list[unmarked_length] or value
end
list[key] = list[key] or value
return list
end
--[=[
Noun declension categories that [[Module:grc-decl/decl]]
uses to determine the declension category of the nominative and genitive forms
that are supplied to the template.
]=]
local infl_categories = {
['1st-alp'] = m_paradigms.alp_pax,
['1st-eta'] = m_paradigms.eta_pax,
['1st-als'] = m_paradigms.als_prx,
['1st-ets'] = m_paradigms.ets_prx,
['1st-M-alp'] = m_paradigms.M_alp_pax,
['1st-M-alp2'] = m_paradigms.M_alp_con, -- add 2 for unique key
['1st-M-eta'] = m_paradigms.M_eta_pax,
['2nd'] = m_paradigms.second,
['2nd-con'] = m_paradigms.second_con,
['2nd-N'] = m_paradigms.second_N,
['2nd-N-con'] = m_paradigms.second_N_con,
['2nd-att'] = m_paradigms.second_att,
['2nd-N-att'] = m_paradigms.second_N_att_prx,
['3rd-εσ'] = m_paradigms.es_adj,
['3rd-εσ-open'] = m_paradigms.es_adj_prx_open,
['3rd-N-εσ'] = m_paradigms.N_es_adj,
['3rd-N-ος'] = m_paradigms.N_es_prx,
['3rd-N-ος-open'] = m_paradigms.N_es_prx_open,
['3rd-N-ᾰσ'] = m_paradigms.N_as_prx,
['3rd-N-ᾰσ-open'] = m_paradigms.N_as_prx_open,
['3rd-κλῆς'] = m_paradigms.kles,
['3rd-κλῆς-open'] = m_paradigms.kles_open, -- add 2 for unique key
['3rd-weak-ι'] = m_paradigms.weak_i_prx,
['3rd-weak-υ'] = m_paradigms.weak_u,
['3rd-N-weak-ι'] = m_paradigms.N_weak_i_prx,
['3rd-N-weak-υ'] = m_paradigms.N_weak_u,
['3rd-pure-ι'] = m_paradigms.pure_i_prx,
['3rd-N-pure-ι'] = m_paradigms.N_pure_i_prx,
['3rd-pure-υ-long'] = m_paradigms.pure_u_long_prx,
['3rd-pure-υ'] = m_paradigms.pure_u,
['3rd-N-pure-υ'] = m_paradigms.N_pure_u_prx,
['3rd-ευς'] = m_paradigms.eus,
['3rd-ευς-con'] = m_paradigms.eus_con,
['3rd-οι'] = m_paradigms.oi,
}
-- Used by the function that generates the list of declension categories on the documentation page.
export.conversion = {
['1st-alp'] = 'alp_pax',
['1st-eta'] = 'eta_pax',
['1st-als'] = 'als_prx',
['1st-ets'] = 'ets_prx',
['1st-M-alp'] = 'M_alp_pax',
['1st-M-alp2'] = 'M_alp_con',
['1st-M-eta'] = 'M_eta_pax',
['2nd'] = 'second',
['2nd-con'] = 'second_con',
['2nd-N'] = 'second_N',
['2nd-N-con'] = 'second_N_con',
['2nd-att'] = 'second_att',
['2nd-N-att'] = 'second_N_att_prx',
['3rd-εσ'] = 'es_adj',
['3rd-εσ-open'] = 'es_adj_prx_open',
['3rd-N-εσ'] = 'N_es_adj',
['3rd-N-ος'] = 'N_es_prx',
['3rd-N-ος-open'] = 'N_es_prx_open',
['3rd-N-ᾰσ'] = 'N_as_prx',
['3rd-κλῆς'] = 'kles',
['3rd-κλῆς-open'] = 'kles_open',
['3rd-weak-ι'] = 'weak_i_prx',
['3rd-weak-υ'] = 'weak_u',
['3rd-N-weak-ι'] = 'N_weak_i_prx',
['3rd-N-weak-υ'] = 'N_weak_u',
['3rd-pure-ι'] = 'pure_i_prx',
['3rd-N-pure-ι'] = 'N_pure_i_prx',
['3rd-pure-υ-long'] = 'pure_u_long_prx',
['3rd-pure-υ'] = 'pure_u',
['3rd-N-pure-υ'] = 'N_pure_u_prx',
['3rd-ευς'] = 'eus',
['3rd-ευς-con'] = 'eus_con',
['3rd-οι'] = 'oi',
}
infl_info = {}
export.ambig_forms = {}
-- Constructs a table for nouns with the same structure as the one for adjectives.
local strip_tone = require("Module:grc-accent").strip_tone
local longest_nominative_ending = 0
for name, decl in pairs(infl_categories) do
local nom = strip_tone(sub(decl.NS, 2))
local gen = strip_tone(sub(strip_tone(decl.GS), 2))
longest_nominative_ending = math.max(longest_nominative_ending, mw.ustring.len(mw.ustring.toNFC(nom)))
if not infl_info[nom] then
infl_info[nom] = {}
end
if type(infl_info[nom]) == "table" then
if infl_info[nom][gen] then
error('Conflict in noun declensions; two declensions with nominative ' .. nom ..
' and genitive ' .. gen .. '.')
end
name = gsub(name, "%d$", "")
infl_info[nom][gen] = name
end
end
infl_info.longest_nominative_ending = longest_nominative_ending
for nominative, list in pairs(infl_info) do
local unmarked_length, opposite_length = mess_with_length(nominative)
local data_for_opposite
if unmarked_length ~= opposite_length then
data_for_opposite = infl_info[opposite_length] or infl_info[toNFC(opposite_length)]
if not data_for_opposite then
infl_info[unmarked_length] = nominative
end
end
if type(list) == "table" then
local new_list = {}
for gen, name in pairs(list) do
local unmarked_length, opposite_length = mess_with_length(gen)
if unmarked_length ~= gen and not list[opposite_length] then
new_list[unmarked_length] = name
end
new_list[gen] = name
end
list = new_list
local combined_gens = {}
if data_for_opposite and not infl_info[unmarked_length] then
local is_ambig = false
for gen, name in pairs(list) do
combined_gens[gen] = name
end
for gen, name in pairs(data_for_opposite or {}) do
local gen_unmarked_length, gen_opposite_length = mess_with_length(gen)
if list[gen] or list[gen_opposite_length] then
--[[
If there are two declension types with the same nominative
and genitive endings aside from the length of the nominative,
then strip the macron or breve from both forms and record them.
]]
is_ambig = true
end
combined_gens = add_unmarked_form(combined_gens, gen, name)
end
if is_ambig then
--[[
Remove length marks and record all the nominative–genitive pairs
that were found.
]]
local nom = mess_with_length(nominative)
for gen, name in pairs(combined_gens) do
gen = mess_with_length(gen)
export.ambig_forms[nom] = export.ambig_forms[nom] or {}
export.ambig_forms[nom][gen] = true
end
else
infl_info[unmarked_length] = combined_gens
end
end
infl_info[nominative] = list
end
end
local infl_info_adj = {
['ος'] = {
['ᾱ'] = '1&2-alp',
['η'] = '1&2-eta',
['ον'] = '2nd',
},
['ους'] = {
['ᾱ'] = '1&2-alp-con',
['η'] = '1&2-eta-con',
['ουσᾰ'] = '1&3-ουντ',
},
['ῠς'] = { ['ειᾰ'] = '1&3-ups' },
-- ['υς'] = 'ῠς',
['ως'] = {
['υιᾰ'] = '1&3-οτ',
['ων'] = '2nd-att',
},
['ᾱς'] = {
['αινᾰ'] = '1&3-ᾰν',
['ᾱσᾰ'] = '1&3-ᾰντ',
},
['ην'] = { ['εινᾰ'] = '1&3-εν' },
['εις'] = {
['εισᾰ'] = '1&3-εντ',
['εσσᾰ'] = '1&3-εσσ',
},
['ων'] = {
['ουσᾰ'] = '1&3-οντ',
['ωσᾰ'] = '1&3-ωντ',
},
['ῡς'] = { ['ῡσᾰ'] = '1&3-ῠντ' },
['ης'] = { ['ες'] = '3rd-εσ' },
}
export.ambig_forms_adj = {}
--[[
[''] = '',
]]
for masculine, list in pairs(infl_info_adj) do
if type(list) == "table" then
-- Decompose masculine and feminine (or neuter) endings.
local new_fems = {}
local fems_changed = false
for feminine, name in pairs(list) do
new_feminine = toNFD(feminine)
if new_feminine ~= feminine then
fems_changed = true
end
new_fems[new_feminine] = name
end
list = new_fems
new_masculine = toNFD(masculine)
if fems_changed or new_masculine ~= masculine then
-- Delete existing entry
infl_info_adj[masculine] = nil
-- Create decomposed one.
infl_info_adj[new_masculine] = list
end
elseif type(list) == "string" then
if not infl_info_adj[list] then
error(masculine .. ' has been redirected to the form ' .. list .. ', which does not exist.')
end
end
end
local longest_masculine_ending = 0
for masculine, list in pairs(infl_info_adj) do
local unmarked_length, opposite_length = mess_with_length(masculine)
local data_for_opposite
longest_masculine_ending =
math.max(longest_masculine_ending, mw.ustring.len(mw.ustring.toNFC(masculine)))
if unmarked_length ~= opposite_length then
data_for_opposite = infl_info_adj[opposite_length] or infl_info_adj[toNFC(opposite_length)]
if not data_for_opposite then
infl_info_adj[unmarked_length] = masculine
end
end
local new_list = {}
for fem, name in pairs(list) do
local unmarked_length, opposite_length = mess_with_length(fem)
if unmarked_length ~= fem and not list[opposite_length] then
new_list[unmarked_length] = name
end
new_list[fem] = name
end
list = new_list
local combined_fems = {}
if data_for_opposite and not infl_info_adj[unmarked_length] then
for fem, name in pairs(list) do
combined_fems[fem] = name
end
for fem, name in pairs(data_for_opposite or {}) do
if list[fem] then
--[[
If there are declension types with the same masculine and
feminine endings, aside from the length (not currently true),
then strip the macron or breve and log them.
]]
local key = mess_with_length(masculine)
local value = mess_with_length(fem)
export.ambig_forms_adj[key] = value
combined_fems = nil
break
end
combined_fems = add_unmarked_form(combined_fems, fem, name)
end
if combined_fems then
infl_info_adj[unmarked_length] = combined_fems
end
end
infl_info_adj[masculine] = list
end
infl_info_adj.longest_masculine_ending = longest_masculine_ending
--[[
Mapping from adjectival declension codes to the declension type used for the masculine (1),
feminine (2), and neuter (3), along with any suffixes added to the stem in the masculine
and neuter (a1) or feminine (a2).
]]
export.headers = {
['1&2'] = 'မလဟုတ်စှ်ေအလန်[[:en:Appendix:Ancient Greek first declension|ပထမ] ကဵု မလဟုတ်စှ်ေအလန်[[:en:Appendix:Ancient Greek second declension|ဒုတိယ]]',
['1&3'] = 'မလဟုတ်စှ်ေအလန်[[:en:Appendix:Ancient Greek first declension|ပထမ]] ကဵု မလဟုတ်စှ်ေအလန်[[:en:Appendix:Ancient Greek third declension|တတိယ]]',
['2nd'] = '[[:en:Appendix:Ancient Greek second declension|မလဟုတ်စှ်ေအလန်ဒုတိယ]]',
['3rd'] = '[[:en:Appendix:Ancient Greek third declension|မလဟုတ်စှ်ေအလန်တတိယ]]',
['Attic'] = '[[:en:Appendix:Ancient Greek Attic declension|ကံကၠတ်မလဟုတ်စှ်ေအလန်ဒုတိယ]]',
['irreg'] = 'လဟုတ်စှ်ေခလံက်ခနက်',
}
for k, header in pairs(m_paradigms.headers) do
if export.headers[k] then
if export.headers[k] ~= header then
error('Two headers with same name: ' .. export.header[k] .. ', ' .. header .. '.')
end
else
export.headers[k] = header
end
end
--First-and-second-declension adjectives
export.adjinflections['1&2-alp'] = { '2nd', '1st-alp', '2nd-N', adeclheader = '1&2' }
export.adjinflections['1&2-alp-con'] = { '2nd', '1st-alp', '2nd-N', a1 = 'ε', a2 = 'ε', adeclheader = '1&2' } -- avoid collisions
export.adjinflections['1&2-eta'] = { '2nd', '1st-eta', '2nd-N', adeclheader = '1&2' }
export.adjinflections['1&2-eta-con'] = { '2nd', '1st-alp', '2nd-N', a1 = 'ε', a2 = 'ε', adeclheader = '1&2' }
-- First-and-third-declension adjectives
export.adjinflections['1&3-ups'] = { '3rd-weak-υ', '1st-als', '3rd-N-weak-υ', a2 = 'ει', adeclheader = '1&3' }
export.adjinflections['1&3-ᾰν'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ᾰν', a2 = 'αιν', adeclheader = '1&3' }
export.adjinflections['1&3-εν'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εν', a2 = 'ειν', adeclheader = '1&3' }
export.adjinflections['1&3-εσσ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εντ', a2 = 'εσσ', adeclheader = '1&3' }
--[[ Participles (subtype of first-and-third) ]]
export.adjinflections['1&3-ουντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'οντ', a2 = 'ουσ', adeclheader = '1&3' }
-- perfect active:
export.adjinflections['1&3-οτ'] = { '3rd-cons', '1st-als', '3rd-N-cons', a1 = 'οτ', a2 = 'υι', adeclheader = '1&3' }
-- From roots with reflex of *h₁, and in the aorist passive:
export.adjinflections['1&3-εντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'εντ', a2 = 'εισ', adeclheader = '1&3' }
-- From roots with reflex of *h₂, and 1st aorist active:
export.adjinflections['1&3-ᾰντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ᾰντ', a2 = 'ᾱσ', adeclheader = '1&3' }
-- From roots with reflex of *h₃, and thematic active:
export.adjinflections['1&3-οντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'οντ', a2 = 'ουσ', adeclheader = '1&3' }
-- έω/όω contract; this category does not appear in infl_info_adj, because it
-- has to be assigned specifically in [[Module:grc-decl/sandbox/decl]], if
-- masculine singular has acute on ultima (is perispomenon):
export.adjinflections['1&3-οντ-con'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ουντ', a2 = 'ουσ', adeclheader = '1&3' }
-- νῡμι active:
export.adjinflections['1&3-ῠντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ῠντ', a2 = 'ῡσ', adeclheader = '1&3' }
-- άω contract:
export.adjinflections['1&3-ωντ'] = { '3rd-cons', '1st-ets', '3rd-N-cons', a1 = 'ωντ', a2 = 'ωσ', adeclheader = '1&3' }
-- Masculine and feminine identical
export.adjinflections['2nd'] = { '2nd', nil, '2nd-N', adeclheader = '2nd' }
export.adjinflections['2nd-att'] = { '2nd-att', nil, '2nd-N-att', adeclheader = 'Attic' }
export.adjinflections['3rd-cons'] = { '3rd-cons', nil, '3rd-N-cons', adeclheader = '3rd' }
export.adjinflections['3rd-εσ-open'] = { '3rd-εσ-open', nil, '3rd-N-εσ-open', adeclheader = '3rd' }
export.adjinflections['1&2-alp-con'] = { '2nd-con', '1st-alp', '2nd-N-con', adeclheader = '1&2' }
export.adjinflections['1&2-eta-con'] = { '2nd-con', '1st-eta', '2nd-N-con', adeclheader = '1&2' }
export.adjinflections['3rd-εσ'] = { '3rd-εσ', nil, '3rd-N-εσ', adeclheader = '3rd' }
export.adjinflections_con['1&2-alp-con'] = export.adjinflections['1&2-alp-con']
export.adjinflections_con['1&2-eta-con'] = export.adjinflections['1&2-eta-con']
export.adjinflections_con['3rd-εσ'] = export.adjinflections['3rd-εσ']
export.infl_info = {}
export.infl_info.noun = infl_info
export.infl_info.adj = infl_info_adj
export.irregular = {}
export.irregular.noun = {}
export.irregular.noun.masculine_feminine = {
S = { false, 'NS', 'GS', 'DS', 'AS', 'VS' },
D = { false, 'ND', 'GD' },
P = { false, 'NP', 'GP', 'DP', 'AP' },
SD = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'ND', 'GD',
},
SP = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'NP', 'GP', 'DP', 'AP'
},
DP = {
false, 'ND', 'GD',
'NP', 'GP', 'DP', 'AP'
},
full = {
false, 'NS', 'GS', 'DS', 'AS', 'VS',
'ND', 'GD',
'NP', 'GP', 'DP', 'AP'
},
}
export.irregular.noun.neuter = {
S = { false, 'NS', 'GS', 'DS',
redirects = {
AS = 'NS', VS = 'NS',
},
},
D = { false, 'DS', 'DG' },
P = { false, 'NP', 'GP', 'DP',
redirects = {
AP = 'NP'
},
},
SD = { false, 'NS', 'GS', 'DS', 'ND', 'GD',
redirects = {
AS = 'NS', VS = 'NS'
},
},
SP = { false, 'NS', 'GS', 'DS', 'NP', 'GP', 'DP',
redirects = {
AS = 'NS', VS = 'NS', AP = 'NP'
}
},
DP = { false, 'ND', 'GD', 'NP', 'GP', 'DP',
redirects = {
AP = 'NP',
},
},
full = { false, 'NS', 'GS', 'DS', 'ND', 'GD', 'NP', 'GP', 'DP',
redirects = {
AS = 'NS', VS = 'NS', AP = 'NP'
},
},
}
export.irregular.adjective = {
S = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS',
'NNS',
redirects = { NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS', },
},
D = {
false, 'MND', 'MGD',
'FND', 'FGD',
redirects = { NND = 'MGD', NGD = 'MGD', }
},
P = {
false, 'MNP', 'MGP', 'MDP', 'MAP',
'FNP', 'FGP', 'FDP', 'FAP',
'NNP',
redirects = { NGP = 'MGP', NDP = 'MDP', NAP = 'NNP' },
},
SD = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MND', 'MGD',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FND', 'FGD',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NND = 'MND', NGD = 'MGD',
},
},
SP = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MNP', 'MGP', 'MDP', 'MAP',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FNP', 'FGP', 'FDP', 'FAP',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
DP = {
false, 'MND', 'MGD', 'MNP', 'MGP', 'MDP', 'MAP',
'FND', 'FGD', 'FNP', 'FGP', 'FDP', 'FAP',
'NNP',
redirects = {
NND = 'MND', NGD = 'MGD',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
full = {
false, 'MNS', 'MGS', 'MDS', 'MAS', 'MVS', 'MND', 'MGD', 'MNP', 'MGP', 'MDP', 'MAP',
'FNS', 'FGS', 'FDS', 'FAS', 'FVS', 'FND', 'FGD', 'FNP', 'FGP', 'FDP', 'FAP',
'NNS', 'NNP',
redirects = {
NGS = 'MGS', NDS = 'MDS', NAS = 'NNS', NVS = 'NNS',
NND = 'MND', NGD = 'MGD',
NGP = 'MGP', NDP = 'MDP', NAP = 'NNP'
},
},
}
return export
2ah26g5pone6iz42v5w2xsw65g3qsbh
မဝ်ဂျူ:grc-decl/decl/staticdata/doc
828
296129
397293
2026-06-21T08:47:15Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "This module contains the data that is used to determine the declension category from the forms that are supplied to the declension template, and the declension and accent type for each gender of an adjective. ==Recognized nominative–genitive combinations for nouns== {{#invoke:grc-decl/decl|show_noun_categories}} ==Recognized masculine–feminine or masculine–neuter combinations for adjectives== {{#in..."
397293
wikitext
text/x-wiki
This module contains the data that is used to determine the declension category from the forms that are supplied to the declension template, and the declension and accent type for each gender of an adjective.
==Recognized nominative–genitive combinations for nouns==
{{#invoke:grc-decl/decl|show_noun_categories}}
==Recognized masculine–feminine or masculine–neuter combinations for adjectives==
{{#invoke:grc-decl/decl|show_adj_categories}}
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူစရၚ်ဘာသာဂရေတ်တြေံဂမၠိုၚ်]]
</includeonly>
d7k6ubmqrzcaloghzr8qne99r2u78k6
397299
397293
2026-06-21T09:38:43Z
咽頭べさ
33
397299
wikitext
text/x-wiki
This module contains the data that is used to determine the declension category from the forms that are supplied to the declension template, and the declension and accent type for each gender of an adjective.
==Recognized nominative–genitive combinations for nouns==
{{#invoke:grc-decl/decl|show_noun_categories}}
==Recognized masculine–feminine or masculine–neuter combinations for adjectives==
{{#invoke:grc-decl/decl|show_adj_categories}}
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူဒေတာဂရေတ်တြေံဂမၠိုၚ်]]
</includeonly>
pkzl2kffgn6vi0qvuc3aqr58rkbpw81
ထာမ်ပလိက်:grc-decl/documentation
10
296130
397295
2026-06-21T08:54:38Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation subpage}} This template is intended to be very simple to use. In most cases, it takes two obligatory arguments, the nominative and genitive singular forms of the noun to be declined. [[Module:grc-decl]] figures out what declension they belong to, and generates a table of forms. ==Parameters== ===Numbered parameters=== ====Regular nouns==== ; {{para|1}} : Nominative singular. ; {{para|2}} : Genitive si..."
397295
wikitext
text/x-wiki
{{documentation subpage}}
This template is intended to be very simple to use. In most cases, it takes two obligatory arguments, the nominative and genitive singular forms of the noun to be declined. [[Module:grc-decl]] figures out what declension they belong to, and generates a table of forms.
==Parameters==
===Numbered parameters===
====Regular nouns====
; {{para|1}}
: Nominative singular.
; {{para|2}}
: Genitive singular.
====Irregular or indeclinable nouns====
; {{para|1}}
: A flag <code>indecl</code> or <code>irreg</code> to indicate that the noun is indeclinable or that its declension is irregular.
; {{para|2}}
# If the noun is indeclinable, the form used for all grammatical cases.
# If the noun is irregular, the nominative singular.
===Named parameters===
; {{para|form}}
: Takes up to four different sets of values:
:# the gender, to add the correct forms of the definite article: one of <code>M</code>, <code>F</code>{{,}} or <code>N</code>. Use <code>MF</code> for words such as {{m|grc|παῖς}} that can be either masculine or feminine, or <code>X</code> to remove articles altogether. Gender is automatically determined by the module for first- and second-declension nouns and some third-declension nouns, but is required otherwise.
:# the numbers shown, one or more of <code>S</code>, <code>D</code>{{,}} or <code>P</code>, or <code>sing</code>, <code>dual</code>{{,}} or <code>plur</code>, for singular, dual{{,}} or plural. <code>full</code> is an alias of <code>SDP</code>, but is not needed, as it is the default for all nouns except <!-- first-declension nouns in {{m|grc||-ᾶς|tr=-}} --> those in {{m|grc||-κλῆς|tr=-}} and {{m|grc||-ώ|tr=-}}, which are only declined in the singular. Note that regardless of the number(s) of the noun, the nominative and genitive must be in the singular.
:# whether to show only the contracted or uncontracted tables of stems in {{m|grc||-εσ, -ᾰσ, -κλῆς|tr=-}}. If <code>open</code> is passed as an argument, only the uncontracted table is shown; if <code>con</code> is passed, only the contracted table is shown; if neither is passed then both tables will be shown.
:# whether to decline a noun using adjectival endings if <code>adj</code> or <code>adjective</code> is passed (used for substantivised forms of adjectives), as in the case of certain third declension neuter nouns like {{m|grc|δασύ}}.
: The order of the arguments to {{para|form}} does not matter; arguments such as <code>M-plur</code>, <code>MF</code>, <code>sing-F-open</code> are all acceptable. The hyphens are unnecessary, but recommended for clarity.
; {{para|dial}}
: Determines which dialect's forms will be shown. The default is <code>att</code> ([[w:Attic Greek|Attic]]). A code (<code>att</code>) or a dialect name (<code>Attic</code>) can be used, as long as it is found in [[Module:labels/data/lang/grc]]. The dialect name will be shown in parentheses in the title of the table.
: Parameter values containing tildes (<code>~</code>) or slashes (<code>/</code>) are no longer supported. Any template with these values will default to Attic (as long as the parameter does not contain <code>~</code> and <code>att</code>).
: Most dialectal forms are added in [[Module:grc-decl/decl/data]], but a few paradigms are divergent enough to be given in [[Module:grc-decl/decl/staticdata/paradigms]]. Not all dialects have forms assigned to them. To find out if a dialect does, search for the dialect code in [[Module:grc-decl/decl/data]] (if you can decrypt the Lua code).
; {{para|voc|α}}
: Indicates vocative singular in {{m|grc||-ᾰ}} rather than {{m|grc|-η}}, for first-declension masculine nouns in {{m|grc||-ης}}, such as {{m|grc|γεωμέτρης}}, vocative {{m|grc|γεωμέτρᾰ}}. This parameter is not needed for nouns in {{m|grc|-της}}, whose vocative always ends in {{m|grc||-ᾰ}}.
; {{para|voc|-}}
: Indicates that a noun has no vocative.
; {{para|NS}}, {{para|GD}}, {{para|DP}}, ...
: used to supply specific irregular forms (the given examples are the nominative singular, genitive dual, and dative plural, respectively). If both contracted and uncontracted tables are shown, 1 and 2 may be appended to the end (VS1, AP2, etc.) to differentiate between tables (if no number is appended the irregular form will be shown for both tables.)
; {{para|titleapp}}
: which adds text to the end of the titlebar. This overrides a titleapp automatically generated by {{para|dial}}.
; {{para|title}}
: overrides the entire title.
; {{para|notes}}
: adds supplementary text to be displayed below the footnotes.
===Example===
<pre>{{grc-decl|ἄρῑστον|ου}}</pre>
{{grc-decl|ἄρῑστον|ου}}
==Notes==
* Even when the noun in question is declined only in the plural, this template takes the nominative and genitive singular.
* With few exceptions, the Attic nominative and genitive should be given, even if the inflection displayed is a dialectical alternative (but with the dialectical stem: e.g. {{temp|grc-decl|[[ἄνηθον]]|ἀνήθου|dial=~aio}}, but {{temp|grc-decl|[[ἄνητον]]|ἀνήτου|dial=aio}} (not **ἀνήτω, even though that form will be displayed.)
* If the noun has an irregular nominative or genitive singular, it must still be supplied as if it were regular, and then overriden with {{para|NS}} or {{para|GS}} (see below).
* With first and second declension nouns, as well as some third declension nouns (specifically stems in -εσ, -ᾰσ, -ῐ, -ῠ, -ωϝ, -οι) it is usually acceptable to use simply the genitive ending instead of the entire genitive (e.g. ῐ̔́ππος|ου), however with most third-declension nouns it is necessary to supply the entire genitive.
* Length marks on α,ι,υ are mandatory in case endings. See [[WT:AGRC]] for instructions on how to order combining diacritics.
* Forms with parentheses that represent a pair of forms, such as forms with and without movable nu, are expanded so that they will show up in search results: {{lang|grc|οἷσι(ν)}} → {{lang|grc|οἷσι}}, {{lang|grc|οἷσιν}}
{{isAccelerated}}
<includeonly>
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်]]
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဂရေတ်တြေံဂမၠိုၚ်]]
</includeonly>
tq2270yaaewlgyh35vppy021zwbdwh0
မဝ်ဂျူ:grc-decl/table/doc
828
296131
397297
2026-06-21T09:28:58Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> {{module cat|grc}} </includeonly>"
397297
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|grc}}
</includeonly>
jjspp8979630ljm9asqtonz1ibyej0n
မဝ်ဂျူ:accel/grc/doc
828
296132
397302
2026-06-21T09:52:59Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "<includeonly> {{module cat|grc}} </includeonly>"
397302
wikitext
text/x-wiki
<includeonly>
{{module cat|grc}}
</includeonly>
fbxy44zcal3ke2gxlr6x172kgyqgx2c
397303
397302
2026-06-21T09:54:32Z
咽頭べさ
33
397303
wikitext
text/x-wiki
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]]
[[ကဏ္ဍ:မဝ်ဂျူဒကုတ်ဍောတ်အေက်သာယ်ဂမၠိုၚ်]]
</includeonly>
4huf67yapkqzhkk1i4gd4hu717yhmpx
မဝ်ဂျူ:grc-utilities/doc
828
296133
397306
2026-06-21T10:01:49Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "This module contains four functions, three of which are called by other modules. <code class="n">standardDiacritics</code> takes spacing or nonstandard diacritics and converts them to standard combining diacritics. This function is used by <code class="n">pronunciationOrder</code>. <code class="n">reorderDiacritics</code> takes the diacritics, removes them from the letter ({{code|lua|mw.ustring.toNFD}}), and reorder..."
397306
wikitext
text/x-wiki
This module contains four functions, three of which are called by other modules.
<code class="n">standardDiacritics</code> takes spacing or nonstandard diacritics and converts them to standard combining diacritics. This function is used by <code class="n">pronunciationOrder</code>.
<code class="n">reorderDiacritics</code> takes the diacritics, removes them from the letter ({{code|lua|mw.ustring.toNFD}}), and reorders them so that macrons or breves are first; diaeresis or breathing mark is second; acute, grave, or circumflex is third; and iota subscript is last. Aside from the iota subscript part, this is the only order in which the diacritics can display correctly, as explained [[Wiktionary:Ancient Greek entry guidelines#Diacritics and accentuation|elsewhere]]. This function is used by [[Module:typing-aids]] and {{temp|chars}}.
* {{#invoke:grc-utilities/templates|printDiacritics|reorderDiacritics|ά̓̆νερ}}
<code class="n">pronunciationOrder</code> does the same thing, except it puts the macron or breve and iota subscript last and recombines the diacritics ({{code|lua|mw.ustring.toNFC}}) after reordering them. The diaeresis or breathing mark and accent mark will recombine, while the macron and breve remains uncombined as a combining character. This function is used by [[Module:grc-pronunciation]] and {{temp|grc-IPA}}.
[[Module:grc-utilities/data]] holds the diacritic definitions and substitutions that are used by this module.
==Tokenization==
The function <code class="n">tokenize</code> breaks the text into meaningful units of a single consonant or monophthong letter, or diphthong, with any diacritics, as shown below. This function is used by [[Module:grc-translit]] and [[Module:grc-accent]], and by the sandbox module [[Module:grc-pronunciation/sandbox]].
The first argument is the word to be tokenized. The second is a boolean: if true, the function will group {{lang|grc|εω}} together as a diphthong, for instance in {{m|grc||πόλεως}}, genitive of {{m|grc|πόλῐς|t=city state}}.
{| class="wikitable"
! word !! tokens
{{#invoke:grc-utilities/templates|printTokens|ἡμεῖς}}
{{#invoke:grc-utilities/templates|printTokens|οἷαι}}
{{#invoke:grc-utilities/templates|printTokens|ἀναῡ̈τέω}}
{{#invoke:grc-utilities/templates|printTokens|δαΐφρων}}
{{#invoke:grc-utilities/templates|printTokens|τούτῳ}}
{{#invoke:grc-utilities/templates|printTokens|ὑϊκός}}
{{#invoke:grc-utilities/templates|printTokens|ἡ Ἑλήνη}}
{{#invoke:grc-utilities/templates|printTokens|γλᾰυκός}}
{{#invoke:grc-utilities/templates|printTokens|ἑᾱυτοῦ}}
{{#invoke:grc-utilities/templates|printTokens|γρᾱῦς}}
{{#invoke:grc-utilities/templates|printTokens|νηῦς}}
{{#invoke:grc-utilities/templates|printTokens|Μωυσής}}
{{#invoke:grc-utilities/templates|printTokens|υἱός}}
{{#invoke:grc-utilities/templates|printTokens|ωὑτός}}
{{#invoke:grc-utilities/templates|printTokens|ᾰὐτός}}
{{#invoke:grc-utilities/templates|printTokens|ᾱὑτοῦ}}
{{#invoke:grc-utilities/templates|printTokens|ὄργυιᾰ}}
{{#invoke:grc-utilities/templates|printTokens|τετληϋῖα}}
{{#invoke:grc-utilities/templates|printTokens|αὐτέ͜ων}}
{{#invoke:grc-utilities/templates|printTokens|οὐ δοκεῖν ἀλλ’ εἶναι ἀγαθὸν}}
|}
==Testcases==
{{grc-IPA|Γᾱ́δ}}
<includeonly>
{{module cat|grc}}
</includeonly>
o2m1v9n4ovliq8w7dcm9l42tpih2vkd
မဝ်ဂျူ:grc-utilities/templates/doc
828
296134
397308
2026-06-21T10:04:38Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. --> <includeonly> [[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]] [[ကဏ္ဍ:မဝ်ဂျူထာမ်ပလိက်အိန်တာဖှေတ်ဂမၠိုၚ်]] </includeonly>"
397308
wikitext
text/x-wiki
{{documentation needed}}<!-- Replace this with a short description of the purpose of the module, and how to use it. -->
<includeonly>
[[ကဏ္ဍ:မဝ်ဂျူဂရေတ်တြေံဂမၠိုၚ်]]
[[ကဏ္ဍ:မဝ်ဂျူထာမ်ပလိက်အိန်တာဖှေတ်ဂမၠိုၚ်]]
</includeonly>
s6f9wovsdbh21v5a0uqvpm0uhv480bt
ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဂရေတ်တြေံဂမၠိုၚ်
14
296135
397310
2026-06-21T10:10:43Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]"
397310
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
q4xjqyhicwe5dyrev3x72r9x4fbs253
ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်တြေံဂမၠိုၚ်
14
296136
397311
2026-06-21T10:12:13Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်ဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]"
397311
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်ဂရေတ်တြေံဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
8ohxt3x843tcqwn4avu6jbsv3nzv8zp
ထာမ်ပလိက်:el-nF-η-1
10
296137
397312
2026-06-21T10:15:19Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "<includeonly>{{el-decl-noun-unc |1={{{1}}}ή |2={{{1}}}ής |3={{{1}}}ή |4={{{1}}}ή |note={{{note|}}} }}{{#if:{{NAMESPACE}}|| }}</includeonly><noinclude> The inflection-table template for Greek nouns declining like '''{{m|el|ρομποτική}}'''. Other examples may be found in the [[:en:Category:Greek nouns declining like 'ρομποτική']]. The syntax <code><nowiki>{{el-nF-η-1|ρομποτικ}}</nowiki></..."
397312
wikitext
text/x-wiki
<includeonly>{{el-decl-noun-unc
|1={{{1}}}ή
|2={{{1}}}ής
|3={{{1}}}ή
|4={{{1}}}ή
|note={{{note|}}}
}}{{#if:{{NAMESPACE}}|| }}</includeonly><noinclude>
The inflection-table template for Greek nouns declining like '''{{m|el|ρομποτική}}'''. Other examples may be found in the [[:en:Category:Greek nouns declining like 'ρομποτική']].
The syntax <code><nowiki>{{el-nF-η-1|ρομποτικ}}</nowiki></code> produces the table:
{{el-nF-η-1|ρομποτικ}}
A full list of other declension-table templates with a brief indication of use can be found at '''[[:en:Wiktionary:Greek noun inflection-table templates]]'''.
{{tcat|ndecl}}
</noinclude>
2kwogkflt75e2rsrfig4li3s2ijou00
ထာမ်ပလိက်:el-decl-noun-unc
10
296138
397313
2026-06-21T10:18:58Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "{{inflection-table-top|title=မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{m-self|el|{{{1}}}|tr=-}}|palette=blue}} ! ! ကိုန်ဨကဝုစ် |- ! မဒုၚ်ယၟု | data-accel-col=1 | {{#switch:{{{1|}}}|-|—=—|{{l-self|el|{{{1}}}}}{{#if:{{{ns|}}}|<br>{{l-self|el|{{{ns|}}}}}}}}} |- ! ဗဳဇဂကူ | data-accel-col=1 | {{#switch:{{{2|}}}|-|—=—|{{l-self|el|{{{2}}}}}{{#if:..."
397313
wikitext
text/x-wiki
{{inflection-table-top|title=မလဟုတ်စှ်ေဆေၚ်စပ်ကဵု {{m-self|el|{{{1}}}|tr=-}}|palette=blue}}
!
! ကိုန်ဨကဝုစ်
|-
! မဒုၚ်ယၟု
| data-accel-col=1 | {{#switch:{{{1|}}}|-|—=—|{{l-self|el|{{{1}}}}}{{#if:{{{ns|}}}|<br>{{l-self|el|{{{ns|}}}}}}}}}
|-
! ဗဳဇဂကူ
| data-accel-col=1 | {{#switch:{{{2|}}}|-|—=—|{{l-self|el|{{{2}}}}}{{#if:{{{gs|}}}|<br>{{l-self|el|{{{gs|}}}}}}}}}
|-
! ကမ္မကာရက
| data-accel-col=1 | {{#switch:{{{3|}}}|-|—=—|{{l-self|el|{{{3}}}}}{{#if:{{{as|}}}|<br>{{l-self|el|{{{as|}}}}}}}}}
|-
! ပရေၚ်ဂယိုၚ်လမျီု
| data-accel-col=1 | {{#switch:{{{4|}}}|-|—=—|{{l-self|el|{{{4}}}}}{{#if:{{{vs|}}}|<br>{{l-self|el|{{{vs|}}}}}}}}}
{{inflection-table-bottom}}
{{{note|}}}{{#if:{{{note|}}}|{{#if:{{{note0|}}}|<br>}}}}{{{note0|}}}<noinclude>{{tcat|ndecl:*}}</noinclude>
2425xfr4s09s5nifzffhk437e24ro63
ကဏ္ဍ:ထာမ်ပလိက်ဂရေတ်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဂမၠိုၚ်
14
296139
397314
2026-06-21T10:20:45Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]"
397314
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏနာမ်ဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
ovefo4yy2w10oz2bz22bclz0kclsnru
ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဂရေတ်ဂမၠိုၚ်
14
296140
397315
2026-06-21T10:23:46Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ထာမ်ပလိက်ဂရေတ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]"
397315
wikitext
text/x-wiki
[[ကဏ္ဍ:ထာမ်ပလိက်ဂရေတ်ဂမၠိုၚ်]][[ကဏ္ဍ:ထာမ်ပလိက်အပြံၚ်အလှာဲပ္တဝ်ထ္ၜးပမာဏဗက်အလိုက်အရေဝ်ဘာသာဂမၠိုၚ်|ဂ]]
hccrbtbpcdn4r2bz4yluzwvi7xhnpvv
ကဏ္ဍ:ဝေါဟာဂရေတ်တြေံမဆက်ဆေန်စှ်ေကၠုၚ်နူတံရိုဟ်အိန်ဒဝ်-ယူရဝ်ပဳယာန်-အခိုက်ကၞာနကဵုအဆက်ဝေါဟာ *gerbʰ-
14
296141
397316
2026-06-21T10:25:15Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "[[ကဏ္ဍ:ဘာသာဂရေတ်တြေံ]]"
397316
wikitext
text/x-wiki
[[ကဏ္ဍ:ဘာသာဂရေတ်တြေံ]]
b78r5wynb9p48d12yi94n04wvs6y1s4
γραμματικῆς
0
296142
397317
2026-06-21T10:28:15Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==ဂရေတ်တြေံ== ===နာမ်=== {{head|grc|ဗီုပြၚ်နာမ်}} # {{plural of|grc|γραμματική}}"
397317
wikitext
text/x-wiki
==ဂရေတ်တြေံ==
===နာမ်===
{{head|grc|ဗီုပြၚ်နာမ်}}
# {{plural of|grc|γραμματική}}
nf2evai2vmt8fuepgrynkd25zotakq2
γρᾰμμᾰτῐκῆς
0
296143
397318
2026-06-21T10:28:25Z
咽頭べさ
33
ခၞံကၠောန်လဝ် မုက်လိက် နကု "==ဂရေတ်တြေံ== ===နာမ်=== {{head|grc|ဗီုပြၚ်နာမ်}} # {{plural of|grc|γραμματική}}"
397318
wikitext
text/x-wiki
==ဂရေတ်တြေံ==
===နာမ်===
{{head|grc|ဗီုပြၚ်နာမ်}}
# {{plural of|grc|γραμματική}}
nf2evai2vmt8fuepgrynkd25zotakq2