Wiktionary viwiktionary https://vi.wiktionary.org/wiki/Wiktionary:Trang_Ch%C3%ADnh MediaWiki 1.46.0-wmf.23 case-sensitive Phương tiện Đặc biệt Thảo luận Thành viên Thảo luận Thành viên Wiktionary Thảo luận Wiktionary Tập tin Thảo luận Tập tin MediaWiki Thảo luận MediaWiki Bản mẫu Thảo luận Bản mẫu Trợ giúp Thảo luận Trợ giúp Thể loại Thảo luận Thể loại Phụ lục Thảo luận Phụ lục TimedText TimedText talk Mô đun Thảo luận Mô đun Event Event talk bệ rạc 0 27341 2344289 2223117 2026-04-11T14:13:21Z Hiyuune 50834 2344289 wikitext text/x-wiki =={{langname|vi}}== ==={{section|pron}}=== {{vi-pron}} ==={{section|adj}}=== {{vie-adj}} # [[lôi thôi|Lôi thôi]], thiếu [[quy củ]], [[nền nếp]], [[lộ]] [[rõ]] sự thiếu [[nhân cách]] trong [[lối sống]]. #: {{ux|vi|Sống '''bệ rạc'''.}} #: {{ux|vi|Nhà cửa quá '''bệ rạc'''.}} ==={{section|ref}}=== * {{R:FVDP}} 8l47m1pxbwziny2np40l2ycgwp1zix9 kvikksølv 0 189368 2344419 1865619 2026-04-12T05:07:01Z Kelly zhrm 58416 2344419 wikitext text/x-wiki =={{langname|nb}}== {{wp|no:}} ==={{ĐM|etym}}=== Từ {{der|nb|non|kviksilfr}}. ==={{ĐM|pron}}=== * {{IPA4|nb|/kʋɪksœl/}} * {{rhymes|nb|œl}} ==={{ĐM|n}}=== {{nb-noun-nu}} # [[thủy ngân|Thủy ngân]] (''nguyên tố hóa học, ký hiệu'' '''[[Hg]]''') ==={{ĐM|ref}}=== * {{R:nb:OB}} {{C|nb|Nguyên tố hóa học}} =={{langname|nn}}== {{wp|nn:}} ==={{ĐM|alt}}=== * {{alt|nn|kvikksylv}} ==={{ĐM|etym}}=== Từ {{der|nn|non|kviksilfr}}. ==={{ĐM|n}}=== {{nn-noun-nu}} # [[thủy ngân|Thủy ngân]]. ==={{ĐM|ref}}=== * {{R:nn:OB}} {{C|nn|Nguyên tố hóa học}} aya80o5xhrx9yl2w4dvnbpbf0f10rd3 từ chương 0 192509 2344404 1937144 2026-04-12T04:56:10Z Hiyuune 50834 2344404 wikitext text/x-wiki {{also|từ-chương}} =={{langname|== ==={{section|alt}}=== * {{alter|vi|từ-chương}} ==={{section|etym}}=== {{vi-etym-sino|辭章}}. ==={{section|pron}}=== {{vi-pron}} ==={{section|n}}=== {{vi-noun}} # {{lb|vi|obsolete}} [[văn chương|Văn chương]] đẹp như [[thơ]], [[phú]] nhưng [[vô ích]] cho [[đời sống]]. #: {{ux|vi|Nạn '''từ chương''' trong nền học cũ.}} #* {{RQ:Tran Trong Kim Nho giao|page=14|volume=I|chapter=Lời phát đoan|url=https://vi.wikisource.org/wiki/Nho_gi%C3%A1o/Quy%E1%BB%83n_I/L%E1%BB%9Di_ph%C3%A1t_%C4%91oan|passage=Cách học tập của người mình lại chỉ vụ lấy '''từ-chương''', chuyên về khoa-cử để làm cái thang lợi danh.}} ==={{section|ref}}=== * {{R:FVDP}} isso2cdkthhv2132y4l7f253mcfllk5 2344405 2344404 2026-04-12T04:56:19Z Hiyuune 50834 2344405 wikitext text/x-wiki {{also|từ-chương}} =={{langname|vi}}== ==={{section|alt}}=== * {{alter|vi|từ-chương}} ==={{section|etym}}=== {{vi-etym-sino|辭章}}. ==={{section|pron}}=== {{vi-pron}} ==={{section|n}}=== {{vi-noun}} # {{lb|vi|obsolete}} [[văn chương|Văn chương]] đẹp như [[thơ]], [[phú]] nhưng [[vô ích]] cho [[đời sống]]. #: {{ux|vi|Nạn '''từ chương''' trong nền học cũ.}} #* {{RQ:Tran Trong Kim Nho giao|page=14|volume=I|chapter=Lời phát đoan|url=https://vi.wikisource.org/wiki/Nho_gi%C3%A1o/Quy%E1%BB%83n_I/L%E1%BB%9Di_ph%C3%A1t_%C4%91oan|passage=Cách học tập của người mình lại chỉ vụ lấy '''từ-chương''', chuyên về khoa-cử để làm cái thang lợi danh.}} ==={{section|ref}}=== * {{R:FVDP}} mg7ek0js8ur8ezoub1negjqvxx03rhn tormenta 0 243911 2344292 1931787 2026-04-11T14:30:27Z Kelly zhrm 58416 2344292 wikitext text/x-wiki =={{langname|en}}== ==={{ĐM|n}}=== {{head|en|Biến thể hình thái danh từ}} # {{plural of|en|tormentum}} ==={{ĐM|ana}}=== * {{anagrams|en|a=aemnortt|Metatron|no matter}} =={{langname|ast}}== ==={{ĐM|etym}}=== Từ {{der|ast|la|tormenta}}, số nhiều của {{mention|la|tormentum}}. ==={{ĐM|pron}}=== {{ast-pr}} ==={{ĐM|n}}=== {{ast-noun|f|tormentes}} # [[bão|Bão]]. ==={{ĐM|further}}=== * {{R:ast:DGLA}} * {{R:ast:DALLA}} =={{langname|es}}== ==={{ĐM|pron}}=== {{es-pr|+<audio:LL-Q1321 (spa)-AdrianAbdulBaha-tormenta.wav<a:Colombia>>}} ==={{ĐM|n}}=== {{es-noun|f}} # [[bão|Bão]]. #: {{syn|es|tempestad}} # [[giông|Giông]]. #: {{syn|es|tronada}} ===={{ĐM|drv}}==== {{col|es|tormenta de arena|tormenta de citocinas|tormenta de citoquinas|tormenta de ideas|tormenta de polvo|tormenta ígnea}} ===={{ĐM|rel}}==== {{col|es|tormento}} ==={{ĐM|ref}}=== <references/> ==={{ĐM|further}}=== * {{R:es:DRAE}} {{C|es|Thời tiết}} 5vjdl6fhm41uxmjxob0kw24n280ntwp 0 245507 2344391 2335741 2026-04-12T04:38:42Z Hiyuune 50834 /* Từ nguyên 1 */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]) 2344391 wikitext text/x-wiki {{also|头}} {{character info}} =={{langname|mul}}== {{stroke order|strokes=16}} ==={{section|han}}=== {{Han char|rn=181|rad=頁|as=07|sn=16|four=11186|canj=MTMBC|ids=⿰豆頁}} ===={{section|drv}}==== * {{charlist|sc=Hani|䕱}} {{col-top|1|Các ký tự dẫn xuất}} * {{charlist|sc=Hani|𭀆𫷒𢸸𤃌𨯲𡾣𨷩}} {{col-bottom}} ===={{section|rel}}==== * {{l-lite|mul|sc=Hans|头}} {{q-lite|{{w|chữ Hán giản thể}}}} ===={{section|ref}}==== {{Han ref|kx=1404.200|dkj=43490|dj=1921.130|hdz=74372.050|uh=982D}} =={{langname|vi}}== ==={{section|han}}=== {{vi-readings|reading=đầu|rs=頁07}} # {{lb|vi|anatomy}} [[đầu|Đầu]]. #: {{syn|vi|trốc}} =={{langname|jpx-hcj}}== ==={{ĐM|Kanji}}=== {{jpx-hcj-kanji}} ==={{ĐM|etym}}=== Cùng gốc với {{cog|ja|頭|tr=tsuburi}}. ==={{ĐM|noun}}=== {{jpx-hcj-head|noun|つぶり}} # [[đầu]]. =={{langname|ja}}== ==={{section|kanji}}=== {{ja-kanji|grade=2|rs=頁07}} # [[trán|Trán]]. # [[đầu|Đầu]]. # [[chủ nhân|Chủ nhân]]. # Đếm số lượng gia súc lớn (trâu, bò, ngựa). ===={{section|reading}}==== {{ja-readings |goon=ず<づ |kanon=とう<とう |toon=じゅう<ぢゆう |kanyoon=と |kun=あたま-, かしら-, かぶり-, こうべ-<かうべ-, かみ-, ほとり- |nanori=かぶ, かぶし, かみ, ちゃん, つぶり, つむ, つむり, づ, どたま }} ==={{section|etym}} 1=== {{etymid|ja|atama}} {{ja-kanjitab|あたま|yomi=k}} {{wp|ja:}} ===={{section|pron}}==== {{ja-pron|あたま|acc=3|acc_ref=DJR,NHK,<ref name="NKD2O_atama"/>|acc2=2|acc2_ref=DJR,NHK}} {{ja-accent-dialectal|region=Kyoto|k|あ|たま|áꜜtàmà|ref=<ref name="NKD2O_atama">{{R:ja:NKD2O|あたま 【頭・天窓】|lid=2002001764183y1rk2CW|kotobank=頭-22205#w-1866565}}</ref>}} {{ja-accent-historical|h=LLL|ref=<ref name="NKD2O_atama"/>}} ===={{section|n}}==== {{ja-noun|あたま}} # [[đầu|Đầu]]. #: {{syn|ja|びんた|q=phương ngữ, Kagoshima}} ====={{ĐM|desc}}===== * {{desc|ycr|atama}} ==={{section|etym}} 2=== {{etymid|ja|kashira}} {{ja-kanjitab|yomi=k|かしら|alt=首}} ===={{section|pron}}==== {{sense|danh từ}} {{ja-pron|かしら|acc=3|acc_ref=DJR,NHK,<ref name="NKD2O_kashira"/>}} {{ja-accent-dialectal|region=Kyoto|k|か|しら|káꜜshìrà|ref=<ref name="NKD2O_kashira">{{R:ja:NKD2O|かしら 【頭】|lid=200200d1bce38Q12u6x6|kotobank=頭-22205#w-1915250}}</ref>}} {{ja-accent-historical|h=LLL|k=LLL|m=HHL|e=HHL|ref=<ref name="NKD2O_kashira"/>}} ===={{section|counter}}==== {{ja-pos|counter|かしら}} # Đếm số lượng [[gia súc]] lớn. ===={{section|n}}==== {{ja-noun|かしら}} # {{ja-def|頭}} [[ông|Ông]] [[chủ]]; [[sếp]]. ==={{section|etym}} 3=== {{etymid|ja|kaburi}} {{ja-kanjitab|かぶり|yomi=k}} ===={{section|pron}}==== {{ja-pron|かぶり|acc=0|acc_ref=DJR,NHK|acc2=3|acc2_ref=DJR,NHK,<ref name="NKD2O_kaburi"/>|acc3=1|acc3_ref=DJR,NHK,<ref name="NKD2O_kaburi"/>}} {{ja-accent-dialectal|region=Kyoto|k-0|かぶり|kábúrí|ref=<ref name="NKD2O_kaburi">{{R:ja:NKD2O|かぶり 【頭】|lid=200200e4a818lnZeX4f1|kotobank=頭-22205#w-1920202}}</ref>}} ===={{section|n}}==== {{ja-noun|かぶり}} # [[đầu|Đầu]]. ==={{section|etym}} 4=== {{etymid|ja|kabu}} {{ja-kanjitab|かぶ|yomi=irr}} ===={{section|pron}}==== {{ja-pron|かぶ}} ===={{section|n}}==== {{ja-noun|かぶ}} # {{lb|ja|obsolete|_|or|_|Yamagata|sort=かぶ}} [[đầu|Đầu]]. ===={{section|ref}}==== <references/> :* {{R:Kanjipedia Kotoba|0005233000|<sup>△</sup>頭}} =={{langname|zh}}== {{zh-forms|s=头|alt=䫁,𥘖}} ==={{section|glyph origin}}=== {{Han etym}} {{Han compound|豆|頁|ls=psc|c1=p|c2=s|t2=đầu}}. ==={{section|etym}}=== Kết hợp hình-thanh ([[形聲]]): [[豆]]([[đậu]]) + [[頁]]([[hiệt]]). ==={{section|pron}} 1=== {{zh-pron |m=tóu |m-s=tou2 |m-x=tóu |m-nj=tóu |dg=ту1 |c=tau4,tau4-2 |ca=LL-Q9186-Justinrleung-頭.wav |c_note=tau4-2 |c-dg=taau4 |c-t=heu3,heu3* |c-t_note=heu3* |c-yj=tau4 |g=teu2 |h=pfs=thèu;hrs=h:teu;gd=têu2 |j=tou1 |mb=tê |md=tàu |mn=ml,jj,tp,kh,tn,tc,hc,lk,sx,yl,km,mg,pn,ph,sg:thâu/xm,zz,yl,km,mg:thô͘/qz,jj,tp,kh,tn,lk,sx,hc:thiô |mn_note=thâu - vernacular; thô͘/thiô - văn chương |mn-t=tao5 |mn-l=tao5 |px=pt,xy:tao2/pt,xy:tieo2 |px_note=tao2 - vernacular; tieo2 - văn chương |sp=dau4 |w-j=3tieu,2dieu |x=dou2 |x-l=ddieu2 |x-h=dou2 |mc=y |oc=y |ma=y |cat=n,cls,a }} ===={{section|dfn}}==== {{head|zh|Hanzi}} # [[đầu|Đầu]] ([[bộ phận]] trên [[chóp]] [[cơ thể]]). # [[tóc|Tóc]]; [[kiểu]] [[tóc]]. # [[đầu|Đầu]] (phần trước nhất hoặc phần trên cùng). # [[đầu tiên|Đầu tiên]]. # [[chủ nhân|Chủ nhân]]. ====={{section|syn}}===== {{zh-dial}} {{zh-dial|頭-2}} {{zh-dial|頭-3}} {{zh-dial|口-2}} {{zh-dial|匹}} {{zh-dial|隻}} {{zh-dial|條}} {{zh-dial|朵}} ==={{section|pron}} 2=== {{zh-pron |m=tou |m-s=tou2 |dg= |c=tau4,tau4-2 |c-t=heu3,heu4 |g=teu/teu2 |h=pfs=thèu;hrs=h:teu;gd=têu2 |j=tou2 |mb=tê |md=tàu |mn=ml,tp,kh,tn,tc,hc,lk,sx,yl,km,mg,pn,sg:thâu/xm,zz,yl,km,mg:thô͘/qz,tp,kh,tn,lk,sx,hc:thiô/tp,kh,tn,lk,sx,yl,tc:thô |mn_note=thâu - ngôn ngữ bản địa; thô͘/thiô - văn chương; thô - chỉ dùng với {{l-lite|zh|sc=Hani|饅頭}} |mn-t=tao5 |px=pt,xy:tao2/pt,xy:tieo2 |px_note=tao2 - ngôn ngữ bản địa; tieo2 - văn chương |w=sh:6deu |x=dou |dial=n |mc=y |oc=y |ma=y |cat=suf }} ===={{section|dfn}}==== {{head|zh|Hanzi}} # {{gloss|[[hậu tố|Hậu tố]] của [[danh từ]]}}. ==={{section|compound}}=== {{col3|zh|一彆頭|一托頭|一踅頭|一頭|三道頭|三頭兩日|三頭兩緒|三頭兩面|三頭六臂|三頭對案|三頭臂肌|上流頭|上頭|下場頭|下溜頭|下頭|不妨頭|不律頭|不徹頭|不是頭|不防頭|並頭|丫頭|丹頭|九頭鳥|乞頭|乳頭|亂頭|事頭|二婚頭|二鍋頭|二頭股肌|二頭臂肌|五路總頭|交頭接耳|人頭|伸頭探腦|伸頭縮頸|低頭|佛頭著糞|作鼻子頭|來頭|依頭縷當|依頭順尾|俏頭|個頭|倒頭|倔頭倔腦|做頭|停頭|傲頭傲腦|傻頭傻腦|兆頭|先頭|光頭|兌頭|兜頭|入頭|兩頭|冒頭|冤頭|出人頭地|出頭|刀頭|分頭|刊頭|初頭|判官頭|刮頭|到頭|刺兒頭|剃胎頭|剃頭|前頭|剪頭|剷頭|劈頭|劍頭一吷|力巴頭|力把兒頭|勁頭|務頭|勢頭|勾頭|包葫蘆頭|包頭|匹頭|千頭橘奴|千頭百緒|千頭萬緒|占鰲頭|卸頭|原頭|參頭|口頭|叩頭|叫頭|吃回頭草|合頭|名頭|吳頭楚尾|呆腦呆頭|呆頭呆腦|呆頭木腦|和頭|咬頭|咽頭|哀江頭|品頭論足|品頭題足|唱頭|問頭|喉頭|喚頭|嘑頭|嘴頭|噴頭|噱頭|囂頭|囊頭|回頭|因頭|圓頭|團頭|土頭土腦|地頭|坐頭|垂頭|埋頭|埠頭|埤頭鄉|堂頭和尚|報頭|堵頭|堽頭|塊頭|塔頭|境頭|墳頭|壽頭|外頭|多頭|大姊頭|大姐頭|大拍頭|大頭|夫頭|奉頭鼠竄|套頭|奶頭|姘頭|媒頭|媽媽頭|字頭|孩子頭|孱頭|容頭過身|宿頭|寡頭|尋頭討腦|對頭|小頭|少頭無尾|尖頭|尺頭|屯頭|山頭|工頭|巨頭|巴頭探腦|布頭|帕頭|帩頭|帶頭|平頭|年頭|幹頭|床頭|店頭|座頭|廚頭灶腦|龐克頭|弔頭|引頭|彈頭|彩頭|後頭|得勝頭迴|從頭|德勝頭迴|徹頭徹尾|心頭|念短頭經|念頭|怪頭|怯頭怯惱|悟頭詩|悶頭|想頭|意頭|愣頭兒青|愣頭愣腦|愣頭磕腦|懸頭|戇頭戇腦|成頭|戥頭|截頭渡|戲頭|戴頭識臉|戶頭|房頭|手頭|扒頭探腦|打出頭棍|打攔頭雷|打沒頭壇|打破頭|打碗頭|打輪頭|打頭|打鼓津頭|扛頭|扣頭|扭頭折頸|扭頭暴筋|扭頭瞥項|扯頭|扳差頭|扶頭|批頭|找頭|承頭|把頭|抓頭挖耳|折頭|披頭|抬頭|抱頭|抵頭|抹頭|押頭|抽頭|抿頭|拈頭|拋頭露面|拐子頭|拔頭|拘頭|招頭|拳頭|拾頭打滾|指頭|挑頭|捉頭|捕頭|捧頭鼠竄|掉頭|掐頭去尾|排頭|掠頭|探頭|接耳交頭|接頭|推頭|提頭|插頭|換頭|搔頭|搖頭|搞頭|搭頭|摟頭|摣頭|摸頭|撐頭獲腦|撓頭|撞頭搕腦|撥頭|撲頭撲臉|撳頭低|攏頭|攬頭|改頭換面|放頭|教頭|敵頭|斧頭|斫頭|斷頭|方頭|旄頭|旗頭|日頭|昂頭挺立|昏頭|暈頭|曆頭|更頭|替頭|會頭|月頭|朋頭|木頭|本頭|朴實頭|杆子頭|杖子頭|杖頭|枋頭|枕頭|枝頭|柱頭|柴頭|根頭|案頭|梆兒頭|梢頭|梳頭|棒頭|楚尾吳頭|楞頭青|楥頭|楦頭|極頭麻化|榔頭|榫頭|槓子頭|槓頭|槽頭|樸實頭|橋頭|橫頭|歌頭|正頭|步頭|殘頭落腳|段頭|殺頭|殿頭官|毛頭|氣頭上|水頭|汕頭|沒頭仰仗|沒頭公事|沒頭告示|沒頭官司|沒頭帖子|沒頭案子|沒頭沒腦|沒頭沒臉|沒頭神|沒頭脫柄|沒頭蒼蠅|沒頭蹲|沒頭鬼|油頭|泛頭|泥頭|洗頭|派頭|浪頭|浮頭|淨頭|混頭混腦|清頭|渡頭|游頭浪子|湯頭|源頭|準頭|溪頭|滑頭|滿頭|澆頭|灘頭|火頭|灰頭土臉|灰頭土面|灰頭草面|灶頭|炕頭子貨|為頭|烏頭|無頭公案|無頭告示|無頭官事|無頭案|無頭無尾|無頭無腦|無頭罪|無頭蒼蠅|無頭願|焦頭爛額|熬頭|燈頭|燋頭爛額|爛羊頭|爛額焦頭|爭頭鼓腦|牆頭|片頭|牌頭|牛頭|牢頭|牽頭|犀頭|狀頭|狗血淋頭|狗頭軍師|狼吃幞頭|猴頭|獃頭獃腦|獅子頭|獐頭鼠目|獨占鰲頭|班頭|甕頭春|甜頭|田頭|由頭|甲頭|畏頭畏尾|留頭|當頭|疋頭|疏頭|疢頭怪腦|瘌痢頭|癩頭|癲頭癲腦|發頭|白頭|百丈竿頭|百尺竿頭|皮頭夯腦|盔頭|盡頭|盤子頭|直頭布袋|盼頭|眉頭|看頭|看香頭的|矇頭轉向|矛頭|短頭|石頭|砍頭|砧頭|破頭楔|硬頭硬腦|碰頭|磁頭|碼頭|磕素頭|磕過頭的|磕頭|磚頭|磨頭|礬頭|社頭|神頭鬼臉|神頭鬼面|禍種頭|萬丈竿頭|萬緒千頭|萬頭攢動|禿頭|科頭|空頭|窩頭|竹頭木屑|竿頭一步|笨頭笨腦|筆頭|管頭|箭頭|篙頭|篦頭|籠頭|米酒頭|粉頭|糟頭|紅頭|納頭|紙糊頭|索頭|組頭|絡頭|綃頭|綠頭鴨|綵頭|線頭|縮頭烏龜|縮頭縮腦|縮頭縮腳|纏頭|缽盂頭|缽頭|罐頭|羊胃羊頭|羊頭狗肉|老實頭|老頭|耐頭|聚頭|聳頭聳腦|聽頭|肉頭|肥頭大耳|肩頭|胖頭魚|腰頭硬|腳頭|臉紅頭脹|臘鎗頭|臨頭|臭頭|臼頭深目|興頭|舉頭|舌頭|舒頭|船頭|芋頭|芒頭|花頭|苗頭|苦頭|茶頭|草頭大王|草頭天子|草頭方兒|草頭神|草頭藥|草頭露|菜頭|菸頭|著糞佛頭|蒙頭|蒜頭|蒼頭|蓋頭|蓬頭|蔥頭|薄頭|薦頭|藏頭亢腦|藏頭漏影|藏頭露尾|藥頭|蘇頭|蘿蔔頭|虎頭|虛頭|號頭|蛇頭鼠眼|蛋頭|蠅頭|蠟槍頭|蠶頭燕尾|行頭|街頭|衲頭|袁頭|被頭|裡頭|裹頭|襆頭|角頭|解頭|討頭|訛頭|評頭品足|評頭評足|評頭論足|詞頭|話頭|認犯頭|認頭|課頭|調頭|論頭|謎頭|護頭|豬頭肥|豹頭猿臂|豹頭環眼|貓兒頭|貓頭鷹|買頭|賊頭賊腦|賊頭鼠腦|賣頭賣腳|賺頭|走頭無路|起頭|趁頭|跟頭|路頭|車頭|軍頭|轉頭|轡頭|辭頭|辮穗頭|迎頭|迭頭|迷頭|這頭|通頭|連頭帶尾|過頭|道頭會尾|道頭知尾|遨頭|邊頭|都頭|鄉頭|配頭|醜頭怪臉|采頭|重頭戲|金頭銀面|釘頭|針頭|釵頭符|釵頭鳳|鈍頭|鈿頭雲篦|銅頭鐵額|鋒頭|鋤頭|鋪頭|鎖頭|鎬頭|鏟頭|鏡頭|鐘頭|鐺頭|鑞鎗頭|鑽頭|钁頭|長頭布|門頭|開頭|關頭|陌頭|陣頭|隅頭|隱頭花序|隴頭音信|雌一頭灰|雙頭汽鍋|雙頭火杖|雙頭馬車|雞頭|雲頭|零頭|霉頭|霞頭|露尾藏頭|露面拋頭|露頭|靈頭幡|青龍頭上|鞠部頭|韻頭|響頭|頂頭|順頭順腦|領頭|頭一|頭七|頭上安頭|頭上抹下|頭上末下|頭上長角,身上長刺|頭主|頭人|頭伏|頭位|頭信|頭像|頭先|頭兒|頭到|頭前|頭功|頭勢|頭匹|頭半天|頭口|頭名|頭哨|頭回|頭囟|頭場|頭大|頭天|頭套|頭妻|頭子|頭家|頭寸|頭對|頭尾|頭屑|頭巾|頭年|頭廳|頭彩|頭影|頭役|頭懸目眩|頭房|頭手鼓|頭把兒|頭抵|頭挑|頭攔|頭敵|頭明|頭昏|頭晌|頭晚|頭暈|頭會箕斂|頭會箕賦|頭朝裡|頭板|頭條|頭梢|頭櫃|頭正|頭水|頭油|頭燈|頭版|頭牌|頭牙|頭獎|頭班車|頭球|頭由|頭當|頭疼|頭痛|頭癢搔跟|頭癬|頭皮|頭盔|頭目|頭直上|頭眩|頭眼|頭破血出|頭破血流|頭破血淋|頭稍|頭童齒豁|頭等|頭箍兒|頭管|頭籌|頭紗|頭絮兒|頭緒|頭繩|頭罩|頭翁|頭肘子|頭胎|頭胸部|頭腦|頭臉|頭茬|頭蓋|頭蓬眼瘇|頭號|頭蝨|頭行|頭裡|頭角|頭足異所|頭足異處|頭足願|頭路|頭踏|頭輕腳重|頭迓|頭道|頭達|頭遭|頭部|頭醋|頭里|頭重腳輕|頭重身輕|頭銜|頭錢|頭陀|頭陣|頭雁|頭難|頭面|頭頂|頭項|頭領|頭頭|頭頸|頭顱|頭風|頭食|頭飾|頭首|頭香|頭馬|頭骨|頭高|頭髮|頭髲|頭髻|頭鵝|頷頭|額頭|顛頭聳腦|風頭|飯頭|饃頭|饅頭|饒頭|香頭|馬快頭|馬頭|駁頭|駕頭|骨頭|骲頭|高頭|髦頭|鬅頭|鬥頭|鬼頭|魁頭|魔頭|魚頭|鰲頭獨占|鱉縮頭|鳳頭鞋|鴉頭襪|鴨頭|黃頭郎|黑頭|點頭|鼇頭|鼓腦爭頭|鼠目獐頭|鼻子頭|鼻頭|齊頭|齒豁頭童|龍頭|龜頭|廟頭|大頭菜|青字頭|南河頭|黃山頭|後頭灣|扒頭|西頭|鹿頭|髦字頭|卷字頭|竹字頭|西字頭|登字頭|虎字頭|四字頭|爪字頭|老字頭|樹頭|臺頭|魚窩頭|硬著頭皮|水龍頭|斜刀頭|負字頭|包字頭|句字頭|風字頭|六字頭|京字頭|玄字頭|蘭字頭|冒字頭|石屋頭|頭筆|火車頭|頭城|攝像頭|埤頭|頭屋|頭份|方頭括號|煙頭|回頭是岸|頭盤|蓬頭垢面|琯頭|嶼頭|虎頭蜂|捅頭|頭鬃|阿頭|nan:穡頭<tr:sit-thâu>|頭北話|nan:無頭神<tr:bô-thâu-sîn>|蠶頭雁尾|蒻頭|螭頭舫|偏頭關}} ==={{section|desc}}=== {{CJKV|頭|ず|j2=とう|두|đầu}} ''Khác'': * {{desc|tai-pro|*truǝᴬ|t=đầu|bor=1|unc=1}} ** {{desc|aho|𑜑𑜥|𑜍𑜥|𑜍𑜤𑜈𑜫}} ** {{desc|lo|ຫົວ}} ** {{desc|khb|ᦷᦠ}} ** {{desc|nod|ᩉ᩠ᩅᩫ}} ** {{desc|shn|ႁူဝ်}} ** {{desc|blt|ꪬꪺ}} ** {{desc|th|หัว}} ** {{desc|za|hu}} * {{desc|tai-pro|bor=1}} ** {{desc|aho|𑜄𑜥|𑜄𑜤}} ** {{desc|pcc|duez}} ** {{desc|lo|ໂຕ|ຕົວ}} ** {{desc|khb|ᦷᦎ}} ** {{desc|nod|ᨲᩫ᩠ᩅ}} ** {{desc|skb|ทั๊ว}} ** {{desc|shn|တူဝ်}} ** {{desc|blt|ꪶꪔ}} ** {{desc|th|ตัว}} ** {{desc|za|duz}} ==={{section|ref}}=== * {{R:yue:Hanzi}} * {{R:twedu|A04555}} mr2w4ixyw6vfcfzo8voowpcv9t9ig2q 나비 0 246296 2344291 2344265 2026-04-11T14:18:02Z TheHighFighter2 42988 /* Danh từ */ 2344291 wikitext text/x-wiki =={{langname|jje}}== ==={{section|pron}}=== {{jje-IPA}} ==={{section|etym}} 1=== Từ {{inh|jje|okm|나ᄇᆡ〮|tr=nàpóy}}. Cùng gốc từ {{cog|ko|나비}}. ===={{section|n}}==== {{head|jje|Danh từ}} # Con [[bướm]]. ==={{section|etym}} 2=== ===={{section|n}}==== {{head|jje|noun}} # {{alternative form of|jje|납|t=[[tiền]]}} {{C|jje|Lớp Côn trùng}} =={{langname|ko}}== ==={{section|etym}} 1=== [[image:C-Falter Polygonia C-album.jpg|thumb|right|{{m-self|ko|나비}}]] {{ko-etym-native|ne|나ᄇᆡ〮|nàpóy}} {{ko-etym-native|bdb|나뵈〮|nàpwóy|also=y}} {{etystub|ko}} ===={{section|pron}}==== {{ko-IPA}} * {{ko-tone|HL}} ===={{section|n}}==== {{ko-noun}} # Con [[bướm]] #: {{syn|ko|호접(胡蝶)|호접(蝴蝶)}} ====={{section|drv}}===== * {{ko-l|왕나비||bướm hổ cánh nâu}} ====={{section|rel}}===== * {{l|ko|나방}} ==={{section|etym}} 2=== ===={{section|pron}}==== {{ko-IPA}} ===={{section|n}}==== {{ko-noun}} # {{lb|ko|childish}} Con [[mèo]] con. ====={{section|see}}===== * {{l|ko|고양이|t=mèo}} ===={{section|ref}}==== * {{cite-journal|title=ko:'원숭이'의 어휘사|trans-title=A lexical history of [words for] "monkey"|author={{lang|ko|허인영}} (Heo In-yeong)|year=2019|journal=Han'gugeohak|volume=83|pages=243–272}} mowgdrkg5ncrb0ijaisj8hyye2f8un1 照貓畫虎 0 253994 2344379 2065346 2026-04-12T04:26:05Z Hiyuune 50834 2344379 wikitext text/x-wiki =={{langname|zh}}== {{zh-forms|s=照猫画虎}} ==={{section|pron}}=== {{zh-pron |m=zhàomāohuàhǔ |c=ziu3 maau1 waak6 fu2 |cat=cy }} ==={{section|idiom}}=== {{head|zh|Thành ngữ}} # [[chiếu|Chiếu]] [[miêu]] [[họa]] [[hổ]]: [[trông]] theo [[mèo]] [[vẽ]] hổ, [[bắt chước]] [[làm theo]]. ===={{section|syn}}==== * {{zh-l|照葫蘆畫瓢}} * {{zh-l|依樣畫葫蘆}} 517gccagn58k3zgxtzk223hre5yohal little by little 0 254706 2344442 2002401 2026-04-12T07:26:29Z TheHighFighter2 42988 2344442 wikitext text/x-wiki =={{langname|en}}== ==={{ĐM|adv}}=== {{head|en|adverb}} # Từng [[chút]] một; [[dần dà]]; [[lần lần]]. ==={{ĐM|ref}}=== * {{R:Lexico}} {{cln|en|Cặp đẳng kết lặp|Ngữ tuyến tính khẳng định}} p8jdbil9y0gdctjwodafger10obwbur 芒芒 0 254792 2344381 2015065 2026-04-12T04:27:28Z Hiyuune 50834 2344381 wikitext text/x-wiki =={{langname|zh}}== ==={{section|pron}}=== {{zh-pron|m=mángmáng}} ==={{section|adj}}=== {{head|zh|Tính từ}} # [[mang mang|Mang mang]]. b3aw36qhytdxgz1dvm3knvmitgxssum Mô đun:links 828 256182 2344294 2334570 2026-04-11T15:21:43Z TheHighFighter2 42988 2344294 Scribunto text/plain local export = {} --[=[ [[Unsupported titles]], pages with high memory usage, extraction modules and part-of-speech names are listed at [[Module:links/data]]. Other modules used: [[Module:script utilities]] [[Module:scripts]] [[Module:languages]] and its submodules [[Module:gender and number]] [[Module:debug/track]] ]=] local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local gender_and_number_module = "Module:gender and number" local languages_module = "Module:languages" local load_module = "Module:load" local memoize_module = "Module:memoize" local pages_module = "Module:pages" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local script_utilities_module = "Module:script utilities" local string_encode_entities_module = "Module:string/encode entities" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local ucfirst = require("Module:string utilities").ucfirst local concat = table.concat local find = string.find local get_current_title = mw.title.getCurrentTitle local insert = table.insert local ipairs = ipairs local match = string.match local new_title = mw.title.new local pairs = pairs local remove = table.remove local sub = string.sub local toNFC = mw.ustring.toNFC local tostring = tostring local type = type local unstrip = mw.text.unstrip local NAMESPACE = get_current_title().nsText local function anchor_encode(...) anchor_encode = require(memoize_module)(mw.uri.anchorEncode, true) return anchor_encode(...) end local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function decode_uri(...) decode_uri = require(string_utilities_module).decode_uri return decode_uri(...) end -- Can't yet replace, as the [[Module:string utilities]] version no longer has automatic double-encoding prevention, which requires changes here to account for. local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_genders(...) format_genders = require(gender_and_number_module).format_genders return format_genders(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function get_current_L2(...) get_current_L2 = require(pages_module).get_current_L2 return get_current_L2(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function request_script(...) request_script = require(script_utilities_module).request_script return request_script(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function tag_translit(...) tag_translit = require(script_utilities_module).tag_translit return tag_translit(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local m_headword_data local function get_headword_data() m_headword_data = load_data("Module:headword/data") return m_headword_data end local function track(page, code) local tracking_page = "links/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function selective_trim(...) -- Unconditionally trimmed charset. local always_trim = "\194\128-\194\159" .. -- U+0080-009F (C1 control characters) "\194\173" .. -- U+00AD (soft hyphen) "\226\128\170-\226\128\174" .. -- U+202A-202E (directionality formatting characters) "\226\129\166-\226\129\169" -- U+2066-2069 (directionality formatting characters) -- Standard trimmed charset. local standard_trim = "%s" .. -- (default whitespace charset) "\226\128\139-\226\128\141" .. -- U+200B-200D (zero-width spaces) always_trim -- If there are non-whitespace characters, trim all characters in `standard_trim`. -- Otherwise, only trim the characters in `always_trim`. selective_trim = function(text) if text == "" then return text end local trimmed = trim(text, standard_trim) if trimmed ~= "" then return trimmed end return trim(text, always_trim) end return selective_trim(...) end local function escape(text, str) local rep repeat text, rep = text:gsub("\\\\(\\*" .. str .. ")", "\5%1") until rep == 0 return (text:gsub("\\" .. str, "\6")) end local function unescape(text, str) return (text :gsub("\5", "\\") :gsub("\6", str)) end -- Remove bold, italics, soft hyphens, strip markers and HTML tags. local function remove_formatting(str) str = str :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") return (unstrip(str) :gsub("<[^<>]+>", "")) end --[==[Takes an input and splits on a double slash (taking account of escaping backslashes).]==] function export.split_on_slashes(text) if text:find("\\", nil, true) then track("escaped", "split_on_slashes") end text = split(escape(text, "//"), "//", true) or {} for i, v in ipairs(text) do text[i] = unescape(v, "//") if v == "" then text[i] = false end end return text end --[==[Takes a wikilink and outputs the link target and display text. By default, the link target will be returned as a title object, but if `allow_bad_target` is set it will be returned as a string, and no check will be performed as to whether it is a valid link target.]==] function export.get_wikilink_parts(text, allow_bad_target) -- TODO: replace `allow_bad_target` with `allow_unsupported`, with support for links to unsupported titles, including escape sequences. if ( -- Filters out anything but "[[...]]" with no intermediate "[[" or "]]". not match(text, "^()%[%[") or -- Faster than sub(text, 1, 2) ~= "[[". find(text, "[[", 3, true) or find(text, "]]", 3, true) ~= #text - 1 ) then return nil, nil end local pipe, title, display = find(text, "|", 3, true) if pipe then title, display = sub(text, 3, pipe - 1), sub(text, pipe + 1, -3) else title = sub(text, 3, -3) display = title end if allow_bad_target then return title, display end title = new_title(title) -- No title object means the target is invalid. if title == nil then return nil, nil -- If the link target starts with "#" then mw.title.new returns a broken -- title object, so grab the current title and give it the correct fragment. elseif title.prefixedText == "" then local fragment = title.fragment if fragment == "" then -- [[#]] isn't valid return nil, nil end title = get_current_title() title.fragment = fragment end return title, display end -- Does the work of export.get_fragment, but can be called directly to avoid unnecessary checks for embedded links. local function get_fragment(text) text = escape(text, "#") -- Replace numeric character references with the corresponding character (&#39; → '), -- as they contain #, which causes the numeric character reference to be -- misparsed (wa'a → wa&#39;a → pagename wa&, fragment 39;a). text = decode_entities(text) local target, fragment = text:match("^(.-)#(.+)$") target = target or text target = unescape(target, "#") fragment = fragment and unescape(fragment, "#") return target, fragment end --[==[Takes a link target and outputs the actual target and the fragment (if any).]==] function export.get_fragment(text) if text:find("\\", nil, true) then track("escaped", "get_fragment") end -- If there are no embedded links, process input. local open = find(text, "[[", nil, true) if not open then return get_fragment(text) end local close = find(text, "]]", open + 2, true) if not close then return get_fragment(text) -- If there is one, but it's redundant (i.e. encloses everything with no pipe), remove and process. elseif open == 1 and close == #text - 1 and not find(text, "|", 3, true) then return get_fragment(sub(text, 3, -3)) end -- Otherwise, return the input. return text end --[==[ Given a link target as passed to `full_link()`, get the actual page that the target refers to. This removes bold, italics, strip markets and HTML; calls `makeEntryName()` for the language in question; converts targets beginning with `*` to the Reconstruction namespace; and converts appendix-constructed languages to the Appendix namespace. Returns up to three values: # the actual page to link to, or {nil} to not link to anything; # how the target should be displayed as, if the user didn't explicitly specify any display text; generally the same as the original target, but minus any anti-asterisk !!; # the value `true` if the target had a backslash-escaped * in it (FIXME: explain this more clearly). ]==] function export.get_link_page_with_auto_display(target, lang, sc, plain) local orig_target = target if not target then return nil elseif target:find("\\", nil, true) then track("escaped", "get_link_page") end target = remove_formatting(target) if target:sub(1, 1) == ":" then track("initial colon") -- FIXME, the auto_display (second return value) should probably remove the colon return target:sub(2), orig_target end local prefix = target:match("^(.-):") -- Convert any escaped colons target = target:gsub("\\:", ":") if prefix then -- If this is an a link to another namespace or an interwiki link, ensure there's an initial colon and then -- return what we have (so that it works as a conventional link, and doesn't do anything weird like add the term -- to a category.) prefix = ulower(trim(prefix)) if prefix ~= "" and ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then return target, orig_target end end -- Check if the term is reconstructed and remove any asterisk. Also check for anti-asterisk (!!). -- Otherwise, handle the escapes. local reconstructed, escaped, anti_asterisk if not plain then target, reconstructed = target:gsub("^%*(.)", "%1") if reconstructed == 0 then target, anti_asterisk = target:gsub("^!!(.)", "%1") if anti_asterisk == 1 then -- Remove !! from original. FIXME! We do it this way because the call to remove_formatting() above -- may cause non-initial !! to be interpreted as anti-asterisks. We should surely move the -- remove_formatting() call later. orig_target = orig_target:gsub("^!!", "") end end end target, escaped = target:gsub("^(\\-)\\%*", "%1*") if not (sc and sc:getCode() ~= "None") then sc = lang:findBestScript(target) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). if (not sc:hasCapitalization()) and sc:isTransliterated() and target:match("%^") then target = escape(target, "^") :gsub("%^", "") target = unescape(target, "^") end -- Get the entry name for the language. target = lang:makeEntryName(target, sc, reconstructed == 1 or lang:hasType("appendix-constructed")) -- If the link contains unexpanded template parameters, then don't create a link. if target:match("{{{.-}}}") then -- FIXME: Should we return the original target as the default display value (second return value)? return nil end -- Link to appendix for reconstructed terms and terms in appendix-only languages. Plain links interpret * -- literally, however. if reconstructed == 1 then if lang:getFullCode() == "und" then -- Return the original target as default display value. If we don't do this, we wrongly get -- [Term?] displayed instead. return nil, orig_target end target = "Từ tái tạo:" .. ucfirst(lang:getFullName()) .. "/" .. target -- Reconstructed languages and substrates require an initial *. elseif anti_asterisk ~= 1 and (lang:hasType("reconstructed") or lang:getFamilyCode() == "qfa-sub") then error(("The specified language %s is unattested, while the term '%s' does not begin with '*' to indicate that it is reconstructed."): format(lang:getCanonicalName(), orig_target)) elseif lang:hasType("appendix-constructed") then target = "Phụ lục:" .. ucfirst(lang:getFullName()) .. "/" .. target else target = target end return target, orig_target, escaped > 0 end function export.get_link_page(target, lang, sc, plain) local target, auto_display, escaped = export.get_link_page_with_auto_display(target, lang, sc, plain) return target, escaped end -- Make a link from a given link's parts local function make_link(link, lang, sc, id, isolated, cats, no_alt_ast, plain) -- Convert percent encoding to plaintext. link.target = link.target and decode_uri(link.target, "PATH") link.fragment = link.fragment and decode_uri(link.fragment, "PATH") -- Find fragments (if one isn't already set). -- Prevents {{l|en|word#Etymology 2|word}} from linking to [[word#Etymology 2#English]]. -- # can be escaped as \#. if link.target and link.fragment == nil then link.target, link.fragment = get_fragment(link.target) end -- Process the target local auto_display, escaped link.target, auto_display, escaped = export.get_link_page_with_auto_display(link.target, lang, sc, plain) -- Create a default display form. -- If the target is "" then it's a link like [[#English]], which refers to the current page. if auto_display == "" then auto_display = (m_headword_data or get_headword_data()).pagename end -- If the display is the target and the reconstruction * has been escaped, remove the escaping backslash. if escaped then auto_display = auto_display:gsub("\\([^\\]*%*)", "%1", 1) end -- Process the display form. if link.display then local orig_display = link.display link.display = lang:makeDisplayText(link.display, sc, true) if cats then auto_display = lang:makeDisplayText(auto_display, sc) -- If the alt text is the same as what would have been automatically generated, then the alt parameter is redundant (e.g. {{l|en|foo|foo}}, {{l|en|w:foo|foo}}, but not {{l|en|w:foo|w:foo}}). -- If they're different, but the alt text could have been entered as the term parameter without it affecting the target page, then the target parameter is redundant (e.g. {{l|ru|фу|фу́}}). -- If `no_alt_ast` is true, use pcall to catch the error which will be thrown if this is a reconstructed lang and the alt text doesn't have *. if link.display == auto_display then insert(cats, "Liên kết mục từ có tham số alt thừa " .. lang:getFullName()) else local ok, check if no_alt_ast then ok, check = pcall(export.get_link_page, orig_display, lang, sc, plain) else ok = true check = export.get_link_page(orig_display, lang, sc, plain) end if ok and link.target == check then insert(cats, "Liên kết mục từ có tham số mục tiêu thừa " .. lang:getFullName()) end end end else link.display = lang:makeDisplayText(auto_display, sc) end if not link.target then return link.display end -- If the target is the same as the current page, there is no sense id -- and either the language code is "und" or the current L2 is the current -- language then return a "self-link" like the software does. if link.target == get_current_title().prefixedText then local fragment, current_L2 = link.fragment, get_current_L2() if ( fragment and fragment == current_L2 or not (id or fragment) and (lang:getFullCode() == "und" or lang:getFullName() == current_L2) ) then return tostring(mw.html.create("strong") :addClass("selflink") :wikitext(link.display)) end end -- Add fragment. Do not add a section link to "Undetermined", as such sections do not exist and are invalid. -- TabbedLanguages handles links without a section by linking to the "last visited" section, but adding -- "Undetermined" would break that feature. For localized prefixes that make syntax error, please use the -- format: ["xyz"] = true. local prefix = link.target:match("^:*([^:]+):") prefix = prefix and ulower(prefix) if prefix ~= "category" and not (prefix and load_data("Module:data/interwikis")[prefix]) then if (link.fragment or link.target:sub(-1) == "#") and not plain then track("fragment", lang:getFullCode()) if cats then insert(cats, "Liên kết có phân mảnh thủ công " .. lang:getFullName()) end end if not link.fragment then if id then link.fragment = lang:getFullCode() == "und" and anchor_encode(id) or language_anchor(lang, id) elseif lang:getFullCode() ~= "und" and not (link.target:match("^Phụ lục:") or link.target:match("^Từ tái tạo:")) then link.fragment = anchor_encode(ucfirst(lang:getFullName())) end end end -- Put inward-facing square brackets around a link to isolated spacing character(s). if isolated and #link.display > 0 and not umatch(decode_entities(link.display), "%S") then link.display = "&#x5D;" .. link.display .. "&#x5B;" end link.target = link.target:gsub("^(:?)(.*)", function(m1, m2) return m1 .. encode_entities(m2, "#%&+/:<=>@[\\]_{|}") end) link.fragment = link.fragment and encode_entities(remove_formatting(link.fragment), "#%&+/:<=>@[\\]_{|}") return "[[" .. link.target:gsub("^[^:]", ":%0") .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]" end -- Split a link into its parts local function parse_link(linktext) local link = {target = linktext} local target = link.target link.target, link.display = target:match("^(..-)|(.+)$") if not link.target then link.target = target link.display = target end -- There's no point in processing these, as they aren't real links. local target_lower = link.target:lower() for _, false_positive in ipairs({"category", "cat", "file", "image"}) do if target_lower:match("^" .. false_positive .. ":") then return nil end end link.display = decode_entities(link.display) link.target, link.fragment = get_fragment(link.target) -- So that make_link does not look for a fragment again. if not link.fragment then link.fragment = false end return link end local function check_params_ignored_when_embedded(alt, lang, id, cats) if alt then track("alt-ignored") if cats then insert(cats, "Liên kết mục từ có tham số alt bỏ qua " .. lang:getFullName()) end end if id then track("id-ignored") if cats then insert(cats, "Liên kết mục từ có tham số id bỏ qua " .. lang:getFullName()) end end end -- Find embedded links and ensure they link to the correct section. local function process_embedded_links(text, alt, lang, sc, id, cats, no_alt_ast, plain) -- Process the non-linked text. text = lang:makeDisplayText(text, sc, true) -- If the text begins with * and another character, then act as if each link begins with *. However, don't do this if the * is contained within a link at the start. E.g. `|*[[foo]]` would set all_reconstructed to true, while `|[[*foo]]` would not. local all_reconstructed = false if not plain then -- anchor_encode removes links etc. if anchor_encode(text):sub(1, 1) == "*" then all_reconstructed = true end -- Otherwise, handle any escapes. text = text:gsub("^(\\-)\\%*", "%1*") end check_params_ignored_when_embedded(alt, lang, id, cats) local function process_link(space1, linktext, space2) local capture = "[[" .. linktext .. "]]" local link = parse_link(linktext) -- Return unprocessed false positives untouched (e.g. categories). if not link then return capture end if all_reconstructed then if link.target:find("^!!") then -- Check for anti-asterisk !! at the beginning of a target, indicating that a reconstructed term -- wants a part of the term to link to a non-reconstructed term, e.g. Old English -- {{ang-noun|m|head=*[[!!Crist|Cristes]] [[!!mæsseǣfen]]}}. link.target = link.target:sub(3) -- Also remove !! from the display, which may have been copied from the target (as in mæsseǣfen in -- the example above). link.display = link.display:gsub("^!!", "") elseif not link.target:match("^%*") then link.target = "*" .. link.target end end linktext = make_link(link, lang, sc, id, false, nil, no_alt_ast, plain) :gsub("^%[%[", "\3") :gsub("%]%]$", "\4") return space1 .. linktext .. space2 end -- Use chars 1 and 2 as temporary substitutions, so that we can use charsets. These are converted to chars 3 and 4 by process_link, which means we can convert any remaining chars 1 and 2 back to square brackets (i.e. those not part of a link). text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- If the script uses ^ to capitalize transliterations, make sure that any carets preceding links are on the inside, so that they get processed with the following text. if ( text:find("^", nil, true) and not sc:hasCapitalization() and sc:isTransliterated() ) then text = escape(text, "^") :gsub("%^\1", "\1%^") text = unescape(text, "^") end text = text:gsub("\1(%s*)([^\1\2]-)(%s*)\2", process_link) -- Remove the extra * at the beginning of a language link if it's immediately followed by a link whose display begins with * too. if all_reconstructed then text = text:gsub("^%*\3([^|\1-\4]+)|%*", "\3%1|*") end return (text :gsub("[\1\3]", "[[") :gsub("[\2\4]", "]]") ) end local function simple_link(term, fragment, alt, lang, sc, id, cats, no_alt_ast, srwc) local plain if lang == nil then lang, plain = get_lang("und"), true end -- Get the link target and display text. If the term is the empty string, treat the input as a link to the current page. if term == "" then term = get_current_title().prefixedText elseif term then local new_term, new_alt = export.get_wikilink_parts(term, true) if new_term then check_params_ignored_when_embedded(alt, lang, id, cats) -- [[|foo]] links are treated as plaintext "[[|foo]]". -- FIXME: Pipes should be handled via a proper escape sequence, as they can occur in unsupported titles. if new_term == "" then term, alt = nil, term else local title = new_title(new_term) if title then local ns = title.namespace -- File: and Category: links should be returned as-is. if ns == 6 or ns == 14 then return term end end term, alt = new_term, new_alt if cats then if not (srwc and srwc(term, alt)) then insert(cats, "Liên kết mục từ có liên kết wiki thừa " .. lang:getFullName()) end end end end end if alt then alt = selective_trim(alt) if alt == "" then alt = nil end end -- If there's nothing to process, return nil. if not (term or alt) then return nil end -- If there is no script, get one. if not sc then sc = lang:findBestScript(alt or term) end -- Embedded wikilinks need to be processed individually. if term then local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, alt, lang, sc, id, cats, no_alt_ast, plain) end term = selective_trim(term) end -- If not, make a link using the parameters. return make_link({ target = term, display = alt, fragment = fragment }, lang, sc, id, true, cats, no_alt_ast, plain) end --[==[Creates a basic link to the given term. It links to the language section (such as <code>==English==</code>), but it does not add language and script wrappers, so any code that uses this function should call the <code class="n">[[Module:script utilities#tag_text|tag_text]]</code> from [[Module:script utilities]] to add such wrappers itself at some point. The first argument, <code class="n">data</code>, may contain the following items, a subset of the items used in the <code class="n">data</code> argument of <code class="n">full_link</code>. If any other items are included, they are ignored. { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, id = sense_id, } } ; <code class="n">term</code> : Text to turn into a link. This is generally the name of a page. The text can contain wikilinks already embedded in it. These are processed individually just like a single link would be. The <code class="n">alt</code> argument is ignored in this case. ; <code class="n">alt</code> (''optional'') : The alternative display for the link, if different from the linked page. If this is {{code|lua|nil}}, the <code class="n">text</code> argument is used instead (much like regular wikilinks). If <code class="n">text</code> contains wikilinks in it, this argument is ignored and has no effect. (Links in which the alt is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/alt-ignored}}.) ; <code class="n">lang</code> : The [[Module:languages#Language objects|language object]] for the term being linked. If this argument is defined, the function will determine the language's canonical name (see [[Template:language data documentation]]), and point the link or links in the <code class="n">term</code> to the language's section of an entry, or to a language-specific senseid if the <code class="n">id</code> argument is defined. ; <code class="n">id</code> (''optional'') : Sense id string. If this argument is defined, the link will point to a language-specific sense id ({{ll|en|identifier|id=HTML}}) created by the template {{temp|senseid}}. A sense id consists of the language's canonical name, a hyphen (<code>-</code>), and the string that was supplied as the <code class="n">id</code> argument. This is useful when a term has more than one sense in a language. If the <code class="n">term</code> argument contains wikilinks, this argument is ignored. (Links in which the sense id is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/id-ignored}}.) The second argument is as follows: ; <code class="n">allow_self_link</code> : If {{code|lua|true}}, the function will also generate links to the current page. The default ({{code|lua|false}}) will not generate a link but generate a bolded "self link" instead. The following special options are processed for each link (both simple text and with embedded wikilinks): * The target page name will be processed to generate the correct entry name. This is done by the [[Module:languages#makeEntryName|makeEntryName]] function in [[Module:languages]], using the <code class="n">entry_name</code> replacements in the language's data file (see [[Template:language data documentation]] for more information). This function is generally used to automatically strip dictionary-only diacritics that are not part of the normal written form of a language. * If the text starts with <code class="n">*</code>, then the term is considered a reconstructed term, and a link to the Reconstruction: namespace will be created. If the text contains embedded wikilinks, then <code class="n">*</code> is automatically applied to each one individually, while preserving the displayed form of each link as it was given. This allows linking to phrases containing multiple reconstructed terms, while only showing the * once at the beginning. * If the text starts with <code class="n">:</code>, then the link is treated as "raw" and the above steps are skipped. This can be used in rare cases where the page name begins with <code class="n">*</code> or if diacritics should not be stripped. For example: ** {{temp|l|en|*nix}} links to the nonexistent page [[Reconstruction:English/nix]] (<code class="n">*</code> is interpreted as a reconstruction), but {{temp|l|en|:*nix}} links to [[*nix]]. ** {{temp|l|sl|Franche-Comté}} links to the nonexistent page [[Franche-Comte]] (<code>é</code> is converted to <code>e</code> by <code class="n">makeEntryName</code>), but {{temp|l|sl|:Franche-Comté}} links to [[Franche-Comté]].]==] function export.language_link(data) if type(data) ~= "table" then error("The first argument to the function language_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "language_link") end -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Liên kết ngôn ngữ không xác định") end return simple_link( data.term, data.fragment, data.alt, lang, data.sc, data.id, cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end function export.plain_link(data) if type(data) ~= "table" then error("The first argument to the function plain_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "plain_link") end return simple_link( data.term, data.fragment, data.alt, nil, data.sc, data.id, data.cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end --[==[Replace any links with links to the correct section, but don't link the whole text if no embedded links are found. Returns the display text form.]==] function export.embedded_language_links(data) if type(data) ~= "table" then error("The first argument to the function embedded_language_links must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "embedded_language_links") end local term, lang, sc = data.term, data.lang, data.sc -- If we don't have a script, get one. if not sc then sc = lang:findBestScript(term) end -- Do we have embedded wikilinks? If so, they need to be processed individually. local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, data.alt, lang, sc, data.id, data.cats, data.no_alt_ast) end -- If not, return the display text. term = selective_trim(term) -- FIXME: Double-escape any percent-signs, because we don't want to treat non-linked text as having percent-encoded characters. This is a hack: percent-decoding should come out of [[Module:languages]] and only dealt with in this module, as it's specific to links. term = term:gsub("%%", "%%25") return lang:makeDisplayText(term, sc, true) end function export.mark(text, item_type, face, lang) local tag = { "", "" } if item_type == "gloss" then tag = { '<span class="mention-gloss-double-quote">“</span><span class="mention-gloss">', '</span><span class="mention-gloss-double-quote">”</span>' } if type(text) == "string" and text:match("^''[^'].*''$") then -- Temporary tracking for mention glosses that are entirely italicized or bolded, which is probably -- wrong. (Note that this will also find bolded mention glosses since they use triple apostrophes.) track("italicized-mention-gloss", lang and lang:getFullCode() or nil) end elseif item_type == "tr" then if face == "term" then tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr mention-tr Latn">', '</span>' } else tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr Latn">', '</span>' } end elseif item_type == "ts" then -- \226\129\160 = word joiner (zero-width non-breaking space) U+2060 tag = { '<span class="ts mention-ts Latn">/\226\129\160', '\226\129\160/</span>' } elseif item_type == "pos" then tag = { '<span class="ann-pos">', '</span>' } elseif item_type == "non-gloss" then tag = { '<span class="ann-non-gloss">', '</span>' } elseif item_type == "annotations" then tag = { '<span class="mention-gloss-paren annotation-paren">(</span>', '<span class="mention-gloss-paren annotation-paren">)</span>' } end if type(text) == "string" then return tag[1] .. text .. tag[2] else return "" end end local pos_tags --[==[Formats the annotations that are displayed with a link created by {{code|lua|full_link}}. Annotations are the extra bits of information that are displayed following the linked term, and include things such as gender, transliteration, gloss and so on. * The first argument is a table possessing some or all of the following keys: *:; <code class="n">genders</code> *:: Table containing a list of gender specifications in the style of [[Module:gender and number]]. *:; <code class="n">tr</code> *:: Transliteration. *:; <code class="n">gloss</code> *:: Gloss that translates the term in the link, or gives some other descriptive information. *:; <code class="n">pos</code> *:: Part of speech of the linked term. If the given argument matches one of the aliases in `pos_aliases` in [[Module:headword/data]], or consists of a part of speech or alias followed by `f` (for a non-lemma form), expand it appropriately. Otherwise, just show the given text as it is. *:; <code class="n">ng</code> *:: Arbitrary non-gloss descriptive text for the link. This should be used in preference to putting descriptive text in `gloss` or `pos`. *:; <code class="n">lit</code> *:: Literal meaning of the term, if the usual meaning is figurative or idiomatic. *:Any of the above values can be omitted from the <code class="n">info</code> argument. If a completely empty table is given (with no annotations at all), then an empty string is returned. * The second argument is a string. Valid values are listed in [[Module:script utilities/data]] "data.translit" table.]==] function export.format_link_annotations(data, face) local output = {} -- Interwiki link if data.interwiki then insert(output, data.interwiki) end -- Genders if type(data.genders) ~= "table" then data.genders = { data.genders } end if data.genders and #data.genders > 0 then local genders, gender_cats = format_genders(data.genders, data.lang) insert(output, "&nbsp;" .. genders) if gender_cats then local cats = data.cats if cats then extend(cats, gender_cats) end end end local annotations = {} -- Transliteration and transcription if data.tr and data.tr[1] or data.ts and data.ts[1] then local kind if face == "term" then kind = face else kind = "default" end if data.tr[1] and data.ts[1] then insert(annotations, tag_translit(data.tr[1], data.lang, kind) .. " " .. export.mark(data.ts[1], "ts")) elseif data.ts[1] then insert(annotations, export.mark(data.ts[1], "ts")) else insert(annotations, tag_translit(data.tr[1], data.lang, kind)) end end -- Gloss/translation if data.gloss then insert(annotations, export.mark(data.gloss, "gloss")) end -- Part of speech if data.pos then -- debug category for pos= containing transcriptions if data.pos:match("/[^><]-/") then data.pos = data.pos .. "[[Category:links likely containing transcriptions in pos]]" end -- Canonicalize part of speech aliases as well as non-lemma aliases like 'nf' or 'nounf' for "noun form". pos_tags = pos_tags or (m_headword_data or get_headword_data()).pos_aliases local pos = pos_tags[data.pos] if not pos and data.pos:find("f$") then local pos_form = data.pos:sub(1, -2) -- We only expand something ending in 'f' if the result is a recognized non-lemma POS. pos_form = (pos_tags[pos_form] or pos_form) .. " form" if (m_headword_data or get_headword_data()).nonlemmas[pos_form .. "s"] then pos = pos_form end end insert(annotations, export.mark(pos or data.pos, "pos")) end -- Non-gloss text if data.ng then insert(annotations, export.mark(data.ng, "non-gloss")) end -- Literal/sum-of-parts meaning if data.lit then insert(annotations, "nghĩa đen " .. export.mark(data.lit, "gloss")) end -- Provide a hook to insert additional annotations such as nested inflections. if data.postprocess_annotations then data.postprocess_annotations { data = data, annotations = annotations } end if #annotations > 0 then insert(output, " " .. export.mark(concat(annotations, ", "), "annotations")) end return concat(output) end -- Encode certain characters to avoid various delimiter-related issues at various stages. We need to encode < and > -- because they end up forming part of CSS class names inside of <span ...> and will interfere with finding the end -- of the HTML tag. I first tried converting them to URL encoding, i.e. %3C and %3E; they then appear in the URL as -- %253C and %253E, which get mapped back to %3C and %3E when passed to [[Module:accel]]. But mapping them to &lt; -- and &gt; somehow works magically without any further work; they appear in the URL as < and >, and get passed to -- [[Module:accel]] as < and >. I have no idea who along the chain of calls is doing the encoding and decoding. If -- someone knows, please modify this comment appropriately! local accel_char_map local function get_accel_char_map() accel_char_map = { ["%"] = ".", [" "] = "_", ["_"] = u(0xFFF0), ["<"] = "&lt;", [">"] = "&gt;", } return accel_char_map end local function encode_accel_param_chars(param) return (param:gsub("[% <>_]", accel_char_map or get_accel_char_map())) end local function encode_accel_param(prefix, param) if not param then return "" end if type(param) == "table" then local filled_params = {} -- There may be gaps in the sequence, especially for translit params. local maxindex = 0 for k in pairs(param) do if type(k) == "number" and k > maxindex then maxindex = k end end for i = 1, maxindex do filled_params[i] = param[i] or "" end -- [[Module:accel]] splits these up again. param = concat(filled_params, "*~!") end -- This is decoded again by [[WT:ACCEL]]. return prefix .. encode_accel_param_chars(param) end local function insert_if_not_blank(list, item) if item == "" then return end insert(list, item) end local function get_class(lang, tr, accel, nowrap) if not accel and not nowrap then return "" end local classes = {} if accel then insert(classes, "form-of lang-" .. lang:getFullCode()) local form = accel.form if form then insert(classes, encode_accel_param_chars(form) .. "-form-of") end insert_if_not_blank(classes, encode_accel_param("gender-", accel.gender)) insert_if_not_blank(classes, encode_accel_param("pos-", accel.pos)) insert_if_not_blank(classes, encode_accel_param("transliteration-", accel.translit or (tr ~= "-" and tr or nil))) insert_if_not_blank(classes, encode_accel_param("target-", accel.target)) insert_if_not_blank(classes, encode_accel_param("origin-", accel.lemma)) insert_if_not_blank(classes, encode_accel_param("origin_transliteration-", accel.lemma_translit)) if accel.no_store then insert(classes, "form-of-nostore") end end if nowrap then insert(classes, nowrap) end return concat(classes, " ") end -- Add any left or right regular or accent qualifiers, labels or references to a formatted term. `data` is the object -- specifying the term, which should optionally contain: -- * a language object in `lang`; required if any accent qualifiers or labels are given; -- * left regular qualifiers in `q` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * right regular qualifiers in `qq` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * left accent qualifiers in `a` (an array of strings); an empty array will be ignored; -- * right accent qualifiers in `aa` (an array of strings); an empty array will be ignored; -- * left labels in `l` (an array of strings); an empty array will be ignored; -- * right labels in `ll` (an array of strings); an empty array will be ignored; -- * references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text` -- (formatted reference text) and optionally `name` and/or `group`. -- `formatted` is the formatted version of the term itself. local function add_qualifiers_and_refs_to_term(data, formatted) local q = data.q if type(q) == "string" then q = {q} end local qq = data.qq if type(qq) == "string" then qq = {qq} end if q and q[1] or qq and qq[1] or data.a and data.a[1] or data.aa and data.aa[1] or data.l and data.l[1] or data.ll and data.ll[1] or data.refs and data.refs[1] then formatted = format_qualifiers{ lang = data.lang, text = formatted, q = q, qq = qq, a = data.a, aa = data.aa, l = data.l, ll = data.ll, refs = data.refs, } end return formatted end --[==[ Creates a full link, with annotations (see `[[#format_link_annotations|format_link_annotations]]`), in the style of {{tl|l}} or {{tl|m}}. The first argument, `data`, must be a table. It contains the various elements that can be supplied as parameters to {{tl|l}} or {{tl|m}}: { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, sc = script_object, track_sc = boolean, no_nonstandard_sc_cat = boolean, fragment = link_fragment, id = sense_id, genders = { "gender1", "gender2", ... }, tr = transliteration, respect_link_tr = boolean, ts = transcription, gloss = gloss, pos = part_of_speech_tag, ng = non-gloss text, lit = literal_translation, no_alt_ast = boolean, accel = {accelerated_creation_tags}, interwiki = interwiki, pretext = "text_at_beginning" or nil, posttext = "text_at_end" or nil, q = { "left_qualifier1", "left_qualifier2", ...} or "left_qualifier", qq = { "right_qualifier1", "right_qualifier2", ...} or "right_qualifier", l = { "left_label1", "left_label2", ...}, ll = { "right_label1", "right_label2", ...}, a = { "left_accent_qualifier1", "left_accent_qualifier2", ...}, aa = { "right_accent_qualifier1", "right_accent_qualifier2", ...}, refs = { "formatted_ref1", "formatted_ref2", ...} or { {text = "text", name = "name", group = "group"}, ... }, show_qualifiers = boolean, } } Any one of the items in the `data` table may be {nil}, but an error will be shown if neither `term` nor `alt` nor `tr` is present. Thus, calling {full_link{ term = term, lang = lang, sc = sc }}, where `term` is the page to link to (which may have diacritics that will be stripped and/or embedded bracketed links) and `lang` is a [[Module:languages#Language objects|language object]] from [[Module:languages]], will give a plain link similar to the one produced by the template {{tl|l}}, and calling {full_link( { term = term, lang = lang, sc = sc }, "term" )} will give a link similar to the one produced by the template {{tl|m}}. The function will: * Try to determine the script, based on the characters found in the `term` or `alt` argument, if the script was not given. If a script is given and `track_sc` is {true}, it will check whether the input script is the same as the one which would have been automatically generated and add the category [[:Category:LANG terms with redundant script codes]] if yes, or [[:Category:LANG terms with non-redundant manual script codes]] if no. This should be used when the input script object is directly determined by a template's `sc` parameter. * Call `[[#language_link|language_link]]` on the `term` or `alt` forms, to remove diacritics in the page name, process any embedded wikilinks and create links to Reconstruction or Appendix pages when necessary. * Call `[[Module:script utilities#tag_text]]` to add the appropriate language and script tags to the term and italicize terms written in the Latin script if necessary. Accelerated creation tags, as used by [[WT:ACCEL]], are included. * Generate a transliteration, based on the `alt` or `term` arguments, if the script is not Latin, no transliteration was provided in `tr` and the combination of the term's language and script support automatic transliteration. The transliteration itself will be linked if both `.respect_link_tr` is specified and the language of the term has the `link_tr` property set for the script of the term; but not otherwise. * Add the annotations (transliteration, gender, gloss, etc.) after the link. * If `no_alt_ast` is specified, then the `alt` text does not need to contain an asterisk if the language is reconstructed. This should only be used by modules which really need to allow links to reconstructions that don't display asterisks (e.g. number boxes). * If `pretext` or `posttext` is specified, this is text to (respectively) prepend or append to the output, directly before processing qualifiers, labels and references. This can be used to add arbitrary extra text inside of the qualifiers, labels and references. * If `show_qualifiers` is specified or the `show_qualifiers` argument is given, then left and right qualifiers, accent qualifiers, labels and references will be displayed, otherwise they will be ignored. (This is because a fair amount of code stores qualifiers, labels and/or references in these fields and displays them itself, rather than expecting {full_link()} to display them.)]==] function export.full_link(data, face, allow_self_link, show_qualifiers) if type(data) ~= "table" then error("The first argument to the function full_link must be a table. " .. "See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "full_link") end -- Prevent data from being destructively modified. local data = shallow_copy(data) -- FIXME: this shouldn't be added to `data`, as that means the input table needs to be cloned. data.cats = {} -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Liên kết ngôn ngữ không xác định") end local terms = {true} -- Generate multiple forms if applicable. for _, param in ipairs{"term", "alt"} do if type(data[param]) == "string" and data[param]:find("//", nil, true) then data[param] = export.split_on_slashes(data[param]) elseif type(data[param]) == "string" and not (type(data.term) == "string" and data.term:find("//", nil, true)) then if not data.no_generate_forms then data[param] = lang:generateForms(data[param]) else data[param] = {data[param]} end else data[param] = {} end end for _, param in ipairs{"sc", "tr", "ts"} do data[param] = {data[param]} end for _, param in ipairs{"term", "alt", "sc", "tr", "ts"} do for i in pairs(data[param]) do terms[i] = true end end -- Create the link local output = {} local id, no_alt_ast, srwc, accel, nevercalltr = data.id, data.no_alt_ast, data.suppress_redundant_wikilink_cat, data.accel, data.never_call_transliteration_module local link_tr = data.respect_link_tr and lang:link_tr(data.sc[1]) for i in ipairs(terms) do local link -- Is there any text to show? if (data.term[i] or data.alt[i]) then -- Try to detect the script if it was not provided local display_term = data.alt[i] or data.term[i] local best = lang:findBestScript(display_term) -- no_nonstandard_sc_cat is intended for use in [[Module:interproject]] if ( not data.no_nonstandard_sc_cat and best:getCode() == "None" and find_best_script_without_lang(display_term):getCode() ~= "None" ) then insert(cats, "Mục từ có chữ viết không chuẩn " .. lang:getFullName()) end if not data.sc[i] then data.sc[i] = best -- Track uses of sc parameter. elseif data.track_sc then if data.sc[i]:getCode() == best:getCode() then insert(cats, "Mục từ có mã chữ viết thừa " .. lang:getFullName()) else insert(cats, "Mục từ có mã chữ viết thủ công không thừa " .. lang:getFullName()) end end -- If using a discouraged character sequence, add to maintenance category if data.sc[i]:hasNormalizationFixes() == true then if (data.term[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.term[i])) ~= toNFC(data.term[i])) or (data.alt[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.alt[i])) ~= toNFC(data.alt[i])) then insert(cats, "Pages using discouraged character sequences") end end link = simple_link( data.term[i], data.fragment, data.alt[i], lang, data.sc[i], id, cats, no_alt_ast, srwc ) end -- simple_link can return nil, so check if a link has been generated. if link then -- Add "nowrap" class to prefixes in order to prevent wrapping after the hyphen local nowrap local display_term = data.alt[i] or data.term[i] if display_term and (display_term:find("^%-") or display_term:find("^־")) then -- Hebrew maqqef -- FIXME, use hyphens from [[Module:affix]] nowrap = "nowrap" end link = tag_text(link, lang, data.sc[i], face, get_class(lang, data.tr[i], accel, nowrap)) else --[[ No term to show. Is there at least a transliteration we can work from? ]] link = request_script(lang, data.sc[i]) -- No link to show, and no transliteration either. Show a term request (unless it's a substrate, as they rarely take terms). if (link == "" or (not data.tr[i]) or data.tr[i] == "-") and lang:getFamilyCode() ~= "qfa-sub" then -- If there are multiple terms, break the loop instead. if i > 1 then remove(output) break elseif NAMESPACE ~= "Bản mẫu" then insert(cats, "Yêu cầu mục từ " .. lang:getFullName()) end link = "<small>[Mục từ gì?]</small>" end end insert(output, link) if i < #terms then insert(output, "<span class=\"Zsym mention\" style=\"font-size:100%;\">&nbsp;/ </span>") end end -- TODO: Currently only handles the first transliteration, pending consensus on how to handle multiple translits for multiple forms, as this is not always desirable (e.g. traditional/simplified Chinese). if data.tr[1] == "" or data.tr[1] == "-" then data.tr[1] = nil else local phonetic_extraction = load_data("Module:links/data").phonetic_extraction phonetic_extraction = phonetic_extraction[lang:getCode()] or phonetic_extraction[lang:getFullCode()] if phonetic_extraction then data.tr[1] = data.tr[1] or require(phonetic_extraction).getTranslit(export.remove_links(data.alt[1] or data.term[1])) elseif (data.term[1] or data.alt[1]) and data.sc[1]:isTransliterated() then -- Track whenever there is manual translit. The categories below like 'terms with redundant transliterations' -- aren't sufficient because they only work with reference to automatic translit and won't operate at all in -- languages without any automatic translit, like Persian and Hebrew. if data.tr[1] then local full_code = lang:getFullCode() track("manual-tr", full_code) end if not nevercalltr then -- Try to generate a transliteration. local text = data.alt[1] or data.term[1] if not link_tr then text = export.remove_links(text, true) end local automated_tr = lang:transliterate(text, data.sc[1]) if automated_tr then local manual_tr = data.tr[1] if manual_tr then if export.remove_links(manual_tr) == export.remove_links(automated_tr) then insert(cats, "Mục từ có chuyển tự thừa " .. lang:getFullName()) else -- Prevents Arabic root categories from flooding the tracking categories. if NAMESPACE ~= "Thể loại" then insert(cats, "Mục từ có chuyển tự thủ công không thừa " .. lang:getFullName()) end end end if not manual_tr or lang:overrideManualTranslit(data.sc[1]) then data.tr[1] = automated_tr end end end end end -- Link to the transliteration entry for languages that require this if data.tr[1] and link_tr and not data.tr[1]:match("%[%[(.-)%]%]") then data.tr[1] = simple_link( data.tr[1], nil, nil, lang, get_script("Latn"), nil, cats, no_alt_ast, srwc ) elseif data.tr[1] and not link_tr then -- Remove the pseudo-HTML tags added by remove_links. data.tr[1] = data.tr[1]:gsub("</?link>", "") end if data.tr[1] and not umatch(data.tr[1], "[^%s%p]") then data.tr[1] = nil end insert(output, export.format_link_annotations(data, face)) if data.pretext then insert(output, 1, data.pretext) end if data.posttext then insert(output, data.posttext) end local categories = cats[1] and format_categories(cats, lang, "-", nil, nil, data.sc) or "" output = concat(output) if show_qualifiers or data.show_qualifiers then output = add_qualifiers_and_refs_to_term(data, output) end return output .. categories end --[==[Replaces all wikilinks with their displayed text, and removes any categories. This function can be invoked either from a template or from another module. -- Strips links: deletes category links, the targets of piped links, and any double square brackets involved in links (other than file links, which are untouched). If `tag` is set, then any links removed will be given pseudo-HTML tags, which allow the substitution functions in [[Module:languages]] to properly subdivide the text in order to reduce the chance of substitution failures in modules which scrape pages like [[Module:zh-translit]]. -- FIXME: This is quite hacky. We probably want this to be integrated into [[Module:languages]], but we can't do that until we know that nothing is pushing pipe linked transliterations through it for languages which don't have link_tr set. * <code><nowiki>[[page|displayed text]]</nowiki></code> &rarr; <code><nowiki>displayed text</nowiki></code> * <code><nowiki>[[page and displayed text]]</nowiki></code> &rarr; <code><nowiki>page and displayed text</nowiki></code> * <code><nowiki>[[Category:English lemmas|WORD]]</nowiki></code> &rarr; ''(nothing)'']==] function export.remove_links(text, tag) if type(text) == "table" then text = text.args[1] end if not text or text == "" then return "" end text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Parse internal links for the display text. text = text:gsub("(\1)([^\1\2]-)(\2)", function(c1, c2, c3) -- Don't remove files. for _, false_positive in ipairs({"file", "image"}) do if c2:lower():match("^" .. false_positive .. ":") then return c1 .. c2 .. c3 end end -- Remove categories completely. for _, false_positive in ipairs({"category", "cat"}) do if c2:lower():match("^" .. false_positive .. ":") then return "" end end -- In piped links, remove all text before the pipe, unless it's the final character (i.e. the pipe trick), in which case just remove the pipe. c2 = c2:match("^[^|]*|(.+)") or c2:match("([^|]+)|$") or c2 if tag then return "<link>" .. c2 .. "</link>" else return c2 end end) text = text :gsub("\1", "[[") :gsub("\2", "]]") return text end function export.section_link(link) if type(link) ~= "string" then error("The first argument to section_link was a " .. type(link) .. ", but it should be a string.") elseif link:find("\\", nil, true) then track("escaped", "section_link") end local target, section = get_fragment((link:gsub("_", " "))) if not section then error("No \"#\" delineating a section name") end return simple_link( target, section, target .. " §&nbsp;" .. section ) end return export 3dq6a9yxp2zvi13deuk2plyhl97k8ll 2344295 2344294 2026-04-11T15:33:08Z TheHighFighter2 42988 2344295 Scribunto text/plain local export = {} --[=[ [[Unsupported titles]], pages with high memory usage, extraction modules and part-of-speech names are listed at [[Module:links/data]]. Other modules used: [[Module:script utilities]] [[Module:scripts]] [[Module:languages]] and its submodules [[Module:gender and number]] [[Module:debug/track]] ]=] local anchors_module = "Module:anchors" local debug_track_module = "Module:debug/track" local gender_and_number_module = "Module:gender and number" local languages_module = "Module:languages" local load_module = "Module:load" local memoize_module = "Module:memoize" local pages_module = "Module:pages" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local script_utilities_module = "Module:script utilities" local string_encode_entities_module = "Module:string/encode entities" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local ucfirst = require("Module:string utilities").ucfirst local concat = table.concat local find = string.find local get_current_title = mw.title.getCurrentTitle local insert = table.insert local ipairs = ipairs local match = string.match local new_title = mw.title.new local pairs = pairs local remove = table.remove local sub = string.sub local toNFC = mw.ustring.toNFC local tostring = tostring local type = type local unstrip = mw.text.unstrip local NAMESPACE = get_current_title().nsText local function anchor_encode(...) anchor_encode = require(memoize_module)(mw.uri.anchorEncode, true) return anchor_encode(...) end local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function decode_uri(...) decode_uri = require(string_utilities_module).decode_uri return decode_uri(...) end -- Can't yet replace, as the [[Module:string utilities]] version no longer has automatic double-encoding prevention, which requires changes here to account for. local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function extend(...) extend = require(table_module).extend return extend(...) end local function find_best_script_without_lang(...) find_best_script_without_lang = require(scripts_module).findBestScriptWithoutLang return find_best_script_without_lang(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_genders(...) format_genders = require(gender_and_number_module).format_genders return format_genders(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function get_current_L2(...) get_current_L2 = require(pages_module).get_current_L2 return get_current_L2(...) end local function get_lang(...) get_lang = require(languages_module).getByCode return get_lang(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) end local function language_anchor(...) language_anchor = require(anchors_module).language_anchor return language_anchor(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function request_script(...) request_script = require(script_utilities_module).request_script return request_script(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function split(...) split = require(string_utilities_module).split return split(...) end local function tag_text(...) tag_text = require(script_utilities_module).tag_text return tag_text(...) end local function tag_translit(...) tag_translit = require(script_utilities_module).tag_translit return tag_translit(...) end local function trim(...) trim = require(string_utilities_module).trim return trim(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ulower(...) ulower = require(string_utilities_module).lower return ulower(...) end local function umatch(...) umatch = require(string_utilities_module).match return umatch(...) end local m_headword_data local function get_headword_data() m_headword_data = load_data("Module:headword/data") return m_headword_data end local function track(page, code) local tracking_page = "links/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function selective_trim(...) -- Unconditionally trimmed charset. local always_trim = "\194\128-\194\159" .. -- U+0080-009F (C1 control characters) "\194\173" .. -- U+00AD (soft hyphen) "\226\128\170-\226\128\174" .. -- U+202A-202E (directionality formatting characters) "\226\129\166-\226\129\169" -- U+2066-2069 (directionality formatting characters) -- Standard trimmed charset. local standard_trim = "%s" .. -- (default whitespace charset) "\226\128\139-\226\128\141" .. -- U+200B-200D (zero-width spaces) always_trim -- If there are non-whitespace characters, trim all characters in `standard_trim`. -- Otherwise, only trim the characters in `always_trim`. selective_trim = function(text) if text == "" then return text end local trimmed = trim(text, standard_trim) if trimmed ~= "" then return trimmed end return trim(text, always_trim) end return selective_trim(...) end local function escape(text, str) local rep repeat text, rep = text:gsub("\\\\(\\*" .. str .. ")", "\5%1") until rep == 0 return (text:gsub("\\" .. str, "\6")) end local function unescape(text, str) return (text :gsub("\5", "\\") :gsub("\6", str)) end -- Remove bold, italics, soft hyphens, strip markers and HTML tags. local function remove_formatting(str) str = str :gsub("('*)'''(.-'*)'''", "%1%2") :gsub("('*)''(.-'*)''", "%1%2") :gsub("­", "") return (unstrip(str) :gsub("<[^<>]+>", "")) end --[==[Takes an input and splits on a double slash (taking account of escaping backslashes).]==] function export.split_on_slashes(text) if text:find("\\", nil, true) then track("escaped", "split_on_slashes") end text = split(escape(text, "//"), "//", true) or {} for i, v in ipairs(text) do text[i] = unescape(v, "//") if v == "" then text[i] = false end end return text end --[==[Takes a wikilink and outputs the link target and display text. By default, the link target will be returned as a title object, but if `allow_bad_target` is set it will be returned as a string, and no check will be performed as to whether it is a valid link target.]==] function export.get_wikilink_parts(text, allow_bad_target) -- TODO: replace `allow_bad_target` with `allow_unsupported`, with support for links to unsupported titles, including escape sequences. if ( -- Filters out anything but "[[...]]" with no intermediate "[[" or "]]". not match(text, "^()%[%[") or -- Faster than sub(text, 1, 2) ~= "[[". find(text, "[[", 3, true) or find(text, "]]", 3, true) ~= #text - 1 ) then return nil, nil end local pipe, title, display = find(text, "|", 3, true) if pipe then title, display = sub(text, 3, pipe - 1), sub(text, pipe + 1, -3) else title = sub(text, 3, -3) display = title end if allow_bad_target then return title, display end title = new_title(title) -- No title object means the target is invalid. if title == nil then return nil, nil -- If the link target starts with "#" then mw.title.new returns a broken -- title object, so grab the current title and give it the correct fragment. elseif title.prefixedText == "" then local fragment = title.fragment if fragment == "" then -- [[#]] isn't valid return nil, nil end title = get_current_title() title.fragment = fragment end return title, display end -- Does the work of export.get_fragment, but can be called directly to avoid unnecessary checks for embedded links. local function get_fragment(text) text = escape(text, "#") -- Replace numeric character references with the corresponding character (&#39; → '), -- as they contain #, which causes the numeric character reference to be -- misparsed (wa'a → wa&#39;a → pagename wa&, fragment 39;a). text = decode_entities(text) local target, fragment = text:match("^(.-)#(.+)$") target = target or text target = unescape(target, "#") fragment = fragment and unescape(fragment, "#") return target, fragment end --[==[Takes a link target and outputs the actual target and the fragment (if any).]==] function export.get_fragment(text) if text:find("\\", nil, true) then track("escaped", "get_fragment") end -- If there are no embedded links, process input. local open = find(text, "[[", nil, true) if not open then return get_fragment(text) end local close = find(text, "]]", open + 2, true) if not close then return get_fragment(text) -- If there is one, but it's redundant (i.e. encloses everything with no pipe), remove and process. elseif open == 1 and close == #text - 1 and not find(text, "|", 3, true) then return get_fragment(sub(text, 3, -3)) end -- Otherwise, return the input. return text end --[==[ Given a link target as passed to `full_link()`, get the actual page that the target refers to. This removes bold, italics, strip markets and HTML; calls `makeEntryName()` for the language in question; converts targets beginning with `*` to the Reconstruction namespace; and converts appendix-constructed languages to the Appendix namespace. Returns up to three values: # the actual page to link to, or {nil} to not link to anything; # how the target should be displayed as, if the user didn't explicitly specify any display text; generally the same as the original target, but minus any anti-asterisk !!; # the value `true` if the target had a backslash-escaped * in it (FIXME: explain this more clearly). ]==] function export.get_link_page_with_auto_display(target, lang, sc, plain) local orig_target = target if not target then return nil elseif target:find("\\", nil, true) then track("escaped", "get_link_page") end target = remove_formatting(target) if target:sub(1, 1) == ":" then track("initial colon") -- FIXME, the auto_display (second return value) should probably remove the colon return target:sub(2), orig_target end local prefix = target:match("^(.-):") -- Convert any escaped colons target = target:gsub("\\:", ":") if prefix then -- If this is an a link to another namespace or an interwiki link, ensure there's an initial colon and then -- return what we have (so that it works as a conventional link, and doesn't do anything weird like add the term -- to a category.) prefix = ulower(trim(prefix)) if prefix ~= "" and ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then return target, orig_target end end -- Check if the term is reconstructed and remove any asterisk. Also check for anti-asterisk (!!). -- Otherwise, handle the escapes. local reconstructed, escaped, anti_asterisk if not plain then target, reconstructed = target:gsub("^%*(.)", "%1") if reconstructed == 0 then target, anti_asterisk = target:gsub("^!!(.)", "%1") if anti_asterisk == 1 then -- Remove !! from original. FIXME! We do it this way because the call to remove_formatting() above -- may cause non-initial !! to be interpreted as anti-asterisks. We should surely move the -- remove_formatting() call later. orig_target = orig_target:gsub("^!!", "") end end end target, escaped = target:gsub("^(\\-)\\%*", "%1*") if not (sc and sc:getCode() ~= "None") then sc = lang:findBestScript(target) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). if (not sc:hasCapitalization()) and sc:isTransliterated() and target:match("%^") then target = escape(target, "^") :gsub("%^", "") target = unescape(target, "^") end -- Get the entry name for the language. target = lang:makeEntryName(target, sc, reconstructed == 1 or lang:hasType("appendix-constructed")) -- If the link contains unexpanded template parameters, then don't create a link. if target:match("{{{.-}}}") then -- FIXME: Should we return the original target as the default display value (second return value)? return nil end -- Link to appendix for reconstructed terms and terms in appendix-only languages. Plain links interpret * -- literally, however. if reconstructed == 1 then if lang:getFullCode() == "und" then -- Return the original target as default display value. If we don't do this, we wrongly get -- [Term?] displayed instead. return nil, orig_target end target = "Từ tái tạo:" .. ucfirst(lang:getFullName()) .. "/" .. target -- Reconstructed languages and substrates require an initial *. elseif anti_asterisk ~= 1 and (lang:hasType("reconstructed") or lang:getFamilyCode() == "qfa-sub") then error(("The specified language %s is unattested, while the term '%s' does not begin with '*' to indicate that it is reconstructed."): format(lang:getCanonicalName(), orig_target)) elseif lang:hasType("appendix-constructed") then target = "Phụ lục:" .. ucfirst(lang:getFullName()) .. "/" .. target else target = target end return target, orig_target, escaped > 0 end function export.get_link_page(target, lang, sc, plain) local target, auto_display, escaped = export.get_link_page_with_auto_display(target, lang, sc, plain) return target, escaped end -- Make a link from a given link's parts local function make_link(link, lang, sc, id, isolated, cats, no_alt_ast, plain) -- Convert percent encoding to plaintext. link.target = link.target and decode_uri(link.target, "PATH") link.fragment = link.fragment and decode_uri(link.fragment, "PATH") -- Find fragments (if one isn't already set). -- Prevents {{l|en|word#Etymology 2|word}} from linking to [[word#Etymology 2#English]]. -- # can be escaped as \#. if link.target and link.fragment == nil then link.target, link.fragment = get_fragment(link.target) end -- Process the target local auto_display, escaped link.target, auto_display, escaped = export.get_link_page_with_auto_display(link.target, lang, sc, plain) -- Create a default display form. -- If the target is "" then it's a link like [[#English]], which refers to the current page. if auto_display == "" then auto_display = (m_headword_data or get_headword_data()).pagename end -- If the display is the target and the reconstruction * has been escaped, remove the escaping backslash. if escaped then auto_display = auto_display:gsub("\\([^\\]*%*)", "%1", 1) end -- Process the display form. if link.display then local orig_display = link.display link.display = lang:makeDisplayText(link.display, sc, true) if cats then auto_display = lang:makeDisplayText(auto_display, sc) -- If the alt text is the same as what would have been automatically generated, then the alt parameter is redundant (e.g. {{l|en|foo|foo}}, {{l|en|w:foo|foo}}, but not {{l|en|w:foo|w:foo}}). -- If they're different, but the alt text could have been entered as the term parameter without it affecting the target page, then the target parameter is redundant (e.g. {{l|ru|фу|фу́}}). -- If `no_alt_ast` is true, use pcall to catch the error which will be thrown if this is a reconstructed lang and the alt text doesn't have *. if link.display == auto_display then insert(cats, "Liên kết mục từ có tham số alt thừa " .. lang:getFullName()) else local ok, check if no_alt_ast then ok, check = pcall(export.get_link_page, orig_display, lang, sc, plain) else ok = true check = export.get_link_page(orig_display, lang, sc, plain) end if ok and link.target == check then insert(cats, "Liên kết mục từ có tham số mục tiêu thừa " .. lang:getFullName()) end end end else link.display = lang:makeDisplayText(auto_display, sc) end if not link.target then return link.display end -- If the target is the same as the current page, there is no sense id -- and either the language code is "und" or the current L2 is the current -- language then return a "self-link" like the software does. if link.target == get_current_title().prefixedText then local fragment, current_L2 = link.fragment, get_current_L2() if ( fragment and fragment == current_L2 or not (id or fragment) and (lang:getFullCode() == "und" or ucfirst(lang:getFullName()) == current_L2) ) then return tostring(mw.html.create("strong") :addClass("selflink") :wikitext(link.display)) end end -- Add fragment. Do not add a section link to "Undetermined", as such sections do not exist and are invalid. -- TabbedLanguages handles links without a section by linking to the "last visited" section, but adding -- "Undetermined" would break that feature. For localized prefixes that make syntax error, please use the -- format: ["xyz"] = true. local prefix = link.target:match("^:*([^:]+):") prefix = prefix and ulower(prefix) if prefix ~= "category" and not (prefix and load_data("Module:data/interwikis")[prefix]) then if (link.fragment or link.target:sub(-1) == "#") and not plain then track("fragment", lang:getFullCode()) if cats then insert(cats, "Liên kết có phân mảnh thủ công " .. lang:getFullName()) end end if not link.fragment then if id then link.fragment = lang:getFullCode() == "und" and anchor_encode(id) or language_anchor(lang, id) elseif lang:getFullCode() ~= "und" and not (link.target:match("^Phụ lục:") or link.target:match("^Từ tái tạo:")) then link.fragment = anchor_encode(ucfirst(lang:getFullName())) end end end -- Put inward-facing square brackets around a link to isolated spacing character(s). if isolated and #link.display > 0 and not umatch(decode_entities(link.display), "%S") then link.display = "&#x5D;" .. link.display .. "&#x5B;" end link.target = link.target:gsub("^(:?)(.*)", function(m1, m2) return m1 .. encode_entities(m2, "#%&+/:<=>@[\\]_{|}") end) link.fragment = link.fragment and encode_entities(remove_formatting(link.fragment), "#%&+/:<=>@[\\]_{|}") return "[[" .. link.target:gsub("^[^:]", ":%0") .. (link.fragment and "#" .. link.fragment or "") .. "|" .. link.display .. "]]" end -- Split a link into its parts local function parse_link(linktext) local link = {target = linktext} local target = link.target link.target, link.display = target:match("^(..-)|(.+)$") if not link.target then link.target = target link.display = target end -- There's no point in processing these, as they aren't real links. local target_lower = link.target:lower() for _, false_positive in ipairs({"category", "cat", "file", "image"}) do if target_lower:match("^" .. false_positive .. ":") then return nil end end link.display = decode_entities(link.display) link.target, link.fragment = get_fragment(link.target) -- So that make_link does not look for a fragment again. if not link.fragment then link.fragment = false end return link end local function check_params_ignored_when_embedded(alt, lang, id, cats) if alt then track("alt-ignored") if cats then insert(cats, "Liên kết mục từ có tham số alt bỏ qua " .. lang:getFullName()) end end if id then track("id-ignored") if cats then insert(cats, "Liên kết mục từ có tham số id bỏ qua " .. lang:getFullName()) end end end -- Find embedded links and ensure they link to the correct section. local function process_embedded_links(text, alt, lang, sc, id, cats, no_alt_ast, plain) -- Process the non-linked text. text = lang:makeDisplayText(text, sc, true) -- If the text begins with * and another character, then act as if each link begins with *. However, don't do this if the * is contained within a link at the start. E.g. `|*[[foo]]` would set all_reconstructed to true, while `|[[*foo]]` would not. local all_reconstructed = false if not plain then -- anchor_encode removes links etc. if anchor_encode(text):sub(1, 1) == "*" then all_reconstructed = true end -- Otherwise, handle any escapes. text = text:gsub("^(\\-)\\%*", "%1*") end check_params_ignored_when_embedded(alt, lang, id, cats) local function process_link(space1, linktext, space2) local capture = "[[" .. linktext .. "]]" local link = parse_link(linktext) -- Return unprocessed false positives untouched (e.g. categories). if not link then return capture end if all_reconstructed then if link.target:find("^!!") then -- Check for anti-asterisk !! at the beginning of a target, indicating that a reconstructed term -- wants a part of the term to link to a non-reconstructed term, e.g. Old English -- {{ang-noun|m|head=*[[!!Crist|Cristes]] [[!!mæsseǣfen]]}}. link.target = link.target:sub(3) -- Also remove !! from the display, which may have been copied from the target (as in mæsseǣfen in -- the example above). link.display = link.display:gsub("^!!", "") elseif not link.target:match("^%*") then link.target = "*" .. link.target end end linktext = make_link(link, lang, sc, id, false, nil, no_alt_ast, plain) :gsub("^%[%[", "\3") :gsub("%]%]$", "\4") return space1 .. linktext .. space2 end -- Use chars 1 and 2 as temporary substitutions, so that we can use charsets. These are converted to chars 3 and 4 by process_link, which means we can convert any remaining chars 1 and 2 back to square brackets (i.e. those not part of a link). text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- If the script uses ^ to capitalize transliterations, make sure that any carets preceding links are on the inside, so that they get processed with the following text. if ( text:find("^", nil, true) and not sc:hasCapitalization() and sc:isTransliterated() ) then text = escape(text, "^") :gsub("%^\1", "\1%^") text = unescape(text, "^") end text = text:gsub("\1(%s*)([^\1\2]-)(%s*)\2", process_link) -- Remove the extra * at the beginning of a language link if it's immediately followed by a link whose display begins with * too. if all_reconstructed then text = text:gsub("^%*\3([^|\1-\4]+)|%*", "\3%1|*") end return (text :gsub("[\1\3]", "[[") :gsub("[\2\4]", "]]") ) end local function simple_link(term, fragment, alt, lang, sc, id, cats, no_alt_ast, srwc) local plain if lang == nil then lang, plain = get_lang("und"), true end -- Get the link target and display text. If the term is the empty string, treat the input as a link to the current page. if term == "" then term = get_current_title().prefixedText elseif term then local new_term, new_alt = export.get_wikilink_parts(term, true) if new_term then check_params_ignored_when_embedded(alt, lang, id, cats) -- [[|foo]] links are treated as plaintext "[[|foo]]". -- FIXME: Pipes should be handled via a proper escape sequence, as they can occur in unsupported titles. if new_term == "" then term, alt = nil, term else local title = new_title(new_term) if title then local ns = title.namespace -- File: and Category: links should be returned as-is. if ns == 6 or ns == 14 then return term end end term, alt = new_term, new_alt if cats then if not (srwc and srwc(term, alt)) then insert(cats, "Liên kết mục từ có liên kết wiki thừa " .. lang:getFullName()) end end end end end if alt then alt = selective_trim(alt) if alt == "" then alt = nil end end -- If there's nothing to process, return nil. if not (term or alt) then return nil end -- If there is no script, get one. if not sc then sc = lang:findBestScript(alt or term) end -- Embedded wikilinks need to be processed individually. if term then local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, alt, lang, sc, id, cats, no_alt_ast, plain) end term = selective_trim(term) end -- If not, make a link using the parameters. return make_link({ target = term, display = alt, fragment = fragment }, lang, sc, id, true, cats, no_alt_ast, plain) end --[==[Creates a basic link to the given term. It links to the language section (such as <code>==English==</code>), but it does not add language and script wrappers, so any code that uses this function should call the <code class="n">[[Module:script utilities#tag_text|tag_text]]</code> from [[Module:script utilities]] to add such wrappers itself at some point. The first argument, <code class="n">data</code>, may contain the following items, a subset of the items used in the <code class="n">data</code> argument of <code class="n">full_link</code>. If any other items are included, they are ignored. { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, id = sense_id, } } ; <code class="n">term</code> : Text to turn into a link. This is generally the name of a page. The text can contain wikilinks already embedded in it. These are processed individually just like a single link would be. The <code class="n">alt</code> argument is ignored in this case. ; <code class="n">alt</code> (''optional'') : The alternative display for the link, if different from the linked page. If this is {{code|lua|nil}}, the <code class="n">text</code> argument is used instead (much like regular wikilinks). If <code class="n">text</code> contains wikilinks in it, this argument is ignored and has no effect. (Links in which the alt is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/alt-ignored}}.) ; <code class="n">lang</code> : The [[Module:languages#Language objects|language object]] for the term being linked. If this argument is defined, the function will determine the language's canonical name (see [[Template:language data documentation]]), and point the link or links in the <code class="n">term</code> to the language's section of an entry, or to a language-specific senseid if the <code class="n">id</code> argument is defined. ; <code class="n">id</code> (''optional'') : Sense id string. If this argument is defined, the link will point to a language-specific sense id ({{ll|en|identifier|id=HTML}}) created by the template {{temp|senseid}}. A sense id consists of the language's canonical name, a hyphen (<code>-</code>), and the string that was supplied as the <code class="n">id</code> argument. This is useful when a term has more than one sense in a language. If the <code class="n">term</code> argument contains wikilinks, this argument is ignored. (Links in which the sense id is ignored are tracked with the tracking template {{whatlinkshere|tracking=links/id-ignored}}.) The second argument is as follows: ; <code class="n">allow_self_link</code> : If {{code|lua|true}}, the function will also generate links to the current page. The default ({{code|lua|false}}) will not generate a link but generate a bolded "self link" instead. The following special options are processed for each link (both simple text and with embedded wikilinks): * The target page name will be processed to generate the correct entry name. This is done by the [[Module:languages#makeEntryName|makeEntryName]] function in [[Module:languages]], using the <code class="n">entry_name</code> replacements in the language's data file (see [[Template:language data documentation]] for more information). This function is generally used to automatically strip dictionary-only diacritics that are not part of the normal written form of a language. * If the text starts with <code class="n">*</code>, then the term is considered a reconstructed term, and a link to the Reconstruction: namespace will be created. If the text contains embedded wikilinks, then <code class="n">*</code> is automatically applied to each one individually, while preserving the displayed form of each link as it was given. This allows linking to phrases containing multiple reconstructed terms, while only showing the * once at the beginning. * If the text starts with <code class="n">:</code>, then the link is treated as "raw" and the above steps are skipped. This can be used in rare cases where the page name begins with <code class="n">*</code> or if diacritics should not be stripped. For example: ** {{temp|l|en|*nix}} links to the nonexistent page [[Reconstruction:English/nix]] (<code class="n">*</code> is interpreted as a reconstruction), but {{temp|l|en|:*nix}} links to [[*nix]]. ** {{temp|l|sl|Franche-Comté}} links to the nonexistent page [[Franche-Comte]] (<code>é</code> is converted to <code>e</code> by <code class="n">makeEntryName</code>), but {{temp|l|sl|:Franche-Comté}} links to [[Franche-Comté]].]==] function export.language_link(data) if type(data) ~= "table" then error("The first argument to the function language_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "language_link") end -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Liên kết ngôn ngữ không xác định") end return simple_link( data.term, data.fragment, data.alt, lang, data.sc, data.id, cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end function export.plain_link(data) if type(data) ~= "table" then error("The first argument to the function plain_link must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "plain_link") end return simple_link( data.term, data.fragment, data.alt, nil, data.sc, data.id, data.cats, data.no_alt_ast, data.suppress_redundant_wikilink_cat ) end --[==[Replace any links with links to the correct section, but don't link the whole text if no embedded links are found. Returns the display text form.]==] function export.embedded_language_links(data) if type(data) ~= "table" then error("The first argument to the function embedded_language_links must be a table. See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "embedded_language_links") end local term, lang, sc = data.term, data.lang, data.sc -- If we don't have a script, get one. if not sc then sc = lang:findBestScript(term) end -- Do we have embedded wikilinks? If so, they need to be processed individually. local open = find(term, "[[", nil, true) if open and find(term, "]]", open + 2, true) then return process_embedded_links(term, data.alt, lang, sc, data.id, data.cats, data.no_alt_ast) end -- If not, return the display text. term = selective_trim(term) -- FIXME: Double-escape any percent-signs, because we don't want to treat non-linked text as having percent-encoded characters. This is a hack: percent-decoding should come out of [[Module:languages]] and only dealt with in this module, as it's specific to links. term = term:gsub("%%", "%%25") return lang:makeDisplayText(term, sc, true) end function export.mark(text, item_type, face, lang) local tag = { "", "" } if item_type == "gloss" then tag = { '<span class="mention-gloss-double-quote">“</span><span class="mention-gloss">', '</span><span class="mention-gloss-double-quote">”</span>' } if type(text) == "string" and text:match("^''[^'].*''$") then -- Temporary tracking for mention glosses that are entirely italicized or bolded, which is probably -- wrong. (Note that this will also find bolded mention glosses since they use triple apostrophes.) track("italicized-mention-gloss", lang and lang:getFullCode() or nil) end elseif item_type == "tr" then if face == "term" then tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr mention-tr Latn">', '</span>' } else tag = { '<span lang="' .. lang:getFullCode() .. '" class="tr Latn">', '</span>' } end elseif item_type == "ts" then -- \226\129\160 = word joiner (zero-width non-breaking space) U+2060 tag = { '<span class="ts mention-ts Latn">/\226\129\160', '\226\129\160/</span>' } elseif item_type == "pos" then tag = { '<span class="ann-pos">', '</span>' } elseif item_type == "non-gloss" then tag = { '<span class="ann-non-gloss">', '</span>' } elseif item_type == "annotations" then tag = { '<span class="mention-gloss-paren annotation-paren">(</span>', '<span class="mention-gloss-paren annotation-paren">)</span>' } end if type(text) == "string" then return tag[1] .. text .. tag[2] else return "" end end local pos_tags --[==[Formats the annotations that are displayed with a link created by {{code|lua|full_link}}. Annotations are the extra bits of information that are displayed following the linked term, and include things such as gender, transliteration, gloss and so on. * The first argument is a table possessing some or all of the following keys: *:; <code class="n">genders</code> *:: Table containing a list of gender specifications in the style of [[Module:gender and number]]. *:; <code class="n">tr</code> *:: Transliteration. *:; <code class="n">gloss</code> *:: Gloss that translates the term in the link, or gives some other descriptive information. *:; <code class="n">pos</code> *:: Part of speech of the linked term. If the given argument matches one of the aliases in `pos_aliases` in [[Module:headword/data]], or consists of a part of speech or alias followed by `f` (for a non-lemma form), expand it appropriately. Otherwise, just show the given text as it is. *:; <code class="n">ng</code> *:: Arbitrary non-gloss descriptive text for the link. This should be used in preference to putting descriptive text in `gloss` or `pos`. *:; <code class="n">lit</code> *:: Literal meaning of the term, if the usual meaning is figurative or idiomatic. *:Any of the above values can be omitted from the <code class="n">info</code> argument. If a completely empty table is given (with no annotations at all), then an empty string is returned. * The second argument is a string. Valid values are listed in [[Module:script utilities/data]] "data.translit" table.]==] function export.format_link_annotations(data, face) local output = {} -- Interwiki link if data.interwiki then insert(output, data.interwiki) end -- Genders if type(data.genders) ~= "table" then data.genders = { data.genders } end if data.genders and #data.genders > 0 then local genders, gender_cats = format_genders(data.genders, data.lang) insert(output, "&nbsp;" .. genders) if gender_cats then local cats = data.cats if cats then extend(cats, gender_cats) end end end local annotations = {} -- Transliteration and transcription if data.tr and data.tr[1] or data.ts and data.ts[1] then local kind if face == "term" then kind = face else kind = "default" end if data.tr[1] and data.ts[1] then insert(annotations, tag_translit(data.tr[1], data.lang, kind) .. " " .. export.mark(data.ts[1], "ts")) elseif data.ts[1] then insert(annotations, export.mark(data.ts[1], "ts")) else insert(annotations, tag_translit(data.tr[1], data.lang, kind)) end end -- Gloss/translation if data.gloss then insert(annotations, export.mark(data.gloss, "gloss")) end -- Part of speech if data.pos then -- debug category for pos= containing transcriptions if data.pos:match("/[^><]-/") then data.pos = data.pos .. "[[Category:links likely containing transcriptions in pos]]" end -- Canonicalize part of speech aliases as well as non-lemma aliases like 'nf' or 'nounf' for "noun form". pos_tags = pos_tags or (m_headword_data or get_headword_data()).pos_aliases local pos = pos_tags[data.pos] if not pos and data.pos:find("f$") then local pos_form = data.pos:sub(1, -2) -- We only expand something ending in 'f' if the result is a recognized non-lemma POS. pos_form = (pos_tags[pos_form] or pos_form) .. " form" if (m_headword_data or get_headword_data()).nonlemmas[pos_form .. "s"] then pos = pos_form end end insert(annotations, export.mark(pos or data.pos, "pos")) end -- Non-gloss text if data.ng then insert(annotations, export.mark(data.ng, "non-gloss")) end -- Literal/sum-of-parts meaning if data.lit then insert(annotations, "nghĩa đen " .. export.mark(data.lit, "gloss")) end -- Provide a hook to insert additional annotations such as nested inflections. if data.postprocess_annotations then data.postprocess_annotations { data = data, annotations = annotations } end if #annotations > 0 then insert(output, " " .. export.mark(concat(annotations, ", "), "annotations")) end return concat(output) end -- Encode certain characters to avoid various delimiter-related issues at various stages. We need to encode < and > -- because they end up forming part of CSS class names inside of <span ...> and will interfere with finding the end -- of the HTML tag. I first tried converting them to URL encoding, i.e. %3C and %3E; they then appear in the URL as -- %253C and %253E, which get mapped back to %3C and %3E when passed to [[Module:accel]]. But mapping them to &lt; -- and &gt; somehow works magically without any further work; they appear in the URL as < and >, and get passed to -- [[Module:accel]] as < and >. I have no idea who along the chain of calls is doing the encoding and decoding. If -- someone knows, please modify this comment appropriately! local accel_char_map local function get_accel_char_map() accel_char_map = { ["%"] = ".", [" "] = "_", ["_"] = u(0xFFF0), ["<"] = "&lt;", [">"] = "&gt;", } return accel_char_map end local function encode_accel_param_chars(param) return (param:gsub("[% <>_]", accel_char_map or get_accel_char_map())) end local function encode_accel_param(prefix, param) if not param then return "" end if type(param) == "table" then local filled_params = {} -- There may be gaps in the sequence, especially for translit params. local maxindex = 0 for k in pairs(param) do if type(k) == "number" and k > maxindex then maxindex = k end end for i = 1, maxindex do filled_params[i] = param[i] or "" end -- [[Module:accel]] splits these up again. param = concat(filled_params, "*~!") end -- This is decoded again by [[WT:ACCEL]]. return prefix .. encode_accel_param_chars(param) end local function insert_if_not_blank(list, item) if item == "" then return end insert(list, item) end local function get_class(lang, tr, accel, nowrap) if not accel and not nowrap then return "" end local classes = {} if accel then insert(classes, "form-of lang-" .. lang:getFullCode()) local form = accel.form if form then insert(classes, encode_accel_param_chars(form) .. "-form-of") end insert_if_not_blank(classes, encode_accel_param("gender-", accel.gender)) insert_if_not_blank(classes, encode_accel_param("pos-", accel.pos)) insert_if_not_blank(classes, encode_accel_param("transliteration-", accel.translit or (tr ~= "-" and tr or nil))) insert_if_not_blank(classes, encode_accel_param("target-", accel.target)) insert_if_not_blank(classes, encode_accel_param("origin-", accel.lemma)) insert_if_not_blank(classes, encode_accel_param("origin_transliteration-", accel.lemma_translit)) if accel.no_store then insert(classes, "form-of-nostore") end end if nowrap then insert(classes, nowrap) end return concat(classes, " ") end -- Add any left or right regular or accent qualifiers, labels or references to a formatted term. `data` is the object -- specifying the term, which should optionally contain: -- * a language object in `lang`; required if any accent qualifiers or labels are given; -- * left regular qualifiers in `q` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * right regular qualifiers in `qq` (an array of strings or a single string); an empty array or blank string will be -- ignored; -- * left accent qualifiers in `a` (an array of strings); an empty array will be ignored; -- * right accent qualifiers in `aa` (an array of strings); an empty array will be ignored; -- * left labels in `l` (an array of strings); an empty array will be ignored; -- * right labels in `ll` (an array of strings); an empty array will be ignored; -- * references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text` -- (formatted reference text) and optionally `name` and/or `group`. -- `formatted` is the formatted version of the term itself. local function add_qualifiers_and_refs_to_term(data, formatted) local q = data.q if type(q) == "string" then q = {q} end local qq = data.qq if type(qq) == "string" then qq = {qq} end if q and q[1] or qq and qq[1] or data.a and data.a[1] or data.aa and data.aa[1] or data.l and data.l[1] or data.ll and data.ll[1] or data.refs and data.refs[1] then formatted = format_qualifiers{ lang = data.lang, text = formatted, q = q, qq = qq, a = data.a, aa = data.aa, l = data.l, ll = data.ll, refs = data.refs, } end return formatted end --[==[ Creates a full link, with annotations (see `[[#format_link_annotations|format_link_annotations]]`), in the style of {{tl|l}} or {{tl|m}}. The first argument, `data`, must be a table. It contains the various elements that can be supplied as parameters to {{tl|l}} or {{tl|m}}: { { term = entry_to_link_to, alt = link_text_or_displayed_text, lang = language_object, sc = script_object, track_sc = boolean, no_nonstandard_sc_cat = boolean, fragment = link_fragment, id = sense_id, genders = { "gender1", "gender2", ... }, tr = transliteration, respect_link_tr = boolean, ts = transcription, gloss = gloss, pos = part_of_speech_tag, ng = non-gloss text, lit = literal_translation, no_alt_ast = boolean, accel = {accelerated_creation_tags}, interwiki = interwiki, pretext = "text_at_beginning" or nil, posttext = "text_at_end" or nil, q = { "left_qualifier1", "left_qualifier2", ...} or "left_qualifier", qq = { "right_qualifier1", "right_qualifier2", ...} or "right_qualifier", l = { "left_label1", "left_label2", ...}, ll = { "right_label1", "right_label2", ...}, a = { "left_accent_qualifier1", "left_accent_qualifier2", ...}, aa = { "right_accent_qualifier1", "right_accent_qualifier2", ...}, refs = { "formatted_ref1", "formatted_ref2", ...} or { {text = "text", name = "name", group = "group"}, ... }, show_qualifiers = boolean, } } Any one of the items in the `data` table may be {nil}, but an error will be shown if neither `term` nor `alt` nor `tr` is present. Thus, calling {full_link{ term = term, lang = lang, sc = sc }}, where `term` is the page to link to (which may have diacritics that will be stripped and/or embedded bracketed links) and `lang` is a [[Module:languages#Language objects|language object]] from [[Module:languages]], will give a plain link similar to the one produced by the template {{tl|l}}, and calling {full_link( { term = term, lang = lang, sc = sc }, "term" )} will give a link similar to the one produced by the template {{tl|m}}. The function will: * Try to determine the script, based on the characters found in the `term` or `alt` argument, if the script was not given. If a script is given and `track_sc` is {true}, it will check whether the input script is the same as the one which would have been automatically generated and add the category [[:Category:LANG terms with redundant script codes]] if yes, or [[:Category:LANG terms with non-redundant manual script codes]] if no. This should be used when the input script object is directly determined by a template's `sc` parameter. * Call `[[#language_link|language_link]]` on the `term` or `alt` forms, to remove diacritics in the page name, process any embedded wikilinks and create links to Reconstruction or Appendix pages when necessary. * Call `[[Module:script utilities#tag_text]]` to add the appropriate language and script tags to the term and italicize terms written in the Latin script if necessary. Accelerated creation tags, as used by [[WT:ACCEL]], are included. * Generate a transliteration, based on the `alt` or `term` arguments, if the script is not Latin, no transliteration was provided in `tr` and the combination of the term's language and script support automatic transliteration. The transliteration itself will be linked if both `.respect_link_tr` is specified and the language of the term has the `link_tr` property set for the script of the term; but not otherwise. * Add the annotations (transliteration, gender, gloss, etc.) after the link. * If `no_alt_ast` is specified, then the `alt` text does not need to contain an asterisk if the language is reconstructed. This should only be used by modules which really need to allow links to reconstructions that don't display asterisks (e.g. number boxes). * If `pretext` or `posttext` is specified, this is text to (respectively) prepend or append to the output, directly before processing qualifiers, labels and references. This can be used to add arbitrary extra text inside of the qualifiers, labels and references. * If `show_qualifiers` is specified or the `show_qualifiers` argument is given, then left and right qualifiers, accent qualifiers, labels and references will be displayed, otherwise they will be ignored. (This is because a fair amount of code stores qualifiers, labels and/or references in these fields and displays them itself, rather than expecting {full_link()} to display them.)]==] function export.full_link(data, face, allow_self_link, show_qualifiers) if type(data) ~= "table" then error("The first argument to the function full_link must be a table. " .. "See Module:links/documentation for more information.") elseif data.term and data.term:find("\\", nil, true) or data.alt and data.alt:find("\\", nil, true) then track("escaped", "full_link") end -- Prevent data from being destructively modified. local data = shallow_copy(data) -- FIXME: this shouldn't be added to `data`, as that means the input table needs to be cloned. data.cats = {} -- Categorize links to "und". local lang, cats = data.lang, data.cats if cats and lang:getCode() == "und" then insert(cats, "Liên kết ngôn ngữ không xác định") end local terms = {true} -- Generate multiple forms if applicable. for _, param in ipairs{"term", "alt"} do if type(data[param]) == "string" and data[param]:find("//", nil, true) then data[param] = export.split_on_slashes(data[param]) elseif type(data[param]) == "string" and not (type(data.term) == "string" and data.term:find("//", nil, true)) then if not data.no_generate_forms then data[param] = lang:generateForms(data[param]) else data[param] = {data[param]} end else data[param] = {} end end for _, param in ipairs{"sc", "tr", "ts"} do data[param] = {data[param]} end for _, param in ipairs{"term", "alt", "sc", "tr", "ts"} do for i in pairs(data[param]) do terms[i] = true end end -- Create the link local output = {} local id, no_alt_ast, srwc, accel, nevercalltr = data.id, data.no_alt_ast, data.suppress_redundant_wikilink_cat, data.accel, data.never_call_transliteration_module local link_tr = data.respect_link_tr and lang:link_tr(data.sc[1]) for i in ipairs(terms) do local link -- Is there any text to show? if (data.term[i] or data.alt[i]) then -- Try to detect the script if it was not provided local display_term = data.alt[i] or data.term[i] local best = lang:findBestScript(display_term) -- no_nonstandard_sc_cat is intended for use in [[Module:interproject]] if ( not data.no_nonstandard_sc_cat and best:getCode() == "None" and find_best_script_without_lang(display_term):getCode() ~= "None" ) then insert(cats, "Mục từ có chữ viết không chuẩn " .. lang:getFullName()) end if not data.sc[i] then data.sc[i] = best -- Track uses of sc parameter. elseif data.track_sc then if data.sc[i]:getCode() == best:getCode() then insert(cats, "Mục từ có mã chữ viết thừa " .. lang:getFullName()) else insert(cats, "Mục từ có mã chữ viết thủ công không thừa " .. lang:getFullName()) end end -- If using a discouraged character sequence, add to maintenance category if data.sc[i]:hasNormalizationFixes() == true then if (data.term[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.term[i])) ~= toNFC(data.term[i])) or (data.alt[i] and data.sc[i]:fixDiscouragedSequences(toNFC(data.alt[i])) ~= toNFC(data.alt[i])) then insert(cats, "Pages using discouraged character sequences") end end link = simple_link( data.term[i], data.fragment, data.alt[i], lang, data.sc[i], id, cats, no_alt_ast, srwc ) end -- simple_link can return nil, so check if a link has been generated. if link then -- Add "nowrap" class to prefixes in order to prevent wrapping after the hyphen local nowrap local display_term = data.alt[i] or data.term[i] if display_term and (display_term:find("^%-") or display_term:find("^־")) then -- Hebrew maqqef -- FIXME, use hyphens from [[Module:affix]] nowrap = "nowrap" end link = tag_text(link, lang, data.sc[i], face, get_class(lang, data.tr[i], accel, nowrap)) else --[[ No term to show. Is there at least a transliteration we can work from? ]] link = request_script(lang, data.sc[i]) -- No link to show, and no transliteration either. Show a term request (unless it's a substrate, as they rarely take terms). if (link == "" or (not data.tr[i]) or data.tr[i] == "-") and lang:getFamilyCode() ~= "qfa-sub" then -- If there are multiple terms, break the loop instead. if i > 1 then remove(output) break elseif NAMESPACE ~= "Bản mẫu" then insert(cats, "Yêu cầu mục từ " .. lang:getFullName()) end link = "<small>[Mục từ gì?]</small>" end end insert(output, link) if i < #terms then insert(output, "<span class=\"Zsym mention\" style=\"font-size:100%;\">&nbsp;/ </span>") end end -- TODO: Currently only handles the first transliteration, pending consensus on how to handle multiple translits for multiple forms, as this is not always desirable (e.g. traditional/simplified Chinese). if data.tr[1] == "" or data.tr[1] == "-" then data.tr[1] = nil else local phonetic_extraction = load_data("Module:links/data").phonetic_extraction phonetic_extraction = phonetic_extraction[lang:getCode()] or phonetic_extraction[lang:getFullCode()] if phonetic_extraction then data.tr[1] = data.tr[1] or require(phonetic_extraction).getTranslit(export.remove_links(data.alt[1] or data.term[1])) elseif (data.term[1] or data.alt[1]) and data.sc[1]:isTransliterated() then -- Track whenever there is manual translit. The categories below like 'terms with redundant transliterations' -- aren't sufficient because they only work with reference to automatic translit and won't operate at all in -- languages without any automatic translit, like Persian and Hebrew. if data.tr[1] then local full_code = lang:getFullCode() track("manual-tr", full_code) end if not nevercalltr then -- Try to generate a transliteration. local text = data.alt[1] or data.term[1] if not link_tr then text = export.remove_links(text, true) end local automated_tr = lang:transliterate(text, data.sc[1]) if automated_tr then local manual_tr = data.tr[1] if manual_tr then if export.remove_links(manual_tr) == export.remove_links(automated_tr) then insert(cats, "Mục từ có chuyển tự thừa " .. lang:getFullName()) else -- Prevents Arabic root categories from flooding the tracking categories. if NAMESPACE ~= "Thể loại" then insert(cats, "Mục từ có chuyển tự thủ công không thừa " .. lang:getFullName()) end end end if not manual_tr or lang:overrideManualTranslit(data.sc[1]) then data.tr[1] = automated_tr end end end end end -- Link to the transliteration entry for languages that require this if data.tr[1] and link_tr and not data.tr[1]:match("%[%[(.-)%]%]") then data.tr[1] = simple_link( data.tr[1], nil, nil, lang, get_script("Latn"), nil, cats, no_alt_ast, srwc ) elseif data.tr[1] and not link_tr then -- Remove the pseudo-HTML tags added by remove_links. data.tr[1] = data.tr[1]:gsub("</?link>", "") end if data.tr[1] and not umatch(data.tr[1], "[^%s%p]") then data.tr[1] = nil end insert(output, export.format_link_annotations(data, face)) if data.pretext then insert(output, 1, data.pretext) end if data.posttext then insert(output, data.posttext) end local categories = cats[1] and format_categories(cats, lang, "-", nil, nil, data.sc) or "" output = concat(output) if show_qualifiers or data.show_qualifiers then output = add_qualifiers_and_refs_to_term(data, output) end return output .. categories end --[==[Replaces all wikilinks with their displayed text, and removes any categories. This function can be invoked either from a template or from another module. -- Strips links: deletes category links, the targets of piped links, and any double square brackets involved in links (other than file links, which are untouched). If `tag` is set, then any links removed will be given pseudo-HTML tags, which allow the substitution functions in [[Module:languages]] to properly subdivide the text in order to reduce the chance of substitution failures in modules which scrape pages like [[Module:zh-translit]]. -- FIXME: This is quite hacky. We probably want this to be integrated into [[Module:languages]], but we can't do that until we know that nothing is pushing pipe linked transliterations through it for languages which don't have link_tr set. * <code><nowiki>[[page|displayed text]]</nowiki></code> &rarr; <code><nowiki>displayed text</nowiki></code> * <code><nowiki>[[page and displayed text]]</nowiki></code> &rarr; <code><nowiki>page and displayed text</nowiki></code> * <code><nowiki>[[Category:English lemmas|WORD]]</nowiki></code> &rarr; ''(nothing)'']==] function export.remove_links(text, tag) if type(text) == "table" then text = text.args[1] end if not text or text == "" then return "" end text = text :gsub("%[%[", "\1") :gsub("%]%]", "\2") -- Parse internal links for the display text. text = text:gsub("(\1)([^\1\2]-)(\2)", function(c1, c2, c3) -- Don't remove files. for _, false_positive in ipairs({"file", "image"}) do if c2:lower():match("^" .. false_positive .. ":") then return c1 .. c2 .. c3 end end -- Remove categories completely. for _, false_positive in ipairs({"category", "cat"}) do if c2:lower():match("^" .. false_positive .. ":") then return "" end end -- In piped links, remove all text before the pipe, unless it's the final character (i.e. the pipe trick), in which case just remove the pipe. c2 = c2:match("^[^|]*|(.+)") or c2:match("([^|]+)|$") or c2 if tag then return "<link>" .. c2 .. "</link>" else return c2 end end) text = text :gsub("\1", "[[") :gsub("\2", "]]") return text end function export.section_link(link) if type(link) ~= "string" then error("The first argument to section_link was a " .. type(link) .. ", but it should be a string.") elseif link:find("\\", nil, true) then track("escaped", "section_link") end local target, section = get_fragment((link:gsub("_", " "))) if not section then error("No \"#\" delineating a section name") end return simple_link( target, section, target .. " §&nbsp;" .. section ) end return export j65lna1gtbkxv8v8ao1y9tn092on82s Bản mẫu:blt-pron 10 260080 2344376 2079761 2026-04-12T04:22:10Z Higashizakura 36666 2344376 wikitext text/x-wiki <includeonly>{{#invoke:blt-pron|show}}</includeonly><noinclude>{{tài liệu}}{{tcat|pron}}</noinclude> 9bxj8e12arw7bpl41tapkfeuut0wzha Phụ lục:Từ điển thuật ngữ 100 263936 2344321 2335804 2026-04-12T02:00:25Z TheHighFighter2 42988 2344321 wikitext text/x-wiki Trang này chú giải [[thuật ngữ]] được sử dụng trong phần nội dung của từ điển này. __TOC__ ==B== ; '''Ban đầu [...]''' : Một từ có nguồn gốc từ một địa phương hoặc vùng miền nào đó, mà ngày nay trở nên phổ biến gần như trở thành từ toàn dân. '''1. {{anchor|Ban đầu Miền Bắc Việt Nam}} Ban đầu Miền Bắc Việt Nam''': Một từ có chú thích “Ban đầu Miền Bắc Việt Nam” tức là từ đó bắt nguồn từ Miền Bắc Việt Nam '''2. {{anchor|Ban đầu Miền Nam Việt Nam}} Ban đầu Miền Nam Việt Nam''': Một từ có chú thích “Ban đầu Miền Nam Việt Nam” tức là từ đó bắt nguồn từ Miền Nam Việt Nam. '''3. {{anchor|Ban đầu Miền Trung Việt Nam}} Ban đầu Miền Trung Việt Nam''': Một từ có chú thích “Ban đầu Miền Trung Việt Nam” tức là từ đó bắt nguồn từ Miền Trung Việt Nam. ==C== ;{{anchor|cách}} '''cách''' : Phạm trù ngữ pháp được sử dụng nhằm thể hiện quan hệ và vai trò giữa các từ ở trong một câu hoặc một cụm từ. Một số các cách bao gồm [[#danh cách|danh cách]], [[#sinh cách|sinh cách]], [[#dữ cách|dữ cách]],... ; {{anchor|cổ xưa}} '''cổ xưa''' : Không còn được sử dụng rộng rãi nữa, nhưng vẫn có thể bắt gặp nó trong một số văn bản đương đại, đặc biệt là những tác phẩm muốn tạo phong cách cổ kính, chẳng hạn như các tác phẩm tiểu thuyết lịch sử. Ví dụ, trong Tiếng Anh, các đại từ [[thee]] và [[thou]] là những từ cổ xưa, giờ vẫn được dùng trong một vài văn bản đương đại, nhưng giờ đây gần như đã được thay thế hoàn toàn bằng [[you]]. ''Cổ xưa'' là một thuật ngữ mang ý nghĩa mạnh hơn [[Phụ lục:Từ điển thuật ngữ#lỗi thời|''lỗi thời'']] nhưng lại không mạnh bằng [[Phụ lục:Từ điển thuật ngữ#không còn dùng|''không còn dùng'']]. ; {{anchor|CN}}'''CN''' : Viết tắt của "[[Công Nguyên]]". ==D== ; {{anchor|dữ cách}} '''dữ cách''' : [[#cách|Cách]] thường được sử dụng làm [[#bổ ngữ gián tiếp|bổ ngữ gián tiếp]] cho một động từ. Lấy ví dụ, trong tiếng Latinh, trong câu ''Sextus Claudiae fābulam dīxit'' (Sextus kể cho Claudia một câu chuyện), từ "Claudiae" (Claudia) được chia ở dữ cách. ==Đ== ; {{anchor|đếm được}}'''đếm được''' :Danh từ có thể được sử dụng tự do với mạo từ không xác định (a hoặc an trong tiếng Anh) và với số, do đó có dạng [[số nhiều]]. ; {{anchor|đối cách}}'''đối cách''' : [[#cách|Cách]] thường được sử dụng làm [[#tân ngữ trực tiếp|tân ngữ trực tiếp]] cho một động từ. Lấy ví dụ, trong tiếng Latinh, trong câu ''Puella puerum amat'' (Cô bé yêu cậu bé), "puerum" (cậu bé) được chia ở đối cách. ; {{anchor|Đph}}'''Đph''' :Viết tắt của "Từ địa phương", là những từ được sử dụng hạn chế ở một hoặc vài [[địa phương]] nào đó. Từ địa phương là một bộ phận của [[phương ngữ]]. ==G== ; {{g|f}} : ''Xem '''{{lg|giống cái}}'''.'' ; {{g|c}} : ''Xem '''{{lg|giống chung}}'''.'' ; {{g|m}} : ''Xem '''{{lg|giống đực}}'''.'' ; {{g|n}} : ''Xem '''{{lg|giống trung}}'''.'' ; {{anchor|giảm nhẹ nghĩa}}'''giảm nhẹ nghĩa''' :Hình thức giảm nhẹ nghĩa, âu yếm, trìu mến nhỏ bé thường được sử dụng để biểu đạt những mối quan hệ thân thiết, gần gũi. ; {{anchor|giống}} [[giống]] : Cách phân loại [[#danh từ|danh từ]] trong một số ngôn ngữ. Theo đó, mỗi danh từ sẽ thuộc về một giống cụ thể (thường dựa trên nghĩa và/hoặc hình thái). Các từ loại khác (nhất là [[#tính từ|tính từ]] và [[#đại từ|đại từ]]) thường phải biến đổi hình thái để phù hợp về giống với danh từ đó. Xem thêm [[#lớp danh từ|lớp danh từ]]. ; {{anchor|gc|giống cái}} [[giống cái]], {{g|f}} : Đề cập đến một từ thuộc phạm trù ngữ pháp [[#giống|giống]] là "cái", thường tương phản với [[#giống đực|giống đực]] và đôi khi là cả [[#giống trung|giống trung]]. ; {{anchor|gch|giống chung}} [[giống chung]], {{g|c}} : Đề cập đến một từ thuộc phạm trù ngữ pháp [[#giống|giống]] là "chung giống". Trong một số ngôn ngữ, giống chung là một phạm trù ngữ pháp riêng biệt được hình thành từ sự kết hợp giữa [[#giống đực|giống đực]] và [[#giống cái|giống cái]], nhưng phân biệt với [[#giống trung|giống trung]]. Trong các ngôn ngữ khác, "danh từ giống chung" là một cặp danh từ (gồm một giống đực và một giống cái) có hình thái giống hệt nhau và tương đồng về nghĩa, nhưng khác nhau đối tượng tham chiếu (một chỉ nam giới, một chỉ nữ giới). Cần phân biệt với [[#giống đôi|giống đôi]]. ; {{anchor|gđ|giống đực}} [[giống đực]], {{g|m}} : Đề cập đến một từ thuộc phạm trù ngữ pháp [[#giống|giống]] là "đực" trong những ngôn ngữ có phân biệt giống. ; {{anchor|gt|giống trung}} [[giống trung]], {{g|n}} : Đề cập đến một từ thuộc phạm trù ngữ pháp [[#giống|giống]] là "trung tính": có hình thái không phải [[#giống đực|giống đực]] hay là [[#giống cái|giống cái]]; hoặc có hình thái không thuộc [[#giống chung|giống chung]]. ==K== ; {{anchor|kh.}}'''kh.''' : Viết tắt của "[[khoảng]]". Một trích dẫn có ghi thông tin chẳng hạn như "kh. 1924" có nghĩa phần đó được trích dẫn từ ngữ liệu có từ khoảng những năm 1924. ; {{anchor|không còn dùng}}'''không còn dùng''' :Không còn được sử dụng nữa. ''Không còn dùng'' là một thuật ngữ mang ý nghĩa mạnh hơn so với [[Phụ lục:Từ điển thuật ngữ#lỗi thời|''lỗi thời'']] và [[Phụ lục:Từ điển thuật ngữ#cổ xưa|''cổ xưa'']]. ; {{anchor|không đếm được}}'''không đếm được''' :Danh từ không thể được sử dụng tự do với số hoặc mạo từ không xác định, và do đó thường không có dạng số nhiều. Nhiều ngôn ngữ không phân biệt danh từ đếm được và không đếm được. ; {{anchor|Kng.}}'''Kng.''' :Viết tắt của [[khẩu ngữ]]. ==L== ; {{anchor|lẫn âm}}'''lẫn âm''' : Từ ngữ được hình thành do hiện tượng đọc lẫn các âm gần giống, dần dà trở thành một từ mới. Nhưng ban đầu là một từ vô nghĩa hoặc có nghĩa khác. Ví dụ như từ [[mãn tính]] là một từ Hán-Việt cấu thành bởi hiện tượng lẫn âm (từ đúng là [[mạn tính]]). ; {{anchor|lóng}}{{anchor|từ lóng}}{{anchor|tiếng lóng}}'''lóng''', '''từ lóng''', '''tiếng lóng''' : Từ ngữ riêng trong một tầng lớp hoặc một nhóm người nào đó, nhằm chỉ để cho trong nội bộ hiểu được với nhau. Các từ ngữ như vậy thường nằm ngoài cách sử dụng thông thường và hầu như không phù hợp trong bối cảnh trang trọng. ; {{anchor|lỗi thời}} '''lỗi thời''' : Từng phổ biến trong quá khứ, đôi khi vẫn được dùng ở hiện tại nhưng bây giờ không còn hợp thời. Ví dụ, trong tiếng Anh, từ [[gay]] (theo nghĩa "sáng sủa", "hạnh phúc") là một từ lỗi thời. ''Lỗi thời'' là một thuật ngữ mang ý nghĩa yếu hơn so với [[Phụ lục: Từ điển thuật ngữ#không còn dùng|''không còn dùng'']] và [[Phụ lục: Từ điển thuật ngữ#cổ xưa|''cổ xưa'']]. ; {{anchor|ly cách}} '''ly cách''' : [[#cách|Cách]] được dùng để diễn tả sự tách biệt, sự tách ra, sự di chuyển khỏi một cái gì đó. Ly cách thường được sử dụng độc lập hoặc đi kèm với một số [[#giới từ|giới từ]] nhất định. Lấy ví dụ, trong tiếng Latinh, trong câu ''Ē Vietnamiā oriundus est Vincentius'' (Vincent đến từ Việt Nam), từ "Vietnamiā" (Việt Nam) được chia ở ly cách và đứng sau giới từ "ē". Trong một số ngôn ngữ, chẳng hạn như tiếng Latinh, ngoài để diễn tả sự tách biệt, ly cách còn có thêm nhiều cách dùng khác như: chỉ nguyên nhân, nơi chốn, thời gian,... ==N== ; {{anchor|nhạc}}'''nhạc''' : Từ thuộc về âm nhạc. ==P== ; {{anchor|phụ tố|af}} [[phụ tố]] : [[hình vị ràng buộc|Hình vị ràng buộc]] được thêm vào thân từ; tức [[tiền tố]], [[hậu tố]], [[trung tố]], v.v.. Theo nghĩa hẹp, đồng nghĩa với cả '''[[#hậu tố|hậu tố]]'''. ==S== ; {{g|p}} : ''Xem '''{{lg|số nhiều}}'''.'' ; {{anchor|so sánh}}'''so sánh''' :Từ so sánh đối tượng này với một hoặc nhiều đối tượng khác nhau. ; {{anchor|so sánh được}}'''so sánh được''' :Tính từ hoặc trạng từ: có thể so sánh, có dạng so sánh hơn và so sánh nhất kết thúc bằng -er và -est (chỉ tính từ), hoặc kết hợp với các từ ''more'' hoặc ''most'', hoặc trong một số trường hợp kết hợp với ''further'' và ''furthest''. ; {{anchor|so sánh hơn}}'''so sánh hơn''' :Tính từ so sánh tương đối, thường biểu thị "ở mức lớn hơn" nhưng không phải "ở mức cuối cùng". Trong tiếng Anh, dạng so sánh hơn so sánh giữa 2 người hoặc 2 vật, thường được hình thành bằng cách thêm -er, hoặc sử dụng từ "more". ; {{anchor|so sánh nhất}}'''so sánh nhất''' :Tính từ so sánh tương đối, biểu thị "ở mức cuối cùng". Trong tiếng Anh, dạng so sánh nhất so sánh giữa 3 người hoặc 3 vật trở lên, thường được hình thành bằng cách thêm -est hoặc sử dụng từ "most". ; {{anchor|số nhiều|sn}} [[số nhiều]] : Phạm trù ngữ pháp [[#số|số]] dùng để biểu thị ý có nhiều cá thể hoặc đối tượng. Phần lớn các ngôn ngữ đặt số nhiều trong thế đối lập với [[#số ít|số ít]], và khi đó số nhiều dùng để chỉ số lượng có từ hai trở lên. Một số ngôn ngữ còn có khái niệm [[#số đôi|số đôi]] hoặc thậm chí là [[#số ba|số ba]]; trong những trường hợp này, số nhiều dùng để chỉ số lượng lớn hơn mốc cao nhất hiện có. ==T== ; {{anchor|TCN}}'''[[TCN]]''' : Viết tắt của "[[trước]] [[Công Nguyên]]". ; {{anchor|Tech}}'''Tech''' :Viết tắt của [[technology|Technology]], nghĩa là [[công nghệ học]] (xem thêm [[tech]] để biết thông tin chi tiết) hoặc [[công nghệ]]. ; {{anchor|thô tục}}'''[[thô tục]]''' : Từ ngữ được coi là gây khó chịu hoặc tục tĩu. : Xem thêm: '''{{glossary|xúc phạm}}''', '''{{glossary|miệt thị}}'''. ; {{anchor|Tnd}} '''Tnd''' : Viết tắt của "từ Toàn dân", là từ được toàn dân biết, phổ biến rộng rãi và được sử dụng trong giao tiếp hằng ngày. ; {{anchor|tôn giáo}} '''tôn giáo''' : Từ thuộc về tôn giáo, giáo lí. ; {{anchor|tuyệt cách}} '''tuyệt cách''' : [[#cách|Cách]] được sử dụng để chỉ bị thể hoặc nghiệm thể của hành động do một [[#động từ|động từ]] biểu thị. ; {{anchor|từ mới}}'''từ mới''' : Từ được tạo mới hoàn toàn hay từ có thêm nét nghĩa mới trong khoảng thời gian gần đây. ; {{anchor|từ tượng hình}} '''từ tượng hình''' : Từ mang tính biểu tượng, gợi ý hình ảnh của sự vật mà nó mô tả. Ví dụ như từ [[tẻo teo]]. ; {{anchor|từ tượng thanh}}{{anchor|tượng thanh}}'''[[từ tượng thanh]]''' : Từ có ngữ âm bắt chước, giống với, hoặc gợi ý âm thanh mà nó mô tả. Ví dụ như các từ ''{{l|vi|bùm}}'', ''{{l|vi|cúc cu}}'', ''{{l|vi|chiếp}}'', ''{{l|vi|bính boong}}'' trong tiếng Việt. ; {{anchor|từ ghép}}'''[[từ ghép]]''' : Từ được cấu tạo bằng cách ghép những tiếng lại với nhau, các tiếng được ghép có quan hệ với nhau về nghĩa. ==V== ;{{anchor|viết tắt}} '''viết tắt''' : Dạng rút gọn của một từ hoặc một cụm từ. ==X== ;{{anchor|xuất cách}} '''xuất cách''' :[[#cách|Cách]] biểu thị rằng một thứ gì đó đến từ một cái gì đó, ở đâu đó hoặc ai đó. ==Khác== ; {{anchor|перен.}}'''перен.''' :Viết tắt của [[переносное значение]], nghĩa là [[nghĩa bóng]]. ; {{anchor|мед.}}'''мед.''' :Viết tắt của [[медицинское]], nghĩa là [[Y học]]. ; {{anchor|лингв.}}'''лингв.''' :Viết tắt của [[лингвистический]], nghĩa là (thuộc về) [[ngôn ngữ học]]. ; {{anchor|анат.}}'''анат.''' :Viết tắt của [[анатомический]], nghĩa là (thuộc về) [[giải phẫu]]. ; {{anchor|нескл.}}'''нескл.''' :Viết tắt của [[несклоняемый]], nghĩa là Không biến cách. ; {{anchor|физ.}}'''физ.''' :Viết tắt của [[физический]], nghĩa là [[vật lý]]. ; {{anchor|уст.}}'''уст.''' :Viết tắt của [[устаревший]], nghĩa là Từ cũ. ; {{anchor|тех.}}'''тех.''' :Viết tắt của [[технический]], nghĩa là [[kỹ thuật]]. ; {{anchor|хим.}}'''хим.''' :Viết tắt của [[химический]], nghĩa là (thuộc về) [[hóa học]]. ; {{anchor|воен.}}'''воен.''' :Viết tắt của [[военный]], nghĩa là (thuộc về) [[quân sự]]. ; {{anchor|мат.}}'''мат.''' :Viết tắt của [[математический]], nghĩa là (thuộc về) [[toán học]]. ; {{anchor|бот.}}'''бот.''' :Viết tắt của [[ботанический]], nghĩa là (thuộc về) [[thực vật học]]. ; {{anchor|собир.}}'''собир.''' :Viết tắt của [[собирательный]], nghĩa là (tính chất) [[tập hợp]]. ; {{anchor|спорт.}}'''спорт.''' :Viết tắt của [[спорт]], nghĩa là (thuộc về) [[thể thao]]. [[Thể loại:Wiktionary]] i3ku9rxip11dnloa3r7o7bcql30k3o3 asaramaab 0 267519 2344411 2063242 2026-04-12T05:01:31Z Hiyuune 50834 2344411 wikitext text/x-wiki =={{langname|bej}}== {{cardinalbox|bej|6|7|8|asagwir|asumhay}} ==={{section|etym}}=== Từ {{l|bej|maloob|t=hai}}. ==={{section|pron}}=== * {{bej-IPA}} ==={{section|num}}=== {{head|bej|Số từ|g=m|giống cái|asaramaat}} # [[bảy|Bảy]]. ==={{section|ref}}=== * {{R:bej:Reinisch|331}} b4fqbl6mj3a9f0mgcbz7kg4yfmz5h8g tamnagwir 0 267523 2344407 2063246 2026-04-12T04:59:22Z Hiyuune 50834 2344407 wikitext text/x-wiki =={{langname|bej}}== ==={{section|num}}=== {{head|bej|Số từ|g=m}} # [[mười một|Mười một]]. omev60b8y6m5u5rvit55rezei8xun3v ᦀᦇᦳᧃ 0 268744 2344490 2067287 2026-04-12T11:56:01Z Hiyuune 50834 2344490 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== {{bor+|khb|th|องุ่น}}, từ {{der|khb|bn|আঙ্গুর}}, từ {{der|khb|fa|انگور}}. ==={{section|pron}}=== {{khb-pron|ᦀ-ᦇᦳᧃ}} ==={{section|n}}=== {{khb-noun|ᦐᦽᧈ|l=ᩋᨦᩩᩁ}} # [[quả|Quả]] [[nho]]. #: {{syn|khb|ᦖᦱᧅᦀᦲᧆᧈ}} ==={{section|ref}}=== * {{R:khb:Hanna}} {{C|khb|Trái cây}} 5rt9nl46tz3816rguvhtrmjwittmk1o ᦶᦀᧅ 0 268983 2344485 2068037 2026-04-12T11:48:25Z Hiyuune 50834 2344485 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== Từ {{inh|khb|tai-pro|*ʔeːkᴰ}}, từ {{der|khb|ltc|-}} {{ltc-l|軛}}. Cùng gốc với {{cog|th|แอก}}, {{cog|tts|แอก}}, {{cog|lo|ແອກ}}, {{cog|nod|ᩋᩯ᩠ᨠ}}, {{cog|kkh|ᩋᩯ᩠ᨠ}}, {{cog|blt|ꪵꪮꪀ}}, {{cog|twh|ꪵꪮꪀ}}, {{cog|shn|ဢႅၵ်ႇ}}, {{cog|tdd|ᥟᥦᥐᥱ}}, {{cog|aho|𑜒𑜢𑜀𑜫}}, {{cog|za|ek}}. ==={{section|pron}}=== {{khb-pron}} ==={{section|n}}=== {{khb-noun|ᦀᧃ}} # [[ách|Ách]]. ==={{section|ref}}=== * {{R:khb:Hanna}} cm1gvhlth1f1ob2xtrl95utzxpv0s62 -ꝰ 0 270158 2344429 2111793 2026-04-12T05:19:41Z Hiyuune 50834 2344429 wikitext text/x-wiki {{also|ꝰ}} =={{langname|la}}== ==={{section|suffix}}=== {{head|la|Biến thể hình thái hậu tố}} {{tlb|la|Medieval Latin}} # {{scrib of|la|-us|addl=khác với danh từ ở dữ cách hoặc ly cách số nhiều}} # {{scrib of|la|-ūs}} # {{scrib of|la|-os}} # {{scrib of|la|-ōs}} ===={{section|usage}}==== Gần như luôn luôn dùng ở cuối từ. ===={{section|rel}}==== * [[-ꝫ]] gq4ma1bfe9anocc7mpml8zopgzr98y1 asagwir tamun 0 271106 2344406 2074155 2026-04-12T04:58:53Z Hiyuune 50834 2344406 wikitext text/x-wiki =={{langname|bej}}== ==={{section|num}}=== {{head|bej|Số từ}} # [[sáu mươi|Sáu mươi]]. lhuqthkbo0e7pp073cw8x59nrtzyiah 2344408 2344406 2026-04-12T04:59:37Z Hiyuune 50834 /* Số từ */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]) 2344408 wikitext text/x-wiki =={{langname|bej}}== ==={{section|num}}=== {{head|bej|Số từ|g=m}} # [[sáu mươi|Sáu mươi]]. 9t2yfa2f2fgr82mxgp4ytsf3e779c49 asarama tamun 0 271107 2344409 2074156 2026-04-12T05:00:26Z Hiyuune 50834 2344409 wikitext text/x-wiki =={{langname|bej}}== ==={{section|num}}=== {{head|bej|Số từ|g=m}} # [[bảy mươi|Bảy mươi]]. n98ybqazptbdw07rzpird4l15upgyk9 ᦀᦞᦲᦈᦲ 0 271547 2344487 2075825 2026-04-12T11:50:29Z Hiyuune 50834 2344487 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== {{etym-from|lang=sa|term=अवीचि}} ==={{section|pron}}=== {{khb-pron|ᦀ-ᦞᦲ-ᦈᦲ}} ==={{section|n}}=== {{khb-noun}} # [[địa ngục|Địa ngục]]. 43qvcir6bzbtrxubi2a7r4983vcozl3 ᦁᦳᧃᦎᦟᦻ 0 272017 2344488 2077158 2026-04-12T11:51:20Z Hiyuune 50834 2344488 wikitext text/x-wiki =={{langname|khb}}== ==={{section|pron}}=== {{khb-pron|ᦁᦳᧃ-ᦎ-ᦟᦻ}} ==={{section|noun}}=== {{khb-noun}} # [[sự|Sự]] [[nguy hiểm]], [[thiên tai]], [[tai nạn]]. sg8tq52yykztu71w77ieaq115rcpmq2 Mô đun:languages/data/3/i 828 272289 2344285 2332251 2026-04-11T13:39:24Z Lcsnes 40261 2344285 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared local m = {} m["iai"] = { "tiếng Iaai", 282888, "poz-occ", "Latn", "Tiếng Iaai", "Iaai", } m["ian"] = { "Iatmul", 5983460, "paa-spk", } m["iar"] = { "Purari", 3499934, "paa", } m["iba"] = { "tiếng Iban", 33424, "poz-mly", "Latn", "Tiếng Iban", "Iban", } m["ibb"] = { "tiếng Ibibio", 33792, "nic-ief", "Latn", "Tiếng Ibibio", "Ibibio", } m["ibd"] = { "tiếng Iwaidja", 1977429, "aus-wdj", "Latn", "Tiếng Iwaidja", "Iwaidja", } m["ibe"] = { "Akpes", 35457, "alv-von", "Latn", } m["ibg"] = { "tiếng Ibanag", 1775596, "phi", "Latn", "Tiếng Ibanag", "Ibanag", } m["ibh"] = { "tiếng Bih", nil, "cmc", "Latn", "Tiếng Bih", "Bih", } m["ibl"] = { "tiếng Ibaloi", 3147383, "phi", "Latn", "Tiếng Ibaloi", "Ibaloi", } m["ibm"] = { "Agoi", 34727, "nic-ucr", "Latn", } m["ibn"] = { "tiếng Ibino", 3813281, "nic-lcr", "Latn", "Tiếng Ibino", "Ibino", } m["ibr"] = { "tiếng Ibuoro", 3813306, "nic-ief", "Latn", "Tiếng Ibuoro", "Ibuoro", } m["ibu"] = { "Ibu", 11732235, "paa-nha", } m["iby"] = { "Ibani", 11280479, "ijo", } m["ica"] = { "tiếng Ede Ica", 12952405, "alv-ede", "Latn", "Tiếng Ede Ica", "Ede Ica", } m["ich"] = { "Etkywan", 3914462, "nic-jkn", "Latn", } m["icl"] = { "Icelandic Sign Language", 3436654, "sgn", "Latn", -- when documented } m["icr"] = { "Islander Creole English", 2044587, "crp", "Latn", ancestors = "en", } m["ida"] = { "Idakho-Isukha-Tiriki", 12952512, "bnt-lok", } m["idb"] = { "tiếng Indo-Bồ Đào Nha", 6025550, "crp", "Latn", "Tiếng Indo-Bồ Đào Nha", "Indo-Bồ Đào Nha", ancestors = "pt", } m["idc"] = { "Idon", 3913366, "nic-plc", } m["idd"] = { "tiếng Ede Idaca", 13123376, "alv-ede", "Latn", "Tiếng Ede Idaca", "Ede Idaca", } m["ide"] = { "Idere", 3813288, "nic-ief", } m["idi"] = { "Idi", 5988630, "paa", } m["idr"] = { "Indri", 35662, "nic-ser", } m["ids"] = { "Idesa", 3913979, "alv-swd", "Latn", ancestors = "oke", } m["idt"] = { "Idaté", 12952511, "poz-tim", "Latn", } m["idu"] = { "Idoma", 35478, "alv-ido", "Latn", } m["ifa"] = { "Amganad Ifugao", 18748222, "phi", } m["ifb"] = { "tiếng Ifugao Batad", 12953578, "phi", "Latn", "Tiếng Ifugao Batad", "Ifugao Batad", } m["ife"] = { "tiếng Ifè", 33606, "alv-ede", "Latn", "Tiếng Ifè", "Ifè", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron}, sort_key = { remove_diacritics = c.tilde, from = {"ɖ", "dz", "ɛ", "gb", "kp", "ny", "ŋ", "ɔ", "ts"}, to = {"d" .. p[1], "d" .. p[2], "e" .. p[1], "g" .. p[1], "k" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "t" .. p[1]} }, } m["iff"] = { "Ifo", 7902545, "poz-oce", "Latn", } m["ifk"] = { "Tuwali Ifugao", 7857158, "phi", } m["ifm"] = { "Teke-Fuumu", 36603, "bnt-tek", } m["ifu"] = { "Mayoyao Ifugao", 12953579, "phi", "Latn", } m["ify"] = { "Keley-I Kallahan", 3192221, "phi", } m["igb"] = { "Ebira", 35363, "alv-nup", "Latn", } m["ige"] = { "Igede", 35420, "alv-ido", "Latn", } m["igg"] = { "Igana", 5991454, "paa", "Latn", } m["igl"] = { "tiếng Igala", 35513, "alv-yrd", "Latn", "Tiếng Igala", "Igala", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.dotabove .. c.caron .. c.lineabove}, sort_key = { from = { "ñm", "ñw", -- 3 chars "ch", "ẹ", "gb", "gw", "kp", "kw", "ny", "ñ", "ọ" -- 2 chars }, to = { "n" .. p[3], "n" .. p[4], "c" .. p[1], "e" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "k" .. p[2], "n" .. p[1], "n" .. p[2], "o" .. p[1] } }, } m["igm"] = { "Kanggape", 6362743, "paa", "Latn", } m["ign"] = { "Ignaciano", 3148190, "awd", } m["igo"] = { "Isebe", 11732248, "ngf-mad", } m["igs"] = { "tiếng Glosa", 1138529, "art", "tiếng Glosa", "Glosa", type = "appendix-constructed", } m["igw"] = { "Igwe", 3913985, "alv-yek", "Latn", } m["ihb"] = { "Pidgin Iha", 12639686, "crp", ancestors = "ihp", } m["ihi"] = { "Ihievbe", 3441193, "alv-eeo", "Latn", ancestors = "ema", } m["ihp"] = { "Iha", 5994495, "ngf", } m["ijc"] = { "tiếng Izon", 35483, "ijo", "Latn", "Tiếng Izon", "Izon", } m["ije"] = { "Biseni", 35010, "ijo", } m["ijj"] = { "Ede Ije", 12952406, "alv-ede", "Latn", } m["ijn"] = { "Kalabari", 35697, "ijo", } m["ijs"] = { "Southeast Ijo", 3915854, "ijo", "Latn", } m["ike"] = { "tiếng Inuktitut Đông Canada", 4126517, "esx-inu", "Cans, Latn", "Tiếng Inuktitut Đông Canada", "Inuktitut Đông Canada", translit = {Cans = "cr-translit"}, override_translit = true, } m["iki"] = { "Iko", 3813290, "nic-lcr", "Latn", } m["ikk"] = { "Ika", 35406, "alv-igb", } m["ikl"] = { "Ikulu", 425973, "nic-plc", "Latn", } m["iko"] = { "Olulumo-Ikom", 3914402, "nic-uce", "Latn", } m["ikp"] = { "Ikpeshi", 3912777, "alv-yek", "Latn", } m["ikr"] = { "Ikaranggal", 5995402, "aus-pam", } m["iks"] = { "Inuit Sign Language", 13360244, "sgn", "Latn", -- when documented } m["ikt"] = { "tiếng Inuvialuktun", 27990, "esx-inu", "Cans, Latn", "Tiếng Inuvialuktun", "Inuvialuktun", translit = {Cans = "cr-translit"}, override_translit = true, } m["ikv"] = { "Iku-Gora-Ankwa", 3913940, "nic-plc", } m["ikw"] = { "tiếng Ikwere", 35399, "alv-igb", "Latn", "Tiếng Ikwere", "Ikwere", } m["ikx"] = { "Ik", 35472, "ssa-klk", "Latn", } m["ikz"] = { "Ikizu", 10977626, "bnt-lok", "Latn", } m["ila"] = { "Ile Ape", 12473380, "poz-cet", } m["ilb"] = { "Ila", 10962725, "bnt-bot", "Latn", } m["ilg"] = { "Ilgar", 5997810, "aus-wdj", "Latn", } m["ili"] = { "tiếng Ili Turki", 33627, "trk-kar", nil, "Tiếng Ili Turki", "Ili Turki", } m["ilk"] = { "Ilongot", 3148787, "phi", "Latn", } m["ill"] = { "Iranun", 12953581, "phi", "Latn, Arab", } m["ilo"] = { "tiếng Ilokano", 35936, "phi", "Latn, Tglg", "Tiếng Ilokano", "Ilokano", translit = { Tglg = "ilo-translit", }, override_translit = true, entry_name = { Latn = { remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer, } }, sort_key = { Latn = "tl-sortkey", }, standardChars = { Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy" .. c.punc, }, } m["ils"] = { "International Sign", 35754, "sgn", } m["ilu"] = { "Ili'uun", 12632888, "poz-tim", } m["ilv"] = { "Ilue", 3813301, "nic-lcr", "Latn", } m["ima"] = { "Mala Malasar", 6740693, "dra-tam", } m["imi"] = { "Anamgura", 3501881, "ngf-mad", } m["iml"] = { "Miluk", 3314550, "nai-coo", "Latn", } m["imn"] = { "Imonda", 6005721, "paa-brd", } m["imo"] = { "Imbongu", 12632895, "ngf-mad", } m["imr"] = { "Imroing", 6008394, "poz-tim", } m["ims"] = { "tiếng Marsi", 1265446, "itc-sbl", "Latn, Ital", "Tiếng Marsi", "Marsi", translit = {Ital = "Ital-translit"}, } m["imy"] = { "Milyan", 3832946, "ine-luw", "Lyci", } m["inb"] = { "Inga", 35491, "qwe", ancestors = "qwe-kch", } m["ing"] = { "tiếng Deg Xinag", 27782, "ath-nor", nil, "Tiếng Deg Xinag", "Deg Xinag", } m["inh"] = { "tiếng Ingush", 33509, "cau-vay", "Cyrl, Latn, Arab", "Tiếng Ingush", "Ingush", translit = { Cyrl = "cau-nec-translit", Arab = "ar-translit", }, override_translit = true, display_text = {Cyrl = s["cau-Cyrl-displaytext"]}, entry_name = { Cyrl = s["cau-Cyrl-entryname"], Latn = s["cau-Latn-entryname"], }, sort_key = { Cyrl = { from = {"аь", "гӏ", "ё", "кх", "къ", "кӏ", "пӏ", "тӏ", "хь", "хӏ", "цӏ", "чӏ", "яь"}, to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "п" .. p[1], "т" .. p[1], "х" .. p[1], "х" .. p[2], "ц" .. p[1], "ч" .. p[1], "я" .. p[1]} }, }, } m["inj"] = { "Jungle Inga", 16115012, "qwe", ancestors = "qwe-kch", } m["inl"] = { "Indonesian Sign Language", 3915477, "sgn", "Latn", -- when documented } m["inm"] = { "Minaean", 737784, "sem-osa", "Sarb", translit = "Sarb-translit", } m["inn"] = { "Isinai", 6081098, "phi", } m["ino"] = { "Inoke-Yate", 6036531, "paa-kag", } m["inp"] = { "Iñapari", 15338035, "awd", "Latn", } m["ins"] = { "Indian Sign Language", 12953486, "sgn", } m["int"] = { "tiếng Intha", 6057507, "tbq-brm", "Mymr", "Tiếng Intha", "Intha", ancestors = "obr", } m["inz"] = { "Ineseño", 35443, "nai-chu", "Latn", } m["ior"] = { "tiếng Inor", 35763, "sem-eth", "Ethi", "Tiếng Inor", "Inor", } m["iou"] = { "Tuma-Irumu", 7852460, "ngf-fin", "Latn", } m["iow"] = { "tiếng Chiwere", 56737, "sio-msv", "Latn", "Tiếng Chiwere", "Chiwere", } m["ipi"] = { "Ipili", 6065141, "paa-eng", } m["ipo"] = { "Ipiko", 10566515, "ngf", } m["iqu"] = { "Iquito", 2669184, "sai-zap", "Latn", } m["iqw"] = { "Ikwo", 11926474, "alv-igb", "Latn", ancestors = "izi", } m["ire"] = { "Iresim", 6069398, "poz-hce", "Latn", } m["irh"] = { "Irarutu", 3027928, "poz-cet", "Latn", } m["iri"] = { "Rigwe", 3912756, "nic-plc", "Latn", } m["irk"] = { "tiếng Iraqw", 33595, "cus-sou", "Latn", "Tiếng Iraqw", "Iraqw", } m["irn"] = { "Irantxe", 3409301, nil, "Latn", } m["irr"] = { "Ir", 3071880, "mkh-kat", } m["iru"] = { "tiếng Irula", 33363, "dra-imd", "Taml", "Tiếng Irula", "Irula", translit = "ta-translit" } m["irx"] = { "Kamberau", 6356317, "ngf", } m["iry"] = { "Iraya", 6068356, "phi", } m["isa"] = { "Isabi", 11732247, "paa-kag", } m["isc"] = { "Isconahua", 3052971, "sai-pan", "Latn", } m["isd"] = { "tiếng Isnag", 6085162, "phi", "Latn", "Tiếng Isnag", "Isnag", } m["ise"] = { "Italian Sign Language", 375619, "sgn", "Latn", -- when documented } m["isg"] = { "Irish Sign Language", 14183, "sgn", "Latn", -- when documented } m["ish"] = { "tiếng Esan", 35268, "alv-eeo", "Latn", "Tiếng Esan", "Esan", } m["isi"] = { "Nkem-Nkum", 36261, "nic-eko", "Latn", } m["isk"] = { "tiếng Ishkashim", 33419, "ira-sgi", "Cyrl, Latn", "Tiếng Ishkashim", "Ishkashim", } m["ism"] = { "Masimasi", 6783273, "poz-ocw", "Latn", } m["isn"] = { "Isanzu", 6078891, "bnt-tkm", "Latn", } m["iso"] = { "tiếng Isoko", 35414, "alv-swd", "Latn", "Tiếng Isoko", "Isoko", } m["isr"] = { "Israeli Sign Language", 2911863, "sgn", "Sgnw", } m["ist"] = { "tiếng Istria", 35845, "roa-itd", "Latn", "Tiếng Istria", "Istria", } m["isu"] = { "Isu", 6089423, "nic-rnw", "Latn", } m["itb"] = { "Binongan Itneg", 12953584, "phi", } m["itd"] = { "Southern Tidong", 7049643, "poz-san", } m["ite"] = { "Itene", 3038640, "sai-cpc", "Latn", } m["iti"] = { "Inlaod Itneg", 12953585, "phi", } m["itk"] = { "tiếng Ý-Do Thái", 1145414, "roa-itd", "Hebr, Latn", "Tiếng Ý-Do Thái", "Ý-Do Thái", } m["itl"] = { "tiếng Itelmen", 33624, "qfa-cka", "Cyrl, Latn", "Tiếng Itelmen", "Itelmen", entry_name = { Cyrl = { from = {"['’]", "[ӅԮ]", "[ӆԯ]", "Ҳ", "ҳ"}, to = {"ʼ", "Ԓ", "ԓ", "Ӽ", "ӽ"} }, }, sort_key = { Cyrl = { from = { "ӑ", "ё", "кʼ", "ӄʼ", "о̆", "пʼ", "тʼ", "ў", "чʼ", -- 2 chars "ӄ", "љ", "ԓ", "њ", "ӈ", "ӽ", "ә" -- 1 char }, to = { "а" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[3], "о" .. p[1], "п" .. p[1], "т" .. p[1], "у" .. p[1], "ч" .. p[1], "к" .. p[2], "л" .. p[1], "л" .. p[2], "н" .. p[1], "н" .. p[2], "х" .. p[1], "ь" .. p[1] } }, }, } m["itm"] = { "tiếng Itu Mbon Uzo", 10977737, "nic-ief", "Latn", ancestors = "ibr", "Tiếng Itu Mbon Uzo", "Itu Mbon Uzo", } m["ito"] = { "tiếng Itonama", 950585, "qfa-iso", "Latn", "Tiếng Itonama", "Itonama", } m["itr"] = { "Iteri", 2083185, "paa-asa", } m["its"] = { "tiếng Itsekiri", 36045, "alv-edk", "Latn", "Tiếng Itsekiri", "Itsekiri", entry_name = {Latn = {remove_diacritics = c.grave .. c.acute .. c.macron}}, sort_key = { remove_diacritics = c.tilde, from = {"ẹ", "gb", "gh", "kp", "ọ", "ts", "ṣ"}, to = {"e" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "o" .. p[1], "t" .. p[1], "t" .. p[1]} }, } m["itt"] = { "Maeng Itneg", 18748761, "phi", } m["itv"] = { "Itawit", 3915527, "phi", "Latn", } m["itw"] = { "Ito", 11128810, "nic-ief", ancestors = "ibr", } m["itx"] = { "Itik", 6094713, "paa-tkw", } m["ity"] = { "Moyadan Itneg", 12953583, "phi", } m["itz"] = { "Itzá", 35537, "myn", } m["ium"] = { "tiếng Ưu Miền", 2498808, "hmx-mie", nil, "Tiếng Ưu Miền", "Ưu Miền", } m["ivb"] = { "tiếng Ibatan", 18748212, "phi", "Latn", "Tiếng Ibatan", "Ibatan", ancestors = "phi-pro,poz-pro", } m["ivv"] = { "tiếng Ivatan", 3547080, "phi", "Latn", "Tiếng Ivatan", "Ivatan", } m["iwk"] = { "I-Wak", 12632789, "phi", } m["iwm"] = { "Iwam", 3915215, "paa-spk", } m["iwo"] = { "Iwur", 6101006, "ngf-okk", } m["iws"] = { "Sepik Iwam", 16893603, "paa-spk", } m["ixc"] = { "Ixcatec", 56706, "omq", } m["ixl"] = { "tiếng Ixil", 35528, "myn", "Latn", "Tiếng Ixil", "Ixil", } m["iya"] = { "Iyayu", 3913390, "alv-nwd", "Latn", } m["iyo"] = { "tiếng Mesaka", 36080, "nic-tiv", "Latn", "Tiếng Mesaka", "Mesaka", } m["iyx"] = { "Yaa", 36909, "bnt-nze", "Latn", } m["izh"] = { "tiếng Ingria", 33559, "urj-fin", "Latn", "Tiếng Ingria", "Ingria", sort_key = { from = { "š", "ž", }, to = { "s" .. p[1], "z" .. p[1], } }, } m["izi"] = { "Izi-Ezaa-Ikwo-Mgbo", nil, "alv-igb", } m["izr"] = { "Izere", 6101921, "nic-plc", "Latn", } m["izz"] = { "Izi", 3914387, "alv-igb", "Latn", ancestors = "izi", } return require("Module:languages").finalizeData(m, "language") nl8ya3nkye0tw6c0wvybmz551n3x3f7 ᦀᦱᧃᧈᦵᦉᧂ 0 276842 2344489 2090131 2026-04-12T11:54:00Z Hiyuune 50834 2344489 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== Từ {{affix|khb|ᦀᦱᧃᧈ|ᦵᦉᧂ}}. ==={{section|pron}}=== {{khb-pron|ᦀᦱᧃᧈ-ᦵᦉᧂ}} ==={{section|n}}=== {{khb-noun}} # Cách [[phát âm]]. ==={{section|ref}}=== * {{R:khb:Hanna}} {{C|khb|Âm vị học}} kq5g61df5a7zpipc146ij14xozs0hh9 luông 0 278750 2344467 2286155 2026-04-12T09:25:23Z WhoAlone 40420 2344467 wikitext text/x-wiki =={{langname|mng}}== ==={{ĐM|noun}}=== {{head|mng|Danh từ}} # {{label|mng|Rơlơm}} [[củi]]. ==={{ĐM|ref}}=== * Blood, Evangeline; Blood, Henry (1972) ''Vietnam word list (revised): Mnong Rolom''. SIL International. {{-aav-tam-}} {{-noun-}} {{head|aav-tam|Danh từ}} # [[củi]]. {{-ref-}} * Phan Trần Công (2017). Tương ứng từ vựng và mối quan hệ giữa các ngôn ngữ trong nhóm Bahnar Nam. Tạp chí Phát triển Khoa học và Công nghệ: Chuyên san Khoa học xã hội và Nhân văn, tập 1, số 4, 2017. {{-tyz-}} {{-pron-}} {{tyz-IPA}} {{-adj-}} {{pn}} # [[to lớn]]. {{-ref-}} {{R:Lương Bèn}} {{catname|Tính từ|tiếng Tày}} =={{langname|tdr}}== ==={{ĐM|noun}}=== {{head|tdr|Danh từ}} # {{label|tdr|Didrá}} [[cây]]. ==={{ĐM|ref}}=== * Gregerson, Kenneth J. và Smith, Kenneth D. (1973). ''The development of Todrah register''. SIL International. =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]]. ==={{đm|ref}}=== {{R:VOV}} kuz7ibhe1bf85u5pgn1ynla15cqd4vq Mô đun:languages/data/exceptional 828 279282 2344293 2343455 2026-04-11T15:00:36Z TheHighFighter2 42988 2344293 Scribunto text/plain local m_langdata = require("Module:languages/data") -- Loaded on demand, as it may not be needed (depending on the data). local function u(...) u = require("Module:string utilities").char return u(...) end local c = m_langdata.chars local p = m_langdata.puaChars local s = m_langdata.shared local m = {} m["aav-bhu"] = { "tiếng Bhumij", 57920059, "mun", nil, "Tiếng Bhumij", "Bhumij", } m["aav-khs-pro"] = { "tiếng Khasi nguyên thủy", nil, "aav-khs", "Latn", "Tiếng Khasi nguyên thủy", "Khasi nguyên thủy", type = "reconstructed", } m["aav-nic-pro"] = { "tiếng Nicobar nguyên thủy", nil, "aav-nic", "Latn", "Tiếng Nicobar nguyên thủy", "Nicobar nguyên thủy", type = "reconstructed", } m["aav-pkl-pro"] = { "tiếng Pnar-Khasi-Lyngngam nguyên thủy", nil, "aav-pkl", "Latn", "Tiếng Pnar-Khasi-Lyngngam nguyên thủy", "Pnar-Khasi-Lyngngam nguyên thủy", type = "reconstructed", } m["aav-pro"] = { --The mkh-pro will merge into this. "tiếng Nam Á nguyên thủy", nil, "aav", "Latn", "Tiếng Nam Á nguyên thủy", "Nam Á nguyên thủy", type = "reconstructed", } m["aav-tam"] = { "tiếng Tà Mun", 130370566, "mkh-ban", nil, "Tiếng Tà Mun", "Tà Mun", } m["afa-pro"] = { "tiếng Phi-Á nguyên thủy", 269125, "afa", "Latn", "Tiếng Phi-Á nguyên thủy", "Phi-Á nguyên thủy", type = "reconstructed", } m["alg-aga"] = { "tiếng Agawam", nil, "alg-eas", "Latn", "Tiếng Agawam", "Agawam", } m["alg-pro"] = { "tiếng Algonquin nguyên thủy", 7251834, "alg", "Latn", "Tiếng Algonquin nguyên thủy", "Algonquin nguyên thủy", type = "reconstructed", sort_key = {remove_diacritics = "·"}, } m["alv-ama"] = { "Amasi", 4740400, "nic-grs", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron}, } m["alv-bgu"] = { "Baïnounk Gubëeher", 17002646, "alv-bny", "Latn", } m["alv-bua-pro"] = { "Proto-Bua", nil, "alv-bua", "Latn", type = "reconstructed", } m["alv-cng-pro"] = { "Proto-Cangin", nil, "alv-cng", "Latn", type = "reconstructed", } m["alv-edo-pro"] = { "tiếng Edoid nguyên thủy", nil, "alv-edo", "Latn", "Tiếng Edoid nguyên thủy", "Edoid nguyên thủy", type = "reconstructed", } m["alv-fli-pro"] = { "Proto-Fali", nil, "alv-fli", "Latn", type = "reconstructed", } m["alv-gbe-pro"] = { "tiếng Gbe nguyên thủy", nil, "alv-gbe", "Latn", "Tiếng Gbe nguyên thủy", "Gbe nguyên thủy", type = "reconstructed", } m["alv-gng-pro"] = { "Proto-Guang", nil, "alv-gng", "Latn", type = "reconstructed", } m["alv-gtm-pro"] = { "Proto-Central Togo", nil, "alv-gtm", "Latn", type = "reconstructed", } m["alv-gwa"] = { "Gwara", 16945580, "nic-pla", "Latn", } m["alv-hei-pro"] = { "Proto-Heiban", nil, "alv-hei", "Latn", type = "reconstructed", } m["alv-ido-pro"] = { "Proto-Idomoid", nil, "alv-ido", "Latn", type = "reconstructed", } m["alv-igb-pro"] = { "Proto-Igboid", nil, "alv-igb", "Latn", type = "reconstructed", } m["alv-kwa-pro"] = { "Proto-Kwa", nil, "alv-kwa", "Latn", type = "reconstructed", } m["alv-mum-pro"] = { "Proto-Mumuye", nil, "alv-mum", "Latn", type = "reconstructed", } m["alv-nup-pro"] = { "Proto-Nupoid", nil, "alv-nup", "Latn", type = "reconstructed", } m["alv-pro"] = { "tiếng Đại Tây Dương–Congo nguyên thủy", nil, "alv", "Latn", "Tiếng Đại Tây Dương–Congo nguyên thủy", "Đại Tây Dương–Congo nguyên thủy", type = "reconstructed", } m["alv-edk-pro"] = { "tiếng Edekiri nguyên thủy", nil, "alv-edk", "Latn", "Tiếng Edekiri nguyên thủy", "Edekiri nguyên thủy", type = "reconstructed", } m["alv-yor-pro"] = { "tiếng Yoruba nguyên thủy", nil, "alv-yor", "Latn", "Tiếng Yoruba nguyên thủy", "Yoruba nguyên thủy", type = "reconstructed", } m["alv-yrd-pro"] = { "tiếng Yorubo nguyên thủy", 116773824, "alv-yrd", "Latn", "Tiếng Yorubo nguyên thủy", "Yorubo nguyên thủy", type = "reconstructed", } m["alv-von-pro"] = { "tiếng Volta-Niger nguyên thủy", nil, "alv-von", "Latn", "Tiếng Volta-Niger nguyên thủy", "Volta-Niger nguyên thủy", type = "reconstructed", } m["apa-pro"] = { "Proto-Apachean", nil, "apa", "Latn", type = "reconstructed", } m["aql-pro"] = { "tiếng Algic nguyên thủy", 18389588, "aql", "Latn", "Tiếng Algic nguyên thủy", "Algic nguyên thủy", type = "reconstructed", sort_key = {remove_diacritics = "·"}, } m["art-blk"] = { "Bolak", 2909283, "art", "Latn", type = "appendix-constructed", } m["art-bsp"] = { "Black Speech", 686210, "art", "Latn, Teng", type = "appendix-constructed", } m["art-com"] = { "Communicationssprache", 35227, "art", "Latn", type = "appendix-constructed", } m["art-dtk"] = { "Dothraki", 2914733, "art", "Latn", type = "appendix-constructed", } m["art-elo"] = { "Eloi", nil, "art", "Latn", type = "appendix-constructed", } m["art-gld"] = { "Goa'uld", 19823, "art", "Latn, Egyp, Mero", type = "appendix-constructed", } m["art-lap"] = { "Lapine", 6488195, "art", "Latn", type = "appendix-constructed", } m["art-man"] = { "Mandalorian", 54289, "art", "Latn", type = "appendix-constructed", } m["art-mun"] = { "Mundolinco", 851355, "art", "Latn", type = "appendix-constructed", } m["art-nav"] = { "Na'vi", 316939, "art", "Latn", type = "appendix-constructed", } m["art-nox"] = { "Noxilo", nil, "art", "Latn", type = "appendix-constructed", } m["art-una"] = { "Unas", nil, "art", "Latn", type = "appendix-constructed", } m["ath-nic"] = { "Nicola", 20609, "ath-nor", "Latn", } m["ath-pro"] = { "tiếng Athabasca nguyên thủy", 104841722, "ath", "Latn", type = "reconstructed", "Tiếng Athabasca nguyên thủy", "Athabasca nguyên thủy", } m["auf-pro"] = { "Proto-Arawa", nil, "auf", "Latn", type = "reconstructed", } m["aus-alu"] = { "Alungul", 16827670, "aus-pmn", "Latn", } m["aus-and"] = { "Andjingith", 4754509, "aus-pmn", "Latn", } m["aus-ang"] = { "tiếng Angkula", 16828520, "aus-pmn", "Latn", "Tiếng Angkula", "Angkula", } m["aus-arn-pro"] = { "Proto-Arnhem", nil, "aus-arn", "Latn", type = "reconstructed", } m["aus-bra"] = { "Barranbinya", 4863220, "aus-pmn", "Latn", } m["aus-brm"] = { "Barunggam", 4865914, "aus-pmn", "Latn", } m["aus-cww-pro"] = { "Proto-Central New South Wales", nil, "aus-cww", "Latn", type = "reconstructed", } m["aus-dal-pro"] = { "Proto-Daly", nil, "aus-dal", "Latn", type = "reconstructed", } m["aus-guw"] = { "Guwar", 6652138, "aus-pam", "Latn", } m["aus-lsw"] = { "Little Swanport", 6652138, nil, "Latn", } m["aus-mbi"] = { "Mbiywom", 6799701, "aus-pmn", "Latn", } m["aus-ngk"] = { "Ngkoth", 7022405, "aus-pmn", "Latn", } m["aus-nyu-pro"] = { "Proto-Nyulnyulan", nil, "aus-nyu", "Latn", type = "reconstructed", } m["aus-pam-pro"] = { "tiếng Pama-Nyungar nguyên thủy", 33942, "aus-pam", "Latn", "Tiếng Pama-Nyungar nguyên thủy", "Pama-Nyungar nguyên thủy", type = "reconstructed", } m["aus-tul"] = { "Tulua", 16938541, "aus-pam", "Latn", } m["aus-uwi"] = { "Uwinymil", 7903995, "aus-arn", "Latn", } m["aus-wdj-pro"] = { "Proto-Iwaidjan", nil, "aus-wdj", "Latn", type = "reconstructed", } m["aus-won"] = { "Wong-gie", nil, "aus-pam", "Latn", } m["aus-wul"] = { "Wulguru", 8039196, "aus-dyb", "Latn", } m["aus-ynk"] = { -- contrast nny "Yangkaal", 3913770, "aus-tnk", "Latn", } m["awd-amc-pro"] = { "Proto-Amuesha-Chamicuro", nil, "awd", "Latn", type = "reconstructed", ancestors = "awd-pro", } m["awd-kmp-pro"] = { "Proto-Kampa", nil, "awd", "Latn", type = "reconstructed", ancestors = "awd-pro", } m["awd-prw-pro"] = { "Proto-Paresi-Waura", nil, "awd", "Latn", type = "reconstructed", ancestors = "awd-pro", } m["awd-ama"] = { "Amarizana", 16827787, "awd", "Latn", } m["awd-ana"] = { "tiếng Anauyá", 16828252, "awd", "Latn", "Tiếng Anauyá", "Anauyá", } m["awd-apo"] = { "Apolista", 16916645, "awd", "Latn", } m["awd-cav"] = { "Cavere", nil, "awd", "Latn", } m["awd-gnu"] = { "Guinau", 3504087, "awd", "Latn", } m["awd-kar"] = { "Cariay", 16920253, "awd", "Latn", } m["awd-kaw"] = { "Kawishana", 6379993, "awd-nwk", "Latn", } m["awd-kus"] = { "Kustenau", 5196293, "awd", "Latn", } m["awd-man"] = { "Manao", 6746920, "awd", "Latn", } m["awd-mar"] = { "Marawan", 6755108, "awd", "Latn", } m["awd-mpr"] = { "Maypure", nil, "awd", "Latn", } m["awd-mrt"] = { "Mariaté", 16910017, "awd-nwk", "Latn", } m["awd-nwk-pro"] = { "Proto-Nawiki", nil, "awd-nwk", "Latn", type = "reconstructed", } m["awd-pai"] = { "Paikoneka", nil, "awd", "Latn", } m["awd-pas"] = { "Passé", nil, "awd-nwk", "Latn", } m["awd-pro"] = { "tiếng Arawak nguyên thủy", nil, "awd", "Latn", "Tiếng Arawak nguyên thủy", "Arawak nguyên thủy", type = "reconstructed", } m["awd-she"] = { "tiếng Shebayo", 7492248, "awd", "Latn", "Tiếng Shebayo", "Shebayo" } m["awd-taa-pro"] = { "Proto-Ta-Arawak", nil, "awd-taa", "Latn", type = "reconstructed", } m["awd-wai"] = { "Wainumá", 16910017, "awd-nwk", "Latn", } m["awd-yum"] = { "Yumana", 8061062, "awd-nwk", "Latn", } m["azc-caz"] = { "Cazcan", 5055514, "azc", "Latn", } m["azc-cup-pro"] = { "Proto-Cupan", nil, "azc-cup", "Latn", type = "reconstructed", } m["azc-ktn"] = { "Kitanemuk", 3197558, "azc-tak", "Latn", } m["azc-nah-pro"] = { "tiếng Nahua nguyên thủy", 7251860, "azc-nah", "Latn", "Tiếng Nahua nguyên thủy", "Nahua nguyên thủy", type = "reconstructed", } m["azc-num-pro"] = { "Proto-Numic", nil, "azc-num", "Latn", type = "reconstructed", } m["azc-pro"] = { "tiếng Ute-Aztec nguyên thủy", 96400333, "azc", "Latn", "Tiếng Ute-Aztec nguyên thủy", "Ute-Aztec nguyên thủy", type = "reconstructed", } m["azc-tak-pro"] = { "Proto-Takic", nil, "azc-tak", "Latn", type = "reconstructed", } m["azc-tat"] = { "Tataviam", 743736, "azc", "Latn", } m["ber-pro"] = { "tiếng Berber nguyên thủy", 2855698, "ber", "Latn", "Tiếng Berber nguyên thủy", "Berber nguyên thủy", type = "reconstructed", } m["ber-fog"] = { "tiếng Fogaha", 107610173, "ber", "Latn", "Tiếng Fogaha", "Fogaha", } m["ber-zuw"] = { "Zuwara", 4117169, "ber", "Latn", } m["bnt-bal"] = { "Balong", 93935237, "bnt-bbo", "Latn", } m["bnt-bon"] = { "Boma Nkuu", nil, "bnt", "Latn", } m["bnt-boy"] = { "Boma Yumu", nil, "bnt", "Latn", } m["bnt-bwa"] = { "Bwala", nil, "bnt-tek", "Latn", } m["bnt-cmw"] = { "Chimwiini", 4958328, "bnt-swh", "Latn", } m["bnt-ind"] = { "Indanga", 51412803, "bnt", "Latn", } m["bnt-lal"] = { "Lala (South Africa)", 6480154, "bnt-ngu", "Latn", } m["bnt-lwl"] = { "Lwel", 93936908, "bnt-bdz", "Latn", } m["bnt-mpi"] = { "Mpiin", 93937013, "bnt-bdz", "Latn", } m["bnt-mpu"] = { "Mpuono", --not to be confused with Mbuun zmp 36056, "bnt", "Latn", } m["bnt-ngu-pro"] = { "tiếng Nguni nguyên thủy", 961559, "bnt-ngu", "Latn", "Tiếng Nguni nguyên thủy", "Nguni nguyên thủy", type = "reconstructed", sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.caron}, } m["bnt-phu"] = { "Phuthi", 33796, "bnt-ngu", "Latn", entry_name = {remove_diacritics = c.grave .. c.acute}, } m["bnt-pro"] = { "tiếng Bantu nguyên thủy", 3408025, "bnt", "Latn", "Tiếng Bantu nguyên thủy", "Bantu nguyên thủy", type = "reconstructed", sort_key = "bnt-pro-sortkey", } m["bnt-sbo"] = { "South Boma", nil, "bnt", "Latn", } m["bnt-sts-pro"] = { "Proto-Sotho-Tswana", nil, "bnt-sts", "Latn", type = "reconstructed", } m["btk-pro"] = { "Proto-Batak", nil, "btk", "Latn", type = "reconstructed", } m["cau-abz-pro"] = { "tiếng Abkhaz-Abaza nguyên thủy", 7251831, "cau-abz", "Latn", "Tiếng Abkhaz-Abaza nguyên thủy", "Abkhaz-Abaza nguyên thủy", type = "reconstructed", } m["cau-ava-pro"] = { "tiếng Avar-Andic nguyên thủy", 116773187, "cau-ava", "Latn", "Tiếng Avar-Andic nguyên thủy", "Avar-Andic nguyên thủy", type = "reconstructed", } m["cau-cir-pro"] = { "tiếng Circassia nguyên thủy", 7251838, "cau-cir", "Latn", "Tiếng Circassia nguyên thủy", "Circassia nguyên thủy", type = "reconstructed", } m["cau-drg-pro"] = { "tiếng Dargwa nguyên thủy", nil, "cau-drg", "Latn", "Tiếng Dargwa nguyên thủy", "Dargwa nguyên thủy", type = "reconstructed", } m["cau-lzg-pro"] = { "tiếng Lezghi nguyên thủy", nil, "cau-lzg", "Latn", "Tiếng Lezghi nguyên thủy", "Lezghi nguyên thủy", type = "reconstructed", } m["cau-nec-pro"] = { "tiếng Đông Bắc Kavkaz nguyên thủy", nil, "cau-nec", "Latn", "Tiếng Đông Bắc Kavkaz nguyên thủy", "Đông Bắc Kavkaz nguyên thủy", type = "reconstructed", } m["cau-nkh-pro"] = { "tiếng Nakh nguyên thủy", nil, "cau-nkh", "Latn", "Tiếng Nakh nguyên thủy", "Nakh nguyên thủy", type = "reconstructed", } m["cau-nwc-pro"] = { "tiếng Tây Bắc Kavkaz nguyên thủy", 7251861, "cau-nwc", "Latn", "Tiếng Tây Bắc Kavkaz nguyên thủy", "Tây Bắc Kavkaz nguyên thủy", type = "reconstructed", } m["cau-tsz-pro"] = { "Proto-Tsezian", nil, "cau-tsz", "Latn", type = "reconstructed", } m["cba-ata"] = { "Atanques", 4812783, "cba", "Latn", } m["cba-cat"] = { "Catío Chibcha", 7083619, "cba", "Latn", } m["cba-dor"] = { "Dorasque", 5297532, "cba", "Latn", } m["cba-dui"] = { "Duit", 3041061, "cba", "Latn", } m["cba-hue"] = { "Huetar", 35514, "cba", "Latn", } m["cba-nut"] = { "Nutabe", 7070405, "cba", "Latn", } m["cba-pro"] = { "Proto-Chibchan", nil, "cba", "Latn", type = "reconstructed", } m["ccn-pro"] = { "Proto-North Caucasian", nil, "ccn", "Latn", type = "reconstructed", } m["ccs-pro"] = { "tiếng Kartvelia nguyên thủy", 2608203, "ccs", "Latn", type = "reconstructed", "Tiếng Kartvelia nguyên thủy", "Kartvelia nguyên thủy", entry_name = { from = {"q̣", "p̣", "ʓ", "ċ"}, to = {"q̇", "ṗ", "ʒ", "c̣"} }, } m["ccs-gzn-pro"] = { "tiếng Gruzia-Zan nguyên thủy", 23808119, "ccs-gzn", "Latn", "Tiếng Gruzia-Zan nguyên thủy", "Gruzia-Zan nguyên thủy", type = "reconstructed", entry_name = { from = {"q̣", "p̣", "ʓ", "ċ"}, to = {"q̇", "ṗ", "ʒ", "c̣"} }, } m["cdc-cbm-pro"] = { "Proto-Central Chadic", nil, "cdc-cbm", "Latn", type = "reconstructed", } m["cdc-mas-pro"] = { "Proto-Masa", nil, "cdc-mas", "Latn", type = "reconstructed", } m["cdc-pro"] = { "tiếng Tchad nguyên thủy", nil, "cdc", "Latn", "Tiếng Tchad nguyên thủy", "Tchad nguyên thủy", type = "reconstructed", } m["cdd-pro"] = { "Proto-Caddoan", nil, "cdd", "Latn", type = "reconstructed", } m["cel-bry-pro"] = { "tiếng Britton nguyên thủy", 156877, "cel-bry", "Latn, Grek", "Tiếng Britton nguyên thủy", "Britton nguyên thủy", sort_key = "cel-bry-pro-sortkey", } m["cel-gal"] = { "Gallaecian", 3094789, "cel", } m["cel-gau"] = { "tiếng Gaul", 29977, "cel", "Latn, Grek, Ital", "Tiếng Gaul", "Gaul", entry_name = {remove_diacritics = c.macron .. c.breve .. c.diaer}, } m["cel-pro"] = { "tiếng Celt nguyên thủy", 653649, "cel", "Latn", "Tiếng Celt nguyên thủy", "Celt nguyên thủy", sort_key = "cel-pro-sortkey", } m["chi-pro"] = { "Proto-Chimakuan", nil, "chi", "Latn", type = "reconstructed", } m["chm-pro"] = { "tiếng Mari nguyên thủy", nil, "chm", "Latn", "Tiếng Mari nguyên thủy", "Mari nguyên thủy", type = "reconstructed", } m["cmc-pro"] = { "tiếng Chăm nguyên thủy", nil, "cmc", "Latn", "Tiếng Chăm nguyên thủy", "Chăm nguyên thủy", type = "reconstructed", } m["cpe-mar"] = { "Maroon Spirit Language", 1093206, "crp", "Latn", ancestors = "en", } m["cpe-spp"] = { "Samoan Plantation Pidgin", 7409948, "crp", "Latn", ancestors = "en", } m["crp-gep"] = { "West Greenlandic Pidgin", 17036301, "crp", "Latn", ancestors = "kl", } m["crp-mpp"] = { "Macau Pidgin Portuguese", nil, "crp", "Hant, Latn", ancestors = "pt", sort_key = {Hant = "Hani-sortkey"}, } m["crp-rsn"] = { "Russenorsk", 505125, "crp", "Cyrl, Latn", ancestors = "nn, ru", } m["crp-slb"] = { "tiếng Anh Solombala", 7558525, "crp", "Cyrl, Latn", "Tiếng Anh Solombala", "Anh Solombala", ancestors = "en, ru", } m["crp-tpr"] = { "tiếng Nga bồi Taimyr", 16930506, "crp", "Cyrl", "Tiếng Nga bồi Taimyr", "Nga bồi Taimyr", ancestors = "ru", } m["csu-bba-pro"] = { "Proto-Bongo-Bagirmi", nil, "csu-bba", "Latn", type = "reconstructed", } m["csu-maa-pro"] = { "Proto-Mangbetu", nil, "csu-maa", "Latn", type = "reconstructed", } m["csu-pro"] = { "Proto-Central Sudanic", nil, "csu", "Latn", type = "reconstructed", } m["csu-sar-pro"] = { "Proto-Sara", nil, "csu-sar", "Latn", type = "reconstructed", } m["ctp-san"] = { "San Juan Quiahije Chatino", nil, "omq-cha", "Latn", } m["cus-ash"] = { "tiếng Ashraaf", 4805855, "cus-eas", "Latn", "Tiếng Ashraaf", "Ashraaf", } m["cus-hec-pro"] = { "Proto-Highland East Cushitic", nil, "cus-hec", "Latn", type = "reconstructed", } m["cus-som-pro"] = { "tiếng Somali nguyên thủy", nil, "cus-som", "Latn", "Tiếng Somali nguyên thủy", "Somali nguyên thủy", type = "reconstructed", } m["cus-sou-pro"] = { "Proto-South Cushitic", 126081567, "cus-sou", "Latn", type = "reconstructed", } m["cus-pro"] = { "tiếng Cushit nguyên thủy", nil, "cus", "Latn", "Tiếng Cushit nguyên thủy", "Cushit nguyên thủy", type = "reconstructed", } m["dmn-dam"] = { "Dama (Sierra Leone)", 19601574, "dmn", "Latn", } m["dra-mkn"] = { "Middle Kannada", nil, "dra", "Knda", ancestors = "dra-okn", translit = "kn-translit", } m["dra-okn"] = { "tiếng Kannada cổ", 15723156, "dra", "Knda", "Tiếng Kannada cổ", "Kannada cổ", ancestors = "dra-pro", translit = "kn-translit", } m["dra-ote"] = { "tiếng Telugu cổ", 126720868, "dra-tel", "Telu", "Tiếng Telugu cổ", "Telugu cổ", translit = "te-translit", } m["dra-pro"] = { "tiếng Dravida nguyên thủy", 1702853, "dra", "Latn", "Tiếng Dravida nguyên thủy", "Dravida nguyên thủy", type = "reconstructed", } m["dra-sdo-pro"] = { "tiếng Nam Dravida nguyên thủy I", 104847952, -- Wikipedia's "Proto-South Dravidian" is Proto-South Dravidian I in this scheme. "dra-sdo", "Latn", "Tiếng Nam Dravida nguyên thủy I", "Nam Dravida nguyên thủy I", type = "reconstructed", } m["dra-sdt-pro"] = { "tiếng Nam Dravida nguyên thủy II", 128885257, "dra-sdt", "Latn", "Tiếng Nam Dravida nguyên thủy II", "Nam Dravida nguyên thủy II", type = "reconstructed", } m["dra-sou-pro"] = { "tiếng Nam Dravida nguyên thủy", 128886121, "dra-sou", "Latn", "Tiếng Nam Dravida nguyên thủy", "Nam Dravida nguyên thủy", type = "reconstructed", } m["egx-dem"] = { "tiếng Ai Cập bình dân", 36765, "egx", "Latn, Egyd, Polyt", "Tiếng Ai Cập bình dân", "Ai Cập bình dân", display_text = { Polyt = s["Polyt-displaytext"], }, entry_name = { Polyt = s["Polyt-entryname"], }, sort_key = { Latn = { remove_diacritics = "'%-%s", from = {"ꜣ", "j", "e", "ꜥ", "y", "w", "b", "p", "f", "m", "n", "r", "l", "ḥ", "ḫ", "h̭", "ẖ", "h", "š", "s", "q", "k", "g", "ṱ", "ṯ", "t", "ḏ", "%.", "⸗"}, to = {p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[15], p[16], p[16], p[17], p[14], p[19], p[18], p[20], p[21], p[22], p[23], p[24], p[23], p[25], p[26], p[26]} }, Polyt = s["Polyt-sortkey"], }, } m["elu-prk"] = { "Helu", 15080869, "inc-mid", "Brah", ancestors = "inc-pra", translit = "Brah-translit", } m["dmn-pro"] = { "tiếng Mande nguyên thủy", nil, "dmn", "Latn", "Tiếng Mande nguyên thủy", "Mande nguyên thủy", type = "reconstructed", } m["dmn-mdw-pro"] = { "Proto-Western Mande", nil, "dmn-mdw", "Latn", type = "reconstructed", } m["dru-pro"] = { "tiếng Rukai nguyên thủy", nil, "map", "Latn", "Tiếng Rukai nguyên thủy", "Rukai nguyên thủy", type = "reconstructed", } m["ero-tau"] = { "tiếng Stau", nil, "ero", "Latn", "Tiếng Stau", "Stau", } m["esx-esk-pro"] = { "tiếng Eskimo nguyên thủy", 7251842, "esx-esk", "Latn", "Tiếng Eskimo nguyên thủy", "Eskimo nguyên thủy", type = "reconstructed", } m["esx-ink"] = { "Inuktun", 1671647, "esx-inu", "Latn", } m["esx-inq"] = { "Inuinnaqtun", 28070, "esx-inu", "Latn", } m["esx-inu-pro"] = { "tiếng Inuit nguyên thủy", 60785588, "esx-inu", "Latn", "Tiếng Inuit nguyên thủy", "Inuit nguyên thủy", type = "reconstructed", } m["esx-pro"] = { "tiếng Eskimo-Aleut nguyên thủy", 7251843, "esx", "Latn", "Tiếng Eskimo-Aleut nguyên thủy", "Eskimo-Aleut nguyên thủy", type = "reconstructed", } m["esx-tut"] = { "Tunumiisut", 15665389, "esx-inu", "Latn", } m["euq-pro"] = { "tiếng Basque nguyên thủy", 938011, "euq", "Latn", "Tiếng Basque nguyên thủy", "Basque nguyên thủy", type = "reconstructed", } m["gem-bur"] = { "Burgundian", nil, "gme", "Latn", } m["gem-pro"] = { "tiếng German nguyên thủy", 669623, "gem", "Latn", "Tiếng German nguyên thủy", "German nguyên thủy", type = "reconstructed", sort_key = "gem-pro-sortkey", } m["gme-cgo"] = { "Crimean Gothic", 36211, "gme", "Latn", } m["gmq-bot"] = { "Westrobothnian", 7989641, "gmq", "Latn", ancestors = "non", } m["gmq-gut"] = { "tiếng Gotland", 1256646, "gmq", "Latn", "Tiếng Gotland", "Gotland", ancestors = "non", } m["gmq-jmk"] = { "Jamtish", nil, "gmq", "Latn", ancestors = "non", } m["gmq-mno"] = { "Middle Norwegian", 3417070, "gmq", "Latn", ancestors = "non", } m["gmq-oda"] = { "tiếng Đan Mạch cổ", nil, "gmq-eas", "Latn, Runr", "Tiếng Đan Mạch cổ", "Đan Mạch cổ", ancestors = "non", entry_name = {remove_diacritics = c.macron}, } m["gmq-osw"] = { "tiếng Thụy Điển cổ", 2417210, "gmq", "Latn", "Tiếng Thụy Điển cổ", "Thụy Điển cổ", ancestors = "non", entry_name = {remove_diacritics = c.macron}, } m["gmq-pro"] = { "Proto-Norse", 1671294, "gmq", "Runr", translit = "Runr-translit", } m["gmq-scy"] = { "Scanian", 768017, "gmq", "Latn", ancestors = "non", } m["gmw-bgh"] = { "Bergish", 329030, "gmw", "Latn", ancestors = "odt", } m["gmw-cfr"] = { "tiếng Franken Trung", nil, "gmw", "Latn", "Tiếng Franken Trung", "Franken Trung", ancestors = "gmh", wikimedia_codes = "ksh", } m["gmw-ecg"] = { "tiếng Đức Đông Trung", 499344, -- subsumes Q699284, Q152965 "gmw", "Latn", "Tiếng Đức Đông Trung", "Đức Đông Trung", ancestors = "gmh", } m["gmw-gts"] = { "Gottscheerish", 533109, "gmw", "Latn", ancestors = "bar", } m["gmw-jdt"] = { "tiếng Hà Lan Jersey", 1687911, "gmw", "Latn", "Tiếng Hà Lan Jersey", "Hà Lan Jersey", ancestors = "nl", } m["gmw-pro"] = { "tiếng German Tây nguyên thủy", 78079021, "gmw", "Latn", "Tiếng German Tây nguyên thủy", "German Tây nguyên thủy", type = "reconstructed", sort_key = "gmw-pro-sortkey", wikipedia_article = "Chi ngôn ngữ German phía Tây" } m["gmw-rfr"] = { "Rhine Franconian", 707007, "gmw", "Latn", ancestors = "gmh", } m["gmw-stm"] = { "Sathmar Swabian", 2223059, "gmw", "Latn", ancestors = "swg", } m["gmw-tsx"] = { "tiếng Saxon Transylvania", 260942, "gmw", "Latn", "Tiếng Saxon Transylvania", "Saxon Transylvania", ancestors = "gmw-cfr", } m["gmw-vog"] = { "Volga German", 312574, "gmw", "Latn", ancestors = "gmw-rfr", } m["gmw-zps"] = { "Zipser German", 205548, "gmw", "Latn", ancestors = "gmh", } m["gn-cls"] = { "Classical Guaraní", 17478065, "tup-gua", "Latn", ancestors = "gn", } m["grk-cal"] = { "Calabrian Greek", 1146398, "grk", "Latn", ancestors = "grc", } m["grk-ita"] = { "tiếng Hy Lạp Italiot", nil, "grk", "Latn, Grek", "Tiếng Hy Lạp Italiot", "Hy Lạp Italiot", ancestors = "grc", entry_name = {remove_diacritics = c.caron .. c.diaerbelow .. c.brevebelow}, sort_key = s["Grek-sortkey"], } m["grk-mar"] = { "tiếng Hy Lạp Mariupol", 4400023, "grk", "Cyrl, Latn, Grek", ancestors = "grc", translit = "grk-mar-translit", override_translit = true, entry_name = "grk-mar-entryname", sort_key = s["Grek-sortkey"], "Tiếng Hy Lạp Mariupol", "Hy Lạp Mariupol", } m["grk-pro"] = { "tiếng Hellen nguyên thủy", 1231805, "grk", "Latn", "Tiếng Hellen nguyên thủy", "Hellen nguyên thủy", type = "reconstructed", sort_key = { from = {"[áā]", "[éēḗ]", "[íī]", "[óōṓ]", "[úū]", "ď", "ľ", "ň", "ř", "ʰ", "ʷ", c.acute, c.macron}, to = {"a", "e", "i", "o", "u", "d", "l", "n", "r", "¯h", "¯w"} }, } m["hmn-pro"] = { "Proto-Hmong", nil, "hmn", "Latn", type = "reconstructed", } m["hmx-mie-pro"] = { "tiếng Miền nguyên thủy", nil, "hmx-mie", "Latn", "Tiếng Miền nguyên thủy", "Miền nguyên thủy", type = "reconstructed", } m["hmx-pro"] = { "tiếng H'Mông-Miền nguyên thủy", 7251846, "hmx", "Latn", "Tiếng H'Mông-Miền nguyên thủy", "H'Mông-Miền nguyên thủy", type = "reconstructed", } m["hyx-pro"] = { "Proto-Armenian", 3848498, "hyx", "Latn", type = "reconstructed", } m["iir-nur-pro"] = { "tiếng Nuristan nguyên thủy", nil, "iir-nur", "Latn", "Tiếng Nuristan nguyên thủy", "Nuristan nguyên thủy", type = "reconstructed", } m["iir-pro"] = { "tiếng Ấn-Iran nguyên thủy", 966439, "iir", "Latn", "Tiếng Ấn-Iran nguyên thủy", "Ấn-Iran nguyên thủy", type = "reconstructed", } m["ijo-pro"] = { "Proto-Ijoid", nil, "ijo", "Latn", type = "reconstructed", } m["inc-apa"] = { "tiếng Apabhramsa", 616419, "inc-mid", "Deva, Shrd, Sidd", "Tiếng Apabhramsa", "Apabhramsa", ancestors = "pra", translit = { Deva = "sa-translit", Shrd = "Shrd-translit", Sidd = "Sidd-translit", }, } m["inc-ash"] = { "tiếng Prakrit Ashoka", nil, "inc-mid", "Brah, Khar", "Tiếng Prakrit Ashoka", "Prakrit Ashoka", ancestors = "sa", translit = { Brah = "Brah-translit", Khar = "Khar-translit", }, } m["inc-gup"] = { "Gurjar Apabhramsa", nil, "inc-mid", "Deva", ancestors = "psu", } m["inc-kam"] = { "tiếng Kamarupi Prakrit", 6356097, "inc-mid", "Brah, Sidd", "Tiếng Kamarupi Prakrit", "Kamarupi Prakrit", ancestors = "inc-mgd", } m["inc-kha"] = { "tiếng Khasa Prakrit", nil, "inc-nor", "Latn", "Tiếng Khasa Prakrit", "Khasa Prakrit", ancestors = "inc-pra", } m["inc-kho"] = { "tiếng Kholosi", 24952008, "inc-snd", "Latn", "Tiếng Kholosi", "Kholosi", ancestors = "inc-vra", } m["inc-mas"] = { "Middle Assamese", nil, "inc-eas", "as-Beng", ancestors = "inc-oas", translit = "inc-mas-translit", } m["inc-mbn"] = { "Middle Bengali", nil, "inc-eas", "Beng", ancestors = "inc-obn", translit = "inc-mbn-translit", } m["inc-mgd"] = { "Magadhi Prakrit", 2652214, "inc-mid", "Brah", ancestors = "inc-pra", translit = "Brah-translit", } m["inc-mgu"] = { "tiếng Gujarat trung đại", 24907429, "inc-wes", "Deva", "Tiếng Gujarat trung đại", "Gujarat trung đại", ancestors = "inc-ogu", } m["inc-mor"] = { "tiếng Oriya trung đại", 128810882, "inc-eas", "Orya", "Tiếng Oriya trung đại", "Oriya trung đại", ancestors = "inc-oor", } m["inc-oas"] = { "tiếng Assam cận đại", nil, "inc-bas", "as-Beng", "Tiếng Assam cận đại", "Assam cận đại", ancestors = "inc-kam", translit = "inc-oas-translit", } m["inc-obn"] = { "Old Bengali", nil, "inc-eas", "Beng", ancestors = "inc-mgd", } m["inc-ogu"] = { "tiếng Gujarat cổ", 24907427, "inc-wes", "Deva", "Tiếng Gujarat cổ", "Gujarat cổ", ancestors = "inc-gup", translit = "sa-translit", } m["inc-ohi"] = { "Old Hindi", 48767781, "inc-hiw", "Deva", ancestors = "inc-sap", translit = "sa-translit", } m["inc-oor"] = { "tiếng Oriya cổ", 128807801, "inc-eas", "Orya", "Tiếng Oriya cổ", "Oriya cổ", } m["inc-opa"] = { "Old Punjabi", nil, "inc-pan", "Guru, pa-Arab", ancestors = "inc-tak", translit = { Guru = "inc-opa-Guru-translit", ["pa-Arab"] = "pa-Arab-translit", }, entry_name = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun}, } m["inc-ork"] = { "Old Kamta", nil, "inc-eas", "as-Beng", ancestors = "inc-kam", translit = "as-translit", } m["inc-pra"] = { "tiếng Prakrit", 192170, "inc", "Brah, Deva, Knda", "Tiếng Prakrit", "Prakrit", ancestors = "inc-ash", translit = { Brah = "Brah-translit", Deva = "inc-pra-Deva-translit", Knda = "inc-pra-Knda-translit", }, entry_name = { from = {"ऎ", "ऒ", u(0x0946), u(0x094A), "य़", "ಯ಼", u(0x11071), u(0x11072), u(0x11073), u(0x11074)}, to = {"ए", "ओ", u(0x0947), u(0x094B), "य", "ಯ", "𑀏", "𑀑", u(0x11042), u(0x11044)} } , } m["inc-pro"] = { "tiếng Ấn-Arya nguyên thủy", 23808344, "inc", "Latn", "Tiếng Ấn-Arya nguyên thủy", "Ấn-Arya nguyên thủy", type = "reconstructed", } m["inc-psc"] = { "tiếng Prakrit Paisaci", 2995607, "inc-mid", "Brah", ancestors = "inc-ash", translit = "Brah-translit", "Tiếng Prakrit Paisaci", "Prakrit Paisaci", } m["inc-sap"] = { "Sauraseni Apabhramsa", nil, "inc-mid", "Deva", ancestors = "psu", } m["inc-tak"] = { "Takka Apabhramsa", nil, "inc-mid", "Deva", ancestors = "inc-pra", translit = "sa-translit", } m["inc-vra"] = { "Vracada Apabhramsa", nil, "inc-mid", "Deva", ancestors = "inc-pra", translit = "sa-translit", } m["inc-cen-pro"] = { "Proto-Central Indo-Aryan", nil, "inc-cen", "Latn", type = "reconstructed", ancestors = "psu", } m["ine-ana-pro"] = { "Proto-Anatolian", 7251833, "ine-ana", "Latn", type = "reconstructed", } m["ine-bsl-pro"] = { "tiếng Balt-Slav nguyên thủy", 1703347, "ine-bsl", "Latn", "Tiếng Balt-Slav nguyên thủy", "Balt-Slav nguyên thủy", type = "reconstructed", sort_key = { from = {"[áā]", "[éēḗ]", "[íī]", "[óōṓ]", "[úū]", c.acute, c.macron, "ˀ"}, to = {"a", "e", "i", "o", "u"} }, } m["ine-pae"] = { "Paeonian", 2705672, "ine", "polytonic", translit = "grc-translit", entry_name = {remove_diacritics = c.macron .. c.breve}, sort_key = s["Grek-sortkey"], } m["ine-pro"] = { "tiếng Ấn-Âu nguyên thủy", 37178, "ine", "Latn", "Tiếng Ấn-Âu nguyên thủy", "Ấn-Âu nguyên thủy", type = "reconstructed", sort_key = { from = {"[áā]", "[éēḗ]", "[íī]", "[óōṓ]", "[úū]", "ĺ", "ḿ", "ń", "ŕ", "ǵ", "ḱ", "ʰ", "ʷ", "₁", "₂", "₃", c.ringbelow, c.acute, c.macron}, to = {"a", "e", "i", "o", "u", "l", "m", "n", "r", "g'", "k'", "¯h", "¯w", "1", "2", "3"} }, } m["ine-toc-pro"] = { "tiếng Tochari nguyên thủy", 37029, "ine-toc", "Latn", "Tiếng Tochari nguyên thủy", "Tochari nguyên thủy", type = "reconstructed", } m["xme-old"] = { "tiếng Media cổ", 36461, "xme", "Grek, Latn", "Tiếng Media cổ", "Media cổ", } m["xme-mid"] = { "Middle Median", nil, "xme", "Latn", ancestors = "xme-old", } m["xme-ker"] = { "tiếng Kerman", 129850, "xme", "fa-Arab, Latn", "Tiếng Kerman", "Kerman", ancestors = "xme-mid", } m["xme-taf"] = { "Tafreshi", nil, "xme", "fa-Arab, Latn", ancestors = "xme-mid", } m["xme-ttc-pro"] = { "Proto-Tatic", nil, "xme-ttc", "Latn", ancestors = "xme-mid", } m["xme-kls"] = { "Kalasuri", nil, "xme-ttc", ancestors = "xme-ttc-nor", } m["xme-klt"] = { "Kilit", 3612452, "xme-ttc", "Cyrl", -- and fa-Arab? ancestors = "xme-ttc-pro", } m["xme-ott"] = { "Old Tati", 434697, "xme-ttc", "fa-Arab, Latn", ancestors = "xme-ttc-pro", } m["ira-pro"] = { "tiếng Iran nguyên thủy", 4167865, "ira", "Latn", "Tiếng Iran nguyên thủy", "Iran nguyên thủy", type = "reconstructed", } m["ira-mpr-pro"] = { "Proto-Medo-Parthian", nil, "ira-mpr", "Latn", type = "reconstructed", } m["ira-kms-pro"] = { "Proto-Komisenian", nil, "ira-kms", "Latn", type = "reconstructed", } m["ira-zgr-pro"] = { "tiếng Zaza-Goran nguyên thủy", nil, "ira-zgr", "Latn", "Tiếng Zaza-Goran nguyên thủy", "Zaza-Goran nguyên thủy", type = "reconstructed", } m["ira-pat-pro"] = { "tiếng Pathan nguyên thủy", nil, "ira-pat", "Latn", "Tiếng Pathan nguyên thủy", "Pathan nguyên thủy", type = "reconstructed", } m["os-pro"] = { "Proto-Ossetic", nil, "xsc", "Latn", type = "reconstructed", } m["xsc-pro"] = { "tiếng Scythia nguyên thủy", nil, "xsc", "Latn", "Tiếng Scythia nguyên thủy", "Scythia nguyên thủy", type = "reconstructed", } m["xsc-sar-pro"] = { "tiếng Sarmatia nguyên thủy", 116773249, "xsc-sar", "Latn", "Tiếng Sarmatia nguyên thủy", "Sarmatia nguyên thủy", type = "reconstructed", } m["xsc-skw-pro"] = { "tiếng Saka-Wakhi nguyên thủy", nil, "xsc-skw", "Latn", "Tiếng Saka-Wakhi nguyên thủy", "Saka-Wakhi nguyên thủy", type = "reconstructed", ancestors = "xsc-pro", } m["xsc-sak-pro"] = { "Proto-Saka", nil, "xsc-sak", "Latn", type = "reconstructed", ancestors = "xsc-skw-pro", } m["ira-sym-pro"] = { "tiếng Shughnan-Yazghulom-Munji nguyên thủy", nil, "ira-sym", "Latn", "Tiếng Shughnan-Yazghulom-Munji nguyên thủy", "Shughnan-Yazghulom-Munji nguyên thủy", type = "reconstructed", } m["ira-sgi-pro"] = { "Proto-Sanglechi-Ishkashimi", nil, "ira-sgi", "Latn", type = "reconstructed", } m["ira-mny-pro"] = { "Proto-Munji-Yidgha", nil, "ira-mny", "Latn", type = "reconstructed", ancestors = "ira-sym-pro", } m["ira-shy-pro"] = { "tiếng Shughnan-Yazghulom nguyên thủy", nil, "ira-shy", "Latn", "Tiếng Shughnan-Yazghulom nguyên thủy", "Shughnan-Yazghulom nguyên thủy", type = "reconstructed", ancestors = "ira-sym-pro", } m["ira-shr-pro"] = { "tiếng Shughnan-Rushan nguyên thủy", nil, "ira-shy", "Latn", "Tiếng Shughnan-Rushan nguyên thủy", "Shughnan-Rushan nguyên thủy", type = "reconstructed", ancestors = "ira-shy-pro", } m["ira-sgc-pro"] = { "tiếng Sogdia nguyên thủy", nil, "ira-sgc", "Latn", "Tiếng Sogdia nguyên thủy", "Sogdia nguyên thủy", type = "reconstructed", } m["ira-wnj"] = { "Vanji", nil, "ira-shy", "Latn", ancestors = "ira-shy-pro", } m["iro-ere"] = { "Erie", 5388365, "iro-nor", "Latn", } m["iro-min"] = { "Mingo", 128531, "iro-nor", "Latn", } m["iro-nor-pro"] = { "tiếng Bắc Iroquois nguyên thủy", nil, "iro-nor", "Latn", "Tiếng Bắc Iroquois nguyên thủy", "Bắc Iroquois nguyên thủy", type = "reconstructed", } m["iro-pro"] = { "tiếng Iroquois nguyên thủy", 7251852, "iro", "Latn", "Tiếng Iroquois nguyên thủy", "Iroquois nguyên thủy", type = "reconstructed", } m["itc-pro"] = { "tiếng Italic nguyên thủy", 17102720, "itc", "Latn", "Tiếng Italic nguyên thủy", "Italic nguyên thủy", type = "reconstructed", } m["jpx-hcj"] = { "tiếng Hachijō", 5637049, "jpx", "Jpan", "Tiếng Hachijō", "Hachijō", ancestors = "ojp-eas", translit = s["jpx-translit"], display_text = s["jpx-displaytext"], entry_name = s["jpx-entryname"], sort_key = s["jpx-sortkey"], } m["jpx-pro"] = { "tiếng Nhật Bản nguyên thủy", nil, "jpx", "Latn", "Tiếng Nhật Bản nguyên thủy", "Nhật Bản nguyên thủy", type = "reconstructed", } m["jpx-ryu-pro"] = { "tiếng Lưu Cầu nguyên thủy", nil, "jpx-ryu", "Latn", "Tiếng Lưu Cầu nguyên thủy", "Lưu Cầu nguyên thủy", type = "reconstructed", } m["kar-pro"] = { "tiếng Karen nguyên thủy", nil, "kar", "Latn", "Tiếng Karen nguyên thủy", "Karen nguyên thủy", type = "reconstructed", } m["kca-eas"] = { "tiếng Đông Khanty", 30304622, "kca", "Cyrl", "Tiếng Đông Khanty", "Đông Khanty", translit = "kca-translit", override_translit = true, -- TODO temporary until MediaWiki supports Unicode 16 (probably requires a PHP update from their side) sort_key = { Cyrl = { from = {"ᲊ"}, to = {"Ᲊ"} } }, } m["kca-nor"] = { "tiếng Bắc Khanty", 30304527, "kca", "Cyrl", "Tiếng Bắc Khanty", "Bắc Khanty", translit = "kca-translit", override_translit = true, -- TODO temporary until MediaWiki supports Unicode 16 (probably requires a PHP update from their side) sort_key = { Cyrl = { from = {"ᲊ"}, to = {"Ᲊ"} } }, } m["kca-sou"] = { "Southern Khanty", 30304618, "kca", "Cyrl", translit = "kca-translit", override_translit = true, } m["khi-kho-pro"] = { "Proto-Khoe", nil, "khi-kho", "Latn", type = "reconstructed", } m["khi-kun"] = { "ǃKung", 32904, "khi-kxa", "Latn", } m["ko-ear"] = { "Early Modern Korean", 756014, "qfa-kor", "Kore", ancestors = "okm", translit = "okm-translit", entry_name = s["Kore-entryname"], } m["kro-pro"] = { "Proto-Kru", nil, "kro", "Latn", type = "reconstructed", } m["ku-pro"] = { "Proto-Kurdish", nil, "ku", "Latn", type = "reconstructed", } m["map-ata-pro"] = { "Proto-Atayalic", nil, "map-ata", "Latn", type = "reconstructed", } m["map-bms"] = { "tiếng Banyumas", 33219, "map", "Latn", "Tiếng Banyumas", "Banyumas", } m["map-pro"] = { "tiếng Nam Đảo nguyên thủy", 49230, "map", "Latn", "Tiếng Nam Đảo nguyên thủy", "Nam Đảo nguyên thủy", type = "reconstructed", } m["mkh-asl-pro"] = { "tiếng Asli nguyên thủy", 55630680, "mkh-asl", "Latn", "Tiếng Asli nguyên thủy", "Asli nguyên thủy", type = "reconstructed", } m["mkh-ban-pro"] = { "tiếng Bahnar nguyên thủy", nil, "mkh-ban", "Latn", "Tiếng Bahnar nguyên thủy", "Bahnar nguyên thủy", type = "reconstructed", } m["mkh-bhn"] = { "tiếng Bhnong", nil, "mkh-nbn", "Latn", "Tiếng Bhnong", "Bhnong", } m["mkh-kat-pro"] = { "tiếng Cơ Tu nguyên thủy", nil, "mkh-kat", "Latn", "Tiếng Cơ Tu nguyên thủy", "Cơ Tu nguyên thủy", type = "reconstructed", } m["mkh-khm-pro"] = { "tiếng Khơ Mú nguyên thủy", nil, "mkh-khm", "Latn", "Tiếng Khơ Mú nguyên thủy", "Khơ Mú nguyên thủy", type = "reconstructed", } m["mkh-kmr-pro"] = { "tiếng Khmer nguyên thủy", 55630684, "mkh-kmr", "Latn", "Tiếng Khmer nguyên thủy", "Khmer nguyên thủy", type = "reconstructed", } m["mkh-mmn"] = { "tiếng Môn trung đại", 121337926, "mkh-mnc", "Latn, Mymr", --and also Pallava "Tiếng Môn trung đại", "Môn trung đại", ancestors = "omx", } m["mkh-mnc-pro"] = { "tiếng Môn nguyên thủy", 116773231, "mkh-mnc", "Latn", "Tiếng Môn nguyên thủy", "Môn nguyên thủy", type = "reconstructed", } m["mkh-mvi"] = { "tiếng Việt trung cổ", 9199, "mkh-vie", "Hani, Latn", "Tiếng Việt trung cổ", "Việt trung cổ", sort_key = {Hani = "Hani-sortkey"}, } m["mkh-pal-pro"] = { "tiếng Palaung nguyên thủy", nil, "mkh-pal", "Latn", "Tiếng Palaung nguyên thủy", "Palaung nguyên thủy", type = "reconstructed", } m["mkh-pea-pro"] = { "tiếng Pear nguyên thủy", nil, "mkh-pea", "Latn", "Tiếng Pear nguyên thủy", "Pear nguyên thủy", type = "reconstructed", } m["mkh-pkn-pro"] = { "tiếng Pakan nguyên thủy", nil, "mkh-pkn", "Latn", "Tiếng Pakan nguyên thủy", "Pakan nguyên thủy", type = "reconstructed", } m["mkh-pro"] = { --This will be merged into 2015 aav-pro. "tiếng Môn-Khmer nguyên thủy", 7251859, "mkh", "Latn", "Tiếng Môn-Khmer nguyên thủy", "Môn-Khmer nguyên thủy", type = "reconstructed", } m["mkh-vie-pro"] = { "tiếng Việt-Mường nguyên thủy", nil, "mkh-vie", "Latn", "Tiếng Việt-Mường nguyên thủy", "Việt-Mường nguyên thủy", type = "reconstructed", } m["mns-cen"] = { "tiếng Trung Mansi", 128810384, "mns", "Cyrl", "Tiếng Trung Mansi", "Trung Mansi", translit = "mns-translit", override_translit = true, } m["mns-nor"] = { "tiếng Bắc Mansi", 30304537, "mns", "Cyrl", "Tiếng Bắc Mansi", "Bắc Mansi", translit = "mns-translit", override_translit = true, } m["mns-pro"] = { "tiếng Mansi nguyên thủy", 128883093, "mns", "Latn", "Tiếng Mansi nguyên thủy", "Mansi nguyên thủy", type = "reconstructed", } m["mns-sou"] = { "tiếng Nam Mansi", 30304629, "mns", "Cyrl", "Tiếng Nam Mansi", "Nam Mansi", translit = "mns-translit", override_translit = true, } m["mnw-tha"] = { "tiếng Môn Thái", nil, "mkh-mnc", "Mymr, Thai", ancestors = "mkh-mmn", sort_key = { from = {"[%p]", "ျ", "ြ", "ွ", "ှ", "ၞ", "ၟ", "ၠ", "ၚ", "ဿ", "[็-๎]", "([เแโใไ])([ก-ฮ])ฺ?"}, to = {"", "္ယ", "္ရ", "္ဝ", "္ဟ", "္န", "္မ", "္လ", "င", "သ္သ", "", "%2%1"} }, "Tiếng Môn Thái", "Môn Thái" } m["mun-pro"] = { "tiếng Munda nguyên thủy", 105102373, "mun", "Latn", "Tiếng Munda nguyên thủy", "Munda nguyên thủy", type = "reconstructed", } m["myn-chl"] = { -- the stage after ''emy'' "Ch'olti'", 873995, "myn", "Latn", } m["myn-pro"] = { "tiếng Maya nguyên thủy", 3321532, "myn", "Latn", "Tiếng Maya nguyên thủy", "Maya nguyên thủy", type = "reconstructed", } m["nai-ala"] = { "Alazapa", nil, nil, "Latn", } m["nai-bay"] = { "Bayogoula", 1563704, nil, "Latn", } m["nai-bvy"] = { "Buena Vista Yokuts", 4985474, "nai-yok", "Latn", } m["nai-cal"] = { "Calusa", 51782, nil, "Latn", } m["nai-chi"] = { "Chiquimulilla", 25339627, "nai-xin", "Latn", } m["nai-chu-pro"] = { "Proto-Chumash", nil, "nai-chu", "Latn", type = "reconstructed", } m["nai-cig"] = { "Ciguayo", 20741700, nil, "Latn", } m["nai-ckn-pro"] = { "Proto-Chinookan", nil, "nai-ckn", "Latn", type = "reconstructed", } m["nai-dly"] = { "Delta Yokuts", nil, "nai-yok", "Latn", } m["nai-gsy"] = { "Gashowu", nil, "nai-yok", "Latn", } m["nai-guz"] = { "Guazacapán", 19572028, "nai-xin", "Latn", } m["nai-hit"] = { "Hitchiti", 1542882, "nai-mus", "Latn", } m["nai-ipa"] = { "Ipai", 3027474, "nai-yuc", "Latn", } m["nai-jtp"] = { "Jutiapa", nil, "nai-xin", "Latn", } m["nai-jum"] = { "tiếng Jumaytepeque", 25339626, "nai-xin", "Latn", "Tiếng Jumaytepeque", "Jumaytepeque", } m["nai-kat"] = { "Kathlamet", 6376639, "nai-ckn", "Latn", } m["nai-klp-pro"] = { "Proto-Kalapuyan", nil, "nai-klp", type = "reconstructed", } m["nai-knm"] = { "Konomihu", 3198734, "nai-shs", "Latn", } m["nai-kry"] = { "Kings River Yokuts", 6413014, "nai-yok", "Latn", } m["nai-kum"] = { "tiếng Kumeyaay", 4910139, "nai-yuc", "Latn", "Tiếng Kumeyaay", "Kumeyaay", } m["nai-mac"] = { "Macoris", 21070851, nil, "Latn", } m["nai-mdu-pro"] = { "Proto-Maidun", nil, "nai-mdu", "Latn", type = "reconstructed", } m["nai-miz-pro"] = { "Proto-Mixe-Zoque", nil, "nai-miz", "Latn", type = "reconstructed", } m["nai-mus-pro"] = { "tiếng Muskogee nguyên thủy", 116775368, "nai-mus", "Latn", "Tiếng Muskogee nguyên thủy", "Muskogee nguyên thủy", type = "reconstructed", } m["nai-nao"] = { "Naolan", 6964594, nil, "Latn", } m["nai-nrs"] = { "New River Shasta", 7011254, "nai-shs", "Latn", } m["nai-nvy"] = { "Northern Valley Yokuts", nil, "nai-yok", "Latn", } m["nai-okw"] = { "Okwanuchu", 3350126, "nai-shs", "Latn", } m["nai-per"] = { "Pericú", 3375369, nil, "Latn", } m["nai-pic"] = { "Picuris", 7191257, "nai-kta", "Latn", } m["nai-plp-pro"] = { "Proto-Plateau Penutian", nil, "nai-plp", "Latn", type = "reconstructed", } m["nai-ply"] = { "Palewyami", 2387391, "nai-yok", "Latn", } m["nai-pom-pro"] = { "Proto-Pomo", nil, "nai-pom", "Latn", type = "reconstructed", } m["nai-qng"] = { "Quinigua", 36360, nil, "Latn", } m["nai-sca-pro"] = { -- NB 'sio-pro' "Proto-Siouan" which is Proto-Western Siouan "Proto-Siouan-Catawban", nil, "nai-sca", "Latn", type = "reconstructed", } m["nai-sin"] = { "Sinacantán", 24190249, "nai-xin", "Latn", } m["nai-sln"] = { "Salvadoran Lenca", 3229434, "nai-len", "Latn", } m["nai-spt"] = { "Sahaptin", 3833015, "nai-shp", "Latn", } m["nai-svy"] = { "Southern Valley Yokuts", nil, "nai-yok", "Latn", } m["nai-tap"] = { "Tapachultec", 7684401, "nai-miz", "Latn", } m["nai-taw"] = { "Tawasa", 7689233, nil, "Latn", } m["nai-teq"] = { "Tequistlatec", 2964454, "nai-tqn", "Latn", } m["nai-tip"] = { "tiếng Tipai", 3027471, "nai-yuc", "Latn", "Tiếng Tipai", "Tipai", } m["nai-tky"] = { "Tule-Kaweah Yokuts", 7851988, "nai-yok", "Latn", } m["nai-tot-pro"] = { "Proto-Totozoquean", nil, "nai-tot", "Latn", type = "reconstructed", } m["nai-tsi-pro"] = { "Proto-Tsimshianic", nil, "nai-tsi", "Latn", type = "reconstructed", } m["nai-utn-pro"] = { "Proto-Utian", nil, "nai-utn", "Latn", type = "reconstructed", } m["nai-wai"] = { "Waikuri", 3118702, nil, "Latn", } m["nai-yup"] = { "Yupiltepeque", 25339628, "nai-xin", "Latn", } m["nan-hbl"] = { "tiếng Mân Tuyền Chương", 1624231, "zhx-nan", "Hants, Latn, Bopo, Kana", "Tiếng Mân Tuyền Chương", "Mân Tuyền Chương", wikimedia_codes = "zh-min-nan", generate_forms = "zh-generateforms", sort_key = { Hani = "Hani-sortkey", Kana = "Kana-sortkey" }, } m["nan-tws"] = { "tiếng Triều Châu", 36759, "zhx-nan", "Hants", "Tiếng Triều Châu", "Triều Châu", generate_forms = "zh-generateforms", translit = "zh-translit", sort_key = "Hani-sortkey", } m["nds-de"] = { "tiếng Hạ Đức tại Đức", 25433, "gmw", "Latn", "Tiếng Hạ Đức tại Đức", "Hạ Đức tại Đức", ancestors = "nds", wikimedia_codes = "nds", } m["nds-nl"] = { "tiếng Hạ Saxon Hà Lan", 516137, "gmw", "Latn", "Tiếng Hạ Saxon Hà Lan", "Hạ Saxon Hà Lan", ancestors = "nds", } m["ngf-pro"] = { "Proto-Trans-New Guinea", nil, "ngf", "Latn", type = "reconstructed", } m["nic-bco-pro"] = { "tiếng Benue-Congo nguyên thủy", nil, "nic-bco", "Latn", "Tiếng Benue-Congo nguyên thủy", "Benue-Congo nguyên thủy", type = "reconstructed", } m["nic-bod-pro"] = { "Proto-Bantoid", nil, "nic-bod", "Latn", type = "reconstructed", } m["nic-eov-pro"] = { "Proto-Eastern Oti-Volta", nil, "nic-eov", "Latn", type = "reconstructed", } m["nic-gns-pro"] = { "Proto-Gurunsi", nil, "nic-gns", "Latn", type = "reconstructed", } m["nic-grf-pro"] = { "Proto-Grassfields", nil, "nic-grf", "Latn", type = "reconstructed", } m["nic-gur-pro"] = { "Proto-Gur", nil, "nic-gur", "Latn", type = "reconstructed", } m["nic-jkn-pro"] = { "Proto-Jukunoid", nil, "nic-jkn", "Latn", type = "reconstructed", } m["nic-lcr-pro"] = { "Proto-Lower Cross River", nil, "nic-lcr", "Latn", type = "reconstructed", } m["nic-ogo-pro"] = { "Proto-Ogoni", nil, "nic-ogo", "Latn", type = "reconstructed", } m["nic-ovo-pro"] = { "Proto-Oti-Volta", nil, "nic-ovo", "Latn", type = "reconstructed", } m["nic-plt-pro"] = { "tiếng Plateau nguyên thủy", nil, "nic-plt", "Latn", "Tiếng Plateau nguyên thủy", "Plateau nguyên thủy", type = "reconstructed", } m["nic-pro"] = { "tiếng Niger-Congo nguyên thủy", nil, "nic", "Latn", "Tiếng Niger-Congo nguyên thủy", "Niger-Congo nguyên thủy", type = "reconstructed", } m["nic-ubg-pro"] = { "tiếng Ubangi nguyên thủy", nil, "nic-ubg", "Latn", "Tiếng Ubangi nguyên thủy", type = "reconstructed", } m["nic-ucr-pro"] = { "Proto-Upper Cross River", nil, "nic-ucr", "Latn", type = "reconstructed", } m["nic-vco-pro"] = { "tiếng Volta-Congo nguyên thủy", nil, "nic-vco", "Latn", "Tiếng Volta-Congo nguyên thủy", "Volta-Congo nguyên thủy", type = "reconstructed", } m["nub-har"] = { "Haraza", 19572059, "nub", "Arab, Latn", } m["nub-pro"] = { "Proto-Nubian", nil, "nub", "Latn", type = "reconstructed", } m["omq-cha-pro"] = { "Proto-Chatino", nil, "omq-cha", "Latn", type = "reconstructed", } m["omq-maz-pro"] = { "Proto-Mazatec", nil, "omq-maz", "Latn", type = "reconstructed", } m["omq-mix-pro"] = { "tiếng Mixtec nguyên thủy", 21573423, "omq-mix", "Latn", "Tiếng Mixtec nguyên thủy", "Mixtec nguyên thủy", type = "reconstructed", } m["omq-mxt-pro"] = { "Proto-Mixtec", nil, "omq-mxt", "Latn", type = "reconstructed", } m["omq-otp-pro"] = { "Proto-Oto-Pamean", nil, "omq-otp", "Latn", type = "reconstructed", ancestors = "omq-pro", } m["omq-pro"] = { "Proto-Oto-Manguean", 33669, "omq", "Latn", type = "reconstructed", } m["omq-tel"] = { "Teposcolula Mixtec", nil, "omq-mxt", "Latn", } m["omq-teo"] = { "Teojomulco Chatino", 25340451, "omq-cha", "Latn", } m["omq-tri-pro"] = { "tiếng Trique nguyên thủy", nil, "omq-tri", "Latn", "Tiếng Trique nguyên thủy", "Trique nguyên thủy", type = "reconstructed", } m["omq-zap-pro"] = { "Proto-Zapotecan", nil, "omq-zap", "Latn", type = "reconstructed", } m["omq-zpc-pro"] = { "tiếng Zapotec nguyên thủy", 116773296, "omq-zpc", "Latn", "Tiếng Zapotec nguyên thủy", "Zapotec nguyên thủy", type = "reconstructed", } m["omv-aro-pro"] = { "tiếng Aari nguyên thủy", nil, "omv-aro", "Latn", "Tiếng Aari nguyên thủy", "Aari nguyên thủy", type = "reconstructed", } m["omv-diz-pro"] = { "tiếng Dizi nguyên thủy", nil, "omv-diz", "Latn", "Tiếng Dizi nguyên thủy", "Dizi nguyên thủy", type = "reconstructed", } m["omv-pro"] = { "tiếng Omo nguyên thủy", nil, "omv", "Latn", "Tiếng Omo nguyên thủy", "Omo nguyên thủy", type = "reconstructed", } m["oto-otm-pro"] = { "Proto-Otomi", nil, "oto-otm", "Latn", type = "reconstructed", ancestors = "oto-pro", } m["oto-pro"] = { "Proto-Otomian", nil, "oto", "Latn", type = "reconstructed", ancestors = "omq-otp-pro", } m["paa-kom"] = { "Kómnzo", 18344310, "paa-yam", "Latn", } m["paa-kwn"] = { "Kuwani", 6449056, "paa", "Latn", } m["paa-nha-pro"] = { "Proto-North Halmahera", nil, "paa-nha", "Latn", type = "reconstructed" } m["paa-nun"] = { "Nungon", nil, "paa", "Latn", } m["phi-din"] = { "Dinapigue Agta", 16945774, "phi", "Latn", } m["phi-kal-pro"] = { "Proto-Kalamian", nil, "phi-kal", "Latn", type = "reconstructed", } m["phi-nag"] = { "Nagtipunan Agta", 16966111, "phi", "Latn", } m["phi-pro"] = { "tiếng Philippines nguyên thủy", 18204898, "phi", "Latn", "Tiếng Philippines nguyên thủy", "Philippines nguyên thủy", type = "reconstructed", } m["poz-abi"] = { "tiếng Abai", 19570729, "poz-san", "Latn", "Tiếng Abai", "Abai", } m["poz-bal"] = { "Baliledo", 4850912, "poz", "Latn", } m["poz-btk-pro"] = { "Proto-Bungku-Tolaki", nil, "poz-btk", "Latn", type = "reconstructed", } m["poz-cet-pro"] = { "tiếng Mã Lai-Đa Đảo Trung Đông nguyên thủy", 2269883, "poz-cet", "Latn", "Tiếng Mã Lai-Đa Đảo Trung Đông nguyên thủy", "Mã Lai-Đa Đảo Trung Đông nguyên thủy", type = "reconstructed", } m["poz-hce-pro"] = { "Proto-Halmahera-Cenderawasih", nil, "poz-hce", "Latn", type = "reconstructed", } m["poz-lgx-pro"] = { "Proto-Lampungic", nil, "poz-lgx", "Latn", type = "reconstructed", } m["poz-mcm-pro"] = { "tiếng Mã Lai-Chăm nguyên thủy", nil, "poz-mcm", "Latn", "Tiếng Mã Lai-Chăm nguyên thủy", "Mã Lai-Chăm nguyên thủy", type = "reconstructed", } m["poz-mly-pro"] = { "tiếng Mã Lai nguyên thủy", nil, "poz-mly", "Latn", "Tiếng Mã Lai nguyên thủy", "Mã Lai nguyên thủy", type = "reconstructed", } m["poz-msa-pro"] = { "tiếng Mã Lai-Sumbawa nguyên thủy", nil, "poz-msa", "Latn", "Tiếng Mã Lai-Sumbawa nguyên thủy", "Mã Lai-Sumbawa nguyên thủy", type = "reconstructed", } m["poz-oce-pro"] = { "tiếng Châu Đại Dương nguyên thủy", 141741, "poz-oce", "Latn", "Tiếng Châu Đại Dương nguyên thủy", "Châu Đại Dương nguyên thủy", type = "reconstructed", } m["poz-pep-pro"] = { "tiếng Đa Đảo Đông nguyên thủy", nil, "poz-pep", "Latn", "Tiếng Đa Đảo Đông nguyên thủy", "Đa Đảo Đông nguyên thủy", type = "reconstructed", } m["poz-pnp-pro"] = { "tiếng Đa Đảo hạt nhân nguyên thủy", nil, "poz-pnp", "Latn", "Tiếng Đa Đảo hạt nhân nguyên thủy", "Đa Đảo hạt nhân nguyên thủy", type = "reconstructed", } m["poz-pol-pro"] = { "tiếng Đa Đảo nguyên thủy", 1658709, "poz-pol", "Latn", "Tiếng Đa Đảo nguyên thủy", "Đa Đảo nguyên thủy", type = "reconstructed", } m["poz-pro"] = { "tiếng Mã Lai-Đa Đảo nguyên thủy", 3832960, "poz", "Latn", "Tiếng Mã Lai-Đa Đảo nguyên thủy", "Mã Lai-Đa Đảo nguyên thủy", type = "reconstructed", } m["poz-ssw-pro"] = { "Proto-South Sulawesi", nil, "poz-ssw", "Latn", type = "reconstructed", } m["poz-sus-pro"] = { "Proto-Sunda-Sulawesi", nil, "poz-sus", "Latn", type = "reconstructed", } m["poz-swa-pro"] = { "Proto-North Sarawak", nil, "poz-swa", "Latn", type = "reconstructed", } m["pqe-pro"] = { "tiếng Mã Lai-Đa Đảo Đông nguyên thủy", 2269883, "pqe", "Latn", "Tiếng Mã Lai-Đa Đảo Đông nguyên thủy", "Mã Lai-Đa Đảo Đông nguyên thủy", type = "reconstructed", } m["pra-niy"] = { "tiếng Prakrit Niya", nil, "inc-mid", "Khar", ancestors = "inc-ash", translit = "Khar-translit", "Tiếng Prakrit Niya", "Prakrit Niya", } m["qfa-adm-pro"] = { "Proto-Great Andamanese", nil, "qfa-adm", "Latn", type = "reconstructed", } m["qfa-bet-pro"] = { "tiếng Bối-Thái nguyên thủy", 116773193, "qfa-bet", "Latn", "Tiếng Bối-Thái nguyên thủy", "Bối-Thái nguyên thủy", type = "reconstructed", } m["qfa-cka-pro"] = { "Proto-Chukotko-Kamchatkan", 7251837, "qfa-cka", "Latn", type = "reconstructed", } m["qfa-hur-pro"] = { "Proto-Hurro-Urartian", nil, "qfa-hur", "Latn", type = "reconstructed", } m["qfa-kad-pro"] = { "Proto-Kadu", nil, "qfa-kad", "Latn", type = "reconstructed", } m["qfa-kms-pro"] = { "tiếng Động-Thủy nguyên thủy", nil, "qfa-kms", "Latn", "Tiếng Động-Thủy nguyên thủy", "Động-Thủy nguyên thủy", type = "reconstructed", } m["qfa-kor-pro"] = { "tiếng Triều Tiên nguyên thủy", 467883, "qfa-kor", "Latn", "Tiếng Triều Tiên nguyên thủy", "Triều Tiên nguyên thủy", type = "reconstructed", } m["qfa-kra-pro"] = { "tiếng Kra nguyên thủy", 7251854, "qfa-kra", "Latn", "Tiếng Kra nguyên thủy", "Kra nguyên thủy", type = "reconstructed", } m["qfa-lic-pro"] = { "tiếng Hlai nguyên thủy", 7251845, "qfa-lic", "Latn", "Tiếng Hlai nguyên thủy", "Hlai nguyên thủy", type = "reconstructed", } m["qfa-onb-pro"] = { "tiếng Ông Bối nguyên thủy", nil, "qfa-onb", "Latn", "Tiếng Ông Bối nguyên thủy", "Ông Bối nguyên thủy", type = "reconstructed", } m["qfa-ong-pro"] = { "tiếng Önge nguyên thủy", nil, "qfa-ong", "Latn", "Tiếng Önge nguyên thủy", "Önge nguyên thủy", type = "reconstructed", } m["qfa-tak-pro"] = { "tiếng Kra-Dai nguyên thủy", nil, "qfa-tak", "Latn", "Tiếng Kra-Dai nguyên thủy", "Kra-Dai nguyên thủy", type = "reconstructed", } m["qfa-xgx-rou"] = { "tiếng Nhu Nhiên", 48816637, "qfa-xgx", "Hani, Latn", "Tiếng Nhu Nhiên", "Nhu Nhiên", sort_key = {Hani = "Hani-sortkey"}, } m["qfa-xgx-tuh"] = { "tiếng Thổ Dục Hồn", 48816625, "qfa-xgx", "Hani, Latn", "Tiếng Thổ Dục Hồn", "Thổ Dục Hồn", sort_key = {Hani = "Hani-sortkey"}, } m["qfa-xgx-tuo"] = { "tiếng Thác Bạt", 48816629, "qfa-xgx", "Hani, Latn", "Tiếng Thác Bạt", "Thác Bạt", sort_key = {Hani = "Hani-sortkey"}, } m["qfa-xgx-xbi"] = { "tiếng Tiên Ti", 4448647, "qfa-xgx", "Hani, Latn", "Tiếng Tiên Ti", "Tiên Ti", sort_key = {Hani = "Hani-sortkey"}, } m["qfa-yen-pro"] = { "tiếng Enisei nguyên thủy", 27639, "qfa-yen", "Latn", "Tiếng Enisei nguyên thủy", "Enisei nguyên thủy", type = "reconstructed", } m["qfa-yuk-pro"] = { "tiếng Yukaghir nguyên thủy", nil, "qfa-yuk", "Latn", "Tiếng Yukaghir nguyên thủy", "Yukaghir nguyên thủy", type = "reconstructed", } m["qwe-kch"] = { "Kichwa", 1740805, "qwe", "Latn", ancestors = "qu", } m["roa-ang"] = { "Angevin", 56782, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["roa-bbn"] = { "Bourbonnais-Berrichon", nil, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["roa-brg"] = { "tiếng Bourguignon", 508332, "roa-oil", "Latn", "Tiếng Bourguignon", "Bourguignon", sort_key = s["roa-oil-sortkey"], } m["roa-cha"] = { "Champenois", 430018, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["roa-fcm"] = { "tiếng Franche-Comté", 510561, "roa-oil", "Latn", "Tiếng Franche-Comté", "Franche-Comté", sort_key = s["roa-oil-sortkey"], } m["roa-gal"] = { "tiếng Gallo", 37300, "roa-oil", "Latn", "Tiếng Gallo", "Gallo", sort_key = s["roa-oil-sortkey"], } m["roa-leo"] = { "tiếng León", 34108, "roa-ibe", "Latn", "Tiếng León", "León", ancestors = "roa-ole", } m["roa-lor"] = { "tiếng Lorrain", 671198, "roa-oil", "Latn", "Tiếng Lorrain", "Lorrain", sort_key = s["roa-oil-sortkey"], } m["roa-oan"] = { "Navarro-Aragonese", 2736184, "roa-ibe", "Latn", } m["roa-oca"] = { "tiếng Catalan cổ", 15478520, "roa-ocr", "Latn", "Tiếng Catalan cổ", "Catalan cổ", sort_key = { from = {"à", "[èé]", "[íï]", "[òó]", "[úü]", "ç", "·"}, to = {"a", "e", "i", "o", "u", "c"} }, } m["roa-ole"] = { "tiếng León cổ", 125977465, "roa-asl", "Latn", "Tiếng León cổ", "León cổ", } m["roa-opt"] = { "tiếng Galicia-Bồ Đào Nha", 1072111, "roa-ibe", "Latn", "Tiếng Galicia-Bồ Đào Nha", "Galicia-Bồ Đào Nha", } m["roa-orl"] = { "Orléanais", nil, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["roa-poi"] = { "Poitevin-Saintongeais", 514123, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["roa-tar"] = { "tiếng Tarantino", 695526, "roa-itd", "Latn", "Tiếng Tarantino", "Tarantino", ancestors = "nap", wikimedia_codes = "roa-tara", } m["roa-tou"] = { "Tourangeau", nil, "roa-oil", "Latn", sort_key = s["roa-oil-sortkey"], } m["sai-ajg"] = { "Ajagua", nil, nil, "Latn", } m["sai-all"] = { "tiếng Alyentiyak", 19570789, "sai-hrp", "Latn", "Tiếng Alyentiyak", "Alyentiyak", } m["sai-and"] = { -- not to be confused with 'cbc' or 'ano' "Andoquero", 16828359, "sai-wit", "Latn", } m["sai-ayo"] = { "Ayomán", 16937754, "sai-jir", "Latn", } m["sai-bae"] = { "Baenan", 3401998, nil, "Latn", } m["sai-bag"] = { "tiếng Bagua", 5390321, nil, "Latn", "Tiếng Bagua", "Bagua", } m["sai-bet"] = { "Betoi", 926551, "qfa-iso", "Latn", } m["sai-bor-pro"] = { "Proto-Boran", nil, "sai-bor", "Latn", } m["sai-cac"] = { "Cacán", 945482, nil, "Latn", } m["sai-caq"] = { "Caranqui", 2937753, "sai-bar", "Latn", } m["sai-car-pro"] = { "tiếng Carib nguyên thủy", nil, "sai-car", "Latn", "Tiếng Carib nguyên thủy", "Carib nguyên thủy", type = "reconstructed", } m["sai-cat"] = { "Catacao", 5051136, "sai-ctc", "Latn", } m["sai-cer-pro"] = { "tiếng Cerrado nguyên thủy", nil, "sai-cer", "Latn", "Tiếng Cerrado nguyên thủy", "Cerrado nguyên thủy", type = "reconstructed", } m["sai-chi"] = { "Chirino", 5390321, nil, "Latn", } m["sai-chn"] = { "Chaná", 5072718, "sai-crn", "Latn", } m["sai-chp"] = { "Chapacura", 5072884, "sai-cpc", "Latn", } m["sai-chr"] = { "Charrua", 5086680, "sai-crn", "Latn", } m["sai-chu"] = { "Churuya", 5118339, "sai-guh", "Latn", } m["sai-cje-pro"] = { "Proto-Central Jê", nil, "sai-cje", "Latn", type = "reconstructed", } m["sai-cmg"] = { "Comechingon", 6644203, nil, "Latn", } m["sai-cno"] = { "Chono", 5104704, nil, "Latn", } m["sai-cnr"] = { "Cañari", 5055572, nil, "Latn", } m["sai-coe"] = { "Coeruna", 6425639, "sai-wit", "Latn", } m["sai-col"] = { "Colán", 5141893, "sai-ctc", "Latn", } m["sai-cop"] = { "Copallén", 5390321, nil, "Latn", } m["sai-crd"] = { "Coroado Puri", 24191321, "sai-mje", "Latn", } m["sai-ctq"] = { "Catuquinaru", 16858455, nil, "Latn", } m["sai-cul"] = { "Culli", 2879660, nil, "Latn", } m["sai-cva"] = { "Cueva", nil, nil, "Latn", } m["sai-esm"] = { "Esmeralda", 3058083, nil, "Latn", } m["sai-ewa"] = { "Ewarhuyana", 16898104, nil, "Latn", } m["sai-gam"] = { "Gamela", 5403661, nil, "Latn", } m["sai-gay"] = { "Gayón", 5528902, "sai-jir", "Latn", } m["sai-gmo"] = { "Guamo", 5613495, nil, "Latn", } m["sai-gue"] = { "Güenoa", 5626799, "sai-crn", "Latn", } m["sai-hau"] = { "tiếng Haush", 3128376, "sai-cho", "Latn", "Tiếng Haush", "Haush", } m["sai-hoc-pro"] = { "Proto-Huitoto-Ocaina", nil, "sai-hoc", "Latn", type = "reconstructed", } m["sai-jee-pro"] = { "tiếng Jê nguyên thủy", nil, "sai-jee", "Latn", "Tiếng Jê nguyên thủy", "Jê nguyên thủy", type = "reconstructed", } m["sai-jko"] = { "Jeikó", 6176527, "sai-mje", "Latn", } m["sai-jrj"] = { "Jirajara", 6202966, "sai-jir", "Latn", } m["sai-kat"] = { -- contrast xoo, kzw, sai-xoc "Katembri", 6375925, nil, "Latn", } m["sai-mal"] = { "Malalí", 6741212, nil, "Latn", } m["sai-mar"] = { "Maratino", 6755055, nil, "Latn", } m["sai-mat"] = { "Matanawi", 6786047, nil, "Latn", } m["sai-mcn"] = { "Mocana", 3402048, nil, "Latn", } m["sai-men"] = { "Menien", 16890110, "sai-mje", "Latn", } m["sai-mil"] = { "Millcayac", 19573012, "sai-hrp", "Latn", } m["sai-mlb"] = { "Malibu", 3402048, nil, "Latn", } m["sai-msk"] = { "Masakará", 6782426, "sai-mje", "Latn", } m["sai-muc"] = { "Mucuchí", nil, nil, "Latn", } m["sai-mue"] = { "Muellama", 16886936, "sai-bar", "Latn", } m["sai-muz"] = { "Muzo", 6644203, nil, "Latn", } m["sai-mys"] = { "Maynas", 16919393, nil, "Latn", } m["sai-nat"] = { "Natú", 9006749, nil, "Latn", } m["sai-nje-pro"] = { "tiếng Jê Bắc nguyên thủy", nil, "sai-nje", "Latn", "Tiếng Jê Bắc nguyên thủy", "Jê Bắc nguyên thủy", type = "reconstructed", } m["sai-opo"] = { "Opón", 7099152, "sai-car", "Latn", } m["sai-oto"] = { "Otomaco", 16879234, "sai-otm", "Latn", } m["sai-pal"] = { "Palta", 3042978, nil, "Latn", } m["sai-pam"] = { "Pamigua", 5908689, "sai-otm", "Latn", } m["sai-par"] = { "Paratió", 16890038, nil, "Latn", } m["sai-pnz"] = { "Panzaleo", 3123275, nil, "Latn", } m["sai-prh"] = { "Puruhá", 3410994, nil, "Latn", } m["sai-ptg"] = { "Patagón", nil, nil, "Latn", } m["sai-pur"] = { "Purukotó", 7261622, "sai-pem", "Latn", } m["sai-pyg"] = { "Payaguá", 7156643, "sai-guc", "Latn", } m["sai-pyk"] = { "Pykobjê", 98113977, "sai-nje", "Latn", } m["sai-qmb"] = { "Quimbaya", 7272043, nil, "Latn", } m["sai-qtm"] = { "Quitemo", 7272651, "sai-cpc", "Latn", } m["sai-rab"] = { "Rabona", 6644203, nil, "Latn", } m["sai-ram"] = { "Ramanos", 16902824, nil, "Latn", } m["sai-sac"] = { "Sácata", 5390321, nil, "Latn", } m["sai-san"] = { "Sanaviron", 16895999, nil, "Latn", } m["sai-sap"] = { "Sapará", 7420922, "sai-car", "Latn", } m["sai-sec"] = { "Sechura", 7442912, nil, "Latn", } m["sai-sin"] = { "Sinúfana", 7525275, nil, "Latn", } m["sai-sje-pro"] = { "Proto-Southern Jê", nil, "sai-sje", "Latn", type = "reconstructed", } m["sai-tab"] = { "Tabancale", 5390321, nil, "Latn", } m["sai-tal"] = { "Tallán", 16910468, nil, "Latn", } m["sai-tap"] = { "Tapayuna", nil, "sai-nje", "Latn", } m["sai-tar-pro"] = { "Proto-Taranoan", nil, "sai-tar", "Latn", type = "reconstructed", } m["sai-teu"] = { "Teushen", 3519243, nil, "Latn", } m["sai-tim"] = { "Timote", nil, nil, "Latn", } m["sai-tpr"] = { "Taparita", 7684460, "sai-otm", "Latn", } m["sai-trr"] = { "Tarairiú", 7685313, nil, "Latn", } m["sai-wai"] = { "Waitaká", 16918610, nil, "Latn", } m["sai-way"] = { "Wayumará", nil, "sai-car", "Latn", } m["sai-wit-pro"] = { "Proto-Witotoan", nil, "sai-wit", "Latn", type = "reconstructed", } m["sai-wnm"] = { "Wanham", 16879440, "sai-cpc", "Latn", } m["sai-xoc"] = { -- contrast xoo, kzw, sai-kat "Xocó", 12953620, nil, "Latn", } m["sai-yao"] = { "tiếng Yao (Nam Mĩ)", nil, "sai-ven", "Latn", "Tiếng Yao (Nam Mĩ)", "Yao (Nam Mĩ)", } m["sai-yar"] = { -- not the same family as 'suy' "Yarumá", 3505859, "sai-pek", "Latn", } m["sai-yri"] = { "tiếng Yuri", nil, "sai-tyu", "Latn", "Tiếng Yuri", "Yuri", } m["sai-yup"] = { "Yupua", 8061430, "sai-tuc", "Latn", } m["sai-yur"] = { "Yurumanguí", 1281291, nil, "Latn", } m["sal-pro"] = { "tiếng Salish nguyên thủy", nil, "sal", "Latn", "Tiếng Salish nguyên thủy", "Salish nguyên thủy", type = "reconstructed", } m["sdv-daj-pro"] = { "Proto-Daju", nil, "sdv-daj", "Latn", type = "reconstructed", } m["sdv-eje-pro"] = { "Proto-Eastern Jebel", nil, "sdv-eje", "Latn", type = "reconstructed", } m["sdv-nil-pro"] = { "Proto-Nilotic", nil, "sdv-nil", "Latn", type = "reconstructed", } m["sdv-nyi-pro"] = { "Proto-Nyima", nil, "sdv-nyi", "Latn", type = "reconstructed", } m["sdv-tmn-pro"] = { "Proto-Taman", nil, "sdv-tmn", "Latn", type = "reconstructed", } m["sel-nor"] = { "tiếng Bắc Selkup", 30304565, "sel", "Cyrl", "Tiếng Bắc Selkup", "Bắc Selkup", } m["sel-pro"] = { "tiếng Selkup nguyên thủy", 128884235, "sel", "Latn", "Tiếng Selkup nguyên thủy", "Selkup nguyên thủy", type = "reconstructed", } m["sel-sou"] = { "tiếng Nam Selkup", 30304639, "sel", "Cyrl", "Tiếng Nam Selkup", "Nam Selkup", } m["sem-amm"] = { "Ammonite", 279181, "sem-can", "Phnx", translit = "Phnx-translit", } m["sem-amo"] = { "Amorite", 35941, "sem-nwe", "Xsux, Latn", } m["sem-cha"] = { "Chaha", nil, "sem-eth", "Ethi", translit = "Ethi-translit", ancestors = "sem-pro", } m["sem-dad"] = { "Dadanitic", 21838040, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-dum"] = { "Dumaitic", nil, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-has"] = { "Hasaitic", 3541433, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-him"] = { "Himyaritic", 35604, "sem", "Arab, Sarb", } m["sem-his"] = { "Hismaic", 22948260, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-mhr"] = { "Muher", 33743, "sem-eth", "Latn", } m["sem-pro"] = { "tiếng Semit nguyên thủy", 1658554, "sem", "Latn", "Tiếng Semit nguyên thủy", "Semit nguyên thủy", type = "reconstructed", } m["sem-saf"] = { "Safaitic", 472586, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-srb"] = { "tiếng Nam Ả Rập cổ", 35025, "sem-osa", "Sarb", "Tiếng Nam Ả Rập cổ", "Nam Ả Rập cổ", translit = "Sarb-translit", } m["sem-tay"] = { "tiếng Tayma", 24912301, "sem-cen", "Narb", "Tiếng Tayma", "Tayma", translit = "Narb-translit", } m["sem-tha"] = { "Thamudic", 843030, "sem-cen", "Narb", translit = "Narb-translit", } m["sem-wes-pro"] = { "tiếng Semit Tây nguyên thủy", 98021726, "sem-wes", "Latn", "Tiếng Semit Tây nguyên thủy", "Semit Tây nguyên thủy", type = "reconstructed", } m["sio-pro"] = { -- NB this is not Proto-Siouan-Catawban 'nai-sca-pro' "tiếng Sioux nguyên thủy", 34181, "sio", "Latn", "Tiếng Sioux nguyên thủy", "Sioux nguyên thủy", type = "reconstructed", } m["sit-aao-pro"] = { "tiếng Naga Trung nguyên thủy", nil, "sit-aao", "Latn", "Tiếng Naga Trung nguyên thủy", "Naga Trung nguyên thủy", type = "reconstructed", } m["sit-bai-pro"] = { "tiếng Bạch nguyên thủy", nil, "sit-bai", "Latn", "Tiếng Bạch nguyên thủy", "Bạch nguyên thủy", type = "reconstructed", } m["sit-ban"] = { "Bangru", 56071779, "sit-hrs", "Latn", } m["sit-bdi-pro"] = { "Proto-Bodish", nil, "sit-bdi", "Latn", type = "reconstructed", } m["sit-bok"] = { "tiếng Bokar", 4938727, "sit-tan", "Latn, Tibt", "Tiếng Bokar", "Bokar", translit = {Tibt = "Tibt-translit"}, override_translit = true, display_text = {Tibt = s["Tibt-displaytext"]}, entry_name = {Tibt = s["Tibt-entryname"]}, sort_key = {Tibt = "Tibt-sortkey"}, } m["sit-cha"] = { "Chairel", 5068066, "sit-luu", "Latn", } m["sit-gkh"] = { "Gokhy", 5578069, "tbq-lol", "Latn", } m["sit-hrs-pro"] = { "Proto-Hrusish", nil, "sit-hrs", type = "reconstructed", } m["sit-jap"] = { "tiếng Japhug", 3162245, "sit-egy", "Latn", "Tiếng Japhug", "Japhug", } m["sit-kha-pro"] = { "Proto-Kham", nil, "sit-kha", type = "reconstructed", } m["sit-liz"] = { "Lizu", 6660653, "sit-qia", "Latn", -- and Ersu Shaba } m["sit-lrn"] = { "tiếng Lư Nhân", 6660653, "sit-qia", nil, "Tiếng Lư Nhân", "Lư Nhân", } m["sit-luu-pro"] = { "Proto-Luish", nil, "sit-luu", type = "reconstructed", } m["sit-mor"] = { "Moran", 6909216, "tbq-bdg", "Latn", } m["sit-prn"] = { "Puiron", 7259048, "sit-zem", } m["sit-pro"] = { "tiếng Hán-Tạng nguyên thủy", 45961, "sit", "Latn", "Tiếng Hán-Tạng nguyên thủy", "Hán-Tạng nguyên thủy", type = "reconstructed", } m["sit-sit"] = { "tiếng Tứ Thổ", 19840830, "sit-egy", "Latn", "Tiếng Tứ Thổ", "Tứ Thổ", } m["sit-tan-pro"] = { "Proto-Tani", nil, "sit-tan", "Latn", -- needs verification type = "reconstructed", } m["sit-tgm"] = { "Tangam", 17041370, "sit-tan", "Latn", } m["sit-tos"] = { "Tosu", 7827899, "sit-qia", "Latn", -- also Ersu Shaba } m["sit-tsh"] = { "Tshobdun", 19840950, "sit-egy", "Latn", } m["sit-zbu"] = { "Zbu", 19841106, "sit-egy", "Latn", } m["sla-pro"] = { "tiếng Slav nguyên thủy", 747537, "sla", "Latn", "Tiếng Slav nguyên thủy", "Slav nguyên thủy", type = "reconstructed", entry_name = { remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve, remove_exceptions = {'ś'}, }, sort_key = { from = {"č", "ď", "ě", "ę", "ь", "ľ", "ň", "ǫ", "ř", "š", "ś", "ť", "ъ", "ž"}, to = {"c²", "d²", "e²", "e³", "i²", "l²", "nj", "o²", "r²", "s²", "s³", "t²", "u²", "z²"}, } } m["smi-pro"] = { "tiếng Sami nguyên thủy", 7251862, "smi", "Latn", "Tiếng Sami nguyên thủy", "Sami nguyên thủy", type = "reconstructed", sort_key = { from = {"ā", "č", "δ", "[ëē]", "ŋ", "ń", "ō", "š", "θ", "%([^()]+%)"}, to = {"a", "c²", "d", "e", "n²", "n³", "o", "s²", "t²"} }, } m["son-pro"] = { "Proto-Songhay", nil, "son", "Latn", type = "reconstructed", } m["sqj-pro"] = { "tiếng Albani nguyên thủy", 18210846, "sqj", "Latn", "Tiếng Albani nguyên thủy", "Albani nguyên thủy", type = "reconstructed", } m["ssa-klk-pro"] = { "Proto-Kuliak", nil, "ssa-klk", "Latn", type = "reconstructed", } m["ssa-kom-pro"] = { "tiếng Koman nguyên thủy", nil, "ssa-kom", "Latn", "Tiếng Koman nguyên thủy", "Koman nguyên thủy", type = "reconstructed", } m["ssa-pro"] = { "tiếng Nin-Sahara nguyên thủy", nil, "ssa", "Latn", "Tiếng Nin-Sahara nguyên thủy", "Nin-Sahara nguyên thủy", type = "reconstructed", } m["syd-fne"] = { "Forest Nenets", 1295107, "syd", "Cyrl", entry_name = {remove_diacritics = c.grave .. c.acute .. c.macron .. c.breve .. c.dotabove}, } m["syd-pro"] = { "tiếng Samoyed nguyên thủy", 7251863, "syd", "Latn", "Tiếng Samoyed nguyên thủy", "Samoyed nguyên thủy", type = "reconstructed", } m["tai-pro"] = { "tiếng Thái nguyên thủy", 6583709, "tai", "Latn", "Tiếng Thái nguyên thủy", "Thái nguyên thủy", type = "reconstructed", } m["tai-swe-pro"] = { "tiếng Tai Tây Nam nguyên thủy", nil, "tai-swe", "Latn", "Tiếng Tai Tây Nam nguyên thủy", "Tai Tây Nam nguyên thủy", type = "reconstructed", } m["tbq-bdg-pro"] = { "tiếng Bodo-Garo nguyên thủy", nil, "tbq-bdg", "Latn", "Tiếng Bodo-Garo nguyên thủy", "Bodo-Garo nguyên thủy", type = "reconstructed", } m["tbq-kuk-pro"] = { "Proto-Kuki-Chin", nil, "tbq-kuk", "Latn", type = "reconstructed", } m["tbq-lal-pro"] = { "Proto-Lalo", nil, "tbq-lol", "Latn", type = "reconstructed", } m["tbq-laz"] = { "Laze", 17007626, "sit-nax", } m["tbq-lob-pro"] = { "tiếng Lô Lô-Miến nguyên thủy", 116773224, "tbq-lob", "Latn", "Tiếng Lô Lô-Miến nguyên thủy", "Lô Lô-Miến nguyên thủy", type = "reconstructed", } m["tbq-lol-pro"] = { "Proto-Loloish", 7251855, "tbq-lol", "Latn", type = "reconstructed", } m["tbq-ngo"] = { "Ngochang", nil, "tbq-brm", "Latn", } m["tbq-plg"] = { "Pai-lang", 2879843, "tbq-lob", "Hani, Latn", sort_key = {Hani = "Hani-sortkey"}, } -- tbq-pro is now etymology-only m["trk-dkh"] = { "tiếng Dukha", nil, "trk-sib", "Latn, Cyrl, Mong", "Tiếng Dukha", "Dukha", translit = {Mong = "Mong-translit"}, display_text = {Mong = s["Mong-displaytext"]}, entry_name = {Mong = s["Mong-entryname"]}, } m["trk-eog"] = { "tiếng Oghuz cổ sơ kỳ", nil, "trk-ogz", "ota-Arab", strip_diacritics = {["ota-Arab"] = "ar-stripdiacritics"}, } m["trk-fyk"] = { "tiếng Kyrgyz Phú Dụ", 2598963, nil, "Latn", "Tiếng Kyrgyz Phú Dụ", "Kyrgyz Phú Dụ", } m["trk-oat"] = { "tiếng Thổ Nhĩ Kỳ Anatolia cổ", 7083390, "trk-ogz", "ota-Arab", strip_diacritics = {["ota-Arab"] = "ar-stripdiacritics"}, ancestors = "trk-eog", "Tiếng Thổ Nhĩ Kỳ Anatolia cổ", "Thổ Nhĩ Kỳ Anatolia cổ", } m["trk-pro"] = { "tiếng Turk nguyên thủy", 3657773, "trk", "Latn", "Tiếng Turk nguyên thủy", "Turk nguyên thủy", type = "reconstructed", } m["trk-soy"] = { "tiếng Soyot", 4426878, "trk", "Cyrl", "Tiếng Soyot", "Soyot", translit = "trk-soy-translit", } m["tup-gua-pro"] = { "tiếng Tupi-Guarani nguyên thủy", nil, "tup-gua", "Latn", "Tiếng Tupi-Guarani nguyên thủy", "Tupi-Guarani nguyên thủy", type = "reconstructed", } m["tup-kab"] = { "Kabishiana", 15302988, "tup", "Latn", } m["tup-pro"] = { "tiếng Tupi nguyên thủy", 10354700, "tup", "Latn", "Tiếng Tupi nguyên thủy", "Tupi nguyên thủy", type = "reconstructed", } m["tuw-alk"] = { "tiếng Alchuka", 113553616, "tuw-jrc", "Latn, Hans", "Tiếng Alchuka", "Alchuka", sort_key = {Hans = "Hani-sortkey"}, } m["tuw-bal"] = { "tiếng Bala", 86730632, "tuw-jrc", "Latn, Hans", "Tiếng Bala", "Bala", sort_key = {Hans = "Hani-sortkey"}, } m["tuw-kil"] = { "tiếng Kili", 6406892, "tuw", nil, "Tiếng Kili", "Kili", } m["tuw-pro"] = { "tiếng Tungus nguyên thủy", nil, "tuw", "Latn", "Tiếng Tungus nguyên thủy", "Tungus nguyên thủy", type = "reconstructed", } m["tuw-kkl"] = { "tiếng Kyakala", nil, "tuw", "Latn, Hani", "Tiếng Kyakala", "Kyakala", sort_key = {Hani = "Hani-sortkey"}, } m["tuw-sol"] = { "tiếng Solon", 30004, "tuw", nil, "Tiếng Solon", "Solon", } m["und-isa"] = { "Isaurian", 16956868, nil, -- "Xsux, Hluw, Latn", } m["und-kas"] = { "Kassite", 35612, nil, "Xsux", } m["und-mil"] = { "Milang", 6850761, nil, "Deva, Latn", } m["und-mmd"] = { "Mimi of Decorse", 6862206, nil, "Latn", } m["und-mmn"] = { "Mimi of Nachtigal", 6862207, nil, "Latn", } m["und-phi"] = { "Philistine", 2230924, nil, "Phnx", } m["und-wji"] = { "Western Jicaque", 3178610, "hok", "Latn", } m["urj-fin-pro"] = { "tiếng Finn nguyên thủy", 11883720, "urj-fin", "Latn", "Tiếng Finn nguyên thủy", "Finn nguyên thủy", type = "reconstructed", } m["urj-koo"] = { "tiếng Komi cổ", nil, "urj-prm", "Perm, Cyrs", "Tiếng Komi cổ", "Komi cổ", translit = "urj-koo-translit", sort_key = {Cyrs = s["Cyrs-sortkey"]}, } m["urj-kuk"] = { "Kukkuzi", 107410460, "urj-fin", "Latn", ancestors = "vot", } m["urj-kya"] = { "tiếng Komi-Yazva", 2365210, "urj-prm", "Cyrl", "Tiếng Komi-Yazva", "Komi-Yazva", translit = "kv-translit", override_translit = true, entry_name = {remove_diacritics = c.acute}, } m["urj-mdv-pro"] = { "tiếng Mordvin nguyên thủy", nil, "urj-mdv", "Latn", "Tiếng Mordvin nguyên thủy", "Mordvin nguyên thủy", type = "reconstructed", } m["urj-prm-pro"] = { "tiếng Perm nguyên thủy", nil, "urj-prm", "Latn", "Tiếng Perm nguyên thủy", "Perm nguyên thủy", type = "reconstructed", } m["urj-pro"] = { "tiếng Ural nguyên thủy", 288765, "urj", "Latn", "Tiếng Ural nguyên thủy", "Ural nguyên thủy", type = "reconstructed", } m["urj-ugr-pro"] = { "tiếng Ugria nguyên thủy", 156631, "urj-ugr", "Latn", "Tiếng Ugria nguyên thủy", "Ugria nguyên thủy", type = "reconstructed", } m["xnd-pro"] = { "Proto-Na-Dene", nil, "xnd", "Latn", type = "reconstructed", } m["xgn-mgr"] = { "tiếng Mangghuer", 34214, "mjg", "Latn", -- also Mong, Cyrl ? "Tiếng Mangghuer", "Mangghuer", } m["xgn-mgl"] = { "tiếng Mongghul", 34214, "mjg", "Latn", -- also Mong, Cyrl ? "Tiếng Mongghul", "Mongghul", } m["xgn-pro"] = { "tiếng Mông Cổ nguyên thủy", 2493677, "xgn", "Latn", "Tiếng Mông Cổ nguyên thủy", "Mông Cổ nguyên thủy", type = "reconstructed", } m["ypk-pro"] = { "Proto-Yupik", nil, "ypk", "Latn", type = "reconstructed", } m["zhx-min-pro"] = { "tiếng Mân nguyên thủy", 19646347, "zhx-min", "Latn", "Tiếng Mân nguyên thủy", "Mân nguyên thủy", type = "reconstructed", } m["zhx-sht"] = { "Shaozhou Tuhua", 1920769, "zhx", "Nshu, Hani, Hant, Hans", generate_forms = "zh-generateforms", sort_key = {Hani = "Hani-sortkey"}, } m["zhx-sic"] = { "tiếng Tứ Xuyên", 2278732, "zhx-man", "Hants", "Tiếng Tứ Xuyên", "Tứ Xuyên", generate_forms = "zh-generateforms", translit = "zh-translit", sort_key = "Hani-sortkey", } m["zhx-tai"] = { "tiếng Đài Sơn", 2208940, "zhx", "Hani, Hant, Hans", "Tiếng Đài Sơn", "Đài Sơn", ancestors = "yue", generate_forms = "zh-generateforms", translit = "zh-translit", sort_key = "Hani-sortkey", } m["zhx-taz"] = { "tiếng Taz", 3516511, "zhx", nil, "Tiếng Taz", "Taz", } m["zhx-twa"] = { "tiếng Đường Uông", 7683179, "zhx", "Hani", "Tiếng Đường Uông", "Đường Uông", } m["zle-ono"] = { "tiếng Novgorod cổ", 162013, "zle", "Cyrs, Glag", "Tiếng Novgorod cổ", "Novgorod cổ", translit = "Cyrs-Glag-translit", entry_name = {Cyrs = s["Cyrs-entryname"]}, sort_key = {Cyrs = s["Cyrs-sortkey"]}, } m["zle-ort"] = { "tiếng Ruthenia cổ", 13211, "zle", "Cyrs", "Tiếng Ruthenia cổ", "Ruthenia cổ", ancestors = "orv", translit = "zle-ort-translit", entry_name = { remove_diacritics = s["Cyrs-entryname"].remove_diacritics, remove_exceptions = {"Ї", "ї"} }, sort_key = s["Cyrs-sortkey"], } m["zls-chs"] = { "tiếng Slav Giáo hội", 33251, "zls", "Cyrs, Glag, Latn", "Tiếng Slav Giáo hội", "Slav Giáo hội", ancestors = "cu", translit = { Cyrs = "Cyrs-translit", Glag = "Glag-translit" }, entry_name = { Cyrs = s["Cyrs-entryname"] }, sort_key = { Cyrs = s["Cyrs-sortkey"] }, } m["zlw-ocs"] = { "tiếng Séc cổ", 593096, "zlw", "Latn", "Tiếng Séc cổ", "Séc cổ", } m["zlw-osk"] = { "tiếng Slovak cổ", 12776676, "zlw", "Latn", "Tiếng Slovak cổ", "Slovak cổ", } m["zlw-opl"] = { "tiếng Ba Lan cổ", 149838, "zlw-lch", "Latn", "Tiếng Ba Lan cổ", "Ba Lan cổ", entry_name = {remove_diacritics = c.ringabove}, } m["zlw-pom-pro"] = { "Proto-Pomeranian", 149588, "zlw-pom", "Latn", type = "reconstructed", } m["zlw-slv"] = { "tiếng Slovincia", 36822, "zlw-pom", "Latn", "Tiếng Slovincia", "Slovincia", ancestors = "zlw-pom-pro", entry_name = "zlw-slv-entryname" } m["aav-qal"] = { "tiếng Quảng Lâm", 19894302, "mkh-pal", "Latn", "Tiếng Quảng Lâm", "Quảng Lâm", } return require("Module:languages").finalizeData(m, "language") 8s1t8v06w5s74kz456bx84n431dy6bv хирлиг 0 280304 2344420 2098370 2026-04-12T05:07:27Z Hiyuune 50834 2344420 wikitext text/x-wiki =={{langname|tyv}}== ==={{section|pron}}=== * {{IPA4|tyv|/xɪrˈlɪɣ/}} ==={{section|adj}}=== {{tyv-adj}} # [[bẩn|Bẩn]]; không [[sạch]]. ===={{section|ant}}==== * {{l|tyv|арыг}} j75oo5hdbdgv9fptmv3tlkebpy1pvj5 боктуг 0 280305 2344422 2098371 2026-04-12T05:09:24Z Hiyuune 50834 2344422 wikitext text/x-wiki =={{langname|tyv}}== ==={{section|adj}}=== {{tyv-adj}} # [[bẩn|Bẩn]]. qcg6dqfrtai9uoc1fvdhch055uh3ql4 алгыг 0 280308 2344424 2098374 2026-04-12T05:10:53Z Hiyuune 50834 2344424 wikitext text/x-wiki =={{langname|tyv}}== ==={{section|adj}}=== {{tyv-noun}} # [[rộng|Rộng]]. #: {{syn|tyv|делгем}} hsdmf0rwl3wryl7i9sdb35831ftu5wz 2344425 2344424 2026-04-12T05:11:01Z Hiyuune 50834 2344425 wikitext text/x-wiki =={{langname|tyv}}== ==={{section|adj}}=== {{tyv-adj}} # [[rộng|Rộng]]. #: {{syn|tyv|делгем}} nqt41gaila5hz5bzwqh7k5njf35meal Mô đun:khb-headword 828 281409 2344395 2245017 2026-04-12T04:50:12Z Hiyuune 50834 2344395 Scribunto text/plain local export = {} local pos_functions = {} local lang = require("Module:languages").getByCode("khb") local PAGENAME = mw.loadData("Module:headword/data").pagename local script = lang:findBestScript(PAGENAME) -- Talu hoặc Lana function export.show(frame) local args = frame:getParent().args local poscat = frame.args[1] or error("Từ loại không được chỉ ró. Vui lòng thêm tham số đầu tiên để gọi mô đun.") local head = args["head"] local tr = args["tr"] local data = { lang = lang, pos_category = poscat, categories = {}, sccat = true, heads = {head}, translits = {tr}, inflections = {} } local lana = {label = "chính tả Tày Lự cũ", lang = lang, sc = require("Module:scripts").getByCode("Lana")} if args["l"] then table.insert(lana, args["l"]) end if args["l2"] then table.insert(lana, args["l2"]) end if args["l3"] then table.insert(lana, args["l3"]) end if #lana > 0 then table.insert(data.inflections, lana) end if pos_functions[poscat] then pos_functions[poscat](args, data) end return require("Module:headword").full_headword(data) end pos_functions["Danh từ"] = function(args, data) local classifiers = {label = "loại từ"} if args[1] then for _,par in ipairs(args) do if par == "*" then table.insert(classifiers, PAGENAME) -- shorthand table.insert(data.categories, "Loại từ tiếng Lự") table.insert(data.categories, "Danh từ có loại từ " .. PAGENAME .. " tiếng Lự") else table.insert(classifiers, par) table.insert(data.categories, "Danh từ có loại từ " .. par .. " tiếng Lự") end end table.insert(data.inflections, classifiers) end end pos_functions["Động từ"] = function(args, data) local par1 = args[1]; if par1 == "" then par1 = nil end local par2 = args[2]; if par2 == "" then par2 = nil end local par3 = args[3]; if par3 == "" then par3 = nil end local abstract_forms = {label = "danh từ trừu tượng", accel = {pos = "Danh từ", form = "abstract-noun"}} if par1 ~= "-" then if not par1 then table.insert(abstract_forms, (script:getCode() == "Talu" and "ᦂᦱᧃ" or "ᨠᩣ᩠ᩁ") .. PAGENAME) else if par1 == "~" then table.insert(abstract_forms, (script:getCode() == "Talu" and "ᦂᦱᧃ" or "ᨠᩣ᩠ᩁ") .. PAGENAME) table.insert(abstract_forms, (script:getCode() == "Talu" and "ᦩᦱᧄ" or "ᨤ᩠ᩅᩣ᩠ᨾ") .. PAGENAME) else table.insert(abstract_forms, par1) table.insert(abstract_forms, par2) table.insert(abstract_forms, par3) end end table.insert(data.inflections, abstract_forms) end end pos_functions["Tính từ"] = function(args, data) local par1 = args[1]; if par1 == "" then par1 = nil end local par2 = args[2]; if par2 == "" then par2 = nil end local par3 = args[3]; if par3 == "" then par3 = nil end local abstract_forms = {label = "danh từ trừu tượng", accel = {pos = "Danh từ", form = "abstract-noun"}} if par1 ~= "-" then if not par1 then table.insert(abstract_forms, (script:getCode() == "Talu" and "ᦩᦱᧄ" or "ᨤ᩠ᩅᩣ᩠ᨾ") .. PAGENAME) else table.insert(abstract_forms, par1) table.insert(abstract_forms, par2) table.insert(abstract_forms, par3) end table.insert(data.inflections, abstract_forms) end end -- same logic pos_functions["Phó từ"] = pos_functions["Tính từ"] return export sdmksgbcwzmfrmg90int19aeptou33i Mô đun:anchors 828 284089 2344296 2299099 2026-04-11T15:54:35Z TheHighFighter2 42988 2344296 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local ucfirst = require("Module:string utilities").ucfirst local anchor_encode = mw.uri.anchorEncode local concat = table.concat local insert = table.insert local language_anchor -- Defined below. local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end -- Returns the anchor text to be used as the fragment of a link to a language section. function export.language_anchor(lang, id) return anchor_encode(ucfirst(lang:getFullName()) .. ": " .. id) end language_anchor = export.language_anchor -- Normalizes input text (removes formatting etc.), which can then be used as an anchor in an `id=` field. function export.normalize_anchor(str) return decode_entities(anchor_encode(str)) end function export.make_anchors(ids) local anchors = {} for i = 1, #ids do local id = ids[i] insert(anchors, "<span class=\"template-anchor\" id=\"" .. anchor_encode(id) .. "\" data-id=\"" .. encode_entities(id) .. "\"></span>") end return concat(anchors) end function export.senseid(lang, id, tag_name) -- The following tag is opened but never closed, where is it supposed to be closed? -- with <li> it doesn't matter, as it is closed automatically. -- with <p> it is a problem return "<" .. tag_name .. " class=\"senseid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\">" end function export.etymid(lang, id) -- Use a <ul> tag to ensure spacing doesn't get messed up. return "<ul class=\"etymid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\"></ul>" end function export.etymonid(lang, id) -- Use a <ul> tag to ensure spacing doesn't get messed up. return "<ul class=\"etymonid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\"></ul>" end return export qsl4iurtak58jv52szlqxc2g663z1by 2344304 2344296 2026-04-11T23:54:39Z TheHighFighter2 42988 Đã lùi lại sửa đổi [[Special:Diff/2344296|2344296]] của [[Special:Contributions/TheHighFighter2|TheHighFighter2]] ([[User talk:TheHighFighter2|thảo luận]]) 2344304 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local anchor_encode = mw.uri.anchorEncode local concat = table.concat local insert = table.insert local language_anchor -- Defined below. local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end -- Returns the anchor text to be used as the fragment of a link to a language section. function export.language_anchor(lang, id) return anchor_encode(lang:getFullName() .. ": " .. id) end language_anchor = export.language_anchor -- Normalizes input text (removes formatting etc.), which can then be used as an anchor in an `id=` field. function export.normalize_anchor(str) return decode_entities(anchor_encode(str)) end function export.make_anchors(ids) local anchors = {} for i = 1, #ids do local id = ids[i] insert(anchors, "<span class=\"template-anchor\" id=\"" .. anchor_encode(id) .. "\" data-id=\"" .. encode_entities(id) .. "\"></span>") end return concat(anchors) end function export.senseid(lang, id, tag_name) -- The following tag is opened but never closed, where is it supposed to be closed? -- with <li> it doesn't matter, as it is closed automatically. -- with <p> it is a problem return "<" .. tag_name .. " class=\"senseid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\">" end function export.etymid(lang, id) -- Use a <ul> tag to ensure spacing doesn't get messed up. return "<ul class=\"etymid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\"></ul>" end function export.etymonid(lang, id) -- Use a <ul> tag to ensure spacing doesn't get messed up. return "<ul class=\"etymonid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\"></ul>" end return export buie2kpbi0kb4hc2y1x9ovsfm754yk9 2344320 2344304 2026-04-12T01:45:32Z TheHighFighter2 42988 2344320 Scribunto text/plain local export = {} local string_utilities_module = "Module:string utilities" local anchor_encode = mw.uri.anchorEncode local concat = table.concat local insert = table.insert local language_anchor -- Defined below. local function decode_entities(...) decode_entities = require(string_utilities_module).decode_entities return decode_entities(...) end local function encode_entities(...) encode_entities = require(string_utilities_module).encode_entities return encode_entities(...) end -- Returns the anchor text to be used as the fragment of a link to a language section. function export.language_anchor(lang, id) return anchor_encode(lang:getFullName() .. ": " .. id) end language_anchor = export.language_anchor -- Normalizes input text (removes formatting etc.), which can then be used as an anchor in an `id=` field. function export.normalize_anchor(str) return decode_entities(anchor_encode(str)) end function export.make_anchors(ids) local anchors = {} for i = 1, #ids do local id = ids[i] local el = mw.html.create("span") :addClass("template-anchor") :attr("id", anchor_encode(id)) :attr("data-id", id) insert(anchors, tostring(el)) end return concat(anchors) end function export.senseid(lang, id, tag_name) -- The following tag is opened but never closed, where is it supposed to be closed? -- with <li> it doesn't matter, as it is closed automatically. -- with <p> it is a problem -- Cannot use mw.html here as it always closes tags return "<" .. tag_name .. " class=\"senseid\" id=\"" .. language_anchor(lang, id) .. "\" data-lang=\"" .. lang:getCode() .. "\" data-id=\"" .. encode_entities(id) .. "\">" end function export.etymid(lang, id) -- Use a <ul> tag to ensure spacing doesn't get messed up. local el = mw.html.create("ul") :addClass("etymid") :attr("id", language_anchor(lang, id)) :attr("data-lang", lang:getCode()) :attr("data-id", id) return tostring(el) end function export.etymonid(lang, id, opts) opts = opts or {} -- Use a <ul> tag to ensure spacing doesn't get messed up. local el = mw.html.create("ul") :addClass("etymonid") :attr("data-lang", lang:getCode()) if id then el:attr("id", language_anchor(lang, id)) el:attr("data-id", id) end if opts.no_tree then el:attr("data-no-tree", "1") end if opts.title then el:attr("data-title", opts.title) end if opts.empty_tree then el:attr("data-empty-tree", "1") end return tostring(el) end return export d0onsd99m5ccscopc1i38n0lhzar2z3 Bản mẫu:etymid 10 286106 2344435 2110882 2026-04-12T06:09:15Z TheHighFighter2 42988 2344435 wikitext text/x-wiki <includeonly><onlyinclude>{{safesubst:<noinclude/>#invoke:anchors/templates|etymid_t}}</onlyinclude></includeonly><!-- -->{{documentation}} sm3f1lxol1knum6i82u5texr7lxd45d hızlı 0 289941 2344427 2122980 2026-04-12T05:14:16Z Hiyuune 50834 2344427 wikitext text/x-wiki =={{langname|gag}}== ==={{section|adj}}=== {{head|gag|Tính từ}} # [[nhanh|Nhanh]]. #: {{syn|gag|çabuk}} =={{langname|tr}}== ==={{section|adj}}=== Từ {{inh|tr|ota|حزلو|tr=hızlı}}, tương đương từ {{suffix|tr|hız|-li|alt2=-lı}}. ==={{section|pron}}=== * {{tr-IPA}} * {{audio|tr|LL-Q256 (tur)-ToprakM-hızlı.wav}} * {{rhymes|tr|ɯ|s=2}} ==={{section|adj}}=== {{tr-adj}} # [[nhanh|Nhanh]]. #: {{syn|tr|süratli}} ===={{section|decl}}==== {{tr-pred-c-adj|stem=hızlıy|ı|d}} ===={{section|ant}}==== * {{l|tr|yavaş}} ilh1jd4jfa1v48pzp53y74piyikh7an ōlaʻi 0 307153 2344360 2168084 2026-04-12T03:06:08Z Kelly zhrm 58416 2344360 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|pron}}=== * {{haw-IPA}} ==={{ĐM|n}}=== {{head|haw|Danh từ}} # [[động đất|Động đất]]. 0nmlyp6pirlfqj2qlrqdvwc5me73jnz 南蛮烏瓜 0 318793 2344462 2190198 2026-04-12T09:16:25Z WhoAlone 40420 2344462 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|なん|ばん|からす|うり|yomi=o2,k2}} {{wikipedia|lang=ja|ナンバンカラスウリ}} ==={{ĐM|etym}}=== {{compound|ja|南蛮|烏瓜|tr1=Nanban|t1={{w|Nanman}}|tr2=karasuuri|t2=[[Japanese]] [[snake gourd]]}} ==={{ĐM|noun}}=== {{ja-noun|^なんばん からす.うり|^ナンバン カラス.ウリ}} # [[gấc|Gấc]] ==={{ĐM|synonym}}=== * {{ja-r|木%鼈%子|モク%ベツ%シ}} {{C|ja|Họ Bầu bí|Trái cây}} 9th6coxtvpl8do9cpx06422vv14vhgz klimaendring 0 318990 2344439 2190677 2026-04-12T06:40:27Z Kelly zhrm 58416 2344439 wikitext text/x-wiki =={{langname|nb}}== {{Wikipedia|no:}} ==={{ĐM|etym}}=== Từ {{affix|nb|klima|endring}}. ==={{ĐM|n}}=== {{nb-noun-c}} # [[biến đổi|Biến đổi]] [[khí hậu]] ==={{ĐM|ref}}=== * {{R:NAOB}} =={{langname|nn}}== {{Wikipedia|lang=nn}} ==={{ĐM|etym}}=== Từ ghép giữa {{compound|nn|klima|t1=khí hậu|endring|t2=thay đổi, biến đổi}}. ==={{ĐM|pron}}=== * {{IPA4|nn|/kliːmaɛndriŋɡ/}} ==={{ĐM|n}}=== {{nn-noun-f3}} # [[biến đổi|Biến đổi]] [[khí hậu]] ==={{ĐM|ref}}=== * {{R:The Nynorsk Dictionary}} ez69m8ux7ro17uya73y38xb3oiq84mq Mô đun:etymon 828 331836 2344307 2317904 2026-04-12T01:10:51Z TheHighFighter2 42988 2344307 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. Tác giả: - Triển khai ban đầu: [[Thành viên:Ioaxxere]] - Tái cấu trúc lại mô đun (tháng 9 năm 2025): [[Thành viên:Fenakhay]] ([[:en: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 ]=] local export = {} local etymon_data_module = "Module:etymon/data" local etymon_text_module = "Module:etymon/text" local etymon_tree_module = "Module:etymon/tree" local etymon_categories_module = "Module:etymon/categories" local etymon_descendants_module = "Module:etymon/descendants" 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, max_depth_reached = 0, total_nodes = 0, language_count = {}, toplevel_keyword_stats = {}, warnings = {}, } local loader = require("Module:module loader") local M = loader.init({ require = { data = etymon_data_module, tree = etymon_tree_module, text = etymon_text_module, categories = etymon_categories_module, descendants = etymon_descendants_module, 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", track = "Module:debug/track", 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 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 -- 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 -- Centralized term formatting: handles suppress_term, unknown_term, 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 opts.pos ~= "suppress" then link_params.pos = term.pos 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 -- 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) .. " nominalization of" local phrase = M.en_utilities.add_indefinite_article(adj .. " 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 = { keywords = { "affix", "surf", "univerbation" } } }, conj = {}, -- conjunction for alternatives: "and", "or", "and/or", etc. g = { restrict = { keywords = { "nominalization" } } }, } -- Term modifier definitions EtymonParser.etymon_param_mods = { id = {}, t = {}, tr = {}, ts = {}, q = {}, qq = {}, l = {}, ll = {}, pos = {}, alt = {}, ety = {}, lit = {}, unc = { type = "boolean" }, ref = {}, aftype = { restrict = { keywords = { "affix", "surf", "afeq" } } }, postype = {}, bor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, slbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, lbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, } 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 and 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 -- 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, } -- Validate modifiers against restrictions EtymonParser.check_modifier_restrictions(modifiers, canonical_keyword, EtymonParser.keyword_param_mods) return canonical_keyword, modifiers end function EtymonParser.parse_balanced_segments(str) local segments = {} local current = "" local depth = 0 local i = 1 while i <= #str do local char = str:sub(i, i) if char == "<" then if depth == 0 and current ~= "" then table.insert(segments, current) current = "" end depth = depth + 1 current = current .. char elseif char == ">" then current = current .. char depth = depth - 1 if depth == 0 then table.insert(segments, current) current = "" elseif depth < 0 then error("Unbalanced brackets in etymon: unexpected '>'") end else current = current .. char end i = i + 1 end if depth ~= 0 then error("Unbalanced brackets in etymon: missing '>'") end if current ~= "" then table.insert(segments, current) end return segments end function EtymonParser.parse_inline_ety(ety_string, context_lang) local segments = EtymonParser.parse_balanced_segments(ety_string) if #segments == 0 then error("Empty inline etymology") end local keyword = M.string_utilities.trim(segments[1]) if not is_keyword(keyword, true) then error("Invalid keyword '" .. keyword .. "' in inline etymology <ety:" .. keyword .. "...>") end local args = { context_lang:getCode(), normalize_keyword(get_canonical_keyword(keyword)) } for i = 2, #segments do local segment = segments[i] if segment:sub(1, 1) == "<" and segment:sub(-1) == ">" then local inner = segment:sub(2, -2) if inner ~= "" then table.insert(args, inner) end elseif is_keyword(segment, true) then -- Handle keywords that appear between bracketed segments table.insert(args, normalize_keyword(get_canonical_keyword(get_keyword(segment, true)))) 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 if rest == "" then M.track("etymon/term/empty") elseif rest == "?" then M.track("etymon/term/question-mark") elseif rest == "-" then M.track("etymon/term/hyphen") end if 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 == "") 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 etymons_in_group = {} local keywords = M.data.keywords local function checkGroup() if keywords[current_keyword] and keywords[current_keyword].is_group and current_keyword ~= "affix" and current_keyword ~= "surf" and current_keyword ~= "afeq" and #etymons_in_group <= 1 then error("Detected `:" .. current_keyword .. "` group with fewer than two etymons.") end etymons_in_group = {} 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 error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?") elseif is_keyword(param) then checkGroup() current_keyword = get_canonical_keyword(get_keyword(param)) else local etymon_data = EtymonParser.parse_etymon(param, lang) if etymon_data then table.insert(etymons_in_group, param) local param_lang = etymon_data.lang if etymon_data.is_family and current_keyword == "inherited" then error("`:inh` does not support family codes; use a specific language.") end if etymon_data.is_family and not etymon_data.suppress_term then error("Family codes require suppressed term (use family:-).") end if current_keyword == "from" and param_lang:getFullCode() ~= lang:getFullCode() then error("`:from` is for same-language derivation, but language does not match. " .. "Expected '" .. lang:getFullCode() .. "', got '" .. param_lang:getFullCode() .. "'.") elseif current_keyword == "inherited" then M.etymology.check_ancestor(lang, param_lang) end -- 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(etymons_in_group, param) end end end checkGroup() end local DataRetriever = {} -- 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 has_idless_etymon = false 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 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("^Etymology") then active_etymon_args = nil end elseif node_class == "template" 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 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 has_idless_etymon = true -- 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 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 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 -- Error if multiple etymons exist and at least one is missing an id if #found_templates_for_lang > 1 and has_idless_etymon then error("Page '[[" .. tostring(etymon_page) .. "]]' has " .. #found_templates_for_lang .. " etymon templates for " .. etymon_lang:getCanonicalName() .. ", but at least one is missing an id. All etymons must have unique IDs when there are multiple.") 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 -- 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) 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 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 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 return __state.cached_etymon_args[matched_key], __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 "*" 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 return __state.single_etymons[base_key], __state.cached_etymon_pages[base_key .. ":" .. only_id], nil, descendants_check elseif count > 1 then local id_list = {} for _, id_data in ipairs(ids) do local id = type(id_data) == "table" and id_data.id or id_data if id and id ~= "" then table.insert(id_list, "\"" .. id .. "\"") end end local suggestion_text = "" if #id_list > 0 then suggestion_text = " Available IDs: " .. table.concat(id_list, ", ") .. "." end Util.add_warning("Etymology link to '[[" .. page .. "]]' is ambiguous. The page has " .. count .. " etymon templates for " .. norm_lang:getCanonicalName() .. ". Please specify an ID." .. suggestion_text, true) return M.data.STATUS.AMBIGUOUS, nil, nil, nil else return M.data.STATUS.MISSING, nil, nil, nil end end 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 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 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 -- It's a keyword, check if visible in tree (invisible "all" or "tree" = hidden in tree) local keyword_info = keywords[keyword_base] local inv = keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") 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 = "from" local current_keyword_modifiers = {} local current_container = nil -- Helper to track keyword usage at top level local function track_keyword_usage(keyword, target_lang, source_lang) if not is_toplevel then return end if not __state.toplevel_keyword_stats[keyword] then __state.toplevel_keyword_stats[keyword] = { count = 0, target_langs = {}, source_langs = {}, } end local keyword_data = __state.toplevel_keyword_stats[keyword] keyword_data.count = keyword_data.count + 1 local target_code = target_lang:getCode() keyword_data.target_langs[target_code] = (keyword_data.target_langs[target_code] or 0) + 1 if source_lang then local source_code = source_lang:getCode() keyword_data.source_langs[source_code] = (keyword_data.source_langs[source_code] or 0) + 1 end end local function ensure_container() if not current_container or current_container.keyword ~= current_keyword then current_container = { keyword = current_keyword, keyword_info = M.data.keywords[current_keyword], 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 = {} for k, v in pairs(M.data.keywords[current_keyword]) do current_container.keyword_info[k] = v end current_container.keyword_info.text = labels.text current_container.keyword_info.phrase = labels.phrase end end end for i = 2, #args do local param = args[i] if is_keyword(param) then local keyword, modifiers = EtymonParser.parse_keyword_modifiers(param) 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 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, lang) if etymon_data then -- Track keyword usage at top level track_keyword_usage(current_keyword, lang, etymon_data.lang) local term_node = {} -- Handle suppress_term (-) and unknown_term (empty) directly if etymon_data.suppress_term or etymon_data.unknown_term then 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 term_node.suppress_term = etymon_data.suppress_term term_node.unknown_term = etymon_data.unknown_term term_node.is_family = etymon_data.is_family term_node.is_uncertain = etymon_data.unc term_node.ref = etymon_data.ref term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.alt = etymon_data.alt term_node.pos = etymon_data.pos term_node.lit = etymon_data.lit term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll else -- Regular term: fetch arguments from page local etymon_args, page_of, resolved_etymon_id, descendants_check = DataRetriever.get_etymon_args(etymon_data, is_toplevel) if etymon_data.id and etymon_args == M.data.STATUS.MISSING and not etymon_data.ety then 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 local available_ids = __state.available_etymon_ids[base_key] or {} if #available_ids > 0 then __state.has_mismatched_id = true end end -- 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 track_keyword_usage(inline_keyword, etymon_data.lang, inline_etymon.lang) 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 ensure_container() -- Check if current keyword has no_child_categories - if so, stop recursion local keyword_info = current_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.id = etymon_data.id term_node.etymon_id = resolved_etymon_id -- The actual etymon id when resolved via senseid term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.pos = etymon_data.pos term_node.alt = etymon_data.alt term_node.ref = etymon_data.ref term_node.is_uncertain = etymon_data.unc term_node.override = etymon_data.override term_node.page_of = page_of term_node.aftype = etymon_data.aftype term_node.postype = etymon_data.postype term_node.bor = etymon_data.bor term_node.lbor = etymon_data.lbor term_node.slbor = etymon_data.slbor term_node.lit = etymon_data.lit term_node.is_family = etymon_data.is_family term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll 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(current_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, pos = node.pos, 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 local function track_ranges(base_key, value, ranges, lang_code) M.track("etymon/" .. base_key .. "/" .. value) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. value) end for _, range in ipairs(ranges) do local matches = false if range.min and range.max then matches = value >= range.min and value <= range.max elseif range.min then matches = value >= range.min elseif range.max then matches = value <= range.max elseif range.exact then matches = value == range.exact end if matches then M.track("etymon/" .. base_key .. "/" .. range.label) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. range.label) end break end end 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() 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 ety_data_tree = export.get_tree(lang, display_title or 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 rfe = args.rfe local page_data = Util.get_page_data() if not title then title = page_data.pagename if page_data.namespace == "Từ tái tạo" then title = "*" .. title end 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 local ety_data_tree = export.get_tree(lang, title, etymon_args, { validate = true, pos = args.pos, id = id, json = args.json, }) 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, ref = parsed_etydate.ref or {}, refn = parsed_etydate.refn or { maxindex = 0 } } if etydate_args.refn then local max = 0 for k, v in pairs(etydate_args.refn) do if type(k) == "number" and k > max then max = k end end etydate_args.refn.maxindex = max end ety_data_tree.etydate = M.etydate.format_etydate(etydate_args) -- Parse and store references separately for text rendering local refs_text = "" for _, ref in ipairs(etydate_args.ref) do refs_text = refs_text .. (refs_text ~= "" and "" or "") .. ref end if refs_text ~= "" then ety_data_tree.etydate_refs = M.references.parse_references(refs_text) end 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 -- Check if there are any visible children in tree (invisible "all" or "tree" = hidden in tree) local has_visible_children = false for _, child in ipairs(ety_data_tree.children or {}) do local child_keyword_info = child.keyword_info local inv = child_keyword_info and child_keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") then has_visible_children = true break end end local tree_disallowed = lang_exc and lang_exc.disallow and lang_exc.disallow.tree local anchor = M.anchors.etymonid(lang, id, { no_tree = args.notree, title = title, empty_tree = (not has_visible_children) or tree_disallowed }) table.insert(output, anchor) 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 table.insert(output, M.text.render({ data_tree = ety_data_tree, format_term_func = Util.format_term, max_depth = max_depth, stop_at_blue_link = stop_at_blue_link, curr_page = page_data.pagename, nodot = args.nodot, stop_at_lang = stop_at_lang, stop_at_lang_or_bluelink = stop_at_lang_or_bluelink, })) end if rfe then local rfe_param_mods = { nocat = { type = "boolean" }, sort = {}, y = {}, m = {}, fragment = {}, section = {}, box = { type = "boolean" }, noes = { type = "boolean" }, } local function generate_rfe_obj(rfe_text) -- Check if it's a boolean true value if M.yesno(rfe_text, false) then return { is_boolean = true } else return { text = rfe_text } end end local rfe_with_defaults = Util.add_boolean_defaults(rfe, rfe_param_mods) local parsed_rfe = M.parse_utilities.parse_inline_modifiers(rfe_with_defaults, { param_mods = rfe_param_mods, generate_obj = generate_rfe_obj }) local rfe_args = { [1] = lang:getCode(), nocat = parsed_rfe.nocat, sort = parsed_rfe.sort, y = parsed_rfe.y, m = parsed_rfe.m, fragment = parsed_rfe.fragment, section = parsed_rfe.section, box = parsed_rfe.box, noes = parsed_rfe.noes, } if not parsed_rfe.is_boolean then rfe_args[2] = parsed_rfe.text end table.insert(output, frame:expandTemplate({ title = "rfe", args = rfe_args })) end if Util.is_content_page() and __state.max_depth_reached > 0 then local lang_code = lang:getCode() local depth_ranges = { { min = 50, label = "extremely-deep" }, { min = 20, label = "20+" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { max = 2, label = "1-2" } } local node_ranges = { { min = 100, label = "extremely-large" }, { min = 50, label = "50+" }, { min = 20, max = 49, label = "20-49" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { max = 4, label = "1-4" } } local language_ranges = { { min = 10, label = "10+" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { exact = 2, label = "2" }, { exact = 1, label = "1" } } track_ranges("depth", __state.max_depth_reached, depth_ranges, lang_code) track_ranges("nodes", __state.total_nodes, node_ranges, lang_code) local unique_languages = 0 for _ in pairs(__state.language_count) do unique_languages = unique_languages + 1 end track_ranges("unique-languages", unique_languages, language_ranges, lang_code) if __state.total_nodes == __state.max_depth_reached + 1 then track_ranges("linear-depth", __state.max_depth_reached, depth_ranges, lang_code) end end local categories = {} if Util.is_content_page() then local should_suppress_categories = lang_exc and lang_exc.suppress_categories if not should_suppress_categories and not args.nocat then categories = M.categories.render({ 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, }) end local target_lang_code = lang:getCode() for keyword, keyword_data in pairs(__state.toplevel_keyword_stats) do -- Track keyword globally M.track("etymon/keyword/" .. keyword) -- Track keyword per target language M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code) -- Track keyword per source language for source_code, count in pairs(keyword_data.source_langs) do M.track("etymon/keyword/" .. keyword .. "/source/" .. source_code) -- Track keyword per target+source combination M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code .. "/source/" .. source_code) end end if tree then table.insert(categories, "Trang có cây từ nguyên") table.insert(categories, "Mục từ có cây từ nguyên " .. lang:getCanonicalName()) end if text then table.insert(categories, lang:getCanonicalName() .. " entries with etymology texts") end if args.exnihilo then table.insert(categories, lang:getCanonicalName() .. " terms coined ex nihilo") end if __state.toplevel_has_inline_etymology then table.insert(categories, "Pages with inline etymon for redlinks") end if __state.toplevel_redundant_etymology then table.insert(categories, "Pages with redundant inline etymon") end if __state.toplevel_idless_etymon then table.insert(categories, "Trang có cây từ nguyên thiếu ID") end if __state.has_mismatched_id then table.insert(categories, lang:getCanonicalName() .. " entries referencing etymons with mismatched IDs") end end if #categories > 0 then table.insert(output, M.utilities.format_categories(categories, lang)) end if __state.warnings then for _, warning in ipairs(__state.warnings) do table.insert(output, "\n" .. warning) end end return table.concat(output) end return export thf5x5bzfynll6hvbv1dzgwqa9fwyii 2344436 2344307 2026-04-12T06:24:54Z TheHighFighter2 42988 2344436 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. Tác giả: - Triển khai ban đầu: [[Thành viên:Ioaxxere]] - Tái cấu trúc lại mô đun (tháng 9 năm 2025): [[Thành viên:Fenakhay]] ([[:en: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 ]=] local export = {} local etymon_data_module = "Module:etymon/data" local etymon_text_module = "Module:etymon/text" local etymon_tree_module = "Module:etymon/tree" local etymon_categories_module = "Module:etymon/categories" local etymon_descendants_module = "Module:etymon/descendants" local ucfirst = require("Module:string utilities").ucfirst 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, max_depth_reached = 0, total_nodes = 0, language_count = {}, toplevel_keyword_stats = {}, warnings = {}, } local loader = require("Module:module loader") local M = loader.init({ require = { data = etymon_data_module, tree = etymon_tree_module, text = etymon_text_module, categories = etymon_categories_module, descendants = etymon_descendants_module, 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", track = "Module:debug/track", 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 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 -- 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 -- Centralized term formatting: handles suppress_term, unknown_term, 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 opts.pos ~= "suppress" then link_params.pos = term.pos 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 -- 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) .. " nominalization of" local phrase = M.en_utilities.add_indefinite_article(adj .. " 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 = { keywords = { "affix", "surf", "univerbation" } } }, conj = {}, -- conjunction for alternatives: "and", "or", "and/or", etc. g = { restrict = { keywords = { "nominalization" } } }, } -- Term modifier definitions EtymonParser.etymon_param_mods = { id = {}, t = {}, tr = {}, ts = {}, q = {}, qq = {}, l = {}, ll = {}, pos = {}, alt = {}, ety = {}, lit = {}, unc = { type = "boolean" }, ref = {}, aftype = { restrict = { keywords = { "affix", "surf", "afeq" } } }, postype = {}, bor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, slbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, lbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, } 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 and 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 -- 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, } -- Validate modifiers against restrictions EtymonParser.check_modifier_restrictions(modifiers, canonical_keyword, EtymonParser.keyword_param_mods) return canonical_keyword, modifiers end function EtymonParser.parse_balanced_segments(str) local segments = {} local current = "" local depth = 0 local i = 1 while i <= #str do local char = str:sub(i, i) if char == "<" then if depth == 0 and current ~= "" then table.insert(segments, current) current = "" end depth = depth + 1 current = current .. char elseif char == ">" then current = current .. char depth = depth - 1 if depth == 0 then table.insert(segments, current) current = "" elseif depth < 0 then error("Unbalanced brackets in etymon: unexpected '>'") end else current = current .. char end i = i + 1 end if depth ~= 0 then error("Unbalanced brackets in etymon: missing '>'") end if current ~= "" then table.insert(segments, current) end return segments end function EtymonParser.parse_inline_ety(ety_string, context_lang) local segments = EtymonParser.parse_balanced_segments(ety_string) if #segments == 0 then error("Empty inline etymology") end local keyword = M.string_utilities.trim(segments[1]) if not is_keyword(keyword, true) then error("Invalid keyword '" .. keyword .. "' in inline etymology <ety:" .. keyword .. "...>") end local args = { context_lang:getCode(), normalize_keyword(get_canonical_keyword(keyword)) } for i = 2, #segments do local segment = segments[i] if segment:sub(1, 1) == "<" and segment:sub(-1) == ">" then local inner = segment:sub(2, -2) if inner ~= "" then table.insert(args, inner) end elseif is_keyword(segment, true) then -- Handle keywords that appear between bracketed segments table.insert(args, normalize_keyword(get_canonical_keyword(get_keyword(segment, true)))) 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 if rest == "" then M.track("etymon/term/empty") elseif rest == "?" then M.track("etymon/term/question-mark") elseif rest == "-" then M.track("etymon/term/hyphen") end if 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 == "") 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 etymons_in_group = {} local keywords = M.data.keywords local function checkGroup() if keywords[current_keyword] and keywords[current_keyword].is_group and current_keyword ~= "affix" and current_keyword ~= "surf" and current_keyword ~= "afeq" and #etymons_in_group <= 1 then error("Detected `:" .. current_keyword .. "` group with fewer than two etymons.") end etymons_in_group = {} 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 error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?") elseif is_keyword(param) then checkGroup() current_keyword = get_canonical_keyword(get_keyword(param)) else local etymon_data = EtymonParser.parse_etymon(param, lang) if etymon_data then table.insert(etymons_in_group, param) local param_lang = etymon_data.lang if etymon_data.is_family and current_keyword == "inherited" then error("`:inh` does not support family codes; use a specific language.") end if etymon_data.is_family and not etymon_data.suppress_term then error("Family codes require suppressed term (use family:-).") end if current_keyword == "from" and param_lang:getFullCode() ~= lang:getFullCode() then error("`:from` is for same-language derivation, but language does not match. " .. "Expected '" .. lang:getFullCode() .. "', got '" .. param_lang:getFullCode() .. "'.") elseif current_keyword == "inherited" then M.etymology.check_ancestor(lang, param_lang) end -- 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(etymons_in_group, param) end end end checkGroup() end local DataRetriever = {} -- 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 has_idless_etymon = false 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 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("^Etymology") then active_etymon_args = nil end elseif node_class == "template" 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 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 has_idless_etymon = true -- 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 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 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 -- Error if multiple etymons exist and at least one is missing an id if #found_templates_for_lang > 1 and has_idless_etymon then error("Page '[[" .. tostring(etymon_page) .. "]]' has " .. #found_templates_for_lang .. " etymon templates for " .. etymon_lang:getCanonicalName() .. ", but at least one is missing an id. All etymons must have unique IDs when there are multiple.") 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 -- 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) 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 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 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 return __state.cached_etymon_args[matched_key], __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 "*" 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 return __state.single_etymons[base_key], __state.cached_etymon_pages[base_key .. ":" .. only_id], nil, descendants_check elseif count > 1 then local id_list = {} for _, id_data in ipairs(ids) do local id = type(id_data) == "table" and id_data.id or id_data if id and id ~= "" then table.insert(id_list, "\"" .. id .. "\"") end end local suggestion_text = "" if #id_list > 0 then suggestion_text = " Available IDs: " .. table.concat(id_list, ", ") .. "." end Util.add_warning("Etymology link to '[[" .. page .. "]]' is ambiguous. The page has " .. count .. " etymon templates for " .. norm_lang:getCanonicalName() .. ". Please specify an ID." .. suggestion_text, true) return M.data.STATUS.AMBIGUOUS, nil, nil, nil else return M.data.STATUS.MISSING, nil, nil, nil end end 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 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 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 -- It's a keyword, check if visible in tree (invisible "all" or "tree" = hidden in tree) local keyword_info = keywords[keyword_base] local inv = keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") 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 = "from" local current_keyword_modifiers = {} local current_container = nil -- Helper to track keyword usage at top level local function track_keyword_usage(keyword, target_lang, source_lang) if not is_toplevel then return end if not __state.toplevel_keyword_stats[keyword] then __state.toplevel_keyword_stats[keyword] = { count = 0, target_langs = {}, source_langs = {}, } end local keyword_data = __state.toplevel_keyword_stats[keyword] keyword_data.count = keyword_data.count + 1 local target_code = target_lang:getCode() keyword_data.target_langs[target_code] = (keyword_data.target_langs[target_code] or 0) + 1 if source_lang then local source_code = source_lang:getCode() keyword_data.source_langs[source_code] = (keyword_data.source_langs[source_code] or 0) + 1 end end local function ensure_container() if not current_container or current_container.keyword ~= current_keyword then current_container = { keyword = current_keyword, keyword_info = M.data.keywords[current_keyword], 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 = {} for k, v in pairs(M.data.keywords[current_keyword]) do current_container.keyword_info[k] = v end current_container.keyword_info.text = labels.text current_container.keyword_info.phrase = labels.phrase end end end for i = 2, #args do local param = args[i] if is_keyword(param) then local keyword, modifiers = EtymonParser.parse_keyword_modifiers(param) 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 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, lang) if etymon_data then -- Track keyword usage at top level track_keyword_usage(current_keyword, lang, etymon_data.lang) local term_node = {} -- Handle suppress_term (-) and unknown_term (empty) directly if etymon_data.suppress_term or etymon_data.unknown_term then 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 term_node.suppress_term = etymon_data.suppress_term term_node.unknown_term = etymon_data.unknown_term term_node.is_family = etymon_data.is_family term_node.is_uncertain = etymon_data.unc term_node.ref = etymon_data.ref term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.alt = etymon_data.alt term_node.pos = etymon_data.pos term_node.lit = etymon_data.lit term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll else -- Regular term: fetch arguments from page local etymon_args, page_of, resolved_etymon_id, descendants_check = DataRetriever.get_etymon_args(etymon_data, is_toplevel) if etymon_data.id and etymon_args == M.data.STATUS.MISSING and not etymon_data.ety then 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 local available_ids = __state.available_etymon_ids[base_key] or {} if #available_ids > 0 then __state.has_mismatched_id = true end end -- 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 track_keyword_usage(inline_keyword, etymon_data.lang, inline_etymon.lang) 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 ensure_container() -- Check if current keyword has no_child_categories - if so, stop recursion local keyword_info = current_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.id = etymon_data.id term_node.etymon_id = resolved_etymon_id -- The actual etymon id when resolved via senseid term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.pos = etymon_data.pos term_node.alt = etymon_data.alt term_node.ref = etymon_data.ref term_node.is_uncertain = etymon_data.unc term_node.override = etymon_data.override term_node.page_of = page_of term_node.aftype = etymon_data.aftype term_node.postype = etymon_data.postype term_node.bor = etymon_data.bor term_node.lbor = etymon_data.lbor term_node.slbor = etymon_data.slbor term_node.lit = etymon_data.lit term_node.is_family = etymon_data.is_family term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll 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(current_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, pos = node.pos, 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 local function track_ranges(base_key, value, ranges, lang_code) M.track("etymon/" .. base_key .. "/" .. value) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. value) end for _, range in ipairs(ranges) do local matches = false if range.min and range.max then matches = value >= range.min and value <= range.max elseif range.min then matches = value >= range.min elseif range.max then matches = value <= range.max elseif range.exact then matches = value == range.exact end if matches then M.track("etymon/" .. base_key .. "/" .. range.label) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. range.label) end break end end 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() 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 ety_data_tree = export.get_tree(lang, display_title or 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 rfe = args.rfe local page_data = Util.get_page_data() if not title then title = page_data.pagename if page_data.namespace == "Từ tái tạo" then title = "*" .. title end end local current_L2 = M.pages.get_current_L2() if current_L2 then local norm_lang = Util.get_norm_lang(lang) local norm_name = ucfirst(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("Ngôn ngữ '" .. lang_desc .. "' không khớp với đầu mục L2 (" .. current_L2 .. ").") end end local ety_data_tree = export.get_tree(lang, title, etymon_args, { validate = true, pos = args.pos, id = id, json = args.json, }) 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, ref = parsed_etydate.ref or {}, refn = parsed_etydate.refn or { maxindex = 0 } } if etydate_args.refn then local max = 0 for k, v in pairs(etydate_args.refn) do if type(k) == "number" and k > max then max = k end end etydate_args.refn.maxindex = max end ety_data_tree.etydate = M.etydate.format_etydate(etydate_args) -- Parse and store references separately for text rendering local refs_text = "" for _, ref in ipairs(etydate_args.ref) do refs_text = refs_text .. (refs_text ~= "" and "" or "") .. ref end if refs_text ~= "" then ety_data_tree.etydate_refs = M.references.parse_references(refs_text) end 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 -- Check if there are any visible children in tree (invisible "all" or "tree" = hidden in tree) local has_visible_children = false for _, child in ipairs(ety_data_tree.children or {}) do local child_keyword_info = child.keyword_info local inv = child_keyword_info and child_keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") then has_visible_children = true break end end local tree_disallowed = lang_exc and lang_exc.disallow and lang_exc.disallow.tree local anchor = M.anchors.etymonid(lang, id, { no_tree = args.notree, title = title, empty_tree = (not has_visible_children) or tree_disallowed }) table.insert(output, anchor) 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 table.insert(output, M.text.render({ data_tree = ety_data_tree, format_term_func = Util.format_term, max_depth = max_depth, stop_at_blue_link = stop_at_blue_link, curr_page = page_data.pagename, nodot = args.nodot, stop_at_lang = stop_at_lang, stop_at_lang_or_bluelink = stop_at_lang_or_bluelink, })) end if rfe then local rfe_param_mods = { nocat = { type = "boolean" }, sort = {}, y = {}, m = {}, fragment = {}, section = {}, box = { type = "boolean" }, noes = { type = "boolean" }, } local function generate_rfe_obj(rfe_text) -- Check if it's a boolean true value if M.yesno(rfe_text, false) then return { is_boolean = true } else return { text = rfe_text } end end local rfe_with_defaults = Util.add_boolean_defaults(rfe, rfe_param_mods) local parsed_rfe = M.parse_utilities.parse_inline_modifiers(rfe_with_defaults, { param_mods = rfe_param_mods, generate_obj = generate_rfe_obj }) local rfe_args = { [1] = lang:getCode(), nocat = parsed_rfe.nocat, sort = parsed_rfe.sort, y = parsed_rfe.y, m = parsed_rfe.m, fragment = parsed_rfe.fragment, section = parsed_rfe.section, box = parsed_rfe.box, noes = parsed_rfe.noes, } if not parsed_rfe.is_boolean then rfe_args[2] = parsed_rfe.text end table.insert(output, frame:expandTemplate({ title = "rfe", args = rfe_args })) end if Util.is_content_page() and __state.max_depth_reached > 0 then local lang_code = lang:getCode() local depth_ranges = { { min = 50, label = "extremely-deep" }, { min = 20, label = "20+" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { max = 2, label = "1-2" } } local node_ranges = { { min = 100, label = "extremely-large" }, { min = 50, label = "50+" }, { min = 20, max = 49, label = "20-49" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { max = 4, label = "1-4" } } local language_ranges = { { min = 10, label = "10+" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { exact = 2, label = "2" }, { exact = 1, label = "1" } } track_ranges("depth", __state.max_depth_reached, depth_ranges, lang_code) track_ranges("nodes", __state.total_nodes, node_ranges, lang_code) local unique_languages = 0 for _ in pairs(__state.language_count) do unique_languages = unique_languages + 1 end track_ranges("unique-languages", unique_languages, language_ranges, lang_code) if __state.total_nodes == __state.max_depth_reached + 1 then track_ranges("linear-depth", __state.max_depth_reached, depth_ranges, lang_code) end end local categories = {} if Util.is_content_page() then local should_suppress_categories = lang_exc and lang_exc.suppress_categories if not should_suppress_categories and not args.nocat then categories = M.categories.render({ 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, }) end local target_lang_code = lang:getCode() for keyword, keyword_data in pairs(__state.toplevel_keyword_stats) do -- Track keyword globally M.track("etymon/keyword/" .. keyword) -- Track keyword per target language M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code) -- Track keyword per source language for source_code, count in pairs(keyword_data.source_langs) do M.track("etymon/keyword/" .. keyword .. "/source/" .. source_code) -- Track keyword per target+source combination M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code .. "/source/" .. source_code) end end if tree then table.insert(categories, "Trang có cây từ nguyên") table.insert(categories, "Mục từ có cây từ nguyên " .. lang:getCanonicalName()) end if text then table.insert(categories, lang:getCanonicalName() .. " entries with etymology texts") end if args.exnihilo then table.insert(categories, lang:getCanonicalName() .. " terms coined ex nihilo") end if __state.toplevel_has_inline_etymology then table.insert(categories, "Pages with inline etymon for redlinks") end if __state.toplevel_redundant_etymology then table.insert(categories, "Pages with redundant inline etymon") end if __state.toplevel_idless_etymon then table.insert(categories, "Trang có cây từ nguyên thiếu ID") end if __state.has_mismatched_id then table.insert(categories, lang:getCanonicalName() .. " entries referencing etymons with mismatched IDs") end end if #categories > 0 then table.insert(output, M.utilities.format_categories(categories, lang)) end if __state.warnings then for _, warning in ipairs(__state.warnings) do table.insert(output, "\n" .. warning) end end return table.concat(output) end return export lmr8pgx7ykhw4tu51hga1betb67oh1q 2344440 2344436 2026-04-12T07:09:29Z TheHighFighter2 42988 2344440 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. Tác giả: - Triển khai ban đầu: [[Thành viên:Ioaxxere]] - Tái cấu trúc lại mô đun (tháng 9 năm 2025): [[Thành viên:Fenakhay]] ([[:en: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 ]=] local export = {} local etymon_data_module = "Module:etymon/data" local etymon_text_module = "Module:etymon/text" local etymon_tree_module = "Module:etymon/tree" local etymon_categories_module = "Module:etymon/categories" local etymon_descendants_module = "Module:etymon/descendants" local ucfirst = require("Module:string utilities").ucfirst 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, max_depth_reached = 0, total_nodes = 0, language_count = {}, toplevel_keyword_stats = {}, warnings = {}, } local loader = require("Module:module loader") local M = loader.init({ require = { data = etymon_data_module, tree = etymon_tree_module, text = etymon_text_module, categories = etymon_categories_module, descendants = etymon_descendants_module, 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", track = "Module:debug/track", 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 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 -- 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 -- Centralized term formatting: handles suppress_term, unknown_term, 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 opts.pos ~= "suppress" then link_params.pos = term.pos 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 -- 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) .. " nominalization of" local phrase = M.en_utilities.add_indefinite_article(adj .. " 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 = { keywords = { "affix", "surf", "univerbation" } } }, conj = {}, -- conjunction for alternatives: "and", "or", "and/or", etc. g = { restrict = { keywords = { "nominalization" } } }, } -- Term modifier definitions EtymonParser.etymon_param_mods = { id = {}, t = {}, tr = {}, ts = {}, q = {}, qq = {}, l = {}, ll = {}, pos = {}, alt = {}, ety = {}, lit = {}, unc = { type = "boolean" }, ref = {}, aftype = { restrict = { keywords = { "affix", "surf", "afeq" } } }, postype = {}, bor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, slbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, lbor = { type = "boolean", restrict = { keywords = { "affix", "surf" } } }, } 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 and 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 -- 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, } -- Validate modifiers against restrictions EtymonParser.check_modifier_restrictions(modifiers, canonical_keyword, EtymonParser.keyword_param_mods) return canonical_keyword, modifiers end function EtymonParser.parse_balanced_segments(str) local segments = {} local current = "" local depth = 0 local i = 1 while i <= #str do local char = str:sub(i, i) if char == "<" then if depth == 0 and current ~= "" then table.insert(segments, current) current = "" end depth = depth + 1 current = current .. char elseif char == ">" then current = current .. char depth = depth - 1 if depth == 0 then table.insert(segments, current) current = "" elseif depth < 0 then error("Unbalanced brackets in etymon: unexpected '>'") end else current = current .. char end i = i + 1 end if depth ~= 0 then error("Unbalanced brackets in etymon: missing '>'") end if current ~= "" then table.insert(segments, current) end return segments end function EtymonParser.parse_inline_ety(ety_string, context_lang) local segments = EtymonParser.parse_balanced_segments(ety_string) if #segments == 0 then error("Empty inline etymology") end local keyword = M.string_utilities.trim(segments[1]) if not is_keyword(keyword, true) then error("Invalid keyword '" .. keyword .. "' in inline etymology <ety:" .. keyword .. "...>") end local args = { context_lang:getCode(), normalize_keyword(get_canonical_keyword(keyword)) } for i = 2, #segments do local segment = segments[i] if segment:sub(1, 1) == "<" and segment:sub(-1) == ">" then local inner = segment:sub(2, -2) if inner ~= "" then table.insert(args, inner) end elseif is_keyword(segment, true) then -- Handle keywords that appear between bracketed segments table.insert(args, normalize_keyword(get_canonical_keyword(get_keyword(segment, true)))) 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 if rest == "" then M.track("etymon/term/empty") elseif rest == "?" then M.track("etymon/term/question-mark") elseif rest == "-" then M.track("etymon/term/hyphen") end if 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 == "") 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 etymons_in_group = {} local keywords = M.data.keywords local function checkGroup() if keywords[current_keyword] and keywords[current_keyword].is_group and current_keyword ~= "affix" and current_keyword ~= "surf" and current_keyword ~= "afeq" and #etymons_in_group <= 1 then error("Detected `:" .. current_keyword .. "` group with fewer than two etymons.") end etymons_in_group = {} 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 error("Invalid keyword '" .. param .. "'. Did you mean a valid keyword like ':bor', ':inh', etc.?") elseif is_keyword(param) then checkGroup() current_keyword = get_canonical_keyword(get_keyword(param)) else local etymon_data = EtymonParser.parse_etymon(param, lang) if etymon_data then table.insert(etymons_in_group, param) local param_lang = etymon_data.lang if etymon_data.is_family and current_keyword == "inherited" then error("`:inh` does not support family codes; use a specific language.") end if etymon_data.is_family and not etymon_data.suppress_term then error("Family codes require suppressed term (use family:-).") end if current_keyword == "from" and param_lang:getFullCode() ~= lang:getFullCode() then error("`:from` is for same-language derivation, but language does not match. " .. "Expected '" .. lang:getFullCode() .. "', got '" .. param_lang:getFullCode() .. "'.") elseif current_keyword == "inherited" then M.etymology.check_ancestor(lang, param_lang) end -- 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(etymons_in_group, param) end end end checkGroup() end local DataRetriever = {} -- 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 has_idless_etymon = false 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 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("^Etymology") then active_etymon_args = nil end elseif node_class == "template" 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 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 has_idless_etymon = true -- 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 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 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 -- Error if multiple etymons exist and at least one is missing an id if #found_templates_for_lang > 1 and has_idless_etymon then error("Page '[[" .. tostring(etymon_page) .. "]]' has " .. #found_templates_for_lang .. " etymon templates for " .. etymon_lang:getCanonicalName() .. ", but at least one is missing an id. All etymons must have unique IDs when there are multiple.") 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 -- 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) 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 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 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 return __state.cached_etymon_args[matched_key], __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 "*" 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 return __state.single_etymons[base_key], __state.cached_etymon_pages[base_key .. ":" .. only_id], nil, descendants_check elseif count > 1 then local id_list = {} for _, id_data in ipairs(ids) do local id = type(id_data) == "table" and id_data.id or id_data if id and id ~= "" then table.insert(id_list, "\"" .. id .. "\"") end end local suggestion_text = "" if #id_list > 0 then suggestion_text = " Available IDs: " .. table.concat(id_list, ", ") .. "." end Util.add_warning("Etymology link to '[[" .. page .. "]]' is ambiguous. The page has " .. count .. " etymon templates for " .. norm_lang:getCanonicalName() .. ". Please specify an ID." .. suggestion_text, true) return M.data.STATUS.AMBIGUOUS, nil, nil, nil else return M.data.STATUS.MISSING, nil, nil, nil end end 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 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 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 -- It's a keyword, check if visible in tree (invisible "all" or "tree" = hidden in tree) local keyword_info = keywords[keyword_base] local inv = keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") 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 = "from" local current_keyword_modifiers = {} local current_container = nil -- Helper to track keyword usage at top level local function track_keyword_usage(keyword, target_lang, source_lang) if not is_toplevel then return end if not __state.toplevel_keyword_stats[keyword] then __state.toplevel_keyword_stats[keyword] = { count = 0, target_langs = {}, source_langs = {}, } end local keyword_data = __state.toplevel_keyword_stats[keyword] keyword_data.count = keyword_data.count + 1 local target_code = target_lang:getCode() keyword_data.target_langs[target_code] = (keyword_data.target_langs[target_code] or 0) + 1 if source_lang then local source_code = source_lang:getCode() keyword_data.source_langs[source_code] = (keyword_data.source_langs[source_code] or 0) + 1 end end local function ensure_container() if not current_container or current_container.keyword ~= current_keyword then current_container = { keyword = current_keyword, keyword_info = M.data.keywords[current_keyword], 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 = {} for k, v in pairs(M.data.keywords[current_keyword]) do current_container.keyword_info[k] = v end current_container.keyword_info.text = labels.text current_container.keyword_info.phrase = labels.phrase end end end for i = 2, #args do local param = args[i] if is_keyword(param) then local keyword, modifiers = EtymonParser.parse_keyword_modifiers(param) 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 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, lang) if etymon_data then -- Track keyword usage at top level track_keyword_usage(current_keyword, lang, etymon_data.lang) local term_node = {} -- Handle suppress_term (-) and unknown_term (empty) directly if etymon_data.suppress_term or etymon_data.unknown_term then 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 term_node.suppress_term = etymon_data.suppress_term term_node.unknown_term = etymon_data.unknown_term term_node.is_family = etymon_data.is_family term_node.is_uncertain = etymon_data.unc term_node.ref = etymon_data.ref term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.alt = etymon_data.alt term_node.pos = etymon_data.pos term_node.lit = etymon_data.lit term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll else -- Regular term: fetch arguments from page local etymon_args, page_of, resolved_etymon_id, descendants_check = DataRetriever.get_etymon_args(etymon_data, is_toplevel) if etymon_data.id and etymon_args == M.data.STATUS.MISSING and not etymon_data.ety then 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 local available_ids = __state.available_etymon_ids[base_key] or {} if #available_ids > 0 then __state.has_mismatched_id = true end end -- 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 track_keyword_usage(inline_keyword, etymon_data.lang, inline_etymon.lang) 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 ensure_container() -- Check if current keyword has no_child_categories - if so, stop recursion local keyword_info = current_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.id = etymon_data.id term_node.etymon_id = resolved_etymon_id -- The actual etymon id when resolved via senseid term_node.t = etymon_data.t term_node.tr = etymon_data.tr term_node.ts = etymon_data.ts term_node.pos = etymon_data.pos term_node.alt = etymon_data.alt term_node.ref = etymon_data.ref term_node.is_uncertain = etymon_data.unc term_node.override = etymon_data.override term_node.page_of = page_of term_node.aftype = etymon_data.aftype term_node.postype = etymon_data.postype term_node.bor = etymon_data.bor term_node.lbor = etymon_data.lbor term_node.slbor = etymon_data.slbor term_node.lit = etymon_data.lit term_node.is_family = etymon_data.is_family term_node.q = etymon_data.q term_node.qq = etymon_data.qq term_node.l = etymon_data.l term_node.ll = etymon_data.ll 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(current_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, pos = node.pos, 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 local function track_ranges(base_key, value, ranges, lang_code) M.track("etymon/" .. base_key .. "/" .. value) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. value) end for _, range in ipairs(ranges) do local matches = false if range.min and range.max then matches = value >= range.min and value <= range.max elseif range.min then matches = value >= range.min elseif range.max then matches = value <= range.max elseif range.exact then matches = value == range.exact end if matches then M.track("etymon/" .. base_key .. "/" .. range.label) if lang_code then M.track("etymon/lang/" .. lang_code .. "/" .. base_key .. "/" .. range.label) end break end end 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() 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 ety_data_tree = export.get_tree(lang, display_title or 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 rfe = args.rfe local page_data = Util.get_page_data() if not title then title = page_data.pagename if page_data.namespace == "Từ tái tạo" then title = "*" .. title end end local current_L2 = M.pages.get_current_L2() if current_L2 then local norm_lang = Util.get_norm_lang(lang) local norm_name = ucfirst(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("Ngôn ngữ '" .. lang_desc .. "' không khớp với đầu mục L2 (" .. current_L2 .. ").") end end local ety_data_tree = export.get_tree(lang, title, etymon_args, { validate = true, pos = args.pos, id = id, json = args.json, }) 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, ref = parsed_etydate.ref or {}, refn = parsed_etydate.refn or { maxindex = 0 } } if etydate_args.refn then local max = 0 for k, v in pairs(etydate_args.refn) do if type(k) == "number" and k > max then max = k end end etydate_args.refn.maxindex = max end ety_data_tree.etydate = M.etydate.format_etydate(etydate_args) -- Parse and store references separately for text rendering local refs_text = "" for _, ref in ipairs(etydate_args.ref) do refs_text = refs_text .. (refs_text ~= "" and "" or "") .. ref end if refs_text ~= "" then ety_data_tree.etydate_refs = M.references.parse_references(refs_text) end 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 -- Check if there are any visible children in tree (invisible "all" or "tree" = hidden in tree) local has_visible_children = false for _, child in ipairs(ety_data_tree.children or {}) do local child_keyword_info = child.keyword_info local inv = child_keyword_info and child_keyword_info.invisible if not (inv == "all" or inv == true or inv == "tree") then has_visible_children = true break end end local tree_disallowed = lang_exc and lang_exc.disallow and lang_exc.disallow.tree local anchor = M.anchors.etymonid(lang, id, { no_tree = args.notree, title = title, empty_tree = (not has_visible_children) or tree_disallowed }) table.insert(output, anchor) 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 table.insert(output, M.text.render({ data_tree = ety_data_tree, format_term_func = Util.format_term, max_depth = max_depth, stop_at_blue_link = stop_at_blue_link, curr_page = page_data.pagename, nodot = args.nodot, stop_at_lang = stop_at_lang, stop_at_lang_or_bluelink = stop_at_lang_or_bluelink, })) end if rfe then local rfe_param_mods = { nocat = { type = "boolean" }, sort = {}, y = {}, m = {}, fragment = {}, section = {}, box = { type = "boolean" }, noes = { type = "boolean" }, } local function generate_rfe_obj(rfe_text) -- Check if it's a boolean true value if M.yesno(rfe_text, false) then return { is_boolean = true } else return { text = rfe_text } end end local rfe_with_defaults = Util.add_boolean_defaults(rfe, rfe_param_mods) local parsed_rfe = M.parse_utilities.parse_inline_modifiers(rfe_with_defaults, { param_mods = rfe_param_mods, generate_obj = generate_rfe_obj }) local rfe_args = { [1] = lang:getCode(), nocat = parsed_rfe.nocat, sort = parsed_rfe.sort, y = parsed_rfe.y, m = parsed_rfe.m, fragment = parsed_rfe.fragment, section = parsed_rfe.section, box = parsed_rfe.box, noes = parsed_rfe.noes, } if not parsed_rfe.is_boolean then rfe_args[2] = parsed_rfe.text end table.insert(output, frame:expandTemplate({ title = "rfe", args = rfe_args })) end if Util.is_content_page() and __state.max_depth_reached > 0 then local lang_code = lang:getCode() local depth_ranges = { { min = 50, label = "extremely-deep" }, { min = 20, label = "20+" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { max = 2, label = "1-2" } } local node_ranges = { { min = 100, label = "extremely-large" }, { min = 50, label = "50+" }, { min = 20, max = 49, label = "20-49" }, { min = 10, max = 19, label = "10-19" }, { min = 5, max = 9, label = "5-9" }, { max = 4, label = "1-4" } } local language_ranges = { { min = 10, label = "10+" }, { min = 5, max = 9, label = "5-9" }, { min = 3, max = 4, label = "3-4" }, { exact = 2, label = "2" }, { exact = 1, label = "1" } } track_ranges("depth", __state.max_depth_reached, depth_ranges, lang_code) track_ranges("nodes", __state.total_nodes, node_ranges, lang_code) local unique_languages = 0 for _ in pairs(__state.language_count) do unique_languages = unique_languages + 1 end track_ranges("unique-languages", unique_languages, language_ranges, lang_code) if __state.total_nodes == __state.max_depth_reached + 1 then track_ranges("linear-depth", __state.max_depth_reached, depth_ranges, lang_code) end end local categories = {} if Util.is_content_page() then local should_suppress_categories = lang_exc and lang_exc.suppress_categories if not should_suppress_categories and not args.nocat then categories = M.categories.render({ 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, }) end local target_lang_code = lang:getCode() for keyword, keyword_data in pairs(__state.toplevel_keyword_stats) do -- Track keyword globally M.track("etymon/keyword/" .. keyword) -- Track keyword per target language M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code) -- Track keyword per source language for source_code, count in pairs(keyword_data.source_langs) do M.track("etymon/keyword/" .. keyword .. "/source/" .. source_code) -- Track keyword per target+source combination M.track("etymon/keyword/" .. keyword .. "/target/" .. target_lang_code .. "/source/" .. source_code) end end if tree then table.insert(categories, "Trang có cây từ nguyên") table.insert(categories, "Mục từ có cây từ nguyên " .. lang:getCanonicalName()) end if text then table.insert(categories, "Mục từ có văn bản giải thích từ nguyên " .. lang:getCanonicalName()) end if args.exnihilo then table.insert(categories, lang:getCanonicalName() .. " terms coined ex nihilo") end if __state.toplevel_has_inline_etymology then table.insert(categories, "Pages with inline etymon for redlinks") end if __state.toplevel_redundant_etymology then table.insert(categories, "Pages with redundant inline etymon") end if __state.toplevel_idless_etymon then table.insert(categories, "Trang có nguyên từ thiếu ID") end if __state.has_mismatched_id then table.insert(categories, lang:getCanonicalName() .. " entries referencing etymons with mismatched IDs") end end if #categories > 0 then table.insert(output, M.utilities.format_categories(categories, lang)) end if __state.warnings then for _, warning in ipairs(__state.warnings) do table.insert(output, "\n" .. warning) end end return table.concat(output) end return export dt4d8dgp6y6mfgvdwa78t9i2h34mum0 𞗣𞗖𞗡𞗫𞗜 0 332695 2344298 2217736 2026-04-11T17:12:39Z WhoAlone 40420 /* Tham khảo */ 2344298 wikitext text/x-wiki =={{langname|aav-bhu}}== ==={{ĐM|noun}}=== {{head|aav-bhu|Danh từ|tr=kanči}} # [[rổ]]. ==={{ĐM|ref}}=== * N. Ramaswamy (1992). ''Bhumij Grammar''. {{C|aav-bhu|Dụng cụ}} lgsz0dm3u8q6fj153to0kk06bj9qrh6 Bản mẫu:R:blt:TĐTV 10 339078 2344374 2228345 2026-04-12T04:17:50Z Higashizakura 36666 2344374 wikitext text/x-wiki {{Chú thích sách |author1=Hoàng Trần Nghịch |author2=Tòng Kim Ân |title=Từ điển Thái - Việt |url=https://nguyenvietkhoi.github.io/SinicIME/TayDamDict |year=1991 |publisher=Nhà xuất bản Khoa học xã hội |location=Hà Nội}} <noinclude>{{tài liệu}}{{tcat}}</noinclude> 8fjx157jodfy0j4dg5ln40fu4xa3f14 Mô đun:etymon/data 828 378443 2344311 2317908 2026-04-12T01:20:16Z TheHighFighter2 42988 2344311 Scribunto text/plain local export = {} export.STATUS = { OK = "ok", INLINE = "inline", MISSING = "missing", REDLINK = "redlink", AMBIGUOUS = "ambiguous", } export.TRANSITIVE = { ALWAYS = "always", -- always recurse into children NEVER = "never", -- never recurse into children CROSS_LANG = "cross_lang", -- only recurse when source lang differs from target lang (but pos chain continues) CROSS_LANG_NO_INTERNAL_SOURCE = "cross_lang_no_internal_source", -- like CROSS_LANG, but source breaks for internal derivations in the same language context } -- Deep merge tables (nested tables are merged recursively, later values override earlier) local function deep_merge(...) local result = {} for _, t in ipairs({ ... }) do for k, v in pairs(t) do if type(v) == "table" and type(result[k]) == "table" then result[k] = deep_merge(result[k], v) else result[k] = v end end end return result end local function make_glossary_link(term, display_text) if not term then return display_text end return "[[Phụ lục:Từ điển thuật ngữ#" .. term:gsub(" ", "_") .. "|" .. display_text .. "]]" end -- Extract base word and connector from text like "Borrowed from" or "calque of" local function split_glossary_text(text) for _, pattern in ipairs({ "^(.-)(%s+[Oo][Ff])$", "^(.-)(%s+[Ff][Rr][Oo][Mm])$" }) do local base, rest = text:match(pattern) if base then return base, rest end end return text, "" end local TRANSITIVE = export.TRANSITIVE local function create_keyword(opts) local entry = { is_group = opts.is_group or false, abbrev = opts.abbrev, glossary = opts.glossary, transitive = opts.transitive or TRANSITIVE.ALWAYS, -- default "always" inherited_chain = opts.inherited_chain or false, affix_categories = opts.affix_categories or false, borrowing_type = opts.borrowing_type, specialized_borrowing = opts.specialized_borrowing, toplevel_category = opts.toplevel_category, no_child_categories = opts.no_child_categories or false, source_category_type = opts.source_category_type, invisible = (opts.invisible == true and "all") or opts.invisible or false, pos_override = opts.pos_override, new_sentence = opts.new_sentence or false, separate_clause = opts.separate_clause or false, aliases = opts.aliases, } -- Only set text/phrase when visible in text (invisible ~= "all" and ~= "text") local inv = entry.invisible if inv ~= "all" and inv ~= "text" then entry.phrase = opts.phrase if opts.text then if opts.glossary then local base_word, rest = split_glossary_text(opts.text) entry.text = make_glossary_link(opts.glossary, base_word) .. rest else entry.text = opts.text end end end return entry end -- Shared defaults for keyword groups local DEFAULTS = { -- Keywords that pass through inheritance chain inheritance = { transitive = TRANSITIVE.ALWAYS, inherited_chain = true, }, -- Standard transitive derivation transitive = { transitive = TRANSITIVE.ALWAYS, }, -- Standard for internal derivations: transitive across languages, but not within them internal_derivation = { transitive = TRANSITIVE.CROSS_LANG, }, -- Borrowing keywords borrowing = { transitive = TRANSITIVE.ALWAYS, }, -- Affix group keywords (compound words, blends, etc.) affix_group = { is_group = true, transitive = TRANSITIVE.CROSS_LANG, affix_categories = true, }, -- Calque-like keywords (calque, partial calque, semantic loan) calque_like = { transitive = TRANSITIVE.NEVER, no_child_categories = true, new_sentence = true, }, -- Non-transitive influence influence_like = { transitive = TRANSITIVE.NEVER, no_child_categories = true, }, } export.keywords = { -- -- Inheritance keywords -- ["from"] = create_keyword(deep_merge(DEFAULTS.inheritance, { text = "From", phrase = "from", })), ["inherited"] = create_keyword(deep_merge(DEFAULTS.inheritance, { text = "Inherited from", phrase = "from", glossary = "inherited", aliases = { "inh" }, })), -- -- Basic derivation keywords -- ["uder"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "From", phrase = "from", toplevel_category = "undefined derivations", })), ["derived"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Derived from", phrase = "from", abbrev = "der.", glossary = "derived terms", aliases = { "der" }, })), -- -- Affix/compound group keywords -- ["affix"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "From", phrase = "from", aliases = { "af" }, })), ["surf"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "By surface analysis,", phrase = "by surface analysis,", abbrev = "surf.", glossary = "surface analysis", new_sentence = true, invisible = "tree", })), ["blend"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "Blend of", phrase = "a blend of", abbrev = "blend", glossary = "blend", toplevel_category = "blends", })), ["univerbation"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "Univerbation of", phrase = "univerbation of", abbrev = "univ.", glossary = "univerbation", toplevel_category = "univerbations", aliases = { "univ" }, })), -- -- Borrowing keywords -- ["bor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Borrowed from", phrase = "borrowed from", abbrev = "bor.", glossary = "loanword", borrowing_type = "borrowed", aliases = { "borrowed" }, })), ["lbor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Learned borrowing from", phrase = "a learned borrowing from", abbrev = "lbor.", glossary = "learned borrowing", specialized_borrowing = "learned", })), ["obor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Orthographic borrowing from", phrase = "an orthographic borrowing from", abbrev = "obor.", glossary = "orthographic borrowing", specialized_borrowing = "orthographic", })), ["slbor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Semi-learned borrowing from", phrase = "a semi-learned borrowing from", abbrev = "slbor.", glossary = "semi-learned borrowing", specialized_borrowing = "semi-learned", })), ["ubor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Unadapted borrowing from", phrase = "an unadapted borrowing from", abbrev = "ubor.", glossary = "unadapted borrowing", specialized_borrowing = "unadapted", })), -- -- Calque-like keywords (non-transitive, start new sentence) -- ["calque"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Calque of", phrase = "a calque of", abbrev = "calq.", glossary = "calque", specialized_borrowing = "calque", aliases = { "cal", "clq" }, })), ["partial calque"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Partial calque of", phrase = "a partial calque of", abbrev = "pcalq.", glossary = "partial calque", specialized_borrowing = "partial-calque", aliases = { "pcal" }, })), ["semantic loan"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Semantic loan of", phrase = "a semantic loan of", abbrev = "sl.", glossary = "semantic loan", specialized_borrowing = "semantic-loan", aliases = { "sl" }, })), -- -- Influence keywords (non-transitive, separate clause) -- ["influence"] = create_keyword(deep_merge(DEFAULTS.influence_like, { text = "Influenced by", phrase = "influenced by", abbrev = "influ.", glossary = "contamination", separate_clause = true, })), -- -- Morphological derivation keywords -- ["clipping"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Clipping of", phrase = "clipping of", abbrev = "clip.", glossary = "clipping", toplevel_category = "clippings", aliases = { "clip" }, })), ["ellipsis"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Ellipsis of", phrase = "ellipsis of", abbrev = "ellip.", glossary = "ellipsis", toplevel_category = "ellipses", aliases = { "ellip" }, })), ["back-formation"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Back-formation from", phrase = "a back-formation from", abbrev = "bf.", glossary = "back-formation", toplevel_category = "back-formations", aliases = { "bf" }, })), ["nominalization"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Nominalization of", phrase = "a nominalization of", abbrev = "nom.", glossary = "nominalization", toplevel_category = "nominalizations", aliases = { "nom" }, })), ["transliteration"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Transliteration of", phrase = "borrowed from", abbrev = "translit.", glossary = "transliteration", aliases = { "translit" }, })), ["vrd"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Vṛddhi derivative of", phrase = "a vṛddhi derivative of", abbrev = "vṛd.", glossary = "vṛddhi derivative", })), ["apheretic"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Apheretic form of", phrase = "an apheretic form of", abbrev = "aph.", glossary = "apheresis", aliases = { "apheresis", "aphetic" }, })), ["denominal"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Denominal verb from", phrase = "denominal verb from", abbrev = "denom.", glossary = "denominal", toplevel_category = "denominal verbs", aliases = { "denom" }, })), ["deverbal"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Deverbal from", phrase = "deverbal from", abbrev = "deverb.", glossary = "deverbal", toplevel_category = "deverbals", })), ["reduplication"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Reduplication of", phrase = "reduplication of", abbrev = "redup.", glossary = "reduplication", toplevel_category = "reduplications", aliases = { "redup" }, })), ["abbreviation"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Abbreviation of", phrase = "abbreviation of", abbrev = "abbr.", glossary = "abbreviation", aliases = { "abbr" }, })), ["acronym"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Acronym of", phrase = "acronym of", abbrev = "acronym", glossary = "acronym", aliases = { "acro" }, })), ["initialism"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Initialism of", phrase = "initialism of", abbrev = "init.", glossary = "initialism", aliases = { "init" }, })), ["metathesis"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Metathesis of", phrase = "metathesis of", abbrev = "meta.", glossary = "metathesis", toplevel_category = "words derived through metathesis", aliases = { "meta" }, })), -- -- Invisible keywords (no text output) -- ["root"] = create_keyword { transitive = TRANSITIVE.ALWAYS, invisible = "all", pos_override = "root", }, ["afeq"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "From", phrase = "from", transitive = TRANSITIVE.NEVER, invisible = "all", })), } local aliases_to_register = {} local canonical_aliases = {} -- Map every keyword (canonical or alias) to its canonical form for consistent checks and tracking. export.keyword_canonical = {} for name, keyword_data in pairs(export.keywords) do export.keyword_canonical[name] = name if keyword_data.aliases then canonical_aliases[name] = keyword_data.aliases for _, alias in ipairs(keyword_data.aliases) do if export.keywords[alias] then error("Alias '" .. alias .. "' defined in keyword '" .. name .. "' collides with existing keyword '" .. alias .. "'.") end if aliases_to_register[alias] then error("Alias '" .. alias .. "' defined in keyword '" .. name .. "' is already claimed by another keyword.") end aliases_to_register[alias] = keyword_data export.keyword_canonical[alias] = name end keyword_data.aliases = nil end end for alias, data in pairs(aliases_to_register) do export.keywords[alias] = data end -- -- Language exception presets -- local EXCEPTION_PRESETS = { -- Fully disallowed: no tree, no text, no categories disallowed = { disallow = { tree = true, text = true }, suppress_categories = true, }, -- Suppress transliteration only no_translit = { suppress_tr = true, }, -- Suppress all categories only no_categories = { suppress_categories = true, }, } --[=[ Available exception options: disallow = { Related options for disallowing output: tree Disallow etymology trees for this language text Disallow etymology text generation for this language ref Reference link shown when tree/text is disallowed } suppress_tr Suppress transliteration in links suppress_categories Suppress all category generation normalize_to Normalize language code to a different code normalize_from_families Apply normalization to languages in these families normalize_exclude_families Exclude these families from normalization keyword_overrides Per-keyword categorisation overrides (e.g. { ["af"] = { transitive = TRANSITIVE.NEVER } }) ]=] local function create_exception(preset, overrides) local base = preset and EXCEPTION_PRESETS[preset] or {} return deep_merge(base, overrides or {}) end export.config = { lang_exceptions = { ["zh"] = create_exception("disallowed", { disallow = { ref = "[[Wiktionary:Beer parlour/2025/May#Template:etymon for Chinese]]" }, suppress_tr = true, normalize_to = "zh", normalize_from_families = { "zhx" }, normalize_exclude_families = { "qfa-cnt" }, }), }, } -- Supported codes for the nominalization <g:code> modifier (subset of common gender/number-style codes) export.nominalization_g_codes = { ["m"] = "masculine", ["f"] = "feminine", ["n"] = "neuter", ["c"] = "common", ["gneut"] = "gender-neutral", ["s"] = "singular", ["p"] = "plural", ["d"] = "dual", ["pauc"] = "paucal", ["mf"] = "masculine or feminine", ["fm"] = "masculine or feminine", ["mfn"] = "masculine, feminine or neuter", ["mnf"] = "masculine, feminine or neuter", ["fmn"] = "masculine, feminine or neuter", ["fnm"] = "masculine, feminine or neuter", ["nmf"] = "masculine, feminine or neuter", ["nfm"] = "masculine, feminine or neuter", } -- -- Propagate keyword overrides to aliases -- if export.config.lang_exceptions then for lang_code, exception in pairs(export.config.lang_exceptions) do if exception.keyword_overrides then for canonical, aliases in pairs(canonical_aliases) do if exception.keyword_overrides[canonical] then local override_data = exception.keyword_overrides[canonical] for _, alias in ipairs(aliases) do if not exception.keyword_overrides[alias] then exception.keyword_overrides[alias] = override_data end end end end end end end return export 1wszme3odnt04424y6bzakrvbjay5q9 2344437 2344311 2026-04-12T06:28:33Z TheHighFighter2 42988 2344437 Scribunto text/plain local export = {} export.STATUS = { OK = "ok", INLINE = "inline", MISSING = "missing", REDLINK = "redlink", AMBIGUOUS = "ambiguous", } export.TRANSITIVE = { ALWAYS = "always", -- always recurse into children NEVER = "never", -- never recurse into children CROSS_LANG = "cross_lang", -- only recurse when source lang differs from target lang (but pos chain continues) CROSS_LANG_NO_INTERNAL_SOURCE = "cross_lang_no_internal_source", -- like CROSS_LANG, but source breaks for internal derivations in the same language context } -- Deep merge tables (nested tables are merged recursively, later values override earlier) local function deep_merge(...) local result = {} for _, t in ipairs({ ... }) do for k, v in pairs(t) do if type(v) == "table" and type(result[k]) == "table" then result[k] = deep_merge(result[k], v) else result[k] = v end end end return result end local function make_glossary_link(term, display_text) if not term then return display_text end return "[[Phụ lục:Từ điển thuật ngữ#" .. term:gsub(" ", "_") .. "|" .. display_text .. "]]" end -- Extract base word and connector from text like "Borrowed from" or "calque of" local function split_glossary_text(text) for _, pattern in ipairs({ "^(.-)(%s+[Oo][Ff])$", "^(.-)(%s+[Ff][Rr][Oo][Mm])$" }) do local base, rest = text:match(pattern) if base then return base, rest end end return text, "" end local TRANSITIVE = export.TRANSITIVE local function create_keyword(opts) local entry = { is_group = opts.is_group or false, abbrev = opts.abbrev, glossary = opts.glossary, transitive = opts.transitive or TRANSITIVE.ALWAYS, -- default "always" inherited_chain = opts.inherited_chain or false, affix_categories = opts.affix_categories or false, borrowing_type = opts.borrowing_type, specialized_borrowing = opts.specialized_borrowing, toplevel_category = opts.toplevel_category, no_child_categories = opts.no_child_categories or false, source_category_type = opts.source_category_type, invisible = (opts.invisible == true and "all") or opts.invisible or false, pos_override = opts.pos_override, new_sentence = opts.new_sentence or false, separate_clause = opts.separate_clause or false, aliases = opts.aliases, } -- Only set text/phrase when visible in text (invisible ~= "all" and ~= "text") local inv = entry.invisible if inv ~= "all" and inv ~= "text" then entry.phrase = opts.phrase if opts.text then if opts.glossary then local base_word, rest = split_glossary_text(opts.text) entry.text = make_glossary_link(opts.glossary, base_word) .. rest else entry.text = opts.text end end end return entry end -- Shared defaults for keyword groups local DEFAULTS = { -- Keywords that pass through inheritance chain inheritance = { transitive = TRANSITIVE.ALWAYS, inherited_chain = true, }, -- Standard transitive derivation transitive = { transitive = TRANSITIVE.ALWAYS, }, -- Standard for internal derivations: transitive across languages, but not within them internal_derivation = { transitive = TRANSITIVE.CROSS_LANG, }, -- Borrowing keywords borrowing = { transitive = TRANSITIVE.ALWAYS, }, -- Affix group keywords (compound words, blends, etc.) affix_group = { is_group = true, transitive = TRANSITIVE.CROSS_LANG, affix_categories = true, }, -- Calque-like keywords (calque, partial calque, semantic loan) calque_like = { transitive = TRANSITIVE.NEVER, no_child_categories = true, new_sentence = true, }, -- Non-transitive influence influence_like = { transitive = TRANSITIVE.NEVER, no_child_categories = true, }, } export.keywords = { -- -- Inheritance keywords -- ["from"] = create_keyword(deep_merge(DEFAULTS.inheritance, { text = "From", phrase = "from", })), ["inherited"] = create_keyword(deep_merge(DEFAULTS.inheritance, { text = "Inherited from", phrase = "from", glossary = "inherited", aliases = { "inh" }, })), -- -- Basic derivation keywords -- ["uder"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "From", phrase = "from", toplevel_category = "undefined derivations", })), ["derived"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Derived from", phrase = "from", abbrev = "der.", glossary = "derived terms", aliases = { "der" }, })), -- -- Affix/compound group keywords -- ["affix"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "Từ", phrase = "từ", aliases = { "af" }, })), ["surf"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "By surface analysis,", phrase = "by surface analysis,", abbrev = "surf.", glossary = "surface analysis", new_sentence = true, invisible = "tree", })), ["blend"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "Blend of", phrase = "a blend of", abbrev = "blend", glossary = "blend", toplevel_category = "blends", })), ["univerbation"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "Univerbation of", phrase = "univerbation of", abbrev = "univ.", glossary = "univerbation", toplevel_category = "univerbations", aliases = { "univ" }, })), -- -- Borrowing keywords -- ["bor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Borrowed from", phrase = "borrowed from", abbrev = "bor.", glossary = "loanword", borrowing_type = "borrowed", aliases = { "borrowed" }, })), ["lbor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Learned borrowing from", phrase = "a learned borrowing from", abbrev = "lbor.", glossary = "learned borrowing", specialized_borrowing = "learned", })), ["obor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Orthographic borrowing from", phrase = "an orthographic borrowing from", abbrev = "obor.", glossary = "orthographic borrowing", specialized_borrowing = "orthographic", })), ["slbor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Semi-learned borrowing from", phrase = "a semi-learned borrowing from", abbrev = "slbor.", glossary = "semi-learned borrowing", specialized_borrowing = "semi-learned", })), ["ubor"] = create_keyword(deep_merge(DEFAULTS.borrowing, { text = "Unadapted borrowing from", phrase = "an unadapted borrowing from", abbrev = "ubor.", glossary = "unadapted borrowing", specialized_borrowing = "unadapted", })), -- -- Calque-like keywords (non-transitive, start new sentence) -- ["calque"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Calque of", phrase = "a calque of", abbrev = "calq.", glossary = "calque", specialized_borrowing = "calque", aliases = { "cal", "clq" }, })), ["partial calque"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Partial calque of", phrase = "a partial calque of", abbrev = "pcalq.", glossary = "partial calque", specialized_borrowing = "partial-calque", aliases = { "pcal" }, })), ["semantic loan"] = create_keyword(deep_merge(DEFAULTS.calque_like, { text = "Semantic loan of", phrase = "a semantic loan of", abbrev = "sl.", glossary = "semantic loan", specialized_borrowing = "semantic-loan", aliases = { "sl" }, })), -- -- Influence keywords (non-transitive, separate clause) -- ["influence"] = create_keyword(deep_merge(DEFAULTS.influence_like, { text = "Influenced by", phrase = "influenced by", abbrev = "influ.", glossary = "contamination", separate_clause = true, })), -- -- Morphological derivation keywords -- ["clipping"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Clipping of", phrase = "clipping of", abbrev = "clip.", glossary = "clipping", toplevel_category = "clippings", aliases = { "clip" }, })), ["ellipsis"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Ellipsis of", phrase = "ellipsis of", abbrev = "ellip.", glossary = "ellipsis", toplevel_category = "ellipses", aliases = { "ellip" }, })), ["back-formation"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Back-formation from", phrase = "a back-formation from", abbrev = "bf.", glossary = "back-formation", toplevel_category = "back-formations", aliases = { "bf" }, })), ["nominalization"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Nominalization of", phrase = "a nominalization of", abbrev = "nom.", glossary = "nominalization", toplevel_category = "nominalizations", aliases = { "nom" }, })), ["transliteration"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Transliteration of", phrase = "borrowed from", abbrev = "translit.", glossary = "transliteration", aliases = { "translit" }, })), ["vrd"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Vṛddhi derivative of", phrase = "a vṛddhi derivative of", abbrev = "vṛd.", glossary = "vṛddhi derivative", })), ["apheretic"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Apheretic form of", phrase = "an apheretic form of", abbrev = "aph.", glossary = "apheresis", aliases = { "apheresis", "aphetic" }, })), ["denominal"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Denominal verb from", phrase = "denominal verb from", abbrev = "denom.", glossary = "denominal", toplevel_category = "denominal verbs", aliases = { "denom" }, })), ["deverbal"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Deverbal from", phrase = "deverbal from", abbrev = "deverb.", glossary = "deverbal", toplevel_category = "deverbals", })), ["reduplication"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Reduplication of", phrase = "reduplication of", abbrev = "redup.", glossary = "reduplication", toplevel_category = "reduplications", aliases = { "redup" }, })), ["abbreviation"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Abbreviation of", phrase = "abbreviation of", abbrev = "abbr.", glossary = "abbreviation", aliases = { "abbr" }, })), ["acronym"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Acronym of", phrase = "acronym of", abbrev = "acronym", glossary = "acronym", aliases = { "acro" }, })), ["initialism"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Initialism of", phrase = "initialism of", abbrev = "init.", glossary = "initialism", aliases = { "init" }, })), ["metathesis"] = create_keyword(deep_merge(DEFAULTS.transitive, { text = "Metathesis of", phrase = "metathesis of", abbrev = "meta.", glossary = "metathesis", toplevel_category = "words derived through metathesis", aliases = { "meta" }, })), -- -- Invisible keywords (no text output) -- ["root"] = create_keyword { transitive = TRANSITIVE.ALWAYS, invisible = "all", pos_override = "root", }, ["afeq"] = create_keyword(deep_merge(DEFAULTS.affix_group, { text = "From", phrase = "from", transitive = TRANSITIVE.NEVER, invisible = "all", })), } local aliases_to_register = {} local canonical_aliases = {} -- Map every keyword (canonical or alias) to its canonical form for consistent checks and tracking. export.keyword_canonical = {} for name, keyword_data in pairs(export.keywords) do export.keyword_canonical[name] = name if keyword_data.aliases then canonical_aliases[name] = keyword_data.aliases for _, alias in ipairs(keyword_data.aliases) do if export.keywords[alias] then error("Alias '" .. alias .. "' defined in keyword '" .. name .. "' collides with existing keyword '" .. alias .. "'.") end if aliases_to_register[alias] then error("Alias '" .. alias .. "' defined in keyword '" .. name .. "' is already claimed by another keyword.") end aliases_to_register[alias] = keyword_data export.keyword_canonical[alias] = name end keyword_data.aliases = nil end end for alias, data in pairs(aliases_to_register) do export.keywords[alias] = data end -- -- Language exception presets -- local EXCEPTION_PRESETS = { -- Fully disallowed: no tree, no text, no categories disallowed = { disallow = { tree = true, text = true }, suppress_categories = true, }, -- Suppress transliteration only no_translit = { suppress_tr = true, }, -- Suppress all categories only no_categories = { suppress_categories = true, }, } --[=[ Available exception options: disallow = { Related options for disallowing output: tree Disallow etymology trees for this language text Disallow etymology text generation for this language ref Reference link shown when tree/text is disallowed } suppress_tr Suppress transliteration in links suppress_categories Suppress all category generation normalize_to Normalize language code to a different code normalize_from_families Apply normalization to languages in these families normalize_exclude_families Exclude these families from normalization keyword_overrides Per-keyword categorisation overrides (e.g. { ["af"] = { transitive = TRANSITIVE.NEVER } }) ]=] local function create_exception(preset, overrides) local base = preset and EXCEPTION_PRESETS[preset] or {} return deep_merge(base, overrides or {}) end export.config = { lang_exceptions = { ["zh"] = create_exception("disallowed", { disallow = { ref = "[[Wiktionary:Beer parlour/2025/May#Template:etymon for Chinese]]" }, suppress_tr = true, normalize_to = "zh", normalize_from_families = { "zhx" }, normalize_exclude_families = { "qfa-cnt" }, }), }, } -- Supported codes for the nominalization <g:code> modifier (subset of common gender/number-style codes) export.nominalization_g_codes = { ["m"] = "masculine", ["f"] = "feminine", ["n"] = "neuter", ["c"] = "common", ["gneut"] = "gender-neutral", ["s"] = "singular", ["p"] = "plural", ["d"] = "dual", ["pauc"] = "paucal", ["mf"] = "masculine or feminine", ["fm"] = "masculine or feminine", ["mfn"] = "masculine, feminine or neuter", ["mnf"] = "masculine, feminine or neuter", ["fmn"] = "masculine, feminine or neuter", ["fnm"] = "masculine, feminine or neuter", ["nmf"] = "masculine, feminine or neuter", ["nfm"] = "masculine, feminine or neuter", } -- -- Propagate keyword overrides to aliases -- if export.config.lang_exceptions then for lang_code, exception in pairs(export.config.lang_exceptions) do if exception.keyword_overrides then for canonical, aliases in pairs(canonical_aliases) do if exception.keyword_overrides[canonical] then local override_data = exception.keyword_overrides[canonical] for _, alias in ipairs(aliases) do if not exception.keyword_overrides[alias] then exception.keyword_overrides[alias] = override_data end end end end end end end return export gbkvnexdjv0vc2y1d7cpq96tx37mzp9 Mô đun:etymon/tree 828 378444 2344318 2342904 2026-04-12T01:36:27Z TheHighFighter2 42988 2344318 Scribunto text/plain local export = {} local html_create = mw.html.create local max = math.max local function create_vertical_connector() return html_create('span'):addClass('etytree-connector-vertical') end local function create_abbr(text, title, glossary) local abbr = html_create('abbr') :attr('title', title) :wikitext(text) if glossary then abbr = '[[Phụ lục:Từ điển thuật ngữ#' .. glossary .. '|' .. tostring(abbr) .. ']]' end return html_create('span'):addClass('etytree-label'):node(abbr) end local function create_uncertainty_marker() return html_create('abbr') :addClass('etytree-unc') :attr('title', 'uncertain') :wikitext('?') end local function create_label_container() return html_create('span'):addClass('etytree-label-container') end local function invisible_in_tree(inv) return inv == "all" or inv == true or inv == "tree" end local function render_label(term_block, keyword_info, keyword_modifiers, is_uncertain, is_group_child, term_labels) -- Skip label when invisible in tree local has_label = keyword_info and keyword_info.abbrev and not is_group_child and not invisible_in_tree(keyword_info.invisible) -- For group children, keyword uncertainty is shown on the group label, not on individual terms local keyword_uncertain = keyword_modifiers and keyword_modifiers.unc and not is_group_child local show_term_uncertainty = is_uncertain -- Check if we have term-specific labels local has_term_labels = term_labels and #term_labels > 0 if not has_label and not show_term_uncertainty and not keyword_uncertain and not has_term_labels then return end local label_span = create_label_container() if has_label then local glossary_title = keyword_info.glossary and keyword_info.glossary:gsub("_", " ") or keyword_info.abbrev label_span:node(create_abbr( keyword_info.abbrev, glossary_title, keyword_info.glossary )) -- Show uncertainty marker if term or keyword is uncertain if show_term_uncertainty or keyword_uncertain then label_span:node(create_uncertainty_marker()) end else -- No label, but term or keyword is uncertain if show_term_uncertainty or keyword_uncertain then label_span:node(create_uncertainty_marker()) end end -- Add term-specific labels if has_term_labels then for _, label_info in ipairs(term_labels) do label_span:node(create_abbr(label_info.abbrev, label_info.title, label_info.glossary)) end end term_block:node(label_span) end local function render_term_block(node_data, format_term_func, is_toplevel) local link_content = html_create() link_content :tag('span') :addClass('etyl') :wikitext(node_data.lang:getCanonicalName()) :done() local term_text = format_term_func(node_data, is_toplevel) if term_text then link_content :wikitext(' ') :tag('span') :addClass('etytree-term') :wikitext(term_text) :done() end local block = html_create('div'):addClass('etytree-block'):node(link_content) -- Add duplicate styling if this is a duplicate node if node_data.is_duplicate then block:addClass('etytree-duplicate') end return block end local function create_dotted_connector() return html_create('span'):addClass('etytree-connector-dotted') end -- Create an L-shaped connector for nodes with hidden ancestry (duplicate or no_child_categories) local function create_duplicate_connector() local container = html_create('div'):addClass('etytree-duplicate-connector') local inner_wrapper = container:tag('div') inner_wrapper:tag('span'):addClass('etytree-dup-right') inner_wrapper:tag('span'):addClass('etytree-dup-horiz') inner_wrapper:tag('span'):addClass('etytree-dup-left') inner_wrapper:tag('span'):addClass('etytree-dup-arrow'):wikitext('▲') return container end local function render_group_label(connecting_line, keyword_info, keyword_modifiers) local has_abbrev = keyword_info and keyword_info.abbrev local keyword_uncertain = keyword_modifiers and keyword_modifiers.unc -- Nothing to show if no abbrev and no uncertainty if not has_abbrev and not keyword_uncertain then return end local label_span = connecting_line:tag('span'):addClass('etytree-group-label') if has_abbrev then local glossary_title = keyword_info.glossary and keyword_info.glossary:gsub("_", " ") or keyword_info.abbrev label_span:node(create_abbr(keyword_info.abbrev, glossary_title, nil)) end -- Add uncertainty marker if keyword has <unc> modifier if keyword_uncertain then label_span:node(create_uncertainty_marker()) end end local function add_branch_connector(column, index, total) if index == 1 then column:tag('span'):addClass('etytree-branch-left') elseif index == total then column:tag('span'):addClass('etytree-branch-right') else column:tag('span'):addClass('etytree-connector-vertical-short') column:tag('span'):addClass('etytree-branch-mid') end end function export.render(opts) opts = opts or {} local data_tree = opts.data_tree local format_term_func = opts.format_term_func -- Forward declaration local render_term -- Render a container (keyword + its terms) local function render_container(container, is_toplevel) local keyword_info = container.keyword_info local keyword_modifiers = container.keyword_modifiers or {} local is_group = keyword_info and keyword_info.is_group local terms = container.terms or {} -- Skip container entirely only when invisible = "all" (or true) if keyword_info and invisible_in_tree(keyword_info.invisible) then return nil, 0, 0 end if #terms == 0 then return nil, 0, 0 end -- For no_child_categories keywords (calque, semantic loan, etc.), don't render term's children local skip_child_rendering = keyword_info and keyword_info.no_child_categories -- Render each term in the container local rendered_terms = {} local container_height = 0 local container_width = 0 for _, term in ipairs(terms) do -- Collect term-specific labels local term_labels = {} if term.bor then table.insert(term_labels, { abbrev = "bor.", title = "vay mượn", glossary = "từ vay mượn" }) end if term.slbor then table.insert(term_labels, { abbrev = "slbor.", title = "semi-learned borrowing", glossary = "semi-learned_borrowing" }) end if term.lbor then table.insert(term_labels, { abbrev = "lbor.", title = "learned borrowing", glossary = "learned_borrowing" }) end local term_tree, term_height, term_width = render_term(term, keyword_info, keyword_modifiers, is_group, false, skip_child_rendering, term_labels) table.insert(rendered_terms, { tree = term_tree, height = term_height, width = term_width, is_uncertain = term.is_uncertain, }) container_height = max(container_height, term_height) container_width = container_width + term_width end local rendered_html local has_connector = false if #rendered_terms == 1 then -- Single term: just return it directly rendered_html = rendered_terms[1].tree container_height = rendered_terms[1].height container_width = rendered_terms[1].width else -- Multiple terms: group them together local subtree_container = html_create('div'):addClass('etytree-branch-group') for i, term_data in ipairs(rendered_terms) do local column = html_create('div'):addClass('etytree-branch') column:node(term_data.tree) add_branch_connector(column, i, #rendered_terms) subtree_container:node(column) end local connecting_line = create_vertical_connector() -- Add group label for group keywords if is_group and not invisible_in_tree(keyword_info.invisible) then render_group_label(connecting_line, keyword_info, keyword_modifiers) end rendered_html = html_create() :node(subtree_container) :node(connecting_line) has_connector = true end return rendered_html, container_height, container_width, has_connector end -- Render a term node render_term = function(term_node, keyword_info, keyword_modifiers, is_group_child, is_toplevel_term, skip_child_rendering, term_labels) local tree_width, tree_height = 0, 0 local subtrees = {} -- Process term's children (which are containers) local has_hidden_children = false if not term_node.is_duplicate and not skip_child_rendering then for _, container in ipairs(term_node.children or {}) do local subtree, sub_height, sub_width, subtree_has_connector = render_container(container, is_toplevel_term) if subtree then table.insert(subtrees, { tree = subtree, height = sub_height, width = sub_width, has_connector = subtree_has_connector, }) tree_height = max(tree_height, sub_height) tree_width = tree_width + sub_width end end elseif skip_child_rendering then -- Check if there are any visible children -- When stop_recursion is true, children aren't parsed, but has_visible_children flag is set if term_node.has_visible_children then has_hidden_children = true elseif term_node.children and #term_node.children > 0 then -- Fallback: check parsed children for visibility for _, container in ipairs(term_node.children) do local child_keyword_info = container.keyword_info if not (child_keyword_info and (child_keyword_info.invisible == "all" or child_keyword_info.invisible == true)) then has_hidden_children = true break end end end end local is_toplevel_node = (keyword_info == nil) local term_block = render_term_block(term_node, format_term_func, is_toplevel_node) render_label(term_block, keyword_info, keyword_modifiers, term_node.is_uncertain, is_group_child, term_labels or {}) local term_html = html_create() if #subtrees == 0 then local show_connector = (term_node.is_duplicate and term_node.original_has_children) or has_hidden_children if show_connector then term_html:node(create_duplicate_connector()) end term_html:node(term_block) tree_width = tree_width + 1 elseif #subtrees == 1 then term_html:node(subtrees[1].tree) if not subtrees[1].has_connector then term_html:node(create_vertical_connector()) end term_html:node(term_block) else -- Multiple containers: need to merge them local subtree_container = html_create('div'):addClass('etytree-branch-group') for i, subtree_data in ipairs(subtrees) do local column = html_create('div'):addClass('etytree-branch') column:node(subtree_data.tree) add_branch_connector(column, i, #subtrees) subtree_container:node(column) end local connecting_line = create_vertical_connector() term_html :node(subtree_container) :node(connecting_line) :node(term_block) end return term_html, tree_height + 1, tree_width end local final_tree, final_height, final_width = render_term(data_tree, nil, nil, false, true) local container = html_create('div') :addClass('etytree-body') :node(final_tree) return tostring(html_create('div') :addClass('etytree NavFrame') :attr('data-etytree-height', final_height) :attr('data-etytree-width', final_width) :tag('div') :addClass('NavHead') :tag('div') :wikitext('Cây từ nguyên') :done() :done() :tag('div') :addClass('NavContent') :node(container) :done()) end return export r4bnhfn2pxf697xu38c89yyp94qikc7 Mô đun:etymon/categories 828 378445 2344314 2317910 2026-04-12T01:28:31Z TheHighFighter2 42988 2344314 Scribunto text/plain local export = {} local M = require("Module:module loader").init({ require = { etymology = "Module:etymology", affix = "Module:affix", etymology_specialized = "Module:etymology/specialized", }, loadData = { data = "Module:etymon/data", }, }) -- Evaluate whether a keyword is transitive for a given term local function is_transitive(transitive_mode, page_lang, term_lang) if transitive_mode == M.data.TRANSITIVE.ALWAYS then return true elseif transitive_mode == M.data.TRANSITIVE.NEVER then return false elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then return page_lang:getCode() ~= term_lang:getCode() elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then return page_lang:getCode() ~= term_lang:getCode() end error("Unknown transitive mode: " .. tostring(transitive_mode)) end -- Get keyword config with language-specific overrides local function get_keyword_config(keyword, lang_exc) local base_config = M.data.keywords[keyword] if not base_config then return nil -- Invalid keyword end local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword] if not overrides then return base_config end -- Merge overrides into base config local merged = {} for k, v in pairs(base_config) do merged[k] = v end for k, v in pairs(overrides) do merged[k] = v end return merged end function export.get_cat_name(source) local _, cat_name = M.etymology.get_display_and_cat_name(source, true) return cat_name end -- Normalize affix type aliases local aftype_aliases = { ["pre"] = "prefix", ["suf"] = "suffix", ["in"] = "infix", ["inter"] = "interfix", ["circum"] = "circumfix", ["naf"] = "non-affix", ["root"] = "non-affix", } -- Collect affix categories from top-level group containers local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) local parts = {} local part_index = 1 for _, container in ipairs(node.children or {}) do local config = container.keyword_info if config and config.affix_categories then for _, term in ipairs(container.terms or {}) do if not term.unknown_term then local part_data = { term = term.title, tr = term.tr, ts = term.ts, alt = term.alt, itemno = part_index, orig_index = part_index } -- Determine affix type: explicit aftype > pos=root > auto-detect local aftype = term.aftype if aftype then aftype = aftype_aliases[aftype] or aftype part_data.type = aftype elseif term.args and term.args.pos and term.args.pos == "root" then part_data.type = "non-affix" end if term.lang:getCode() ~= page_lang:getCode() then part_data.lang = term.lang end local target_ids = available_etymon_ids[term.target_key] local has_multiple_ids = target_ids and #target_ids > 1 local id_exists_in_disambiguation = false local matched_id = nil -- Count available senseids for the target page local senseid_count = 0 local target_prefix = term.target_key .. ":" if senseid_parent_etymon then for key, _ in pairs(senseid_parent_etymon) do if key:sub(1, #target_prefix) == target_prefix then senseid_count = senseid_count + 1 end end end local has_multiple_senseids = senseid_count > 1 if term.id then -- Check if user provided a valid senseid local senseid_key = term.target_key .. ":" .. term.id if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then if has_multiple_senseids then -- Ambiguous senseid: use senseid matched_id = term.id id_exists_in_disambiguation = true elseif has_multiple_ids then -- Unique senseid but ambiguous etymon: use etymon ID matched_id = term.etymon_id or term.id id_exists_in_disambiguation = true end else -- Check if user provided a valid etymon ID if has_multiple_ids and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.id then -- Ambiguous etymon: use etymon ID id_exists_in_disambiguation = true matched_id = term.id break end end end -- Fallback: check resolved etymon_id (e.g. from previous steps) if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.etymon_id then id_exists_in_disambiguation = true matched_id = term.etymon_id break end end end end end -- Use the matched ID if found if term.override or id_exists_in_disambiguation then part_data.id = matched_id or term.id end table.insert(parts, part_data) part_index = part_index + 1 end end end end if #parts == 0 then return {} end local affix_data = { lang = page_lang, parts = parts, pos = "term", sort_key = nil } local affix_categories = M.affix.get_affix_categories_only(affix_data) local result = {} for _, cat in ipairs(affix_categories) do if type(cat) == "table" then table.insert(result, cat.cat) else table.insert(result, cat) end end return result end -- Add borrowing-related categories (top-level only) local function collect_borrowing_categories(categories, page_lang, term, config) if config.borrowing_type == "borrowed" then local temp_categories = {} M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang) for _, cat in ipairs(temp_categories) do categories[cat] = true end end if config.specialized_borrowing then local result = M.etymology_specialized.specialized_borrowing { bortype = config.specialized_borrowing, lang = page_lang, sources = { term.lang }, terms = { { lang = term.lang, term = "-" } }, notext = true, nocat = false, } for cat_name in result:gmatch("%[%[Category:([^%]]+)%]%]") do categories[cat_name] = true end end end -- Add source-based derivation categories (top-level only) local function collect_source_derivation_categories(categories, page_lang, term, config) if not config.source_category_type then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = config.source_category_type, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end -- Add source language categories local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func) if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end if chain.inherited then temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = "terms inherited", nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end end -- Add root/word categories local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain, get_norm_lang_func, lang_exc, keyword) local pos_types = { root = "root", word = "word" } -- Determine pos: from term's postype, keyword's pos_override, or args.pos local pos local config = get_keyword_config(keyword, lang_exc) if term.postype then -- Term-level postype modifier takes highest priority pos = term.postype elseif config and config.pos_override then pos = config.pos_override elseif type(term.args) == "table" and term.args.pos then pos = term.args.pos end local pos_type = pos_types[pos] if not pos_type or term.unknown_term then return end -- Skip root/word categories for descendants of affix groups -- if pos_type then -- return -- end local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode() -- Skip self-references if same_language and root_title == term.title then return end -- Use makeEntryName to strip diacritics for category names local entry_name = term.lang:makeEntryName(term.title) local lang_name = page_lang:getCanonicalName() local cat_name if chain.passed_through then local etymon_lang_name = export.get_cat_name(term.lang) cat_name = lang_name .. " terms derived from the " .. etymon_lang_name .. " " .. pos_type .. " " .. entry_name else cat_name = lang_name .. " terms belonging to the " .. pos_type .. " " .. entry_name end -- Add ID disambiguation if needed (for roots/words: use etymon_id if resolved via senseid, otherwise use id) local target_ids = available_etymon_ids[term.target_key] local effective_id = term.etymon_id or term.id -- etymon_id if senseid, otherwise id is already an etymon id if target_ids and effective_id then local same_pos_count = 0 for _, id_data in ipairs(target_ids) do if type(id_data) == "table" and id_data.pos == pos then same_pos_count = same_pos_count + 1 end end if same_pos_count > 1 then cat_name = cat_name .. " (" .. effective_id .. ")" end end categories[cat_name] = true end -- Compute chain state for a term based on parent chain and keyword config -- Hyphen patterns for affix detection (regular hyphen + script-specific) local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- regular hyphen, Hebrew maqqef, Arabic tatweel, Mongolian hyphen -- Check if a term is an actual affix (not a non-affix member of an affix group) local function is_actual_affix(term) -- Check explicit aftype modifier if term.aftype then local normalized = aftype_aliases[term.aftype] or term.aftype return normalized ~= "non-affix" end -- Check if pos=root (treated as non-affix) if term.args and term.args.pos and term.args.pos == "root" then return false end -- Auto-detect by hyphen: prefix ends with -, suffix starts with -, etc. if term.title then local title = term.title -- Strip leading * for reconstructed terms before checking hyphens title = title:gsub("^%*", "") -- Check for hyphens at start or end (handles script-specific hyphens too) if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then return true end end -- Default: not an affix return false end local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term) -- Track if we're inside an actual affix (for suppressing root categories on descendants) -- Only set if the term is an actual affix (prefix, suffix, etc.), not a non-affix member local inside_affix = parent_chain.inside_affix if config.affix_categories and term and is_actual_affix(term) then inside_affix = true end -- If no_child_categories is set, disable everything if config.no_child_categories then return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = false, source = false, pos = false, recurse = false, inside_affix = inside_affix, } end local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang) local new_source = parent_chain.source and term_is_transitive -- For CROSS_LANG_NO_INTERNAL_SOURCE: track internal derivation language context -- Check if this term is internal relative to parent term's language (if parent_term_lang provided) -- or relative to page language (if no parent_term_lang) local internal_lang = parent_chain.internal_lang local is_internal_in_context = false if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then local check_lang = parent_term_lang or page_lang local term_lang_code = get_norm_lang_func(term_lang):getCode() local check_lang_code = get_norm_lang_func(check_lang):getCode() if internal_lang then -- Already in an internal derivation context: check if this term is also internal is_internal_in_context = term_lang_code == internal_lang else -- Check if this term is internal relative to parent term (or page if no parent) is_internal_in_context = term_lang_code == check_lang_code end end -- Source chain behavior for CROSS_LANG_NO_INTERNAL_SOURCE if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then if is_internal_in_context then -- Internal derivation new_source = false internal_lang = get_norm_lang_func(term_lang):getCode() else -- Cross-language new_source = parent_chain.source and term_is_transitive internal_lang = nil end end local new_pos = parent_chain.pos return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = parent_chain.inherited and config.inherited_chain, source = new_source, pos = new_pos, internal_lang = internal_lang, recurse = new_source or new_pos, inside_affix = inside_affix, } end function export.render(opts) opts = opts or {} local data_tree = opts.data_tree local page_lang = opts.page_lang local available_etymon_ids = opts.available_etymon_ids local senseid_parent_etymon = opts.senseid_parent_etymon local get_norm_lang_func = opts.get_norm_lang_func local lang_exc = opts.lang_exc local categories = {} local seen = {} local lang_name = page_lang:getCanonicalName() local root_title = data_tree.title -- Collect the tree recursively local function collect(node, parent_chain, is_toplevel) -- Avoid processing same node twice if not node.unknown_term and node.title then local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "") if seen[key] then return end seen[key] = true end -- Collect affix categories at top level only if is_toplevel then local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) for _, cat in ipairs(affix_cats) do categories[lang_name .. " " .. cat] = true end end -- Process each container for _, container in ipairs(node.children or {}) do local keyword = container.keyword local config = get_keyword_config(keyword, lang_exc) -- Skip invalid keywords if config then -- Process each term in the container for _, term in ipairs(container.terms or {}) do local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term) local no_child_categories = config.no_child_categories == true local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang) -- Top-level only processing if is_toplevel then -- Missing/ambiguous etymon tracking if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then categories[lang_name .. " entries referencing missing etymons"] = true end if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then categories[lang_name .. " entries referencing ambiguous etymons"] = true end if term.missing_descendants_header then categories[lang_name .. " entries referencing etymons without Descendants sections"] = true end if term.missing_descendants_entry then categories[lang_name .. " entries referencing etymons without this term in Descendants sections"] = true end -- Top-level category (e.g., "undefined derivations") if config.toplevel_category then categories[lang_name .. " " .. config.toplevel_category] = true end -- Borrowing categories (bor, lbor, slbor, ubor, obor) if config.borrowing_type or config.specialized_borrowing then collect_borrowing_categories(categories, page_lang, term, config) end -- Borrowing categories from <bor>, <lbor>, or <slbor> modifiers on :af/:surf terms if keyword == "affix" or keyword == "surf" then if term.bor then local bor_config = { borrowing_type = "borrowed" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.lbor then local bor_config = { specialized_borrowing = "learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.slbor then local bor_config = { specialized_borrowing = "semi-learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) end end -- Source-based derivation categories (sl, calque, pcal) if config.source_category_type then collect_source_derivation_categories(categories, page_lang, term, config) end -- Skip all child categorisation if no_child_categories is set if not no_child_categories then -- Source categories only if transitive if term_is_transitive then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end -- Pos categories always (unless no_child_categories) collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end else -- Below top level, respect the parent chain if parent_chain.source then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end if parent_chain.pos then collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end end -- Recurse into term's children if needed and status allows if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then collect(term, term_chain, false) end end end end end -- Initial chain state local initial_chain = { passed_through = false, inherited = true, source = true, pos = true, internal_lang = nil, recurse = true, inside_affix = false, } collect(data_tree, initial_chain, true) local cat_list = {} for cat in pairs(categories) do table.insert(cat_list, cat) end return cat_list end return export 6x8tux7uka6u4jnngod6ksjr5ghck2r 2344438 2344314 2026-04-12T06:35:26Z TheHighFighter2 42988 2344438 Scribunto text/plain local export = {} local M = require("Module:module loader").init({ require = { etymology = "Module:etymology", affix = "Module:affix", etymology_specialized = "Module:etymology/specialized", }, loadData = { data = "Module:etymon/data", }, }) -- Evaluate whether a keyword is transitive for a given term local function is_transitive(transitive_mode, page_lang, term_lang) if transitive_mode == M.data.TRANSITIVE.ALWAYS then return true elseif transitive_mode == M.data.TRANSITIVE.NEVER then return false elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then return page_lang:getCode() ~= term_lang:getCode() elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then return page_lang:getCode() ~= term_lang:getCode() end error("Unknown transitive mode: " .. tostring(transitive_mode)) end -- Get keyword config with language-specific overrides local function get_keyword_config(keyword, lang_exc) local base_config = M.data.keywords[keyword] if not base_config then return nil -- Invalid keyword end local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword] if not overrides then return base_config end -- Merge overrides into base config local merged = {} for k, v in pairs(base_config) do merged[k] = v end for k, v in pairs(overrides) do merged[k] = v end return merged end function export.get_cat_name(source) local _, cat_name = M.etymology.get_display_and_cat_name(source, true) return cat_name end -- Normalize affix type aliases local aftype_aliases = { ["pre"] = "prefix", ["suf"] = "suffix", ["in"] = "infix", ["inter"] = "interfix", ["circum"] = "circumfix", ["naf"] = "non-affix", ["root"] = "non-affix", } -- Collect affix categories from top-level group containers local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) local parts = {} local part_index = 1 for _, container in ipairs(node.children or {}) do local config = container.keyword_info if config and config.affix_categories then for _, term in ipairs(container.terms or {}) do if not term.unknown_term then local part_data = { term = term.title, tr = term.tr, ts = term.ts, alt = term.alt, itemno = part_index, orig_index = part_index } -- Determine affix type: explicit aftype > pos=root > auto-detect local aftype = term.aftype if aftype then aftype = aftype_aliases[aftype] or aftype part_data.type = aftype elseif term.args and term.args.pos and term.args.pos == "root" then part_data.type = "non-affix" end if term.lang:getCode() ~= page_lang:getCode() then part_data.lang = term.lang end local target_ids = available_etymon_ids[term.target_key] local has_multiple_ids = target_ids and #target_ids > 1 local id_exists_in_disambiguation = false local matched_id = nil -- Count available senseids for the target page local senseid_count = 0 local target_prefix = term.target_key .. ":" if senseid_parent_etymon then for key, _ in pairs(senseid_parent_etymon) do if key:sub(1, #target_prefix) == target_prefix then senseid_count = senseid_count + 1 end end end local has_multiple_senseids = senseid_count > 1 if term.id then -- Check if user provided a valid senseid local senseid_key = term.target_key .. ":" .. term.id if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then if has_multiple_senseids then -- Ambiguous senseid: use senseid matched_id = term.id id_exists_in_disambiguation = true elseif has_multiple_ids then -- Unique senseid but ambiguous etymon: use etymon ID matched_id = term.etymon_id or term.id id_exists_in_disambiguation = true end else -- Check if user provided a valid etymon ID if has_multiple_ids and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.id then -- Ambiguous etymon: use etymon ID id_exists_in_disambiguation = true matched_id = term.id break end end end -- Fallback: check resolved etymon_id (e.g. from previous steps) if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.etymon_id then id_exists_in_disambiguation = true matched_id = term.etymon_id break end end end end end -- Use the matched ID if found if term.override or id_exists_in_disambiguation then part_data.id = matched_id or term.id end table.insert(parts, part_data) part_index = part_index + 1 end end end end if #parts == 0 then return {} end local affix_data = { lang = page_lang, parts = parts, pos = "Từ", sort_key = nil } local affix_categories = M.affix.get_affix_categories_only(affix_data) local result = {} for _, cat in ipairs(affix_categories) do if type(cat) == "table" then table.insert(result, cat.cat) else table.insert(result, cat) end end return result end -- Add borrowing-related categories (top-level only) local function collect_borrowing_categories(categories, page_lang, term, config) if config.borrowing_type == "borrowed" then local temp_categories = {} M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang) for _, cat in ipairs(temp_categories) do categories[cat] = true end end if config.specialized_borrowing then local result = M.etymology_specialized.specialized_borrowing { bortype = config.specialized_borrowing, lang = page_lang, sources = { term.lang }, terms = { { lang = term.lang, term = "-" } }, notext = true, nocat = false, } for cat_name in result:gmatch("%[%[Category:([^%]]+)%]%]") do categories[cat_name] = true end end end -- Add source-based derivation categories (top-level only) local function collect_source_derivation_categories(categories, page_lang, term, config) if not config.source_category_type then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = config.source_category_type, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end -- Add source language categories local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func) if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end if chain.inherited then temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = "terms inherited", nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end end -- Add root/word categories local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain, get_norm_lang_func, lang_exc, keyword) local pos_types = { root = "root", word = "word" } -- Determine pos: from term's postype, keyword's pos_override, or args.pos local pos local config = get_keyword_config(keyword, lang_exc) if term.postype then -- Term-level postype modifier takes highest priority pos = term.postype elseif config and config.pos_override then pos = config.pos_override elseif type(term.args) == "table" and term.args.pos then pos = term.args.pos end local pos_type = pos_types[pos] if not pos_type or term.unknown_term then return end -- Skip root/word categories for descendants of affix groups -- if pos_type then -- return -- end local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode() -- Skip self-references if same_language and root_title == term.title then return end -- Use makeEntryName to strip diacritics for category names local entry_name = term.lang:makeEntryName(term.title) local lang_name = page_lang:getCanonicalName() local cat_name if chain.passed_through then local etymon_lang_name = export.get_cat_name(term.lang) cat_name = lang_name .. " terms derived from the " .. etymon_lang_name .. " " .. pos_type .. " " .. entry_name else cat_name = lang_name .. " terms belonging to the " .. pos_type .. " " .. entry_name end -- Add ID disambiguation if needed (for roots/words: use etymon_id if resolved via senseid, otherwise use id) local target_ids = available_etymon_ids[term.target_key] local effective_id = term.etymon_id or term.id -- etymon_id if senseid, otherwise id is already an etymon id if target_ids and effective_id then local same_pos_count = 0 for _, id_data in ipairs(target_ids) do if type(id_data) == "table" and id_data.pos == pos then same_pos_count = same_pos_count + 1 end end if same_pos_count > 1 then cat_name = cat_name .. " (" .. effective_id .. ")" end end categories[cat_name] = true end -- Compute chain state for a term based on parent chain and keyword config -- Hyphen patterns for affix detection (regular hyphen + script-specific) local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- regular hyphen, Hebrew maqqef, Arabic tatweel, Mongolian hyphen -- Check if a term is an actual affix (not a non-affix member of an affix group) local function is_actual_affix(term) -- Check explicit aftype modifier if term.aftype then local normalized = aftype_aliases[term.aftype] or term.aftype return normalized ~= "non-affix" end -- Check if pos=root (treated as non-affix) if term.args and term.args.pos and term.args.pos == "root" then return false end -- Auto-detect by hyphen: prefix ends with -, suffix starts with -, etc. if term.title then local title = term.title -- Strip leading * for reconstructed terms before checking hyphens title = title:gsub("^%*", "") -- Check for hyphens at start or end (handles script-specific hyphens too) if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then return true end end -- Default: not an affix return false end local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term) -- Track if we're inside an actual affix (for suppressing root categories on descendants) -- Only set if the term is an actual affix (prefix, suffix, etc.), not a non-affix member local inside_affix = parent_chain.inside_affix if config.affix_categories and term and is_actual_affix(term) then inside_affix = true end -- If no_child_categories is set, disable everything if config.no_child_categories then return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = false, source = false, pos = false, recurse = false, inside_affix = inside_affix, } end local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang) local new_source = parent_chain.source and term_is_transitive -- For CROSS_LANG_NO_INTERNAL_SOURCE: track internal derivation language context -- Check if this term is internal relative to parent term's language (if parent_term_lang provided) -- or relative to page language (if no parent_term_lang) local internal_lang = parent_chain.internal_lang local is_internal_in_context = false if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then local check_lang = parent_term_lang or page_lang local term_lang_code = get_norm_lang_func(term_lang):getCode() local check_lang_code = get_norm_lang_func(check_lang):getCode() if internal_lang then -- Already in an internal derivation context: check if this term is also internal is_internal_in_context = term_lang_code == internal_lang else -- Check if this term is internal relative to parent term (or page if no parent) is_internal_in_context = term_lang_code == check_lang_code end end -- Source chain behavior for CROSS_LANG_NO_INTERNAL_SOURCE if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then if is_internal_in_context then -- Internal derivation new_source = false internal_lang = get_norm_lang_func(term_lang):getCode() else -- Cross-language new_source = parent_chain.source and term_is_transitive internal_lang = nil end end local new_pos = parent_chain.pos return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = parent_chain.inherited and config.inherited_chain, source = new_source, pos = new_pos, internal_lang = internal_lang, recurse = new_source or new_pos, inside_affix = inside_affix, } end function export.render(opts) opts = opts or {} local data_tree = opts.data_tree local page_lang = opts.page_lang local available_etymon_ids = opts.available_etymon_ids local senseid_parent_etymon = opts.senseid_parent_etymon local get_norm_lang_func = opts.get_norm_lang_func local lang_exc = opts.lang_exc local categories = {} local seen = {} local lang_name = page_lang:getCanonicalName() local root_title = data_tree.title -- Collect the tree recursively local function collect(node, parent_chain, is_toplevel) -- Avoid processing same node twice if not node.unknown_term and node.title then local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "") if seen[key] then return end seen[key] = true end -- Collect affix categories at top level only if is_toplevel then local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) for _, cat in ipairs(affix_cats) do categories[cat .. " " .. lang_name] = true end end -- Process each container for _, container in ipairs(node.children or {}) do local keyword = container.keyword local config = get_keyword_config(keyword, lang_exc) -- Skip invalid keywords if config then -- Process each term in the container for _, term in ipairs(container.terms or {}) do local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term) local no_child_categories = config.no_child_categories == true local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang) -- Top-level only processing if is_toplevel then -- Missing/ambiguous etymon tracking if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then categories[lang_name .. " entries referencing missing etymons"] = true end if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then categories[lang_name .. " entries referencing ambiguous etymons"] = true end if term.missing_descendants_header then categories[lang_name .. " entries referencing etymons without Descendants sections"] = true end if term.missing_descendants_entry then categories[lang_name .. " entries referencing etymons without this term in Descendants sections"] = true end -- Top-level category (e.g., "undefined derivations") if config.toplevel_category then categories[lang_name .. " " .. config.toplevel_category] = true end -- Borrowing categories (bor, lbor, slbor, ubor, obor) if config.borrowing_type or config.specialized_borrowing then collect_borrowing_categories(categories, page_lang, term, config) end -- Borrowing categories from <bor>, <lbor>, or <slbor> modifiers on :af/:surf terms if keyword == "affix" or keyword == "surf" then if term.bor then local bor_config = { borrowing_type = "borrowed" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.lbor then local bor_config = { specialized_borrowing = "learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.slbor then local bor_config = { specialized_borrowing = "semi-learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) end end -- Source-based derivation categories (sl, calque, pcal) if config.source_category_type then collect_source_derivation_categories(categories, page_lang, term, config) end -- Skip all child categorisation if no_child_categories is set if not no_child_categories then -- Source categories only if transitive if term_is_transitive then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end -- Pos categories always (unless no_child_categories) collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end else -- Below top level, respect the parent chain if parent_chain.source then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end if parent_chain.pos then collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end end -- Recurse into term's children if needed and status allows if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then collect(term, term_chain, false) end end end end end -- Initial chain state local initial_chain = { passed_through = false, inherited = true, source = true, pos = true, internal_lang = nil, recurse = true, inside_affix = false, } collect(data_tree, initial_chain, true) local cat_list = {} for cat in pairs(categories) do table.insert(cat_list, cat) end return cat_list end return export kruf33c8923wu77v66w85fp6eoujhx1 2344441 2344438 2026-04-12T07:18:32Z TheHighFighter2 42988 2344441 Scribunto text/plain local export = {} local M = require("Module:module loader").init({ require = { etymology = "Module:etymology", affix = "Module:affix", etymology_specialized = "Module:etymology/specialized", }, loadData = { data = "Module:etymon/data", }, }) -- Evaluate whether a keyword is transitive for a given term local function is_transitive(transitive_mode, page_lang, term_lang) if transitive_mode == M.data.TRANSITIVE.ALWAYS then return true elseif transitive_mode == M.data.TRANSITIVE.NEVER then return false elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then return page_lang:getCode() ~= term_lang:getCode() elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then return page_lang:getCode() ~= term_lang:getCode() end error("Unknown transitive mode: " .. tostring(transitive_mode)) end -- Get keyword config with language-specific overrides local function get_keyword_config(keyword, lang_exc) local base_config = M.data.keywords[keyword] if not base_config then return nil -- Invalid keyword end local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword] if not overrides then return base_config end -- Merge overrides into base config local merged = {} for k, v in pairs(base_config) do merged[k] = v end for k, v in pairs(overrides) do merged[k] = v end return merged end function export.get_cat_name(source) local _, cat_name = M.etymology.get_display_and_cat_name(source, true) return cat_name end -- Normalize affix type aliases local aftype_aliases = { ["pre"] = "prefix", ["suf"] = "suffix", ["in"] = "infix", ["inter"] = "interfix", ["circum"] = "circumfix", ["naf"] = "non-affix", ["root"] = "non-affix", } -- Collect affix categories from top-level group containers local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) local parts = {} local part_index = 1 for _, container in ipairs(node.children or {}) do local config = container.keyword_info if config and config.affix_categories then for _, term in ipairs(container.terms or {}) do if not term.unknown_term then local part_data = { term = term.title, tr = term.tr, ts = term.ts, alt = term.alt, itemno = part_index, orig_index = part_index } -- Determine affix type: explicit aftype > pos=root > auto-detect local aftype = term.aftype if aftype then aftype = aftype_aliases[aftype] or aftype part_data.type = aftype elseif term.args and term.args.pos and term.args.pos == "root" then part_data.type = "non-affix" end if term.lang:getCode() ~= page_lang:getCode() then part_data.lang = term.lang end local target_ids = available_etymon_ids[term.target_key] local has_multiple_ids = target_ids and #target_ids > 1 local id_exists_in_disambiguation = false local matched_id = nil -- Count available senseids for the target page local senseid_count = 0 local target_prefix = term.target_key .. ":" if senseid_parent_etymon then for key, _ in pairs(senseid_parent_etymon) do if key:sub(1, #target_prefix) == target_prefix then senseid_count = senseid_count + 1 end end end local has_multiple_senseids = senseid_count > 1 if term.id then -- Check if user provided a valid senseid local senseid_key = term.target_key .. ":" .. term.id if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then if has_multiple_senseids then -- Ambiguous senseid: use senseid matched_id = term.id id_exists_in_disambiguation = true elseif has_multiple_ids then -- Unique senseid but ambiguous etymon: use etymon ID matched_id = term.etymon_id or term.id id_exists_in_disambiguation = true end else -- Check if user provided a valid etymon ID if has_multiple_ids and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.id then -- Ambiguous etymon: use etymon ID id_exists_in_disambiguation = true matched_id = term.id break end end end -- Fallback: check resolved etymon_id (e.g. from previous steps) if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then for _, id_data in ipairs(target_ids) do local stored_id = type(id_data) == "table" and id_data.id or id_data if stored_id == term.etymon_id then id_exists_in_disambiguation = true matched_id = term.etymon_id break end end end end end -- Use the matched ID if found if term.override or id_exists_in_disambiguation then part_data.id = matched_id or term.id end table.insert(parts, part_data) part_index = part_index + 1 end end end end if #parts == 0 then return {} end local affix_data = { lang = page_lang, parts = parts, pos = "Từ", sort_key = nil } local affix_categories = M.affix.get_affix_categories_only(affix_data) local result = {} for _, cat in ipairs(affix_categories) do if type(cat) == "table" then table.insert(result, cat.cat) else table.insert(result, cat) end end return result end -- Add borrowing-related categories (top-level only) local function collect_borrowing_categories(categories, page_lang, term, config) if config.borrowing_type == "borrowed" then local temp_categories = {} M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang) for _, cat in ipairs(temp_categories) do categories[cat] = true end end if config.specialized_borrowing then local result = M.etymology_specialized.specialized_borrowing { bortype = config.specialized_borrowing, lang = page_lang, sources = { term.lang }, terms = { { lang = term.lang, term = "-" } }, notext = true, nocat = false, } for cat_name in result:gmatch("%[%[Category:([^%]]+)%]%]") do categories[cat_name] = true end end end -- Add source-based derivation categories (top-level only) local function collect_source_derivation_categories(categories, page_lang, term, config) if not config.source_category_type then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = config.source_category_type, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end -- Add source language categories local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func) if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then return end local temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end if chain.inherited then temp_categories = {} M.etymology.insert_source_cat_get_display { lang = page_lang, source = term.lang, categories = temp_categories, borrowing_type = "terms inherited", nocat = false, } for _, cat in ipairs(temp_categories) do categories[cat] = true end end end -- Add root/word categories local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain, get_norm_lang_func, lang_exc, keyword) local pos_types = { root = "root", word = "word" } -- Determine pos: from term's postype, keyword's pos_override, or args.pos local pos local config = get_keyword_config(keyword, lang_exc) if term.postype then -- Term-level postype modifier takes highest priority pos = term.postype elseif config and config.pos_override then pos = config.pos_override elseif type(term.args) == "table" and term.args.pos then pos = term.args.pos end local pos_type = pos_types[pos] if not pos_type or term.unknown_term then return end -- Skip root/word categories for descendants of affix groups -- if pos_type then -- return -- end local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode() -- Skip self-references if same_language and root_title == term.title then return end -- Use makeEntryName to strip diacritics for category names local entry_name = term.lang:makeEntryName(term.title) local lang_name = page_lang:getCanonicalName() local cat_name if chain.passed_through then local etymon_lang_name = export.get_cat_name(term.lang) cat_name = lang_name .. " terms derived from the " .. etymon_lang_name .. " " .. pos_type .. " " .. entry_name else cat_name = lang_name .. " terms belonging to the " .. pos_type .. " " .. entry_name end -- Add ID disambiguation if needed (for roots/words: use etymon_id if resolved via senseid, otherwise use id) local target_ids = available_etymon_ids[term.target_key] local effective_id = term.etymon_id or term.id -- etymon_id if senseid, otherwise id is already an etymon id if target_ids and effective_id then local same_pos_count = 0 for _, id_data in ipairs(target_ids) do if type(id_data) == "table" and id_data.pos == pos then same_pos_count = same_pos_count + 1 end end if same_pos_count > 1 then cat_name = cat_name .. " (" .. effective_id .. ")" end end categories[cat_name] = true end -- Compute chain state for a term based on parent chain and keyword config -- Hyphen patterns for affix detection (regular hyphen + script-specific) local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- regular hyphen, Hebrew maqqef, Arabic tatweel, Mongolian hyphen -- Check if a term is an actual affix (not a non-affix member of an affix group) local function is_actual_affix(term) -- Check explicit aftype modifier if term.aftype then local normalized = aftype_aliases[term.aftype] or term.aftype return normalized ~= "non-affix" end -- Check if pos=root (treated as non-affix) if term.args and term.args.pos and term.args.pos == "root" then return false end -- Auto-detect by hyphen: prefix ends with -, suffix starts with -, etc. if term.title then local title = term.title -- Strip leading * for reconstructed terms before checking hyphens title = title:gsub("^%*", "") -- Check for hyphens at start or end (handles script-specific hyphens too) if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then return true end end -- Default: not an affix return false end local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term) -- Track if we're inside an actual affix (for suppressing root categories on descendants) -- Only set if the term is an actual affix (prefix, suffix, etc.), not a non-affix member local inside_affix = parent_chain.inside_affix if config.affix_categories and term and is_actual_affix(term) then inside_affix = true end -- If no_child_categories is set, disable everything if config.no_child_categories then return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = false, source = false, pos = false, recurse = false, inside_affix = inside_affix, } end local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang) local new_source = parent_chain.source and term_is_transitive -- For CROSS_LANG_NO_INTERNAL_SOURCE: track internal derivation language context -- Check if this term is internal relative to parent term's language (if parent_term_lang provided) -- or relative to page language (if no parent_term_lang) local internal_lang = parent_chain.internal_lang local is_internal_in_context = false if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then local check_lang = parent_term_lang or page_lang local term_lang_code = get_norm_lang_func(term_lang):getCode() local check_lang_code = get_norm_lang_func(check_lang):getCode() if internal_lang then -- Already in an internal derivation context: check if this term is also internal is_internal_in_context = term_lang_code == internal_lang else -- Check if this term is internal relative to parent term (or page if no parent) is_internal_in_context = term_lang_code == check_lang_code end end -- Source chain behavior for CROSS_LANG_NO_INTERNAL_SOURCE if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then if is_internal_in_context then -- Internal derivation new_source = false internal_lang = get_norm_lang_func(term_lang):getCode() else -- Cross-language new_source = parent_chain.source and term_is_transitive internal_lang = nil end end local new_pos = parent_chain.pos return { passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(), inherited = parent_chain.inherited and config.inherited_chain, source = new_source, pos = new_pos, internal_lang = internal_lang, recurse = new_source or new_pos, inside_affix = inside_affix, } end function export.render(opts) opts = opts or {} local data_tree = opts.data_tree local page_lang = opts.page_lang local available_etymon_ids = opts.available_etymon_ids local senseid_parent_etymon = opts.senseid_parent_etymon local get_norm_lang_func = opts.get_norm_lang_func local lang_exc = opts.lang_exc local categories = {} local seen = {} local lang_name = page_lang:getCanonicalName() local root_title = data_tree.title -- Collect the tree recursively local function collect(node, parent_chain, is_toplevel) -- Avoid processing same node twice if not node.unknown_term and node.title then local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "") if seen[key] then return end seen[key] = true end -- Collect affix categories at top level only if is_toplevel then local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc) for _, cat in ipairs(affix_cats) do categories[cat .. " " .. lang_name] = true end end -- Process each container for _, container in ipairs(node.children or {}) do local keyword = container.keyword local config = get_keyword_config(keyword, lang_exc) -- Skip invalid keywords if config then -- Process each term in the container for _, term in ipairs(container.terms or {}) do local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term) local no_child_categories = config.no_child_categories == true local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang) -- Top-level only processing if is_toplevel then -- Missing/ambiguous etymon tracking if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then categories["Mục từ tham chiếu đến nguyên từ bị thiếu " .. lang_name] = true end if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then categories[lang_name .. " entries referencing ambiguous etymons"] = true end if term.missing_descendants_header then categories[lang_name .. " entries referencing etymons without Descendants sections"] = true end if term.missing_descendants_entry then categories[lang_name .. " entries referencing etymons without this term in Descendants sections"] = true end -- Top-level category (e.g., "undefined derivations") if config.toplevel_category then categories[lang_name .. " " .. config.toplevel_category] = true end -- Borrowing categories (bor, lbor, slbor, ubor, obor) if config.borrowing_type or config.specialized_borrowing then collect_borrowing_categories(categories, page_lang, term, config) end -- Borrowing categories from <bor>, <lbor>, or <slbor> modifiers on :af/:surf terms if keyword == "affix" or keyword == "surf" then if term.bor then local bor_config = { borrowing_type = "borrowed" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.lbor then local bor_config = { specialized_borrowing = "learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) elseif term.slbor then local bor_config = { specialized_borrowing = "semi-learned" } collect_borrowing_categories(categories, page_lang, term, bor_config) end end -- Source-based derivation categories (sl, calque, pcal) if config.source_category_type then collect_source_derivation_categories(categories, page_lang, term, config) end -- Skip all child categorisation if no_child_categories is set if not no_child_categories then -- Source categories only if transitive if term_is_transitive then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end -- Pos categories always (unless no_child_categories) collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end else -- Below top level, respect the parent chain if parent_chain.source then collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func) end if parent_chain.pos then collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain, get_norm_lang_func, lang_exc, keyword) end end -- Recurse into term's children if needed and status allows if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then collect(term, term_chain, false) end end end end end -- Initial chain state local initial_chain = { passed_through = false, inherited = true, source = true, pos = true, internal_lang = nil, recurse = true, inside_affix = false, } collect(data_tree, initial_chain, true) local cat_list = {} for cat in pairs(categories) do table.insert(cat_list, cat) end return cat_list end return export qorsihbwugty14b18kb7pju5xrtdgqv Mô đun:etymon/text 828 378446 2344317 2317912 2026-04-12T01:31:38Z TheHighFighter2 42988 2344317 Scribunto text/plain local export = {} local loader = require("Module:module loader") local M = loader.init({ require = { en_utilities = "Module:en-utilities", references = "Module:references", }, loadData = { data = "Module:etymon/data", }, }) function export.render(opts) opts = opts or {} local data_tree = opts.data_tree local format_term_func = opts.format_term_func local max_depth = opts.max_depth local stop_at_blue_link = opts.stop_at_blue_link local curr_page = opts.curr_page local nodot = opts.nodot local stop_at_lang = opts.stop_at_lang local stop_at_lang_or_bluelink = opts.stop_at_lang_or_bluelink local children = data_tree.children if not children or #children == 0 then return "" end local top_l2 = data_tree.lang:getFullCode() .. ":" .. curr_page -- Get refs for a term local function get_term_refs(term, term_lang, depth) local term_l2 = term_lang:getFullCode() .. ":" .. curr_page if term.parsed_ref and (depth == 1 or term_l2 == top_l2) then return M.references.format_references(term.parsed_ref) end return "" end -- Build a text part for a single term local function build_term_part(term, current_lang, depth) local text = "" local new_lang = current_lang local lang_changed = term.lang:getCanonicalName() ~= current_lang:getCanonicalName() -- Use centralized format_term (handles suppress_term, unknown_term, and regular terms) local term_text = format_term_func(term) if lang_changed then new_lang = term.lang if term_text then text = term.lang:makeWikipediaLink() .. " " .. term_text elseif term.is_family then text = M.en_utilities.add_indefinite_article(term.lang:makeWikipediaLink() .. " language", false) else -- suppress_term with language change: show only language text = term.lang:makeWikipediaLink() end else text = term_text or "" end return { type = "term", text = text, refs = get_term_refs(term, new_lang, depth), lang = new_lang, is_uncertain = term.is_uncertain or false, } end -- Build text parts for a container local function build_container_part(container, node, depth, allow_continuation, fallback_to_bluelink) local keyword_info = container.keyword_info local keyword_modifiers = container.keyword_modifiers or {} local terms = container.terms or {} if not keyword_info or #terms == 0 then return nil end -- Skip building text part when invisible in text ("all", "text", or true) local inv = keyword_info.invisible if inv == "all" or inv == true or inv == "text" then return nil end local is_group = keyword_info.is_group local keyword_uncertain = keyword_modifiers.unc or false -- Determine text and phrase (allowing for overrides) local intro_text = keyword_info.text local phrase = keyword_info.phrase if keyword_modifiers.text then -- User-provided override: assumed to be lowercase phrase = keyword_modifiers.text -- Auto-capitalize for intro text (e.g., "derived from" -> "Derived from") intro_text = mw.ustring.upper(phrase:sub(1, 1)) .. phrase:sub(2) end -- Get keyword references local keyword_refs = "" if keyword_modifiers.ref then local parsed_keyword_refs = M.references.parse_references(keyword_modifiers.ref) if parsed_keyword_refs and parsed_keyword_refs ~= "" then keyword_refs = M.references.format_references(parsed_keyword_refs) end end -- Build term parts local term_parts = {} local current_lang = node.lang for _, term in ipairs(terms) do local term_part = build_term_part(term, current_lang, depth) if term_part.text ~= "" then table.insert(term_parts, term_part) current_lang = term_part.lang end end -- Check uncertainty distribution local uncertain_count = 0 for _, term_part in ipairs(term_parts) do if term_part.is_uncertain then uncertain_count = uncertain_count + 1 end end -- If keyword itself is uncertain, treat all terms as uncertain local all_uncertain = keyword_uncertain or (uncertain_count == #term_parts and #term_parts > 0) local has_mixed_uncertainty = not keyword_uncertain and uncertain_count > 0 and uncertain_count < #term_parts -- Check if there are more steps (only if continuation is allowed) local has_more_steps = false local next_node = nil local first_term = terms[1] -- Check if we should stop at this language local reached_stop_lang = false if stop_at_lang then for _, term in ipairs(terms) do if term.lang and term.lang:getCode() == stop_at_lang then reached_stop_lang = true break end end elseif stop_at_lang_or_bluelink then -- Check if we should stop at this language, or at the first bluelink if it's a redlink for _, term in ipairs(terms) do if term.lang and term.lang:getCode() == stop_at_lang_or_bluelink then if first_term.status == M.data.STATUS.OK then reached_stop_lang = true else fallback_to_bluelink = true end break end end if fallback_to_bluelink and first_term.status == M.data.STATUS.OK then reached_stop_lang = true end end if allow_continuation and not is_group and #terms == 1 and not reached_stop_lang then local first_term_children = first_term.children if first_term_children and #first_term_children > 0 and (not max_depth or depth < max_depth) then local next_container = first_term_children[1] local next_keyword_info = next_container and next_container.keyword_info if not (next_keyword_info and next_keyword_info.invisible) then if stop_at_blue_link then if first_term.status ~= M.data.STATUS.OK then has_more_steps = true next_node = first_term end else has_more_steps = true next_node = first_term end end end end return { type = "container", intro_text = intro_text, phrase = phrase, is_uncertain = all_uncertain, has_mixed_uncertainty = has_mixed_uncertainty, term_parts = term_parts, is_group = is_group, has_more_steps = has_more_steps, next_node = next_node, new_sentence = keyword_info.new_sentence or false, separate_clause = keyword_info.separate_clause or false, conj = keyword_modifiers.conj, -- custom conjunction: "and", "or", "and/or", etc. lit = keyword_modifiers.lit, keyword_refs = keyword_refs, fallback_to_bluelink = fallback_to_bluelink, } end -- Build the full tree of text parts local function build_text_tree(node, depth, allow_continuation, fallback_to_bluelink) local containers = node.children if not containers or #containers == 0 then return nil end local container_parts = {} -- Count containers that get a text part (invisible in text = "all", "text", or true) local visible_container_count = 0 for _, container in ipairs(containers) do local keyword_info = container.keyword_info local inv = keyword_info and keyword_info.invisible if not (inv == "all" or inv == true or inv == "text") then visible_container_count = visible_container_count + 1 end end -- If there are multiple visible containers at this level, don't allow continuation for any local has_multiple_containers = visible_container_count > 1 local should_allow_continuation = allow_continuation and not has_multiple_containers for _, container in ipairs(containers) do local part = build_container_part(container, node, depth, should_allow_continuation, fallback_to_bluelink) if part then -- Recursively build children if there are more steps if part.has_more_steps and part.next_node then part.continuation = build_text_tree(part.next_node, depth + 1, true, part.fallback_to_bluelink) end table.insert(container_parts, part) end end if #container_parts == 0 then return nil end return { type = "tree", container_parts = container_parts, depth = depth, } end -- Check if tree has mixed joining types local function check_complexity(tree) if not tree then return nil end local parts = tree.container_parts if #parts <= 1 then -- Single container if parts[1] and parts[1].continuation then return check_complexity(parts[1].continuation) end return nil end -- Multiple containers local has_or_join = false local has_new_sentence = false local has_separate_clause = false for i = 2, #parts do local part = parts[i] -- Ignore etydate parts for complexity checks if part.type ~= "etydate" then if part.new_sentence then has_new_sentence = true elseif part.separate_clause then has_separate_clause = true else has_or_join = true end end end local join_type_count = 0 if has_or_join then join_type_count = join_type_count + 1 end if has_new_sentence then join_type_count = join_type_count + 1 end if has_separate_clause then join_type_count = join_type_count + 1 end if join_type_count > 1 then error( "Cannot generate etymology text: mixed joining styles (e.g., alternatives joined with 'or' cannot be combined with calques or influences in the same list).") end return nil end -- Analyze tree and assign punctuation local function analyze_punctuation(tree, is_toplevel) if not tree then return end local parts = tree.container_parts local num_parts = #parts for i, part in ipairs(parts) do local is_first = (i == 1) local is_last = (i == num_parts) local next_part = parts[i + 1] -- Analyze term punctuation within container -- Terms use Oxford comma style: "A, B, or C" -- Custom conjunction can be specified via conj modifier (e.g., "and/or", "and") local num_terms = #part.term_parts local term_conj = part.conj or "or" -- default to "or" for j, term_part in ipairs(part.term_parts) do local is_last_term = (j == num_terms) if part.is_group then -- Group: terms joined with " + " term_part.joiner = is_last_term and "" or " + " elseif num_terms > 1 then -- Multiple terms not in a group: Oxford comma style if is_last_term then term_part.joiner = "" elseif j == num_terms - 1 then -- Second to last term if num_terms == 2 then term_part.joiner = " " .. term_conj .. " " else term_part.joiner = ", " .. term_conj .. " " end else term_part.joiner = ", " end else -- Single term term_part.joiner = "" end end -- Determine container punctuation based on what comes next if part.continuation then -- Has continuation part.punctuation = "," -- Recursively analyze continuation analyze_punctuation(part.continuation, false) elseif is_last then -- Last container part.punctuation = (is_toplevel and nodot) and "" or "." elseif next_part and next_part.new_sentence then -- Next container starts a new sentence part.punctuation = "." elseif next_part and next_part.separate_clause then -- Next container is a separate clause part.punctuation = "," else -- Not last, next is joined with "or" -- Containers use repeated "or" style: "A, or B, or C" part.punctuation = "," end -- Determine joiner to next part -- Containers use repeated "or" style: ", or" between each -- Custom conjunction can be specified via conj modifier local container_conj = part.conj or "or" -- default to "or" if not is_last then if next_part and next_part.new_sentence then -- New sentence part.joiner = " " elseif next_part and next_part.separate_clause then -- Separate clause part.joiner = " " else -- Same sentence: use custom conjunction or default "or" part.joiner = " " .. container_conj .. " " end else part.joiner = "" end -- Determine intro formatting -- Capitalize if first at top level, OR if this container starts a new sentence if (is_first and is_toplevel) or part.new_sentence then part.intro_capitalized = true part.use_full_intro = true else part.intro_capitalized = false part.use_full_intro = false end end end -- Assemble text from analyzed tree local function assemble_text(tree) if not tree then return "" end local result = "" for i, part in ipairs(tree.container_parts) do if part.type == "etydate" then result = result .. part.etydate_text if part.punctuation and part.punctuation ~= "" then result = result .. part.punctuation end if part.etydate_refs and part.etydate_refs ~= "" then result = result .. M.references.format_references(part.etydate_refs) end if part.joiner and part.joiner ~= "" then result = result .. part.joiner end else -- Build intro local intro if part.use_full_intro then if part.is_uncertain then intro = "Possibly " .. part.phrase else intro = part.intro_text end else if part.is_uncertain then intro = "possibly " .. part.phrase else intro = part.phrase end end result = result .. intro -- Build terms if #part.term_parts > 0 then result = result .. " " for j, term_part in ipairs(part.term_parts) do -- Add "possibly" prefix for uncertain terms when there's mixed uncertainty if part.has_mixed_uncertainty and term_part.is_uncertain then result = result .. "possibly " end result = result .. term_part.text -- Add joiner between terms if term_part.joiner ~= "" then -- Check if joiner contains comma (punctuation) local comma_pos = term_part.joiner:find(",") if comma_pos then -- Add up to and including comma result = result .. term_part.joiner:sub(1, comma_pos) -- Add refs after comma if term_part.refs ~= "" then result = result .. term_part.refs end -- Add rest of joiner result = result .. term_part.joiner:sub(comma_pos + 1) else -- No comma, add refs before joiner if term_part.refs ~= "" then result = result .. term_part.refs end result = result .. term_part.joiner end end end -- For the last term, add punctuation then refs local last_term = part.term_parts[#part.term_parts] if last_term and last_term.joiner == "" then if part.punctuation ~= "" then -- If we have literal text, punctuation goes AFTER it if part.lit then -- Add refs first (attached to term) if last_term.refs ~= "" then result = result .. last_term.refs end -- Add keyword refs if part.keyword_refs and part.keyword_refs ~= "" then result = result .. part.keyword_refs end -- Add literal text result = result .. ", literally “" .. part.lit .. "”" -- Add punctuation result = result .. part.punctuation else -- Normal behavior: punctuation then refs result = result .. part.punctuation if last_term.refs ~= "" then result = result .. last_term.refs end -- Add keyword refs after term refs if part.keyword_refs and part.keyword_refs ~= "" then result = result .. part.keyword_refs end end else -- No punctuation if last_term.refs ~= "" then result = result .. last_term.refs end -- Add keyword refs if part.keyword_refs and part.keyword_refs ~= "" then result = result .. part.keyword_refs end -- Add literal text if present (even without punctuation) if part.lit then result = result .. ", literally “" .. part.lit .. "”" end end end else -- No terms, just add punctuation and keyword refs if part.punctuation ~= "" then result = result .. part.punctuation end -- Add keyword refs even when there are no terms if part.keyword_refs and part.keyword_refs ~= "" then result = result .. part.keyword_refs end end -- Add continuation if part.continuation then result = result .. " " .. assemble_text(part.continuation) end -- Add joiner to next container if part.joiner ~= "" then result = result .. part.joiner end end end return result end local text_tree = build_text_tree(data_tree, 1, true, false) if not text_tree then return "" end -- Add etydate container if data_tree.etydate and data_tree.etydate ~= "" then table.insert(text_tree.container_parts, { type = "etydate", etydate_text = data_tree.etydate, etydate_refs = data_tree.etydate_refs, term_parts = {}, new_sentence = true, }) end check_complexity(text_tree) analyze_punctuation(text_tree, true) return assemble_text(text_tree) end return export mscg7aggtjqgbl7hwqfxfm3rjn77i82 Bản mẫu:pl-decl-combined-forms 10 392388 2344383 2344282 2026-04-12T04:33:30Z Hiyuune 50834 2344383 wikitext text/x-wiki {{inflection-table-top|title=Dạng kết hợp của {{mention|pl||{{{1|{{pagename}}}}}}}|tall=yes|palette=blue}} ! class="outer" | ! class="outer" | số ít ! class="outer" | số nhiều |- ! ngôi thứ nhất | {{l-self|pl|{{pagename}}m}} | {{l-self|pl|{{pagename}}śmy}} |- ! ngôi thứ hai | {{l-self|pl|{{pagename}}ś}} | {{l-self|pl|{{pagename}}ście}} |- ! ngôi thứ ba | {{l-self|pl|{{pagename}}}} | {{l-self|pl|{{pagename}}}} {{inflection-table-bottom}}<!-- --><noinclude>{{tài liệu}}</noinclude> 2hxu5hs7947e7jpy8hgd6xxehyksviu ū 0 392390 2344286 2026-04-11T13:40:14Z Lcsnes 40261 Trang mới: “{{minitoc}} {{-Latn-}} {{character info|image=Latin alphabet Ūū.png}} ==={{ĐM|desction}}=== {{head|mul|Chữ cái|chữ hoa|Ū}} #[[chữ cái|Chữ cái]] '''[[u]] viết thường''' với dấu phù hiệu ngang bên trên [[◌̄]] ([[macron]]). ==={{ĐM|see}}=== {{Latn-script}} =={{langname|agq}}== ==={{ĐM|pron}}=== *{{IPA4|agq|/ū/}} ==={{ĐM|letter}}=== {{head|agq|Chữ cái|chữ hoa|Ū}} #Chữ cái ''[[u]]'' viết thường với thanh trung ([[◌̄]]). #…” 2344286 wikitext text/x-wiki {{minitoc}} {{-Latn-}} {{character info|image=Latin alphabet Ūū.png}} ==={{ĐM|desction}}=== {{head|mul|Chữ cái|chữ hoa|Ū}} #[[chữ cái|Chữ cái]] '''[[u]] viết thường''' với dấu phù hiệu ngang bên trên [[◌̄]] ([[macron]]). ==={{ĐM|see}}=== {{Latn-script}} =={{langname|agq}}== ==={{ĐM|pron}}=== *{{IPA4|agq|/ū/}} ==={{ĐM|letter}}=== {{head|agq|Chữ cái|chữ hoa|Ū}} #Chữ cái ''[[u]]'' viết thường với thanh trung ([[◌̄]]). #:{{quote|agq|Zwɔ̂ŋ u wə̄n wə m fuŋ ŋgəa tsughu naʼ e Silìa e dzə̀m, ghî ghə̀ n nîi wò mbī tə aghì tə̀ dzaŋā ten tə̀ dzə̀m; ghəla ghe dzaŋā ŋgòʼ e dzàŋà tə̀n tə̀ dzə̀m àsùghò luʼ'''ū''' tə eghùe tò, ghəla ghe ki zʉ̀ ù biigh wo, ghəla ghe bvʉā bvʉ̀ kò, à ghəla ghe kpuw doʼō â luʼ'''ū''' tə ghùe tò, ù m baaŋ kɔʼɔ ghee.|Vậy, danh-tiếng Ngài đồn ra khắp cả xứ Sy-ri, người ta bèn đem cho Ngài mọi người đau-ốm, hay là mắc bịnh nọ tật kia, những kẻ bị quỉ ám, điên-cuồng, bại-xuội, thì Ngài chữa cho họ được lành cả. ([[s:Ma-thi-ơ/4#4:24|Ma-thi-ơ 4:24]])}} ==={{ĐM|see}}=== *{{letters|lang=agq|sc=Latn|qual=Bảng chữ cái Latinh tiếng Aghem|Aa|(Àà)|(Āā)|(Ââ)|(Ǎǎ)|Bb|Bv/bv|Ch/ch|Dd|Dz/dz|Ee|(Èè)|(Ēē)|(Êê)|(Ěě)|Ɛɛ|(Ɛ̀/ɛ̀)|(Ɛ̄/ɛ̄)|(Ɛ̂/ɛ̂)|(Ɛ̌/ɛ̌)|Ff|Gg|Gb/gb|Gh/gh|Hh|Ii|(Ìì)|(Īī)|(Îî)|(Ǐǐ)|Ɨɨ|(Ɨ̀/ɨ̀)|(Ɨ̄/ɨ̄)|(Ɨ̂/ɨ̂)|(Ɨ̌/ɨ̌)|Kk|Kp/kp|ʼ|Ll|Mm|(M̀/m̀)|Nn|(Ǹ/ǹ)|Ŋŋ|Oo|(Òò)|(Ōō)|(Ôô)|(Ǒǒ)|Ɔɔ|(Ɔ̀/ɔ̀)|(Ɔ̄/ɔ̄)|(Ɔ̂/ɔ̂)|(Ɔ̌/ɔ̌)|Pp|Pf/pf|Ss|Sh/sh|Tt|Ts/ts|Uu|(Ùù)|(Ūū)|(Ûû)|(Ǔǔ)|Uw/uw|Ʉʉ|(Ʉ̀/ʉ̀)|(Ʉ̄/ʉ̄)|(Ʉ̂/ʉ̂)|(Ʉ̌/ʉ̌)|Vv|Ww|Yy|Zz}} ==={{ĐM|ref}}=== *{{Chú thích web|agq|work=To kə Kəzə̀ kə̀ Fughu ko|author=Cameroon Association for Bible Translation and Literacy|year=2024|entryurl=https://www.bible.com/bible/2620/MAT.4.AGQ|entry=Matìo 4}} =={{langname|bss}}== ==={{ĐM|symbol}}=== {{head|bss|Ký tự|chữ hoa|Ū}} #Biến thể chữ {{l|bss|u}} viết thường với thanh ngang. #:{{ux|bss|nkú'''ū'''sē|[[kiến]] [[trắng]] [[nhỏ]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=bss|sc=Latn|qual=Bảng chữ cái Latinh tiếng Akoose|Aa|(Áá)|(Ââ)|(Ǎǎ)|Bb|Ch/cc|Dd|Ee|(Éé)|(Êê)|(Ěě)|Əə|(Ə́/ə́)|(Ə̂/ə̂)|(Ə̌/ə̌)|Ɛɛ|(Ɛ́/ɛ́)|(Ɛ̂/ɛ̂)|(Ɛ̌/ɛ̌)|Ff|Gg|Hh|Ii|(Íí)|(Îî)|(Ǐǐ)|Jj|Kk|Ll|Mm|(Ḿḿ)|Nn|(Ńń)|Ny/ny|Ŋŋ|Oo|(Óó)|(Ôô)|(Ǒǒ)|Ɔɔ|(Ɔ́/ɔ́)|(Ɔ̂/ɔ̂)|(Ɔ̌/ɔ̌)|Pp|Rr|Ss|Tt|Uu|(Úú)|(Ûû)|(Ǔǔ)|Vv|Ww|Yy|ʼ}} ==={{ĐM|ref}}=== *{{Chú thích web|entry=nkúūsē|entryurl=https://www.webonary.org/akoose/gf24b52ba-6597-4653-b2d9-136270df5d41/|editor=Robert Hedinger|work=Akoose–English Dictionary|year=2020|publisher=SIL International}} =={{langname|bax}}== ==={{ĐM|symbol}}=== {{head|bax|Ký tự|chữ hoa|Ū}} #Chữ cái ''[[u]]'' viết thường với dấu thanh trung ([[◌̄]]). ==={{ĐM|see}}=== *{{letters|lang=bax|sc=Latn|qual=Bảng chữ cái Latinh tiếng Bamum|Aa|(Áá)|(Àà)|(Ǎǎ)|(Āā)|(Ââ)|Bb|Ɓɓ|Dd|Gb/gb|Mb/mb|Ee|(Éé)|(Èè)|(Ěě)|(Ēē)|(Êê)|Ɛɛ|(Ɛ́/ɛ́)|(Ɛ̀/ɛ̀)|(Ɛ̌/ɛ̌)|(Ɛ̄/ɛ̄)|(Ɛ̂/ɛ̂)|Əə|(Ə́/ə́)|(Ə̀/ə̀)|(Ə̌/ə̌)|(Ə̄/ə̄)|(Ə̂/ə̂)|Ff|Gg|Ɣɣ|Ii|(Íí)|(Ìì)|(Ǐǐ)|(Īī)|(Îî)|Jj|Kk|Kp/kp|Ll|Mm|Ŋŋ|Nn|Ny/ny|Oo|(Óó)|(Òò)|(Ǒǒ)|(Ōō)|(Ôô)|Ɔɔ|(Ɔ́/ɔ́)|(Ɔ̀/ɔ̀)|(Ɔ̌/ɔ̌)|(Ɔ̄/ɔ̄)|(Ɔ̂/ɔ̂)|Pp|Rr|Ss|ʃ/sh|Tt|Uu|(Úú)|(Ùù)|(Ǔǔ)|(Ūū)|(Ûû)|Üü|(Ǘǘ)|(Ǜǜ)|(Ǚǚ)|(Ǖǖ)|(Ü̂/ü̂)|Ʉʉ|(Ʉ́/ʉ́)|(Ʉ̀/ʉ̀)|(Ʉ̌/ʉ̌)|(Ʉ̄/ʉ̄)(Ʉ̂/ʉ̂)|Vv|Ww|Yy|Zz|ʼ}} =={{langname|bcq}}== ==={{ĐM|pron}}=== *{{IPA4|bcq|[u˧]}} ==={{ĐM|letter}}=== {{head|bcq|Chữ cái|chữ hoa|Ū}} #Chữ Latinh {{l|bcq|u}} viết thường với dấu thanh điệu ◌̄. ==={{ĐM|see}}=== *{{letters|lang=bcq|sc=Latn|qual=Bảng chữ cái Latinh tiếng Bench|Aa|(A̋/a̋)|(Áá)|(Āā)|(Àà)|(Ȁȁ)|(Ǎǎ)|Bb|Cc|Ch/ch|Cʼ/cʼ|Dd|Ee|(E̋/e̋)|(Éé)|(Ēē)|(Èè)|(Ȅȅ)|(Ěě)|Gg|Hh|Ii|Kk|Ll|Mm|Nn|Oo|(Őő)|(Óó)|(Ōō)|(Òò)|(Ȍȍ)|(Ǒǒ)|Pp|P’/p’|Qq|Rr|Ss|Sh/sh|Tt|Ts/ts|Uu|(Űű)|(Úú)|(Ūū)|(Ùù)|(Ȕȕ)|(Ǔǔ)|Vv|Ww|Xx|Xh/xh|Xs/xs|X’/x’|Yy|Zh/zh|Zz|Z’/z’}} =={{langname|brx}}== ==={{ĐM|alt}}=== *{{alter|brx|ú}} ==={{ĐM|pron}}=== *{{IPA4|brx|[uː]}} ==={{ĐM|letter}}=== {{head|brx|Chữ cái|chữ hoa|Ū}} #{{n-g|Chữ cái Latinh viết thường biểu thị nguyên âm '''u dài''' trong tiếng Bodo.}} ==={{ĐM|see}}=== *{{letters|lang=brx|sc=Latn|qual=Bảng chữ cái Latinh tiếng Bodo|Aa|(Åå)|(Àà)|(Áá)|(Āā)|Bb|Cc|Dd|Ee|(Êê)|(Èè)|(Éé)|(Ēē)|Gg|Hh|Ii|(Íí)|(Īī)|Kk|Kh/kh|Ll|Mm|Nn|Ṅṅ|Oo|(Ôô)|(Ōō)|Ŏŏ|Pp|Ph/ph|Rr|(Ṛṛ)|Ss|Tt|Th/th|Uu|(Ŭŭ)|(Ùù)|(Úú)|(Ūū)|Ww|Yy|Zz}} =={{langname|ckt}}== ==={{ĐM|letter}}=== {{head|ckt|Chữ cái|chữ hoa|Ū}} #{{label|ckt|obsolete}} Chữ cái thứ 29 viết thường trong bảng chữ cái Latinh tiếng Chukot năm 1931. ==={{ĐM|see}}=== *{{letters|lang=ckt|sc=Latn|qual=Bảng chữ cái Latinh tiếng Chukot 1931-1937|Аа|Āā|Bb|Cc|Dd|Ее|Ēē|Əə|Ə̄/ə̄|Ff|Gg|Hh|Ii|Īī|Jj|Kk|Ll|Mm|Nn|Ŋŋ|Oo|Ōō|Pp|Qq|Rr|Ss|Tt|Uu|Ūū|Vv|Ww|Zz|Ьь}} =={{langname|fmp}}== ==={{ĐM|symbol}}=== {{head|fmp|Ký tự|chữ hoa|Ū}} #Chữ cái {{l|fmp|u}} viết thường với dấu thanh điệu trung ◌̄. ==={{ĐM|see}}=== *{{letters|lang=fmp|sc=Latn|qual=Bảng chữ cái Latinh tiếng Feʼfeʼ|Aa|(Áá)|(Āā)|(Àà)|(Ǎǎ)|(Ââ)|Ɑɑ|(Ɑ́/ɑ́)|(Ɑ̄/ɑ̄)|(Ɑ̀/ɑ̀)|(Ɑ̌/ɑ̌)|(Ɑ̂/ɑ̂)|Bb|Cc|Dd|Ee|(Éé)|(Ēē)|(Èè)|(Ěě)|(Êê)|Əə|(Ə́/ə́)|(Ə̄/ə̄)|(Ə̀/ə̀)|(Ə̌/ə̌)|(Ə̂/ə̂)|Ff|Gg|Gh/gh|Hh|Ii|(Íí)|(Īī)|(Ìì)|(Ǐǐ)|(Îî)|Jj|Kk|Ll|Mm|Nn|Ŋŋ|Oo|(Óó)|(Ōō)|(Òò)|(Ǒǒ)|(Ôô)|Pp|Ss|Sh/sh|Tt|Uu|(Úú)|(Ūū)|(Ùù)|(Ǔǔ)|(Ûû)|Ʉʉ|(Ʉ́/ʉ́)|(Ʉ̄/ʉ̄)|(Ʉ̀/ʉ̀)|(Ʉ̌/ʉ̌)|(Ʉ̂/ʉ̂)|Vv|Ww|Yy|Zz|Zh/zh|ʼ/'}} =={{langname|haw}}== ==={{ĐM|pron}}=== *{{IPA4|haw|/ˈuː/}} ==={{ĐM|letter}}=== {{head|haw|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài. #:{{ux|haw|hōk'''ū'''|[[sao]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=haw|sc=Latn|qual=Bảng chữ cái Latinh tiếng Hawaii|Aa|(Āā)|Ee|(Ēē)|Ii|(Īī)|Oo|(Ōō)|Uu|(Ūū)|Hh|Kk|Ll|Mm|Nn|Pp|Ww|ʻ}} ==={{ĐM|etym}} 1=== {{dercat|haw|poz-oce-pro|pqe-pro|poz-cet-pro|poz-pro|inh=4}} Từ {{inherited|haw|poz-pol-pro|*susu}} (đối chiếu {{cognate|mi|ū}}, {{cognate|to|huhu}}) từ {{inherited|haw|poz-oce-pro|*susu}} (đối chiếu với {{cognate|fj|sucu}}), từ {{inherited|haw|poz-pro|*susu}} (đối chiếu với {{cognate|ms|susu}}), từ {{inherited|haw|map-pro|*susu}} (đối chiếu với {{cognate|tl|suso}}). ===={{ĐM|n}}==== {{head|haw|Danh từ}} #[[ngực|Ngực]]. #[[vú|Vú]]. ====={{ĐM|der}}===== *{{l|haw|waiū||sữa mẹ}} ==={{ĐM|etym}} 2=== Từ {{inherited|haw|poz-pol-pro|*su}}. Đối chiếu {{cognate|to|hū}}. ==={{ĐM|v}}=== {{head|haw|Động từ}} #{{lb|haw|stative}} [[nhỏ giọt|Nhỏ giọt]]. #{{lb|haw|stative}} [[rỉ|Rỉ]] [[nước]]. ====={{ĐM|der}}===== *{{l|haw|[[hoʻoū]], [[hoʻū]]||[[ngâm]], [[dấp]], làm [[ướt]]}} ==={{ĐM|ref}}=== *{{cite-book| author=Pukui, Mary Kawena| author2=Elbert, Samuel H.| year=1957| title=English–Hawaiian Dictionary| chapter=ū| chapterurl=https://wehewehe.org/gsdl2.85/cgi-bin/hdict?e=q-11000-00---off-0hdict--00-1----0-10-0---0---0direct-10-ED--4--textpukuielbert%2ctextmamaka-----0-1l--11-haw-Zz-1---Zz-1-home-%c5%ab--00-4-1-00-0--4----0-0-11-00-2utfZz-8-00&a=d&d=D19619#hero-bottom-banner}}. Trong {{cite-web| work=Nā Puke Wehewehe ʻŌlelo Hawaiʻi| year=2003| url=http://www.wehewehe.org}}. =={{langname|win}}== ==={{ĐM|pron}}=== *{{IPA4|win|[uː]}} ==={{ĐM|letter}}=== {{head|win|Chữ cái|chữ hoa|Ū}} #{{label|win|Nebraska}} Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài, tương ứng với ''{{l|win|uu}}'' tại Wisconsin. #:{{ux|win|'''ū'''c|tr='''uu'''k|[[rìa]], [[cạnh]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=win|sc=Latn|qual=Bảng chữ cái Latinh tiếng Hocak|Aa|(Āā)|Ąą|(Ą̄/ą̄)|Bb|Cc|Ee|(Ēē)|Gg|Ğğ|Hh|Ii|(Īī)|Įį|(Į̄/į̄)|Jj|Kk|Mm|Nn|Oo|(Ōō)|Pp|Rr|Ss|Šš|Tt|Uu|(Ūū)|Ųų|(Ų̄/ų̄)|Ww|Xx|Yy|Zz|Žž|'}} ==={{ĐM|ref}}=== *{{Chú thích web|en|publisher=Ho-Chunk Nation|year=2026|entry=uu|entryurl=https://dictionary.hochunk.org/#/L/uu|work=Ho-Chunk Dictionary Online}} *{{Chú thích sách|en|title=[https://web.archive.org/web/20210710171553/https://www.christianlehmann.eu/publ/ASSidUE21.pdf Hocąk-English/English-Hocąk Learner's Dictionary]|publisher=University of Erfurt|year=2006|page=36|author=Johannes Helmbrecht & Christian Lehmann}} =={{langname|jab}}== ==={{ĐM|letter}}=== {{head|jab|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 30 viết thường trong bảng chữ cái Latinh tiếng Hyam. #:{{quote|jab|S'''ū'''n na̱ ka̱ gywasmen na̱ ywut di gaar Nom ma̱ dzaam ma̱ di nyi, na̱yi nga̱yi shu, ka̱ na̱yi ka̱ shu, ka̱ na̱yi ku ri bo. Ka̱ ywut di gaar mo cu-hyong yikywarfaa di nkiseny gya̱set ghyi kpyob gha.|nguyền xin ân-điển và sự bình-an ban cho anh em từ nơi Đấng hiện có, đã có, và còn đến, cùng từ nơi bảy vì thần ở trước ngôi Ngài, ([[s:Khải huyền/1#1:4|Ma-thi-ơ 1:4]])}} ==={{ĐM|see}}=== *{{letters|lang=jab|sc=Latn|qual=Bảng chữ cái Latinh tiếng Hyam|Aa|Āā|Ǎǎ|A̱/a̱|Bb|Cc|Dd|Ee|Ēē|E̱/e̱|Ff|Gg|Hh|Ii|Ǐǐ|I̱/i̱|Jj|Kk|Ll|Mm|Nn|Oo|Ōō|Ǒǒ|Pp|Rr|Ss|Tt|Uu|Ūū|Vv|Ww|Yy|Zz}} ==={{ĐM|ref}}=== *{{Chú thích web|jab|author=Nigeria Bible Translation Trust|entryurl=https://www.bible.com/bible/2521/REV.1.HYAMNT|entry=Shun-ndaa Yoh 1|year=2017|work=Mbyeny Jok Nom di ho Hyam Ham ma̱}} =={{langname|ifb}}== ==={{ĐM|letter}}=== {{head|ifb|Chữ cái|chữ hoa|Ū}} #Biến thể chữ {{l|ifb|u}} trong bộ chữ Latinh tiếng Ifugao Batad. #:{{ux|ifb|'''ū'''ban|[[tóc bạc]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=ifb|sc=Latn|qual=Bảng chữ cái Latinh tiếng Ifugao Batad|a|(ā)|b|d|e|(ē)|g|h|i|(ī)|k|l|m|n|o|(ō)|p|s|t|u|(ū)|w|y|ꞌ}} ==={{ĐM|ref}}=== *{{Chú thích web|entry=u|entryurl=https://www.webonary.org/batad-ifugao/browse/browse-vernacular/?key=ifb&letter=u&lang=en|editor=Leonard E. Newell|work=Batad Ifugao - English Dictionary|year=1993|publisher=Linguistic Society of the Philippines |location=Manila}} *{{Chú thích web|work=[https://www.sil.org/system/files/reapdata/95/02/13/95021351436193586802650181872024268551/Ifugao_Batad_Orthography_Fact_Sheet__ifb___ifb_.pdf Ifugao Batad Orthography FactSheet ifb]|year=2012|location=Philippines}} =={{langname|igl}}== ==={{ĐM|letter}}=== {{head|igl|Chữ cái|chữ hoa|Ū}} #Chữ cái ''{{l|igl|u}}'' viết thường với thanh điệu cao trung ◌̄. #:{{ux|igl|Íchámú-ógwúmẹ́l'''ū '''|[[chín]] [[trăm]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=igl|sc=Latn|qual=Bảng chữ cái Latinh tiếng Igala|native name=àmulú-ùkọ̀là|Aa|(Áá)|(Àà)|(Āā)|Bb|Ch/ch|Dd|Ee|(Éé)|(Èè)|(Ēē)|Ẹẹ|(Ẹ́/ẹ́)|(Ẹ̀/ẹ̀)|(Ẹ̄/ẹ̄)|Ff|Gg|Gb/gb|Gw/gw|Hh|Ii|(Íí)|(Ìì)|(Īī)|Jj|Kk|Kp/kp|Kw/kw|Ll|Mm|Nn|(Ṅṅ)|Ññ|Ñm/ñm|Ñw/ñw|Ny/ny|Oo|(Óó)|(Òò)|(Ōō)|Ọọ|(Ọ́/ọ́)|(Ọ̀/ọ̀)|(Ọ̄/ọ̄)|Pp|Rr|Tt|Uu|(Úú)|(Ùù)|(Ūū)|Ww|Yy}} ==={{ĐM|ref}}=== *{{Chú thích web|author=Kigala online|title=[https://kigalaonline.wordpress.com/category/vocabulary/ Vocabulary]|work=Wordpress|year=2019}} =={{langname|ket}}== ==={{ĐM|pron}}=== *{{IPA4|ket|[uː]}} ==={{ĐM|letter}}=== {{head|ket|Chữ cái|chữ hoa|Ū}} #{{label|ket|obsolete}} Chữ cái thứ 31 viết thường trong bảng chữ cái Latinh tiếng Ket thập niên 1930. ==={{ĐM|see}}=== *{{letters|lang=ket|sc=Latn|qual=Bảng chữ cái Latinh tiếng Ket thập niên 1930|Aa|Āā|Ææ|Bb|Çç|Dd|Ee|Ēē|Əə|Ff|Gg|Hh|Ҕҕ|Ii|Īī|Jj|Kk|Ll|Mm|Nn|Ņņ|Ŋŋ|Oo|Ōō|Pp|Qq|Rr|Ss|Şş|Tt|Uu|Ūū|Vv|Zz|Ƶƶ|Ьь}} ==={{ĐM|ref}}=== *{{Chú thích sách|author=Kotorova, Elizaveta & Andrey Nefedov (eds.)|year=2015|title=Comprehensive Ket Dictionary / Большой словарь кетского языка (2 vols)|publisher=Lincom Europa|location=Munich}} =={{langname|kix}}== ==={{ĐM|pron}}=== *{{IPA4|kix|/u³³/}} ==={{ĐM|letter}}=== {{head|kix|Chữ cái|chữ hoa|Ū}} #Chữ ''{{l|kix|u}}'' viết thường với dấu thanh điệu ◌̄. #:{{ux|kix|y'''ū'''oh|[[ủn ỉn]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=kix|sc=Latn|qual=Bảng chữ cái Latinh tiếng Khiamniungan|Aa|(Āā)|(Àà)|Ch/ch|Ee|(Ēē)|(Èè)|Hh|Ii|(Īī)|(Ìì)|Jj|Kk|Kh/kh|Ll|Mm|Nn|Ng/ng|Ny/ny|Oo|(Ōō)|(Òò)|Pp|Ph/ph|Ss|Sh/sh|Tt|Th/th|Ts/ts|Tsh/tsh|Uu|(Ūū)|(Ùù)|Üü|(Ǖ/ǖ)|(Ǜ/ǜ)|Vv|Ww|Yy}} =={{langname|naq}}== ==={{ĐM|pron}}=== *{{IPA4|naq|[uː]}} ==={{ĐM|letter}}=== {{head|naq|Chữ cái|chữ hoa|Ū}} #Chữ cái Latinh viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{quote|naq|Tsî nē ǃh'''ū'''b ǃnân ge ǃ'''ū'''mû ǃhuniǀurib, bodelium ǃgâihamx'''ū'''-i tsî oniksǀuidi tsîna gere hōhe.|Vàng xứ nầy rất cao; đó lại có nhũ-hương và bích-ngọc. ([[s:Sáng thế Ký/2#2:12|Sáng thế Ký 2:12]])}} ==={{ĐM|ref}}=== *{{Chú thích web|naq|author=Bible Society in Namibia|entryurl=https://www.bible.com/bible/548/GEN.2.KKG20|entry=Genesis 2|year=2020|work=Khoekhoegowab}} =={{langname|kub}}== ==={{ĐM|letter}}=== {{head|kub|Chữ cái|chữ hoa|Ū}} #Chữ cái ''[[u]]'' viết thường với dấu thanh trung ([[◌̄]]). #:{{quote|kub|Unde w'''ū''' tī kú bá isim-m skeb pú wū ame tí r'''ū'''rōb. Ame kō-m tī ame ú t'''ū'''nn fob apwā afxen-w'''ū''' bē.|Có Đấng quyền-phép hơn ta đến sau ta; ta không đáng cúi xuống mở dây giày Ngài. ([[s:Mác/1#1:7|Mác 1:7]])}} ===={{ĐM|see}}==== *{{letters|lang=kub|sc=Latn|qual=Bảng chữ cái Latinh tiếng Kutep|Aa|(Āā)|(Áá)|(Ââ)|Bb|Cc|Dd|Ee|(Ēē)|(Éé)|(Êê)|Ff|Gg|Hh|Ii|(Īī)|(Íí)|(Îî)|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Rr|Ss|Tt|Uu|(Ūū)|(Úú)|(Ûû)|Vv|Ww|Xx|Yy|Zz}} ==={{ĐM|ref}}=== *{{Chú thích web|kub|author=Wycliffe Bible Translators, Inc. & The Nigeria Bible Translation Trust|entryurl=https://live.bible.is/bible/KUBTBL/MRK/1|entry=Kucangtsi 1|year=1995|work=Bible.is}} =={{langname|ltg}}== ==={{ĐM|pron}}=== *{{IPA4|ltg|/uː/}} ==={{ĐM|letter}}=== {{head|ltg|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 32 viết thường trong bảng chữ cái Latinh tiếng Latgale. #:{{ux|ltg|'''ū'''ga|[[quả]] [[mọng]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=ltg|sc=Latn|qual=Bảng chữ cái Latinh tiếng Latgale|Aa|Āā|Bb|Cc|Čč|Dd|Ee|Ēē|Ff|Gg|Ģģ|Hh|Ii|Yy|Īī|Jj|Kk|Ķķ|Ll|Ļļ|Mm|Nn|Ņņ|Oo|Ōō|Pp|Rr|Ss|Šš|Tt|Uu|Ūū|Vv|Zz|Žž}} =={{langname|lv}}== {{wikipedia|lv:}} ==={{ĐM|etym}}=== Được đề xuất năm 1908 trong chính tả tiếng Latvia mới và đưa vào giảng dạy từ năm 1909. Trước đó, tiếng Latvia được viết bằng chữ Đức Fraktur và đôi khi bằng chữ Kirin. ==={{ĐM|pron}}=== *{{lv-IPA|uː}} ==={{ĐM|letter}}=== {{head|lv|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 30 viết thường trong bảng chữ cái Latinh tiếng Latvia, gọi là chữ '''{{l|lv|garais u}}'''. #:{{ux|lv|[[jūra#Tiếng_Latvia|j'''ū'''ra]]|[[biển]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=lv|sc=Latn|qual=Bảng chữ cái Latinh tiếng Latvia}} =={{langname|lt}}== {{wikipedia|lt:}} ==={{ĐM|pron}}=== *{{IPA4|lt|/uː/}} ==={{ĐM|letter}}=== {{head|lt|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 29 viết thường trong bảng chữ cái Latinh tiếng Litva. #:{{ux|lt|[[sūnus#Tiếng_Litva|s'''ū'''nus]]|[[con trai]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=lt|sc=Latn|qual=Bảng chữ cái Latinh tiếng Litva|Aa|Ąą|Bb|Cc|Čč|Dd|Ee|Ęę|Ėė|Ff|Gg|Hh|Ii|Įį|Yy|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Rr|Ss|Šš|Tt|Uu|Ųų|Ūū|Vv|Yy|Zz|Žž}} =={{langname|liv}}== ==={{ĐM|pron}}=== *{{qualifier|âm tiết}} {{liv-IPA|uː}} ==={{ĐM|letter}}=== {{head|liv|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 36 viết thường trong bảng chữ cái Latinh tiếng Livonia. #:{{ux|liv|'''ū'''ļ|[[môi]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=liv|sc=Latn|qual=Bảng chữ cái Latinh tiếng Livonia}} =={{langname|mi}}== ==={{ĐM|pron}}=== *{{IPA4|mi|/uː/|[uː]}} ==={{ĐM|letter}}=== {{head|mi|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 17 viết thường trong bảng chữ cái Latinh tiếng Maori. #:{{ux|mi|{{l|mi|mātai mat'''ū'''}}|[[hóa học]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=mi|sc=Latn|qual=Bảng chữ cái Latinh tiếng Maori|Aa|Āā|Ee|Ēē|Hh|Ii|Īī|Kk|Mm|Nn|Oo|Ōō|Pp|Rr|Tt|Uu|Ūū|Ww|Ng/ng|Wh/wh}} ==={{ĐM|etym}} 1=== Từ {{inherited|mi|poz-pol-pro|*susu}} (đối chiếu {{cognate|haw|ū}}, {{cognate|to|huhu}}) từ {{inherited|mi|poz-oce-pro|*susu}} (đối chiếu với {{cognate|fj|sucu}}), từ {{inherited|mi|poz-pro|*susu}} (đối chiếu với {{cognate|ms|susu}}), từ {{inherited|mi|map-pro|*susu}} (đối chiếu với {{cog|tl|suso}}). ===={{ĐM|pron}}==== *{{mi-IPA|ū|stress='}} ===={{ĐM|n}}==== {{head|mi|Danh từ}} #[[ngực|Ngực]]. #[[vú|Vú]]. ====={{ĐM|der}}===== *{{l|mi|waiū||sữa mẹ}} ==={{ĐM|etym}} 2=== {{rfe|mi}} ===={{ĐM|v}}==== {{head|mi|Động từ}} #[[đánh|Đánh]] [[trúng]]. #[[cập|Cập]] [[bến]], [[lên bờ]]. #[[tuân thủ|Tuân thủ]]. #{{label|mi|stative}} [[cố định|Cố định]], [[vững chắc]]. ==={{ĐM|ref}}=== *{{Chú thích web|work=Te Aka Māori Dictionary|entryurl=https://maoridictionary.co.nz/search?idiom=&phrase=&proverb=&loan=&histLoanWords=&keywords=%C5%AB|entry=ū|year=2003-2023}} =={{langname|mh}}== ==={{ĐM|pron}}=== *{{IPA4|mh|[ʌ]}} ==={{ĐM|letter}}=== {{head|mh|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 23 viết thường bảng chữ cái Latinh tiếng Marshall. #:{{ux|mh|'''ū'''l'''ū'''l|[[rìu]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=mh|sc=Latn|qual=Bảng chữ cái Latinh tiếng Marshall|Aa|Āā|Bb|Dd|Ee|Ii|Jj|Kk|Ll|Ļļ|Mm|M̧/m̧|Nn|Ņņ|N̄/n̄|Oo|O̧/o̧|Ōō|Pp|Rr|Tt|Uu|Ūū|Ww}} ==={{ĐM|ref}}=== *{{Chú thích web|en|work=Marshallese-English Online Dictionary|entryurl=https://www.trussel2.com/MOD/MED2U.htm|entry=u|year=2023}} =={{langname|nan-hbl}}== {{zh-see|有|poj}} =={{langname|ruq}}== ==={{ĐM|pron}}=== *{{IPA4|ruq|[uː]}} ==={{ĐM|letter}}=== {{head|ruq|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài. ==={{ĐM|see}}=== *{{letters|lang=ruq|sc=Latn|qual=Bảng chữ cái Latinh tiếng Moglena-Rumani|Aa|(Āā)|Ăă|Bb|Cc|Dd|(Dz/dz)|(Dž/dž)|(D̦/d̦)|Ee|(Ēē)|(Ęę)|Ff|Gg|(Ǧǧ)|Hh|i̭/i|(Īī)|Jj|Kk|Ll|(Łł)|L’/l’|Mm|Nn|Ńń|Oo|(Ōō)|(Ǫǫ)|Ọọ|Pp|Qq|Rr|Ss|Șș|Tt|(Tš/tš)|Țț|Uu|(Ūū)|Vv|Ww|Xx|Yy|Zz}} =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-romaji}} #{{ja-romanization of|うう}} #{{ja-romanization of|うー}} #{{ja-romanization of|ウー}} =={{langname|caq}}== ==={{ĐM|pron}}=== *{{IPA4|caq|[uː]}} ==={{ĐM|letter}}=== {{head|caq|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 31 viết thường trong bảng chữ cái Latinh tiếng Nicobar Car. #:{{ux|caq|{{l|caq|'''ū'''ch-ngö-rĕ}}|[[ngồi]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=caq|sc=Latn|qual=Bảng chữ cái Latinh tiếng Nicobar Car|Aa|Āā|Ch/ch|Ĕĕ|Ēē|Ee|Ëë|Ff|Hh|Ii|Īī|Kk|Ll|Mm|Nn|Ng/ng|Ny/ny|Ṅṅ|Oo|Ōō|Òò|Ôô|Öö|Öö/öö|Pp|Rr|Ṛṛ|Ss|Tt|Uu|Ūū|Vv|Yy}} ==={{ĐM|ref}}=== *{{Chú thích web|caq|author=Bible Society of India|entryurl=https://www.bible.com/bible/1060/RUT.1.CANIBSI|entry=RŪT 1|work=TÖHET LĪPÖRE (Re-edited) Bible (BSI)|year=2024}} =={{langname|nik}}== ==={{ĐM|pron}}=== *{{IPA4|nik|[uː]}} ==={{ĐM|letter}}=== {{head|nik|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 31 viết thường trong bảng chữ cái Latinh tiếng Nicobar Nam. #:{{ux|nik|[[tölūi#Tiếng_Nicobar_Nam|töl'''ū'''i]]|[[chuối]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=nik|sc=Latn|qual=Bảng chữ cái Latinh tiếng Nicobar Nam|Aa|Āā|Ch/ch|Ĕĕ|Ēē|Ee|Ëë|Ff|Hh|Ii|Īī|Kk|Ll|Mm|Nn|Ng/ng|Ny/ny|Ṅṅ|Oo|Ōō|Òò|Ôô|Öö|Öö/öö|Pp|Rr|Ṛṛ|Ss|Tt|Uu|Ūū|Vv|Yy}} =={{langname|ncb}}== ==={{ĐM|pron}}=== *{{IPA4|ncb|[uː]}} ==={{ĐM|letter}}=== {{head|ncb|Chữ cái}} #Chữ cái Latinh viết thường thể hiện nguyên âm thứ 9 trong tiếng Nicobar Trung. #:{{ux|ncb|{{l|ncb|y'''ū'''e}}|[[ruồi]] [[nhà]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=ncb|sc=Latn|qual=Chữ Latinh tiếng Nicobar Trung|a/ā|e/ë|ĕ/ē|eu/eū|i/ī|o/ō|ò/ô|ö/öö|u/ū|ea|eö|euö|iö|oö|ua|uö|eaṅ|euöṅ|iöṅ|uaṅ|uöṅ|ch|f|h|k|ḵ|l|m|n|ng|ny|p|r|s|t|v|y}} =={{langname|niu}}== ==={{ĐM|pron}}=== *{{IPA4|niu|[uː]}} ==={{ĐM|letter}}=== {{head|niu|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài. #:{{ux|niu|t'''ū'''mea|[[xám]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=niu|sc=Latn|qual=Bảng chữ cái Latinh tiếng Niue|Aa|(Āā)|Ee|(Ēē)|Ii|(Īī)|Oo|(Ōō)|Uu|(Ūū)|Ff|Gg|Hh|Kk|Ll|Mm|Nn|Pp|Tt|Vv|Rr|Ss}} ==={{ĐM|ref}}=== *{{Chú thích sách|en|author=Niue, University of Hawaii at Manoa. Dept. of Linguistics|page=[https://books.google.com/books?id=hOaGrwSRBMIC&pg=PA336 336]|title=Niue Language Dictionary|year=1997|publisher=University of Hawaii Press|isbn=9780824819330}} =={{langname|bud}}== ==={{ĐM|symbol}}=== {{head|bud|Ký tự|chữ hoa|Ū}} #Chữ {{l|bud|u}} viết thường với thanh bằng. #:{{ux|bud|yùk'''ū'''|[[nhảy]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=bud|sc=Latn|qual=Bảng chữ cái Latinh tiếng Ntcham|Aa|(Áá)|(Àà)|Bb|(B́/b́)|Cc|Dd|Ee/ee|(Ée/ée)|Èe/èe|Ff|Gg|Gb/gb|Ii|(Íí)|(Ìì)|Jj|Kk|Kp/kp|Ll|(Ĺĺ)|Mm|(Ḿḿ)|Nn|(Ńń)|Ny/ny|Ŋŋ|Ŋm/ŋm|Oo/oo|(Óo/óo)|(Òo/òo)|Ɔɔ|(Ɔ́/ɔ́)|(Ɔ̀/ɔ̀)|Pp|Ss|Tt|Uu|(Úú)|(Ùù)|Ww|Yy}} ==={{ĐM|ref}}=== *{{Chú thích web|entry=yùkū, yùkufī, yùkū|entryurl=https://www.webonary.org/ntcham/gdbe0aacd-221e-4402-8d81-685d771d9471/?lang=en|editor=Samuel Kpagheri|work=Ntcham – English Dictionary|year=2019|publisher=SIL International}} =={{langname|pi}}== ==={{ĐM|alt sc}}=== {{pi-alt}} ==={{ĐM|pron}}=== *{{IPA4|pi|[uː]}} ==={{ĐM|letter}}=== {{head|pi|Chữ cái|chữ hoa|Ū}} # {{n-g|Nguyên âm thứ 6 trong tiếng Pali bằng chữ Latinh viết thường.}} #:{{ux|pi|{{l|pi|abhir'''ū'''pa}}|[[đẹp]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=pi|sc=Latn|qual=Chữ Latinh tiếng Pali|Aa|Āā|Ii|Īī|Uu|Ūū|Ee|Oo|Ṃṃ|Kk|Kh/kh|Gg|Gh/gh|Ṅṅ|Cc|Ch/ch|Jj|Jh/jh|Ññ|Ṭṭ|Ṭh/ṭh|Ḍḍ|Ḍh/ḍh|Ṇṇ|Tt|Th/th|Dd|Dh/dh|Nn|Pp|Ph/ph|Bb|Bh/bh|Mm|Yy|Rr|Ll|Ḷḷ|Vv|Ss|Hh}} =={{langname|prg}}== ==={{ĐM|pron}}=== *{{IPA4|prg|[uː]}} ==={{ĐM|letter}}=== {{head|prg|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài và nhấn. #:{{ux|prg|la'''ū'''ws|[[sư tử]]|inline=1}} ==={{ĐM|ref}}=== *[[b:en:Prussian/Pronunciation|Prussian/Pronunciation]] =={{langname|rap}}== ==={{ĐM|pron}}=== *{{IPA4|rap|[uː]}} ==={{ĐM|letter}}=== {{head|rap|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 17 viết thường trong bảng chữ cái Latinh tiếng Rapa Nui. ==={{ĐM|see}}=== *{{letters|lang=rap|sc=Latn|qual=Bảng chữ Latinh tiếng Rapa Nui|Aa|Āā|Ee|Ēē|Hh|Ii|Īī|Kk|Mm|Nn|Ŋŋ|(Gg)|Oo|Ōō|Pp|Rr|Tt|Uu|Ūū|Vv|ʻ’|Ġġ}} =={{langname|rar}}== ==={{ĐM|pron}}=== *{{IPA4|rar|[aː]}} ==={{ĐM|letter}}=== {{head|rar|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 18 viết thường trong bảng chữ cái Latinh tiếng Rarotonga. #:{{ux|rar|{{l|rar|t'''ū'''t'''ū''' mata}}|[[mặt]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=rar|sc=Latn|qual=Bảng chữ cái Latinh tiếng Rarotonga|Aa|Āā|Ee|Ēē|Ng/ng|Hh|Ii|Īī|Kk|Mm|Nn|Oo|Ōō|Pp|Rr|Tt|Uu|Ūū|Vv|'}} =={{langname|rgn}}== ==={{ĐM|pron}}=== *{{IPA4|rgn|[ˈuː]}} ==={{ĐM|letter}}=== {{head|rgn|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]]'' dài nhấn. #:{{ux|rgn|dep'''ū'''|[[sau]], [[rồi]]|inline=1}} =={{langname|sml}}== ==={{ĐM|pron}}=== *{{IPA4|sml|[uː]}} ==={{ĐM|letter}}=== {{head|sml|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 24 viết thường trong trong bảng chữ cái Latinh tiếng Sama Trung. #:{{ux|sml|'''ū'''ng|[[mũi]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=sml|sc=Latn|qual=Bảng chữ cái Latinh tiếng Sama Trung|Āā|Aa|Bb|Cc|Dd|Ēē|Ee|Gg|Hh|Īī|Ii|Jj|Kk|Ll|Mm|Ng/ng|Nn|Ōō|Oo|Pp|Rr|Ss|Tt|Ūū|Uu|Ww|Yy}} ==={{ĐM|ref}}=== *{{Chú thích web|en|author=SIL Philippines|work=[https://sil-philippines-languages.org/prog/sml/dict/index-english/index.htm Central Sinama - English Dictionary]|entry=ū|year=Work in progress}} *{{Chú thích web|sml|author=Wycliffe Bible Translators, Inc.|work=Kitab Injil and Kitab Awal-Jaman|entry=Panagna'an 2|year=2008|entryurl=https://www.bible.com/bible/2394/GEN.2.SML}} =={{langname|sm}}== ==={{ĐM|pron}}=== *{{IPA4|sm|[uː]}} ==={{ĐM|letter}}=== {{head|sm|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{ux|sm|[[w:sm:Mūsika|m'''ū'''sika]]|[[âm nhạc]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=sm|sc=Latn|qual=Bảng chữ cái Latinh tiếng Samoa|Aa|(Āā)|Ee|(Ēē)|Ii|(Īī)|Oo|(Ōō)|Uu|(Ūū)|Ff|Gg|Ll|Mm|Nn|Pp|Ss|Tt|Vv|Hh|Kk|Rr|‘}} ==={{ĐM|ref}}=== *{{Chú thích sách|author=George Pratt|title=A Grammar and Dictionary of the Samoan Language|year=1878|publisher=Trübner & Company|pageurl=https://books.google.com/books?id=1vsrAAAAYAAJ&pg=PA367|page=367}} =={{langname|sgs}}== ==={{ĐM|pron}}=== *{{IPA4|sgs|[uː]|[ʲuː]}} ==={{ĐM|letter}}=== {{head|sgs|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 29 viết thường trong bảng chữ cái Latinh tiếng Samogitia, gọi là chữ ''{{l|sgs|ėlguojė ū}}''. #:{{ux|sgs|[[w:bat-smg:Jūra|j'''ū'''ra]]|[[biển]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=sgs|sc=Latn|qual=Bảng chữ cái Latinh tiếng Samogitia|Aa|Āā|Bb|Cc|Čč|Dd|Ee|Ēē|Ėė|Ė̄/ė̄|Ff|Gg|Hh|Ii|Īī|Jj|Kk|Ll|Mm|Nn|Oo|Ōō|Pp|Rr|Ss|Šš|Tt|Uu|Ūū|Vv|Zz|Žž}} =={{langname|sii}}== ==={{ĐM|pron}}=== *{{IPA4|sii|[uː]}} ==={{ĐM|letter}}=== {{head|sii|Chữ cái}} #Chữ cái Latinh viết thường thể hiện nguyên âm thứ 14 trong tiếng Shompen. ==={{ĐM|see}}=== *{{letters|lang=sii|sc=Latn|qual=Chữ Latinh tiếng Shompen|a|e|ɛ/E|i|o|ɔ/O|u|ā|ē|ɛ̄|ī|ō|ɔ̄|ū|ã|ẽ|ɛ̃|ĩ|õ|ɔ̃|ũ|ā̃|ē̃|ɛ̄̃|ī̃|ō̃|ɔ̄̃|ū̃|b|bh|c|d|ɸ|g|gh|ɣ|h|j|k|kh|l|m|n|ŋ/ṅ|ɲ/ñ|p|ph|t|th|w|x|y|ʔ/?}} ==={{ĐM|ref}}=== *{{Chú thích sách|en|author=Roger Blench|year=2007|title=The language of the Shom Pen: a language isolate in the Nicobar islands|url=https://web.archive.org/web/20241212072542/https://www.rogerblench.info/Language/Isolates/Shompen%20paper.pdf}} =={{langname|ty}}== ==={{ĐM|pron}}=== *{{IPA4|ty|[uː]}} ==={{ĐM|letter}}=== {{head|ty|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{ux|ty|[[w:ty:Pūrau|p'''ū'''rau]]|{{w|tra làm chiếu}}|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=ty|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tahiti|Aa|(Āā)|Ee|(Ēē)|Ff|Hh|Ii|(Īī)|Mm|Nn|Oo|(Ōō)|Pp|Rr|Tt|Uu|(Ūū)|Vv|ʼ}} =={{langname|tsg}}== ==={{ĐM|pron}}=== *{{IPA4|tsg|[uː]}} ==={{ĐM|letter}}=== {{head|tsg|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{ux|tsg|'''ū'''an|[[gối]]|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=tsg|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tausug|Aa|(Āā)|Bb|Dd|Gg|Hh|Ii|(Īī)|Jj|Kk|Ll|Mm|Nn|Ng/ng|Ny/ny|Pp|Rr|Ss|Tt|Uu|(Ūū)|Ww|Yy|’}} ==={{ĐM|etym}}=== ===={{ĐM|n}}==== {{tsg-noun|j=+}} #[[đầu|Đầu]]. ====={{ĐM|der}}===== {{col3|tsg|ūan|ūhan|ū bala'|ū ista'|ū-atay|mag'ūan|umūan|ūanan}} ==={{ĐM|ref}}=== *{{Chú thích web|entry=u|entryurl=https://www.webonary.org/tausug/browse/browse-vernacular/?key=tsg&letter=u&lang=en|author=Kabtangan Iban Maana|work=Tausug-English Dictionary|year=2018|publisher=SIL International}} =={{langname|tkl}}== ==={{ĐM|pron}}=== *{{IPA4|tkl|[uː]}} ==={{ĐM|letter}}=== {{head|tkl|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{ux|tkl|fīlēm'''ū'''|[[yên tĩnh]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=tkl|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tokelau|Aa|(Āā)|Ee|(Ēē)|Ii|(Īī)|Oo|(Ōō)|Uu|(Ūū)|Ff|Gg|Kk|Ll|Mm|Nn|Pp|Hh|Tt|Vv}} =={{langname|to}}== ==={{ĐM|pron}}=== *{{IPA4|to|[uː]}} ==={{ĐM|letter}}=== {{head|to|Chữ cái|chữ hoa|Ū}} #Chữ cái viết thường biểu thị nguyên âm ''[[u]] dài''. #:{{ux|to|[[w:to:Lūsia|L'''ū'''sia]]|[[Nga]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=to|sc=Latn|qual=Bảng chữ cái Latinh tiếng Tonga|Aa|(Āā)|Ee|(Ēē)|Ff|Hh|Ii|(Īī)|Kk|Ll|Mm|Nn|Ng/ng|Oo|(Ōō)|Pp|Ss|Tt|Uu|(Ūū)|Vv|’}} =={{langname|ude}}== {| class="floatright wikitable" style="text-align:center;" |- ! Kirin | [[ӯ#Tiếng_Udihe|ӯ]] |- ! Latinh | {{pn}} |- |} ==={{ĐM|pron}}=== *{{IPA4|ude|[uː]}} ==={{ĐM|letter}}=== {{head|ude|Chữ cái|chữ hoa|Ū}} #{{label|ude|obsolete}} Chữ cái thứ 30 viết thường trong bảng chữ cái Latinh tiếng Udihe năm 1931-1937. #:{{ux|ude|s'''ū'''|tr={{l|ude|с'''ӯ'''}}|[[mặt trời]]|inline=1}} ==={{ĐM|see}}=== *{{letters|lang=ude|sc=Latn|qual=Bảng chữ cái Latinh tiếng Udihe năm 1931-1937|Aa|Āā|Bв|Єє|Dd|Ʒʒ|Ee|Ēē|Ææ|Ff|Gg|Hh|Ii|Īī|Jj|Kk|Ll|Mm|Nn|Ņņ|Ŋŋ|Oo|Ōō|Өө|Pp|Rr|Ss|Tt|Uu|Ūū|Ww|Xx|Yy|Zz|’}} ==={{ĐM|ref}}=== *{{Chú thích sách|ru|author=М. Д. Симонов, В. Т. Кялундзюга|year=1998|title=Словарь удэгейского языка (хорский диалект). Препринт}} =={{langname|yka}}== ==={{ĐM|pron}}=== *{{IPA4|yka|[uː]}} ==={{ĐM|letter}}=== {{head|yka|Chữ cái|chữ hoa|Ū}} #Chữ cái thứ 24 viết thường trong trong bảng chữ cái Latinh tiếng Yakan. #:{{quote|yka|'''ū'''ng-'''ū'''ng|{{w|cá cam thoi}}|inline=1}} ===={{ĐM|see}}==== *{{letters|lang=yka|sc=Latn|qual=Bảng chữ cái Latinh tiếng Yakan|Āā|Aa|Bb|Cc|Dd|Ēē|Ee|Gg|Hh|Īī|Ii|Jj|Kk|Ll|Mm|Ng/ng|Nn|Ōō|Oo|Pp|Rr|Ss|Tt|Ūū|Uu|Ww|Yy}} ==={{ĐM|n}}=== {{head|yka|Danh từ}} #[[cán|Cán]], [[chuôi]]. ==={{ĐM|v}}=== {{head|yka|Động từ}} #[[lắp|Lắp]] [[cán]], [[chuôi]]. ==={{ĐM|ref}}=== *{{Chú thích web|author=SIL Philippines|work=[https://philippines.sil.org/resources/online_resources/yka Yakan-English Dictionary]|entry=ū|year=2013}} =={{langname|yo}}== ==={{ĐM|pron}}=== *{{yor-IPA|ū}} ==={{ĐM|letter}}=== {{head|yo|Chữ cái|chữ hoa|Ū}} #Chữ cái ''[[U]]'' viết thường với thanh trung ([[◌̄]]). ===={{ĐM|see}}==== *{{letters|lang=yo|sc=Latn|qual=Bảng chữ cái Latinh tiếng Yoruba tại Nigeria|native name=lẹ́tà|Aa|(Áá)|(Àà)|(Āā)|Bb|Dd|Ee|(Éé)|(Èè)|(Ēē)|Ẹẹ|(Ẹ́/ẹ́)|(Ẹ̀/ẹ̀)|(Ẹ̄/ẹ̄)|Ff|Gg|Gb/gb|Hh|Ii|(Íí)|(Ìì)|(Īī)|Jj|Kk|Ll|Mm|(Ḿ/ḿ)|(M̀/m̀)|(M̄/m̄)|Nn|(Ń/ń)|(Ǹ/ǹ)|(N̄/n̄)|Oo|(Óó)|(Òò)|(Ōō)|Ọọ|(Ọ́/ọ́)|(Ọ̀/ọ̀)|(Ọ̄/ọ̄)|Pp|Rr|Ss|Ṣṣ|Tt|Uu|(Úú)|(Ùù)|(Ūū)|Ww|Yy}} *{{letters|lang=yo|sc=Latn|qual=Bảng chữ cái Latinh tiếng Yoruba tại Benin|lɛ́tà|Aa|Bb|Dd|Ee|Ɛɛ|Ff|Gg|Gb/gb|Hh|Ii|Jj|Kk|Kp/kp|Ll|Mm|Nn|Oo|Ɔɔ|Pp|Rr|Ss|Sh/sh|Tt|Uu|Ww|Yy}} ==={{ĐM|ref}}=== *{{Chú thích sách|en|title=Dictionary of the Yoruba language|author=Thomas Jefferson Bowen|year=1858|location=Washington|publisher=Smithsonian Institution|page=[https://archive.org/details/grammardictionar00bowerich/page/89 89]|}} [[Thể loại:Khối ký tự Latin Extended-A|6B]] 2py639ol12slj6k5mmwnnyi5q79ud06 cacahuate 0 392391 2344287 2026-04-11T14:00:06Z Kelly zhrm 58416 Trang mới: “=={{langname|es}}== [[Image:ARS peanuts.jpg|thumb|cacahuates]] ==={{ĐM|pron}}=== {{es-pr}} ==={{ĐM|n}}=== {{es-noun|m}} # {{lb|es|Honduras|Mexico}} {{alt form|es|cacahuete|t=đậu phộng, lạc}} ===={{ĐM|drv}}==== {{col|es|cacahuatero}} ==={{ĐM|further}}=== * {{R:es:DRAE}}” 2344287 wikitext text/x-wiki =={{langname|es}}== [[Image:ARS peanuts.jpg|thumb|cacahuates]] ==={{ĐM|pron}}=== {{es-pr}} ==={{ĐM|n}}=== {{es-noun|m}} # {{lb|es|Honduras|Mexico}} {{alt form|es|cacahuete|t=đậu phộng, lạc}} ===={{ĐM|drv}}==== {{col|es|cacahuatero}} ==={{ĐM|further}}=== * {{R:es:DRAE}} 7kos0bokavx3eo1cynw4s3ok6yjhzwf 2344288 2344287 2026-04-11T14:01:21Z Kelly zhrm 58416 2344288 wikitext text/x-wiki =={{langname|es}}== [[Image:ARS peanuts.jpg|thumb|cacahuates]] ==={{ĐM|pron}}=== {{es-pr}} ==={{ĐM|n}}=== {{es-noun|m}} # {{lb|es|Honduras|Mexico}} {{alt form|es|cacahuete|t=đậu phộng, củ lạc}} ===={{ĐM|drv}}==== {{col|es|cacahuatero}} ==={{ĐM|further}}=== * {{R:es:DRAE}} sroq7x7hx8qm0i3puzdm710dmkwe4lk 𡬕 0 392392 2344290 2026-04-11T14:16:08Z Hiyuune 50834 + mul 2344290 wikitext text/x-wiki {{character info}} =={{langname|mul}}== ==={{section|han}}=== {{Han char|rn=40|rad=宀|as=22|sn=25|four=|canj=|ids=⿱𫲽𦓈}} ===={{section|ref}}==== * {{Han ref|kx=0293.281|dkj=|dj=|hdz=20959.210|uh=21B15}} egbv2z6by94e1zxqriqbeym6bivzf2e Thể loại:Mục từ có chứa nhiều từ tiếng Bhumij 14 392393 2344297 2026-04-11T17:11:47Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344297 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:aav-bhu:Dụng cụ 14 392394 2344299 2026-04-11T17:13:01Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344299 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:aav-bhu:Danh sách chủ đề thuộc nhóm loại hình 14 392395 2344300 2026-04-11T17:13:15Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344300 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:aav-bhu:Tất cả chủ đề 14 392396 2344301 2026-04-11T17:13:32Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344301 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:aav-bhu:Công nghệ 14 392397 2344302 2026-04-11T17:14:06Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344302 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:aav-bhu:Danh sách chủ đề thuộc nhóm liên quan 14 392398 2344303 2026-04-11T17:14:58Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344303 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 廣二 0 392399 2344306 2026-04-12T01:05:47Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344306 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} tm0nxh62bca5dx24alzt5pyceh4zq7l Mô đun:etymon/data/text allowed 828 392400 2344308 2026-04-12T01:13:21Z TheHighFighter2 42988 Trang mới: “--[=[ Languages and families that may use the {{etymon}} `text=` parameter (language-community consensus). ]=] return { -- Mode: "off" = disabled, "warn" = warn only, "error" = enforce. default_mode = "warn", langs = { ["bg"] = true, ["bnt-sab-pro"] = true, ["cs"] = true, ["en"] = true, ["fa"] = true, ["hrx"] = true, ["hsb"] = true, ["iir-pro"] = true, ["jbo"] = true, ["jdt"] = true, ["la"] = true, ["ota"] = true, ["sk"] = true, ["sw"] = tr…” 2344308 Scribunto text/plain --[=[ Languages and families that may use the {{etymon}} `text=` parameter (language-community consensus). ]=] return { -- Mode: "off" = disabled, "warn" = warn only, "error" = enforce. default_mode = "warn", langs = { ["bg"] = true, ["bnt-sab-pro"] = true, ["cs"] = true, ["en"] = true, ["fa"] = true, ["hrx"] = true, ["hsb"] = true, ["iir-pro"] = true, ["jbo"] = true, ["jdt"] = true, ["la"] = true, ["ota"] = true, ["sk"] = true, ["sw"] = true, ["tg"] = true, ["tl"] = true, ["tr"] = true, ["uk"] = true, ["uz"] = true, ["zlw-ocs"] = true, ["zlw-osk"] = true, }, families = { ["ber"] = true, -- Berber ["dra"] = true, -- Dravidian ["inc"] = true, -- Indo-Aryan ["iir-nur"] = true, -- Nuristani ["roa-gap"] = true, -- Galician-Portuguese ["sem-ara"] = true, -- Aramaic ["sem-arb"] = true, -- Arabic ["tup"] = true, -- Tupian ["zlw-lch"] = true, -- Lechitic }, } er27mwwc9rh50dmoqbfrik3bz7b91lb وزير اعظم 0 392401 2344309 2026-04-12T01:17:26Z Hiyuune 50834 + sd 2344309 wikitext text/x-wiki =={{langname|sd}}== ==={{section|etym}}=== {{bor+|sd|fa-cls|وَزِیرِ اَعْظَم}}. ==={{section|pron}}=== * {{IPA4|sd|[wə.ziː.ɾeː.ə.zəm]}} ==={{section|n}}=== {{sd-noun|g=m|وَزِيرِ اَعظَم}} # [[thủ tướng|Thủ tướng]]. #: {{syn|sd|پْرَڌانْ مَنْترِي|ll=India}} ==={{section|further}}=== * {{R:sd:SLA|Prime minister}} {{topics|sd|Government|Leaders|Occupations|People}} 7ftudpdaykhn8nqw2j152dto1fhch08 2344310 2344309 2026-04-12T01:18:14Z Hiyuune 50834 /* Tiếng Sindh */ 2344310 wikitext text/x-wiki =={{langname|sd}}== ==={{section|etym}}=== {{bor+|sd|fa-cls|وَزِیرِ اَعْظَم}}. ==={{section|pron}}=== * {{IPA4|sd|[wə.ziː.ɾeː.ə.zəm]}} ==={{section|n}}=== {{sd-noun|g=m|وَزِيرِ اَعظَم}} # [[thủ tướng|Thủ tướng]]. #: {{syn|sd|پْرَڌانْ مَنْترِي|ll=India}} ==={{section|further}}=== * {{R:sd:SLA|Prime minister}} {{topics|sd|Chính phủ|Nhà lãnh đạo|Nghề nghiệp|Mọi người}} ainr1bl99l6x1mces4xy305f5ha7ayt 麦蒔 0 392402 2344312 2026-04-12T01:21:11Z Hiyuune 50834 + ja 2344312 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|むぎ|ま|o2=き|y=k|alt=麦播き}} {{swp|ja:ムギマキ}} ==={{section|n}}=== {{ja-noun|むぎまき|ムギマキ}} # {{taxlink|Ficedula mugimaki|loài}} ===={{section|usage}}==== {{U:ja:biology}} {{C|ja|Họ Đớp ruồi}} haimsts31l3y5alwnexnlku7tnnb9j5 પછવાડું 0 392403 2344313 2026-04-12T01:24:48Z Hiyuune 50834 + gu 2344313 wikitext text/x-wiki =={{langname|gu}}== ==={{section|etym}}=== {{der+|gu|sa|*पश्चपाट}}. ==={{section|n}}=== {{gu-noun|g=n}} # [[đằng sau|Đằng sau]]. ==={{section|adj}}=== {{gu-adj}} # [[gần đây|Gần đây]]; [[cuối cùng]]. 4d31g3vxt0j9f1ipu07fbm06tzawcct Thể loại:Từ đánh vần với 廣 là こう tiếng Nhật 14 392404 2344315 2026-04-12T01:29:12Z WhoAlone 40420 Trang mới: “{{auto cat|goon|kanon}}” 2344315 wikitext text/x-wiki {{auto cat|goon|kanon}} pcfeck6099nlm7ilmenvn80gp1r7w7f Thể loại:Từ đánh vần với 廣 tiếng Nhật 14 392405 2344316 2026-04-12T01:29:39Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344316 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 廣 theo ngôn ngữ 14 392406 2344319 2026-04-12T01:45:14Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344319 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 晃二 0 392407 2344322 2026-04-12T02:11:59Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344322 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} tm0nxh62bca5dx24alzt5pyceh4zq7l 晃司 0 392408 2344323 2026-04-12T02:12:40Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344323 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} 7rq8gagbbg4frk8u7gk343wf6jgicob 晃次 0 392409 2344324 2026-04-12T02:15:43Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344324 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} tm0nxh62bca5dx24alzt5pyceh4zq7l 浩二 0 392410 2344325 2026-04-12T02:16:49Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344325 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|じ}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} tm0nxh62bca5dx24alzt5pyceh4zq7l 浩司 0 392411 2344326 2026-04-12T02:18:21Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ|r=y|y=kanon,o}} {{ja-kanjitab|ひろ|し|y=y}} ==={{ĐM|pron}}=== {{ja-pron|こうじ|ひろし}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ|ひろし}} # {{given name|ja|nam}}” 2344326 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ|r=y|y=kanon,o}} {{ja-kanjitab|ひろ|し|y=y}} ==={{ĐM|pron}}=== {{ja-pron|こうじ|ひろし}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ|ひろし}} # {{given name|ja|nam}} ae6jebj06egeg6yvlq6xhgvuyvafcyq 浩嗣 0 392412 2344327 2026-04-12T02:20:27Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ|yomi=o|r=y}}{{ja-kanjitab|ひろ|し}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ|ひろし}} # {{given name|ja|nam|sort=ひろし}}” 2344327 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|し|k2=じ|yomi=o|r=y}}{{ja-kanjitab|ひろ|し}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ|ひろし}} # {{given name|ja|nam|sort=ひろし}} gnfxbihpghoc7wmyzo8tv9ri3nrd3j7 浩次 0 392413 2344328 2026-04-12T02:21:14Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|こう|じ|yomi=o}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}}” 2344328 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|こう|じ|yomi=o}} ==={{ĐM|pr-noun}}=== {{ja-pos|proper|こうじ}} # {{given name|ja|nam|sort=こうじ}} 1n2mdkhkxo3ocasatzoverehvl47dwh 四肢發達,頭腦簡單 0 392414 2344329 2026-04-12T02:23:45Z WhoAlone 40420 Trang mới: “=={{langname|zh}}== {{zh-forms|s=四肢发达,头脑简单|type=2222|lit=Tứ chi phát đạt, đầu não giản đơn}} ==={{ĐM|pron}}=== {{zh-pron |m=sìzhī fādá, tóunǎo jiǎndān |c=sei3 zi1 faat3 daat6, tau4 nou5 gaan2 daan1 |cat=ph }} ==={{ĐM|phrase}}=== {{head|zh|Cụm từ}} # [[đầu óc ngu si, tứ chi phát triển|Đầu óc ngu si, tứ chi phát triển]]. ===={{ĐM|see also}}==== * {{langname|vi}}: {{l|vi|đầu óc ngu si, tứ chi phát tr…” 2344329 wikitext text/x-wiki =={{langname|zh}}== {{zh-forms|s=四肢发达,头脑简单|type=2222|lit=Tứ chi phát đạt, đầu não giản đơn}} ==={{ĐM|pron}}=== {{zh-pron |m=sìzhī fādá, tóunǎo jiǎndān |c=sei3 zi1 faat3 daat6, tau4 nou5 gaan2 daan1 |cat=ph }} ==={{ĐM|phrase}}=== {{head|zh|Cụm từ}} # [[đầu óc ngu si, tứ chi phát triển|Đầu óc ngu si, tứ chi phát triển]]. ===={{ĐM|see also}}==== * {{langname|vi}}: {{l|vi|đầu óc ngu si, tứ chi phát triển}} tdt8tl03y91mrb78b910z3rjktbvug7 Thể loại:Cụm từ tiếng Trung Quốc 14 392415 2344330 2026-04-12T02:24:21Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344330 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Mục từ có chứa nhiều từ tiếng Trung Quốc 14 392416 2344331 2026-04-12T02:24:53Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344331 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 四 tiếng Trung Quốc 14 392417 2344332 2026-04-12T02:25:36Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344332 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 肢 tiếng Trung Quốc 14 392418 2344333 2026-04-12T02:26:38Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344333 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 肢 theo ngôn ngữ 14 392419 2344334 2026-04-12T02:26:59Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344334 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 發 tiếng Trung Quốc 14 392420 2344335 2026-04-12T02:27:48Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344335 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 發 theo ngôn ngữ 14 392421 2344336 2026-04-12T02:28:14Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344336 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 達 tiếng Trung Quốc 14 392422 2344337 2026-04-12T02:29:15Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344337 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 達 theo ngôn ngữ 14 392423 2344338 2026-04-12T02:30:09Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344338 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 頭 tiếng Trung Quốc 14 392424 2344339 2026-04-12T02:31:26Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344339 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 腦 tiếng Trung Quốc 14 392425 2344340 2026-04-12T02:31:50Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344340 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 腦 theo ngôn ngữ 14 392426 2344341 2026-04-12T02:32:14Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344341 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 簡 tiếng Trung Quốc 14 392427 2344342 2026-04-12T02:33:47Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344342 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 簡 theo ngôn ngữ 14 392428 2344343 2026-04-12T02:34:12Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344343 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 單 tiếng Trung Quốc 14 392429 2344344 2026-04-12T02:35:43Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344344 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Từ đánh vần với 單 theo ngôn ngữ 14 392430 2344345 2026-04-12T02:36:18Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344345 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 四肢发达,头脑简单 0 392431 2344346 2026-04-12T02:37:55Z WhoAlone 40420 Trang mới: “=={{langname|zh}}== {{zh-see|四肢發達,頭腦簡單}}” 2344346 wikitext text/x-wiki =={{langname|zh}}== {{zh-see|四肢發達,頭腦簡單}} lccsdvvd59b3v2hius887qdx8bqy3r1 四肢 0 392432 2344347 2026-04-12T02:38:59Z WhoAlone 40420 Trang mới: “=={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|tứ chi}}” 2344347 wikitext text/x-wiki =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|tứ chi}} k2rw61j8iubo0z0w0m01h1f9iompivu 2344348 2344347 2026-04-12T02:42:07Z WhoAlone 40420 2344348 wikitext text/x-wiki =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|tứ chi}} =={{langname|ja}}== {{ja-kanjitab|し|し|yomi=o}} ==={{ĐM|pron}}=== {{ja-pron|しし|acc=1|acc_ref=DJR}} ==={{ĐM|noun}}=== {{ja-noun|しし}} # [[tứ chi]]. #: {{ja-usex|'''四肢'''[[切断]]|'''しし''' せつだん|cắt cụt '''tứ chi'''}} ==={{ĐM|ref}}=== <references/> :* {{R:Kanjipedia Kotoba|0002717900}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=사지}} # {{hanja form of|사지|[[tứ chi]]}} =={{langname|zh}}== {{zh-forms}} ==={{ĐM|pron}}=== {{zh-pron |m=sìzhī |ma=Zh-sìzhi.ogg |c=sei3 zi1 |ca=LL-Q9186 (yue)-Luilui6666-四肢.wav |mn=ml:sì-ki/tw:sù-ki/qz:sìr-chi/xm,zz:sù-chi |mn-t=si3 zi1 |cat=n }} ==={{ĐM|noun}}=== {{head|zh|Danh từ}} # [[tứ chi]]. #: {{zh-x|四肢 無力|bị yếu ở '''tứ chi'''}} #: {{zh-x|天生 沒有 四肢|sinh ra không có '''tứ chi'''}} ===={{ĐM|derived}}==== {{col3|zh|四肢發達,頭腦簡單}} {{C|zh|Giải phẫu học}} eezu04xqnxbqkn4sfy8xj3epem91dmk sìzhī 0 392433 2344349 2026-04-12T02:42:32Z WhoAlone 40420 Trang mới: “=={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|四肢}}” 2344349 wikitext text/x-wiki =={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|四肢}} 4elro4jb4k4n06uev1a8577co5q80tg しし 0 392434 2344350 2026-04-12T02:49:33Z WhoAlone 40420 Trang mới: “{{also|しじ|じじ}} =={{langname|ja}}== ==={{ĐM|etym}} 1=== {{ja-see-kango|獅子|四肢|志士|嗣子|死屍|梔子}} ==={{ĐM|etym}} 2=== {{ja-see|肉}} ==={{ĐM|etym}} 3=== {{ja-see|獣}} ==={{ĐM|etym}} 4=== {{ja-see|獅子}}” 2344350 wikitext text/x-wiki {{also|しじ|じじ}} =={{langname|ja}}== ==={{ĐM|etym}} 1=== {{ja-see-kango|獅子|四肢|志士|嗣子|死屍|梔子}} ==={{ĐM|etym}} 2=== {{ja-see|肉}} ==={{ĐM|etym}} 3=== {{ja-see|獣}} ==={{ĐM|etym}} 4=== {{ja-see|獅子}} e239os81fusdaemj4nmgp6xwg2zvqau 사지 0 392435 2344351 2026-04-12T02:51:13Z WhoAlone 40420 Trang mới: “=={{langname|ko}}== ==={{ĐM|pron}}=== {{ko-IPA|l=y}} ==={{ĐM|etym}} 1=== {{ko-etym-sino|四肢}}. ===={{ĐM|noun}}==== {{ko-noun|hanja=四肢}} # [[tứ chi]]. ==={{ĐM|etym}} 2=== {{ko-etym-sino|死地}}. ===={{ĐM|noun}}==== {{ko-noun|hanja=死地}} # [[tình huống]] [[chết người]]. {{C|ko|Giải phẫu học|Chết}}” 2344351 wikitext text/x-wiki =={{langname|ko}}== ==={{ĐM|pron}}=== {{ko-IPA|l=y}} ==={{ĐM|etym}} 1=== {{ko-etym-sino|四肢}}. ===={{ĐM|noun}}==== {{ko-noun|hanja=四肢}} # [[tứ chi]]. ==={{ĐM|etym}} 2=== {{ko-etym-sino|死地}}. ===={{ĐM|noun}}==== {{ko-noun|hanja=死地}} # [[tình huống]] [[chết người]]. {{C|ko|Giải phẫu học|Chết}} nwi5swlt497a4pjot0ayqum8wyymy7g 發達 0 392436 2344352 2026-04-12T02:55:28Z WhoAlone 40420 Trang mới: “{{also|发达}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|verb}}=== {{vi-verb|sc=Hani}} # {{vi-Han form of|phát đạt}} =={{langname|ja}}== {{ja-kanjitab|はつ|k1=はっ|たつ|yomi=on}} {{ja-see|発達}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=발달}} # {{hanja form of|발달|sự [[phát triển]]}} =={{langname|zh}}== {{zh-forms|s=发达}} ==={{ĐM|pron}}=== {{zh-pron |m=fādá |ma=Zh-fadá.ogg |c=faat3 daat6 |c-t=fat1 at…” 2344352 wikitext text/x-wiki {{also|发达}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|verb}}=== {{vi-verb|sc=Hani}} # {{vi-Han form of|phát đạt}} =={{langname|ja}}== {{ja-kanjitab|はつ|k1=はっ|たつ|yomi=on}} {{ja-see|発達}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=발달}} # {{hanja form of|발달|sự [[phát triển]]}} =={{langname|zh}}== {{zh-forms|s=发达}} ==={{ĐM|pron}}=== {{zh-pron |m=fādá |ma=Zh-fadá.ogg |c=faat3 daat6 |c-t=fat1 at5 |h=pfs=fat-tha̍t;hrs=h:fad tadˋ |mn=hoat-ta̍t |mn-t=huag4 dag8 |px=pt:huah6 dah7/xy:huoh6 dah7 |w=sh:7faq daq |mc=1,2 |cat=a,v }} ==={{ĐM|adj}}=== {{head|zh|Tính từ}} # [[phát triển]]. ===={{ĐM|syn}}==== * {{zh-l|不發達}} ===={{ĐM|derived}}==== {{col3|zh|不發達|發達國家|四肢發達,頭腦簡單|欠發達}} ==={{ĐM|verb}}=== {{zh-verb}} # [[phát triển]]. # trở nên [[giàu có]]; [[vươn lên]] nắm quyền và [[địa vị]]. #: {{syn|zh|發財}} #: {{zh-x|發達 啦!|Ta giàu rồi!|C}} ===={{ĐM|desc}}==== {{CJKV||s=発達|はったつ|발달|phát đạt}} etehqytu5axdmkp5kunkn4pw13brpx8 Thể loại:Mục từ có ví dụ cách sử dụng tiếng Quảng Đông 14 392437 2344353 2026-04-12T02:57:19Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344353 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 发达 0 392438 2344354 2026-04-12T03:00:10Z WhoAlone 40420 Trang mới: “{{also|發達}} =={{langname|zh}}== {{zh-see|發達}}” 2344354 wikitext text/x-wiki {{also|發達}} =={{langname|zh}}== {{zh-see|發達}} 1ck6lyfyj8jlao06ld53n8zu298ben0 Thể loại:Tính từ tiếng Đài Sơn 14 392439 2344355 2026-04-12T03:00:27Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344355 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Động từ tiếng Đài Sơn 14 392440 2344356 2026-04-12T03:00:29Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344356 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx fādá 0 392441 2344357 2026-04-12T03:03:02Z WhoAlone 40420 Trang mới: “{{also|fada}} =={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|發達}}” 2344357 wikitext text/x-wiki {{also|fada}} =={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|發達}} ilac72lcxeytxe36n25zh13a6h6ttfa 발달 0 392442 2344358 2026-04-12T03:04:43Z WhoAlone 40420 Trang mới: “=={{langname|ko}}== ==={{ĐM|etym}}=== {{ko-etym-Sino|發|phát|達|đạt}}. ==={{ĐM|pron}}=== {{ko-IPA|com=1}} ==={{ĐM|noun}}=== {{ko-noun|hanja=發達}} # Sự [[phát triển]]. ===={{ĐM|drv}}==== * {{ko-l|발달하다|發達—|(động từ) phát triển}} * {{ko-l|발달되다|發達—|(tính từ) phát triển}}” 2344358 wikitext text/x-wiki =={{langname|ko}}== ==={{ĐM|etym}}=== {{ko-etym-Sino|發|phát|達|đạt}}. ==={{ĐM|pron}}=== {{ko-IPA|com=1}} ==={{ĐM|noun}}=== {{ko-noun|hanja=發達}} # Sự [[phát triển]]. ===={{ĐM|drv}}==== * {{ko-l|발달하다|發達—|(động từ) phát triển}} * {{ko-l|발달되다|發達—|(tính từ) phát triển}} bhg976vicpt1a6k8tjwpzylkhgjyy1l poloka 0 392443 2344359 2026-04-12T03:05:08Z Kelly zhrm 58416 Trang mới: “=={{langname|haw}}== ==={{ĐM|etym}}=== {{bor+|haw|en|frog}} ==={{ĐM|pron}}=== * {{haw-IPA}} ==={{ĐM|n}}=== {{head|haw|Danh từ}} # [[ếch|Ếch]]. #: {{syn|haw|lana}} {{C|haw|Lớp Lưỡng cư}}” 2344359 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|etym}}=== {{bor+|haw|en|frog}} ==={{ĐM|pron}}=== * {{haw-IPA}} ==={{ĐM|n}}=== {{head|haw|Danh từ}} # [[ếch|Ếch]]. #: {{syn|haw|lana}} {{C|haw|Lớp Lưỡng cư}} stzo1s2rq067li3doakh6b5jykp2rjf 発達 0 392444 2344361 2026-04-12T03:06:49Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|はつ|k1=はっ|たつ|yomi=o}} ==={{ĐM|pron}}=== * {{ja-pron|はったつ|acc=0|acc_ref=NHK}} ==={{ĐM|noun}}=== {{ja-noun|はったつ}} # Sự [[phát triển]]. ===={{ĐM|see also}}==== * {{ja-r|発展|はってん}}, {{ja-r|開発|かいはつ}} ==={{ĐM|verb}}=== {{ja-verb-suru|はったつ|tr=intransitive}} # [[phát triển]]. #* {{quote-web|ja |work=ja:国会会議録検索システム |publisher=ja:国立国会図書館…” 2344361 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|はつ|k1=はっ|たつ|yomi=o}} ==={{ĐM|pron}}=== * {{ja-pron|はったつ|acc=0|acc_ref=NHK}} ==={{ĐM|noun}}=== {{ja-noun|はったつ}} # Sự [[phát triển]]. ===={{ĐM|see also}}==== * {{ja-r|発展|はってん}}, {{ja-r|開発|かいはつ}} ==={{ĐM|verb}}=== {{ja-verb-suru|はったつ|tr=intransitive}} # [[phát triển]]. #* {{quote-web|ja |work=ja:国会会議録検索システム |publisher=ja:国立国会図書館 |title=ja:第213回国会 衆議院 内閣委員会 第11号 令和6年4月17日 |date=2024-04-17 |url=https://kokkai.ndl.go.jp/txt/121304889X01120240417/111 |quotee=ja:住吉寛紀 |text=近年では、AIツールも'''発達'''して、翻訳も簡単にできます。 |transliteration=Kinnen de wa, ē ai tsūru mo '''hattatsu''' shite, hon'yaku mo kantan ni deki-masu. |translation=Trong những năm gần đây, các công nghệ AI đã '''phát triển''', giúp việc dịch thuật trở nên dễ dàng hơn.}} ===={{ĐM|conjugation}}==== {{ja-suru|はったつ}} ==={{ĐM|ref}}=== <references/> :* {{R:Kanjipedia Kotoba|0005690000}} 937u2irk17i2q7dmn21vn28ni669x57 hattatsu 0 392445 2344362 2026-04-12T03:07:22Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-romaji}} # {{ja-romanization of|はったつ}}” 2344362 wikitext text/x-wiki =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-romaji}} # {{ja-romanization of|はったつ}} lvdent2q1ux5fj9amwd14qn6fi0slq8 はったつ 0 392446 2344363 2026-04-12T03:07:40Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see-kango|発達|八達}}” 2344363 wikitext text/x-wiki =={{langname|ja}}== {{ja-see-kango|発達|八達}} 5q9gtnxr6jq3v85f3s48ja6rk3hrw5w aloha ahiahi 0 392447 2344364 2026-04-12T03:13:07Z Kelly zhrm 58416 Trang mới: “=={{langname|haw}}== ==={{ĐM|pron}}=== * {{haw-IPA|aloha ahi+ahi}} ==={{ĐM|interj}}=== {{head|haw|Thán từ}} # [[chào|Chào]] [[buổi tối]].” 2344364 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|pron}}=== * {{haw-IPA|aloha ahi+ahi}} ==={{ĐM|interj}}=== {{head|haw|Thán từ}} # [[chào|Chào]] [[buổi tối]]. kmzzy0s41xbz2h8wlgmd4w71gsu5tzr 2344370 2344364 2026-04-12T03:22:13Z Kelly zhrm 58416 2344370 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|pron}}=== * {{haw-IPA|aloha ahi+ahi}} ==={{ĐM|interj}}=== {{head|haw|Thán từ}} # [[chào|Chào]] [[buổi tối]]. {{cln|haw|Từ điển đàm thoại}} lwdwfgzc3829oezcqs416pyu7a19a04 aloha kakahiaka 0 392448 2344365 2026-04-12T03:16:38Z Kelly zhrm 58416 Trang mới: “=={{langname|haw}}== ==={{ĐM|etym}}=== Tiếng Hawaii {{mention|haw|aloha}} + {{mention|haw|kakahiaka||buổi sáng}}. ==={{ĐM|pron}}=== * {{haw-IPA|aloha kaka+hiaka}} {{rfap|haw|}} ==={{ĐM|phrase}}=== {{head|haw|Cụm từ}} # [[chào|Chào]] [[buổi sáng]]. {{cln|haw|Từ điển đàm thoại}}” 2344365 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|etym}}=== Tiếng Hawaii {{mention|haw|aloha}} + {{mention|haw|kakahiaka||buổi sáng}}. ==={{ĐM|pron}}=== * {{haw-IPA|aloha kaka+hiaka}} {{rfap|haw|}} ==={{ĐM|phrase}}=== {{head|haw|Cụm từ}} # [[chào|Chào]] [[buổi sáng]]. {{cln|haw|Từ điển đàm thoại}} g6y6sjb5sqa7amq178ayx7io8chldqk 2344366 2344365 2026-04-12T03:17:20Z Kelly zhrm 58416 2344366 wikitext text/x-wiki =={{langname|haw}}== ==={{ĐM|etym}}=== Tiếng Hawaii {{mention|haw|aloha}} + {{mention|haw|kakahiaka||buổi sáng}}. ==={{ĐM|pron}}=== * {{haw-IPA|aloha kaka+hiaka}} {{rfap|haw|}} ==={{ĐM|interj}}=== {{head|haw|Thán từ}} # [[chào|Chào]] [[buổi sáng]]. {{cln|haw|Từ điển đàm thoại}} 2j9sgzef244slh5fl66ybv0etr1iaae Thể loại:Mục từ có chứa nhiều từ tiếng Hawaii 14 392449 2344367 2026-04-12T03:18:19Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344367 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Thán từ tiếng Hawaii 14 392450 2344368 2026-04-12T03:19:37Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344368 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Bảo trì mục từ tiếng Hawaii 14 392451 2344369 2026-04-12T03:20:49Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344369 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx మొసలి 0 392452 2344371 2026-04-12T03:27:09Z Kelly zhrm 58416 Trang mới: “=={{langname|te}}== [[Image:NileCrocodile.jpg|thumb|right|మొసలి.]] ==={{ĐM|etym}}=== {{inh+|te|dra-pro|*mocVḷ}}. Cùng gốc với {{cog|iru|மொஜலெ}}. ==={{ĐM|n}}=== {{te-noun}} # [[cá sấu|Cá sấu]]. ===={{ĐM|quot}}==== {{seeCites|te}} ===={{ĐM|syn}}==== * {{l|te|మకరము}} ==={{ĐM|ref}}=== * {{R:te:CPB|head=మొసలి|1043}} {{topics|te|Bộ Cá sấu}}” 2344371 wikitext text/x-wiki =={{langname|te}}== [[Image:NileCrocodile.jpg|thumb|right|మొసలి.]] ==={{ĐM|etym}}=== {{inh+|te|dra-pro|*mocVḷ}}. Cùng gốc với {{cog|iru|மொஜலெ}}. ==={{ĐM|n}}=== {{te-noun}} # [[cá sấu|Cá sấu]]. ===={{ĐM|quot}}==== {{seeCites|te}} ===={{ĐM|syn}}==== * {{l|te|మకరము}} ==={{ĐM|ref}}=== * {{R:te:CPB|head=మొసలి|1043}} {{topics|te|Bộ Cá sấu}} q6euuo4agjktr4rj3iwnigxgaldmer5 Thể loại:Từ kế thừa từ tiếng Dravida nguyên thủy tiếng Telugu 14 392453 2344372 2026-04-12T03:28:00Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344372 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx ꪹꪖꪷꪨꪀ 0 392454 2344373 2026-04-12T04:14:35Z Higashizakura 36666 Trang mới 2344373 wikitext text/x-wiki =={{langname|blt}}== ==={{đm|pron}}=== {{blt-pron|ꪖꪰ-ꪹꪨꪷꪀ}} ==={{đm|v}}=== {{head|blt|Động từ|tr=thlớk}} # [[trầy|Trầy]]. ==={{đm|ref}}=== * {{R:blt:TĐTV}} 9nqb0yok6d5v9xlfddg12qcb08r73y0 Thể loại:Bản mẫu tham khảo tiếng Thái Đen 14 392455 2344375 2026-04-12T04:18:27Z Higashizakura 36666 Trang mới: “{{auto cat}}” 2344375 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Bản mẫu cách phát âm tiếng Thái Đen 14 392456 2344377 2026-04-12T04:22:23Z Higashizakura 36666 Trang mới: “{{auto cat}}” 2344377 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Bản mẫu tiếng Thái Đen 14 392457 2344378 2026-04-12T04:23:13Z Higashizakura 36666 Trang mới: “{{auto cat}}” 2344378 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 照猫画虎 0 392458 2344380 2026-04-12T04:26:25Z Hiyuune 50834 Trang mới: “=={{langname|zh}}== {{zh-see|照貓畫虎}}” 2344380 wikitext text/x-wiki =={{langname|zh}}== {{zh-see|照貓畫虎}} 9swa3zdnhiqmcl9ij5bso1x8ej986yp Thể loại:Bản mẫu liên kết tiếng Thái Đen 14 392459 2344382 2026-04-12T04:29:24Z Hiyuune 50834 Trang mới: “{{auto cat}}” 2344382 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 頭腦 0 392460 2344384 2026-04-12T04:35:13Z WhoAlone 40420 Trang mới: “{{also|头脑}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|đầu não}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=두뇌}} # {{hanja form of|두뇌|[[não]]}} =={{langname|zh}}== {{zh-forms|s=头脑|lit=đầu não}} ==={{ĐM|pron}}=== {{zh-pron |m=tóunǎo |c=tau4 nou5 |h=pfs=thèu-nó;hrs=h:teu noˊ |mb=tê-nǎu |md=tàu-nō̤ |mn=xm,zz,kh,tn,lk,yl,km,mg,pn,sg:thâu-náu/qz,hc,tc,j…” 2344384 wikitext text/x-wiki {{also|头脑}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|đầu não}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=두뇌}} # {{hanja form of|두뇌|[[não]]}} =={{langname|zh}}== {{zh-forms|s=头脑|lit=đầu não}} ==={{ĐM|pron}}=== {{zh-pron |m=tóunǎo |c=tau4 nou5 |h=pfs=thèu-nó;hrs=h:teu noˊ |mb=tê-nǎu |md=tàu-nō̤ |mn=xm,zz,kh,tn,lk,yl,km,mg,pn,sg:thâu-náu/qz,hc,tc,jj,ph:thâu-ló/tp,sx:thâu-nó͘ |mn-t=tao5 nao2 |px=pt,xy:tao2 nor3 |w=sh:6deu nau |mc=y |cat=n }} ==={{ĐM|noun}}=== {{head|zh|Danh từ}} # {{lb|zh|literary}} [[đầu]]. # [[trí não]]. # [[trí tuệ]], [[trí]] [[thông minh]]. # [[lãnh đạo]]. # {{lb|zh|obsolete}} [[thông tin]] [[nội bộ]]. # {{lb|zh|obsolete}} [[lý do]]; [[nguyên nhân]]. ===={{ĐM|syn}}==== {{zh-dial|頭}} * {{s|trí não}} {{syn-saurus|zh|腦力}} * {{s|thông tin nội bộ}} {{syn-saurus|zh|內情}} ===={{ĐM|derived}}==== {{col3|zh|大頭腦|不知一個頭腦|好頭腦|不知頭腦|摸不著頭腦//摸不着头脑|打大頭腦|沒頭腦官司|沒頭腦的事|沒頭腦|有頭腦|頭腦派|頭腦體操|頭腦湯|頭腦酒|頭腦簡單|頭腦風暴|丈二金剛——摸不著頭腦|丈二和尚——摸不著頭腦|頭腦發熱|四肢發達,頭腦簡單}} ===={{ĐM|desc}}==== {{CJKV||s=頭%脳|ず%のう|두뇌|đầu não}} ppmrc83e4arj588q1hm14iulc83bgra 2344392 2344384 2026-04-12T04:39:01Z WhoAlone 40420 2344392 wikitext text/x-wiki {{also|头脑}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|noun}}=== {{vi-noun|sc=Hani}} # {{vi-Han form of|đầu não}} =={{langname|ja}}== {{ja-see|頭脳}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|noun}}=== {{ko-noun|hangeul=두뇌}} # {{hanja form of|두뇌|[[não]]}} =={{langname|zh}}== {{zh-forms|s=头脑|lit=đầu não}} ==={{ĐM|pron}}=== {{zh-pron |m=tóunǎo |c=tau4 nou5 |h=pfs=thèu-nó;hrs=h:teu noˊ |mb=tê-nǎu |md=tàu-nō̤ |mn=xm,zz,kh,tn,lk,yl,km,mg,pn,sg:thâu-náu/qz,hc,tc,jj,ph:thâu-ló/tp,sx:thâu-nó͘ |mn-t=tao5 nao2 |px=pt,xy:tao2 nor3 |w=sh:6deu nau |mc=y |cat=n }} ==={{ĐM|noun}}=== {{head|zh|Danh từ}} # {{lb|zh|literary}} [[đầu]]. # [[trí não]]. # [[trí tuệ]], [[trí]] [[thông minh]]. # [[lãnh đạo]]. # {{lb|zh|obsolete}} [[thông tin]] [[nội bộ]]. # {{lb|zh|obsolete}} [[lý do]]; [[nguyên nhân]]. ===={{ĐM|syn}}==== {{zh-dial|頭}} * {{s|trí não}} {{syn-saurus|zh|腦力}} * {{s|thông tin nội bộ}} {{syn-saurus|zh|內情}} ===={{ĐM|derived}}==== {{col3|zh|大頭腦|不知一個頭腦|好頭腦|不知頭腦|摸不著頭腦//摸不着头脑|打大頭腦|沒頭腦官司|沒頭腦的事|沒頭腦|有頭腦|頭腦派|頭腦體操|頭腦湯|頭腦酒|頭腦簡單|頭腦風暴|丈二金剛——摸不著頭腦|丈二和尚——摸不著頭腦|頭腦發熱|四肢發達,頭腦簡單}} ===={{ĐM|desc}}==== {{CJKV||s=頭%脳|ず%のう|두뇌|đầu não}} 0dstpn9dtxjvb16g20bij91trygf1g3 头脑 0 392461 2344385 2026-04-12T04:35:38Z WhoAlone 40420 Trang mới: “{{also|頭腦}} =={{langname|zh}}== {{zh-see|頭腦}}” 2344385 wikitext text/x-wiki {{also|頭腦}} =={{langname|zh}}== {{zh-see|頭腦}} gghdub8o8srfluwotqtqoobumcx661c tóunǎo 0 392462 2344386 2026-04-12T04:36:21Z WhoAlone 40420 Trang mới: “=={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|頭腦}}” 2344386 wikitext text/x-wiki =={{langname|cmn}}== ==={{ĐM|rom}}=== {{cmn-pinyin}} # {{cmn-pinyin of|頭腦}} nw7123cpu50v08h2pi2j90gf3nx6oi6 Bản mẫu:list:Ngày trong tuần/blt 10 392463 2344387 2026-04-12T04:37:19Z Higashizakura 36666 Trang mới: “{{#invoke:topic list|show |([[ꪫꪽ]]) [[ꪊꪽ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪮꪉ]] |([[ꪫꪽ]]) [[ꪮꪰꪉ ꪅꪱꪙ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪱꪣ]] |([[ꪫꪽ]]) [[ꪡꪴꪒ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪲ꪿]] |([[ꪫꪽ]]) [[ꪡꪱꪀ ꪬꪰꪒ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪬ꫁ꪱ]] |([[ꪫꪽ]]) [[ꪎꪴꪀ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪶꪬ꪿ꪀ]] |([[ꪫꪽ]]) [[ꪹꪎꪱ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪹꪊꪸꪒ]] |(ꪫ…” 2344387 wikitext text/x-wiki {{#invoke:topic list|show |([[ꪫꪽ]]) [[ꪊꪽ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪮꪉ]] |([[ꪫꪽ]]) [[ꪮꪰꪉ ꪅꪱꪙ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪱꪣ]] |([[ꪫꪽ]]) [[ꪡꪴꪒ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪎꪲ꪿]] |([[ꪫꪽ]]) [[ꪡꪱꪀ ꪬꪰꪒ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪬ꫁ꪱ]] |([[ꪫꪽ]]) [[ꪎꪴꪀ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪶꪬ꪿ꪀ]] |([[ꪫꪽ]]) [[ꪹꪎꪱ]] / ([[ꪣꪳ꫁]]) [[ꪖꪳ꪿ ꪹꪊꪸꪒ]] |([[ꪫꪽ]]) [[ꪗꪲꪒ]] / ([[ꪣꪳ꫁]]) [[ꪊꪴ꫁ ꪹꪑꪷꪒ]] }}<noinclude>{{list doc}}</noinclude> qvlqxuvp3ndpnipu1mcwo48yxadbk0y 頭脳 0 392464 2344388 2026-04-12T04:37:25Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ず|のう|yomi=o}} ==={{ĐM|pron}}=== {{ja-pron|ずのう|acc=1|acc_ref=NHK}} ==={{ĐM|noun}}=== {{ja-noun|ずのう}} # [[trí tuệ]]. ==={{ĐM|ref}}=== <references/> :* {{R:Kanjipedia Kotoba|0005234100}}” 2344388 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ず|のう|yomi=o}} ==={{ĐM|pron}}=== {{ja-pron|ずのう|acc=1|acc_ref=NHK}} ==={{ĐM|noun}}=== {{ja-noun|ずのう}} # [[trí tuệ]]. ==={{ĐM|ref}}=== <references/> :* {{R:Kanjipedia Kotoba|0005234100}} 3ujroed0h49y4lg7g23j42jstv715kt zunō 0 392465 2344389 2026-04-12T04:37:55Z WhoAlone 40420 Trang mới: “{{also|zuno|Zuno|žuno}} =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-romaji}} # {{ja-romanization of|ずのう}}” 2344389 wikitext text/x-wiki {{also|zuno|Zuno|žuno}} =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-romaji}} # {{ja-romanization of|ずのう}} 3zew72rlkksaaodgt17c1co8xmbhwjx ずのう 0 392466 2344390 2026-04-12T04:38:16Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|頭脳}}” 2344390 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|頭脳}} rs4aqb9v0voapnkgyqzkbnrhc7ld44u 𑜑𑜥 0 392467 2344393 2026-04-12T04:41:25Z Hiyuune 50834 + aho 2344393 wikitext text/x-wiki =={{langname|aho}}== ==={{section|etym}}=== So sánh với {{cog|och|-}} {{och-l|牛}}. Cùng gốc với {{cog|khb|ᦷᦣ}}. So sánh với {{cog|khb|ᦷᦇ}}, {{cog|th|วัว}} hoặc {{mention|th|งัว}}, {{cog|nod|ᨦ᩠ᩅᩫ}}, {{cog|tts|งัว}}, {{cog|lo|ງົວ}}, {{cog|blt|ꪉꪺ}}. ==={{section|n}}=== {{head|aho|Danh từ}} # Con [[bò]]. {{C|aho|Động vật|Lớp Thú}} 4397q9k9iac8l5larva8dkzobmsjvru ᦷᦣ 0 392468 2344394 2026-04-12T04:43:34Z Hiyuune 50834 Trang mới: “=={{langname|khb}}== ==={{section|etym}}=== * {{alt|khb|ᦷᦇ|ᦷᦞ}} ==={{section|etym}}=== {{inh+|khb|tai-swe-pro|*ŋuəᴬ⁴||bò}} (Jonsson, 1991). So sánh với {{cog|och|-}} {{och-l|牛}}. Cùng gốc với {{cog|th|วัว}} hoặc {{mention|th|งัว}}, {{cog|nod|ᨦ᩠ᩅᩫ}}, {{cog|tts|งัว}}, {{cog|lo|ງົວ}}, {{cog|blt|ꪉꪺ}}, {{cog|twh|ꪉꪺ}}, {{cog|shn|ငူဝ်း}} hoặc {{mention|shn|ဝူဝ်း}}, {{cog|tdd|ᥒᥨᥝᥰ}}…” 2344394 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== * {{alt|khb|ᦷᦇ|ᦷᦞ}} ==={{section|etym}}=== {{inh+|khb|tai-swe-pro|*ŋuəᴬ⁴||bò}} (Jonsson, 1991). So sánh với {{cog|och|-}} {{och-l|牛}}. Cùng gốc với {{cog|th|วัว}} hoặc {{mention|th|งัว}}, {{cog|nod|ᨦ᩠ᩅᩫ}}, {{cog|tts|งัว}}, {{cog|lo|ງົວ}}, {{cog|blt|ꪉꪺ}}, {{cog|twh|ꪉꪺ}}, {{cog|shn|ငူဝ်း}} hoặc {{mention|shn|ဝူဝ်း}}, {{cog|tdd|ᥒᥨᥝᥰ}} hoặc {{mention|tdd|ᥝᥨᥝᥰ}}, {{cog|aho|𑜆𑜥}} hoặc {{mention|aho|𑜑𑜥}}. ==={{section|pron}}=== {{khb-pron}} ==={{section|n}}=== {{khb-noun|ᦷᦎ}} # Con [[bò]]. ==={{section|ref}}=== * {{R:khb:Hanna}} jwv4v1f2j5opvrubiciymudp36ktk04 2344396 2344394 2026-04-12T04:50:41Z Hiyuune 50834 /* Tiếng Lự */ (sử dụng [[MediaWiki:Gadget-AjaxEdit.js|AjaxEdit]]) 2344396 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== * {{alt|khb|ᦷᦇ|ᦷᦞ}} ==={{section|etym}}=== {{inh+|khb|tai-swe-pro|*ŋuəᴬ⁴||bò}} (Jonsson, 1991). So sánh với {{cog|och|-}} {{och-l|牛}}. Cùng gốc với {{cog|th|วัว}} hoặc {{mention|th|งัว}}, {{cog|nod|ᨦ᩠ᩅᩫ}}, {{cog|tts|งัว}}, {{cog|lo|ງົວ}}, {{cog|blt|ꪉꪺ}}, {{cog|twh|ꪉꪺ}}, {{cog|shn|ငူဝ်း}} hoặc {{mention|shn|ဝူဝ်း}}, {{cog|tdd|ᥒᥨᥝᥰ}} hoặc {{mention|tdd|ᥝᥨᥝᥰ}}, {{cog|aho|𑜆𑜥}} hoặc {{mention|aho|𑜑𑜥}}. ==={{section|pron}}=== {{khb-pron}} ==={{section|n}}=== {{khb-noun|ᦷᦎ}} # Con [[bò]]. ==={{section|ref}}=== * {{R:khb:Hanna}} {{C|khb|Động vật|Lớp Thú}} nlcy0cjmlc4o5g2fxckl3shyzkrspjx 2344443 2344396 2026-04-12T07:50:41Z Hiyuune 50834 /* Tiếng Lự */ 2344443 wikitext text/x-wiki =={{langname|khb}}== ==={{section|alt}}=== * {{alt|khb|ᦷᦇ|ᦷᦞ}} ==={{section|etym}}=== {{inh+|khb|tai-swe-pro|*ŋuəᴬ⁴||bò}} (Jonsson, 1991). So sánh với {{cog|och|-}} {{och-l|牛}}. Cùng gốc với {{cog|th|วัว}} hoặc {{mention|th|งัว}}, {{cog|nod|ᨦ᩠ᩅᩫ}}, {{cog|tts|งัว}}, {{cog|lo|ງົວ}}, {{cog|blt|ꪉꪺ}}, {{cog|twh|ꪉꪺ}}, {{cog|shn|ငူဝ်း}} hoặc {{mention|shn|ဝူဝ်း}}, {{cog|tdd|ᥒᥨᥝᥰ}} hoặc {{mention|tdd|ᥝᥨᥝᥰ}}, {{cog|aho|𑜆𑜥}} hoặc {{mention|aho|𑜑𑜥}}. ==={{section|pron}}=== {{khb-pron}} ==={{section|n}}=== {{khb-noun|ᦷᦎ}} # Con [[bò]]. ==={{section|ref}}=== * {{R:khb:Hanna}} {{C|khb|Động vật|Lớp Thú}} 0ogg02r9fdbwha9tu8ldcrcqk2v2m3v Thể loại:Danh từ có loại từ ᦷᦎ tiếng Lự 14 392469 2344397 2026-04-12T04:51:12Z Hiyuune 50834 Trang mới: “{{auto cat}}” 2344397 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 簡單 0 392470 2344398 2026-04-12T04:51:59Z WhoAlone 40420 Trang mới: “{{also|簡単|简单}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|adj}}=== {{vi-adj|sc=Hani}} # {{vi-Han form of|giản đơn}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=o}} {{ja-gv|簡単}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|root}}=== {{ko-pos|root|hangeul=간단}} # {{hanja form of|간단}} =={{langname|zh}}== {{zh-forms|s=简单}} ==={{ĐM|pron}}=== {{zh-pron |m=jiǎndān |ma=Zh-jiǎndān.ogg |c=gaan2 daan1 |ca=LL-Q9186-Luilui6666-简单.…” 2344398 wikitext text/x-wiki {{also|簡単|简单}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|adj}}=== {{vi-adj|sc=Hani}} # {{vi-Han form of|giản đơn}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=o}} {{ja-gv|簡単}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|root}}=== {{ko-pos|root|hangeul=간단}} # {{hanja form of|간단}} =={{langname|zh}}== {{zh-forms|s=简单}} ==={{ĐM|pron}}=== {{zh-pron |m=jiǎndān |ma=Zh-jiǎndān.ogg |c=gaan2 daan1 |ca=LL-Q9186-Luilui6666-简单.wav |h=pfs=kién-tân;hrs=h:gienˊ danˋ |j=jie2 dan1 |md=gāng-dăng |mn=kán-tan |mn-t=gang2 duan1 |px=pt,xy:gang3 *dang1 |w=sh:5ci te |cat=a }} ==={{ĐM|adj}}=== {{head|zh|Tính từ}} # [[đơn giản]], [[dễ dàng]]. #: {{zh-x|簡單 碳水.化合物|'''simple''' carbohydrate}} #: {{zh-x|簡單 易用|'''đơn giản''', tiện dụng}} #: {{zh-x|這 道 題 太 簡單 了。|Câu hỏi này '''dễ''' quá.}} # {{lb|zh|chủ yếu ở dạng phủ định}} [[thông thường]]; [[bình thường]]. # [[cẩu thả]]; [[bất cẩn]]; [[sơ sài]]; [[tùy tiện]]; [[đơn giản]] hóa quá mức. ===={{ĐM|syn}}==== * {{s|đơn giản}} {{syn-saurus|zh|不複雜}} * {{s|thông thường}} {{syn-saurus|zh|正常}} * {{s|cẩu thả}} {{syn-saurus|zh|粗心}} ===={{ĐM|antonym}}==== * {{as|simple}} {{zh-l|複雜}} ===={{ĐM|drv}}==== {{col3|zh|簡單機械|簡單明瞭|頭腦簡單|簡單粗暴|四肢發達,頭腦簡單}} ===={{ĐM|desc}}==== {{CJKV|j=簡%単||かん%たん|간단|giản đơn}} f08g2j2l7ch46mt9k8dehclr1dxj8j8 2344410 2344398 2026-04-12T05:01:25Z WhoAlone 40420 /* {{ĐM|antonym}} */ 2344410 wikitext text/x-wiki {{also|簡単|简单}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|adj}}=== {{vi-adj|sc=Hani}} # {{vi-Han form of|giản đơn}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=o}} {{ja-gv|簡単}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|root}}=== {{ko-pos|root|hangeul=간단}} # {{hanja form of|간단}} =={{langname|zh}}== {{zh-forms|s=简单}} ==={{ĐM|pron}}=== {{zh-pron |m=jiǎndān |ma=Zh-jiǎndān.ogg |c=gaan2 daan1 |ca=LL-Q9186-Luilui6666-简单.wav |h=pfs=kién-tân;hrs=h:gienˊ danˋ |j=jie2 dan1 |md=gāng-dăng |mn=kán-tan |mn-t=gang2 duan1 |px=pt,xy:gang3 *dang1 |w=sh:5ci te |cat=a }} ==={{ĐM|adj}}=== {{head|zh|Tính từ}} # [[đơn giản]], [[dễ dàng]]. #: {{zh-x|簡單 碳水.化合物|'''simple''' carbohydrate}} #: {{zh-x|簡單 易用|'''đơn giản''', tiện dụng}} #: {{zh-x|這 道 題 太 簡單 了。|Câu hỏi này '''dễ''' quá.}} # {{lb|zh|chủ yếu ở dạng phủ định}} [[thông thường]]; [[bình thường]]. # [[cẩu thả]]; [[bất cẩn]]; [[sơ sài]]; [[tùy tiện]]; [[đơn giản]] hóa quá mức. ===={{ĐM|syn}}==== * {{s|đơn giản}} {{syn-saurus|zh|不複雜}} * {{s|thông thường}} {{syn-saurus|zh|正常}} * {{s|cẩu thả}} {{syn-saurus|zh|粗心}} ===={{ĐM|antonym}}==== * {{label|zh|giản thể}} {{zh-l|複雜}} ===={{ĐM|drv}}==== {{col3|zh|簡單機械|簡單明瞭|頭腦簡單|簡單粗暴|四肢發達,頭腦簡單}} ===={{ĐM|desc}}==== {{CJKV|j=簡%単||かん%たん|간단|giản đơn}} 4h9monncq056aa0ytvoafuq04xioox4 2344412 2344410 2026-04-12T05:01:35Z WhoAlone 40420 /* {{ĐM|antonym}} */ 2344412 wikitext text/x-wiki {{also|簡単|简单}} =={{langname|vi}}== {{vi-hantutab}} ==={{ĐM|adj}}=== {{vi-adj|sc=Hani}} # {{vi-Han form of|giản đơn}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=o}} {{ja-gv|簡単}} =={{langname|ko}}== {{ko-hanjatab}} ==={{ĐM|root}}=== {{ko-pos|root|hangeul=간단}} # {{hanja form of|간단}} =={{langname|zh}}== {{zh-forms|s=简单}} ==={{ĐM|pron}}=== {{zh-pron |m=jiǎndān |ma=Zh-jiǎndān.ogg |c=gaan2 daan1 |ca=LL-Q9186-Luilui6666-简单.wav |h=pfs=kién-tân;hrs=h:gienˊ danˋ |j=jie2 dan1 |md=gāng-dăng |mn=kán-tan |mn-t=gang2 duan1 |px=pt,xy:gang3 *dang1 |w=sh:5ci te |cat=a }} ==={{ĐM|adj}}=== {{head|zh|Tính từ}} # [[đơn giản]], [[dễ dàng]]. #: {{zh-x|簡單 碳水.化合物|'''simple''' carbohydrate}} #: {{zh-x|簡單 易用|'''đơn giản''', tiện dụng}} #: {{zh-x|這 道 題 太 簡單 了。|Câu hỏi này '''dễ''' quá.}} # {{lb|zh|chủ yếu ở dạng phủ định}} [[thông thường]]; [[bình thường]]. # [[cẩu thả]]; [[bất cẩn]]; [[sơ sài]]; [[tùy tiện]]; [[đơn giản]] hóa quá mức. ===={{ĐM|syn}}==== * {{s|đơn giản}} {{syn-saurus|zh|不複雜}} * {{s|thông thường}} {{syn-saurus|zh|正常}} * {{s|cẩu thả}} {{syn-saurus|zh|粗心}} ===={{ĐM|antonym}}==== * {{label|zh|đơn giản}} {{zh-l|複雜}} ===={{ĐM|drv}}==== {{col3|zh|簡單機械|簡單明瞭|頭腦簡單|簡單粗暴|四肢發達,頭腦簡單}} ===={{ĐM|desc}}==== {{CJKV|j=簡%単||かん%たん|간단|giản đơn}} natjnnfolpmu9w0of0jbvgdce0tgt4g Thể loại:Gốc từ tiếng Triều Tiên 14 392471 2344399 2026-04-12T04:52:24Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344399 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Danh từ có loại từ tiếng Lự 14 392472 2344400 2026-04-12T04:52:33Z Hiyuune 50834 Trang mới: “{{auto cat}}” 2344400 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Tính từ tiếng Tấn 14 392473 2344401 2026-04-12T04:52:49Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344401 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx 简单 0 392474 2344402 2026-04-12T04:53:44Z WhoAlone 40420 Trang mới: “{{also|簡單|簡単}} =={{langname|zh}}== {{zh-see|簡單}}” 2344402 wikitext text/x-wiki {{also|簡單|簡単}} =={{langname|zh}}== {{zh-see|簡單}} j1pwmtjjmmj3mr5wzl18161dpp6xzk8 간단 0 392475 2344403 2026-04-12T04:55:57Z WhoAlone 40420 Trang mới: “=={{langname|ko}}== ==={{ĐM|etym}} 1=== {{ko-etym-Sino|間斷}}. ===={{ĐM|pron}}==== {{ko-IPA|l=y}} ===={{ĐM|noun}}==== {{ko-noun|hanja=間斷}} # {{lb|ko|formal}} Một khoảng [[dừng]] ngắn. ====={{ĐM|derived}}===== {{col3|ko|간단(間斷)하다}} ==={{ĐM|etym}} 2=== {{ko-etym-Sino|簡單}}. ===={{ĐM|pron}}==== {{ko-IPA}} ===={{ĐM|root}}==== {{ko-root|hanja=簡單}} # {{ko-root of|[[간단하다]]/[[간단히]]}}” 2344403 wikitext text/x-wiki =={{langname|ko}}== ==={{ĐM|etym}} 1=== {{ko-etym-Sino|間斷}}. ===={{ĐM|pron}}==== {{ko-IPA|l=y}} ===={{ĐM|noun}}==== {{ko-noun|hanja=間斷}} # {{lb|ko|formal}} Một khoảng [[dừng]] ngắn. ====={{ĐM|derived}}===== {{col3|ko|간단(間斷)하다}} ==={{ĐM|etym}} 2=== {{ko-etym-Sino|簡單}}. ===={{ĐM|pron}}==== {{ko-IPA}} ===={{ĐM|root}}==== {{ko-root|hanja=簡單}} # {{ko-root of|[[간단하다]]/[[간단히]]}} 2uleaxjuvyndgi982qbnz71kc9x8z4y Mô đun:bej-pronunciation 828 392476 2344413 2026-04-12T05:02:23Z Hiyuune 50834 Trang mới: “local export = {} local m_IPA = require("Module:IPA") local m_table = require("Module:table") local lang = require("Module:languages").getByCode("bej") local U = mw.ustring.char local rsub = mw.ustring.gsub local rlower = mw.ustring.lower local rfind = mw.ustring.find local raised = U(0x031D) local consonants = "bpmwfdtɖʈznɲŋɳrlkɡhxjsvʃʷɣʤʔ̠" local C = "[" .. consonants .. "]" local vowels = "aeiou" local V = "[" .. vowels .. "]" local function track(page)…” 2344413 Scribunto text/plain local export = {} local m_IPA = require("Module:IPA") local m_table = require("Module:table") local lang = require("Module:languages").getByCode("bej") local U = mw.ustring.char local rsub = mw.ustring.gsub local rlower = mw.ustring.lower local rfind = mw.ustring.find local raised = U(0x031D) local consonants = "bpmwfdtɖʈznɲŋɳrlkɡhxjsvʃʷɣʤʔ̠" local C = "[" .. consonants .. "]" local vowels = "aeiou" local V = "[" .. vowels .. "]" local function track(page) require("Module:debug").track("bej-IPA/" .. page) return true end local function rsub_repeatedly(term, foo, bar) while true do local new_term = rsub(term, foo, bar) if new_term == term then return term end term = new_term end end local trigraphs = { ["nth"] = "ɳʈ", ["ndh"] = "ɳɖ", } local digraphs = { ["aa"] = "aː", ["ee"] = "eː", ["ii"] = "iː", ["oo"] = "oː", ["uu"] = "uː", ["áá"] = "áː", ["éé"] = "éː", ["íí"] = "íː", ["óó"] = "óː", ["úú"] = "úː", ["áa"] = "áː", ["ée"] = "éː", ["íi"] = "íː", ["óo"] = "óː", ["úu"] = "úː", ["aá"] = "áː", ["eé"] = "éː", ["ií"] = "íː", ["oó"] = "óː", ["uú"] = "úː", ["dh"] = "ɖ", ["gh"] = "ɣ", ["gw"] = "ɡʷ", ["nj"] = "ɲd͡ʒ", ["nk"] = "ŋk", ["ng"] = "ŋɡ", ["kw"] = "kʷ", ["sh"] = "ʃ", ["th"] = "ʈ", ["kh"] = "x", } local function flatmap(items, fun) local new = {} for _, item in ipairs(items) do local results = fun(item) mw.logObject(results, "results") for _, result in ipairs(results) do table.insert(new, result) end mw.logObject(new, "new") end return new end local phon = { ["'"] = "ʔ", ["a"] = "a", ["i"] = "i", ["u"] = "u", ["b"] = "b", ["d"] = "d", ["f"] = "f", ["g"] = "ɡ", ["h"] = "h", ["j"] = "d͡ʒ", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", ["r"] = "r", ["s"] = "s", ["t"] = "t", ["w"] = "w", ["y"] = "j", [":"] = "ː", ["?"] = "ʔ" } function export.phonemic(text, post) text = rlower(text) text = rsub(text, " | ", "# | #") text = "##" .. rsub(text, " ", "# #") .. "##" -- basic phonology for digraph, replacement in pairs(digraphs) do text = rsub(text, digraph, replacement) end text = rsub(text, ".", phon) text = rsub(text, "^ˈ%-", "-") text = rsub(text, "(" .. C .. "*[áéíóú])", "ˈ%1") if not rfind(text, "ˈ") then text = rsub(text, text, "ˈ" .. text) end text = rsub(text, "á", "a") text = rsub(text, "é", "e") text = rsub(text, "í", "i") text = rsub(text, "ó", "o") text = rsub(text, "ú", "u") text = rsub(text, "'", "ˈ") text = rsub(text, "-", "") local variants = {text} local function flatmap_and_sub_pre(from, to1, to2) variants = flatmap( variants, function(item) if rfind(item, from) then local retval = {rsub_repeatedly(item, from, to1)} if to2 then m_table.insertIfNot(retval, rsub_repeatedly(item, from, to2)) end return retval else return {item} end end ) end flatmap_and_sub_pre("#", "") return variants end function export.IPA(frame) local terms = {} args = frame:getParent().args local currentTitle = mw.loadData("Module:headword/data").pagename for _, term in ipairs(args) do if term == currentTitle then track("redundant") end table.insert(terms, term) end if #terms == 0 then terms = {currentTitle} end local results = {} for _, term in ipairs(terms) do local phonemic = export.phonemic(term) for _, variant in ipairs(phonemic) do table.insert(results, {pron = "/" .. variant .. "/"}) end end return "*" .. m_IPA.format_IPA_full { lang = lang, items = results } end return export is07mbtm9m98v02rkmuxbtmi5ms0mvb 簡単 0 392477 2344414 2026-04-12T05:03:02Z WhoAlone 40420 Trang mới: “{{also|簡單|简单}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=on}} ==={{ĐM|etym}}=== Từ {{der|ja|ltc|-}} {{ltc-l|簡單|id=1,1}}. So sánh {{cog|nan-hbl|簡單|tr=kán-tan}} và {{cog|yue|簡單}}. ==={{ĐM|pron}}=== {{ja-pron|かんたん|acc=0|acc_ref=DJR,NHK,SMK5}} ==={{ĐM|adj}}=== {{ja-adj|infl=な|かんたん}} # [[dễ dàng]]. # [[đơn giản]]. # [[ngắn ngủi]]. ===={{ĐM|inflection}}==== {{ja-na|かんたん}} ===={{ĐM|antonym}}====…” 2344414 wikitext text/x-wiki {{also|簡單|简单}} =={{langname|ja}}== {{ja-kanjitab|かん|たん|yomi=on}} ==={{ĐM|etym}}=== Từ {{der|ja|ltc|-}} {{ltc-l|簡單|id=1,1}}. So sánh {{cog|nan-hbl|簡單|tr=kán-tan}} và {{cog|yue|簡單}}. ==={{ĐM|pron}}=== {{ja-pron|かんたん|acc=0|acc_ref=DJR,NHK,SMK5}} ==={{ĐM|adj}}=== {{ja-adj|infl=な|かんたん}} # [[dễ dàng]]. # [[đơn giản]]. # [[ngắn ngủi]]. ===={{ĐM|inflection}}==== {{ja-na|かんたん}} ===={{ĐM|antonym}}==== * {{antsense|đơn giản}} {{ja-r|複%雑|ふく%ざつ}} ==={{ĐM|noun}}=== {{ja-noun|かんたん}} # Sự [[dễ dàng]]. # Sự [[đơn giản]]. # Sự [[ngắn ngủi]]. ==={{ĐM|ref}}=== <references/> :* {{R:Kanjipedia Kotoba|0001136200}} :* {{R:Shogakukan}} cnv01o93xjt0e01odv2nr7v7otepyqs Bản mẫu:bej-IPA 10 392478 2344415 2026-04-12T05:03:36Z Hiyuune 50834 Trang mới: “{{#invoke:bej-pronunciation|IPA}}<noinclude>{{tài liệu}}{{tcat|pron}}</noinclude>” 2344415 wikitext text/x-wiki {{#invoke:bej-pronunciation|IPA}}<noinclude>{{tài liệu}}{{tcat|pron}}</noinclude> bdcrdk2d5ql8lb4qrhry9gudpks16xk かんたん 0 392479 2344416 2026-04-12T05:04:02Z WhoAlone 40420 Trang mới: “{{also|がんたん|かんだん}} =={{langname|ja}}== {{ja-see|簡単|感嘆|肝胆|邯鄲|管端}}” 2344416 wikitext text/x-wiki {{also|がんたん|かんだん}} =={{langname|ja}}== {{ja-see|簡単|感嘆|肝胆|邯鄲|管端}} 1bzo2dmx91j96qk14p96ndk71a85s94 Thể loại:Bản mẫu cách phát âm tiếng Beja 14 392480 2344417 2026-04-12T05:05:39Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344417 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Bản mẫu tiếng Beja 14 392481 2344418 2026-04-12T05:05:46Z WhoAlone 40420 Trang mới: “{{auto cat}}” 2344418 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Mục từ có cách phát âm IPA tiếng Na Uy (Bokmål) 14 392482 2344421 2026-04-12T05:09:03Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344421 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Bảo trì mục từ tiếng Na Uy (Bokmål) 14 392483 2344423 2026-04-12T05:09:55Z Kelly zhrm 58416 Trang mới: “{{auto cat}}” 2344423 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx ひろい 0 392484 2344426 2026-04-12T05:13:25Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|alt=広い,弘い,宏い,博い,裕い:hiếm}} ==={{ĐM|etym}} 1=== {{ja-adj-ku|広し|firo}} Từ {{inh|ja|ojp|-}}, từ {{inh|ja|jpx-pro|*pirə}}. ===={{ĐM|pron}}==== {{ja-pron|acc=2}} {{ja-acc-table|adj-i|ひろい|acc=2|くて-form-acc=2,1|lemma=広い}} ===={{ĐM|adj}}==== {{ja-adj|infl=i}} # {{ja-def|広い|弘い|宏い}} [[rộng]] (bề ngang). #: {{ja-usex|[[その]][[川]]は'''広い'''。|その かわ は '''ひろい'…” 2344426 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|alt=広い,弘い,宏い,博い,裕い:hiếm}} ==={{ĐM|etym}} 1=== {{ja-adj-ku|広し|firo}} Từ {{inh|ja|ojp|-}}, từ {{inh|ja|jpx-pro|*pirə}}. ===={{ĐM|pron}}==== {{ja-pron|acc=2}} {{ja-acc-table|adj-i|ひろい|acc=2|くて-form-acc=2,1|lemma=広い}} ===={{ĐM|adj}}==== {{ja-adj|infl=i}} # {{ja-def|広い|弘い|宏い}} [[rộng]] (bề ngang). #: {{ja-usex|[[その]][[川]]は'''広い'''。|その かわ は '''ひろい'''。|Dòng sông đó '''rộng'''.}} # {{ja-def|広い|弘い|宏い}} [[rộng]] (diện tích). #: {{ja-usex|[[一%番]]'''広い'''[[都%道%府%県]]|いち%ばん '''ひろい''' と%どう%ふ%けん|tỉnh '''lớn nhất''' của Nhật Bản}} #* {{RQ:Botchan}} #*: {{ja-usex|'''広い'''[[細%長い]][[部%屋]]の[[周%囲]]に[[机]]を[[並べる|並べて]][[みんな]][[腰]]を[[かける|かけて]][[いる]]。|'''ひろい''' ほそ%ながい へ%や の しゅう%い に つくえ を ならべて みんな こし を かけて いる。|Trong một căn phòng hình chữ nhật '''rộng rãi''', mỗi người ngồi trước một chiếc bàn được kê dọc theo các bức tường.}} # {{ja-def|広い|弘い|宏い}} [[lớn]], [[rộng rãi]]. # {{ja-def|広い|弘い|宏い|博い}} [[rộng]]. ====={{ĐM|inflection}}===== {{ja-i}} ====={{ĐM|antonym}}===== * {{antsense|rộng}} {{ja-r|狭い|せまい}} ====={{ĐM|derived}}===== {{col|ja |{{ja-r|だだっ広い|だだっぴろい}}, {{ja-r|徒広い|だだっぴろい}} |{{ja-r|世%間は広い様で狭い|せ%けん は ひろい よう で せまい}} |{{ja-r|幅の広い|はば の ひろい}} |{{ja-r|幅%広い|はば%ひろい}} |{{ja-r|広い支%持|ひろい し%じ}} |{{ja-r|広い額|ひろい ひたい}} |{{ja-r|心が広い|こころ が ひろい}} |{{ja-r|心の広い|こころ の ひろい}} |{{ja-r|手%広い|て%びろい}} |{{ja-r|用%途が広い|よう%と が ひろい}} |{{ja-r|用%途の広い|よう%と の ひろい}} |{{ja-r|肩%身が広い|かた%み が ひろい}} |{{ja-r|顔が広い|かお が ひろい}} |{{ja-r|顔の広い|かお の ひろい}} }} ===={{ĐM|ref}}==== * {{R:Shogakukan}} ==={{ĐM|etym}} 2=== {{ja-see|広井}} dr635ndwux1jxd83snxbv4smg3l9d6a 2344430 2344426 2026-04-12T05:19:49Z WhoAlone 40420 2344430 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|alt=広い,弘い,宏い,博い,裕い:hiếm}} ==={{ĐM|etym}} 1=== {{ja-adj-ku|広し|firo}} Từ {{inh|ja|ojp|-}}, từ {{inh|ja|jpx-pro|*pirə}}. ===={{ĐM|pron}}==== {{ja-pron|acc=2}} {{ja-acc-table|adj-i|ひろい|acc=2|くて-form-acc=2,1|lemma=広い}} ===={{ĐM|adj}}==== {{ja-adj|infl=i}} # {{ja-def|広い|弘い|宏い}} [[rộng]] (bề ngang). #: {{ja-usex|[[その]][[川]]は'''広い'''。|その かわ は '''ひろい'''。|Dòng sông đó '''rộng'''.}} # {{ja-def|広い|弘い|宏い}} [[rộng]] (diện tích). #: {{ja-usex|[[一%番]]'''広い'''[[都%道%府%県]]|いち%ばん '''ひろい''' と%どう%ふ%けん|tỉnh '''lớn nhất''' của Nhật Bản}} #* {{RQ:Botchan}} #*: {{ja-usex|'''広い'''[[細%長い]][[部%屋]]の[[周%囲]]に[[机]]を[[並べる|並べて]][[みんな]][[腰]]を[[かける|かけて]][[いる]]。|'''ひろい''' ほそ%ながい へ%や の しゅう%い に つくえ を ならべて みんな こし を かけて いる。|Trong một căn phòng hình chữ nhật '''rộng rãi''', mỗi người ngồi trước một chiếc bàn được kê dọc theo các bức tường.}} # {{ja-def|広い|弘い|宏い}} [[lớn]], [[rộng rãi]]. # {{ja-def|広い|弘い|宏い|博い}} [[rộng]]. ====={{ĐM|inflection}}===== {{ja-i}} ====={{ĐM|antonym}}===== * {{antsense|rộng}} {{ja-r|狭い|せまい}} ====={{ĐM|derived}}===== {{col|ja |{{ja-r|だだっ広い|だだっぴろい}}, {{ja-r|徒広い|だだっぴろい}} |{{ja-r|世%間は広い様で狭い|せ%けん は ひろい よう で せまい}} |{{ja-r|幅の広い|はば の ひろい}} |{{ja-r|幅%広い|はば%ひろい}} |{{ja-r|広い支%持|ひろい し%じ}} |{{ja-r|広い額|ひろい ひたい}} |{{ja-r|心が広い|こころ が ひろい}} |{{ja-r|心の広い|こころ の ひろい}} |{{ja-r|手%広い|て%びろい}} |{{ja-r|用%途が広い|よう%と が ひろい}} |{{ja-r|用%途の広い|よう%と の ひろい}} |{{ja-r|肩%身が広い|かた%み が ひろい}} |{{ja-r|顔が広い|かお が ひろい}} |{{ja-r|顔の広い|かお の ひろい}} }} ====={{ĐM|desc}}===== * {{desc|ycr|hiroy}} ===={{ĐM|ref}}==== * {{R:Shogakukan}} ==={{ĐM|etym}} 2=== {{ja-see|広井}} an5pks9odxu6ubdbyduxrphmghjxnn4 Bản mẫu:scribal abbreviation of 10 392485 2344428 2026-04-12T05:18:26Z Hiyuune 50834 Trang mới: “{{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!-- -->{{#invoke:form of/templates|form_of_t|chữ viết tắt thời trung đại của|cat=Chữ viết tắt thời trung đại|withencap=1}}<!-- -->}}<!-- --><noinclude>{{documentation}}</noinclude>” 2344428 wikitext text/x-wiki {{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!-- -->{{#invoke:form of/templates|form_of_t|chữ viết tắt thời trung đại của|cat=Chữ viết tắt thời trung đại|withencap=1}}<!-- -->}}<!-- --><noinclude>{{documentation}}</noinclude> 36s3hah63i0igbtlcp32y6hy6dhxto6 Bản mẫu:scrib of 10 392486 2344431 2026-04-12T05:20:04Z Hiyuune 50834 Đổi hướng đến [[Bản mẫu:scribal abbreviation of]] 2344431 wikitext text/x-wiki #redirect [[Bản mẫu:scribal abbreviation of]] j3j8uoz619dzn88ppnl533dcmph21fj 広い 0 392487 2344432 2026-04-12T05:20:18Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ひろ|sort=ひろい|yomi=kun}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002145900}}” 2344432 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ひろ|sort=ひろい|yomi=kun}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002145900}} mu51bc4gizguhjhuk1jxceb231y1mei 廣い 0 392488 2344433 2026-04-12T05:20:57Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|廣い}}” 2344433 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|廣い}} ei8z6354l46822ltotbvqs5uqemi6nr 2344434 2344433 2026-04-12T05:21:38Z WhoAlone 40420 2344434 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab}} {{ja-gv|ひろい}} f5jekxnbrtl9xmejco9xx9rth3d5pm4 弘い 0 392489 2344444 2026-04-12T08:46:59Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|yomi=k|ひろ}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002147900|<sup>▲</sup>弘い}}” 2344444 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|yomi=k|ひろ}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002147900|<sup>▲</sup>弘い}} p8lfclnl2iduf8fppf25l52atg1ike4 宏い 0 392490 2344445 2026-04-12T08:48:57Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|yomi=k|ひろ}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002182200|<sup>▲</sup>宏い}}” 2344445 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|yomi=k|ひろ}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0002182200|<sup>▲</sup>宏い}} 1xkgt9jafbax6wv65xsyvxoymi8d2wa 博い 0 392491 2344446 2026-04-12T08:49:20Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0005636600|<sup>△</sup>博い}}” 2344446 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろい}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0005636600|<sup>△</sup>博い}} 264ckw4zwigzh3mwfu6480ncxdub5sq 裕い 0 392492 2344447 2026-04-12T08:51:03Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-gv|ひろい}}” 2344447 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-gv|ひろい}} l8q6aczo85vylwvezeofxaqvmko9d5v ひろく 0 392493 2344448 2026-04-12T08:54:43Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|alt=広く,廣く}} ==={{ĐM|etym}}=== [[連用形|Ren'yōkei]] của {{ja-r|ひろい|gloss=[[rộng]]}}. ==={{ĐM|adv}}=== {{ja-pos|adv}} # Một cách [[rộng rãi]]. #: {{ja-usex|'''広く'''[[知る|知ら]]れている|'''ひろく''' しられている|được biết đến '''rộng rãi'''}} # Một cách [[phổ biến]]. ==={{ĐM|see also}}=== * {{ja-r|あまねく}}” 2344448 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|alt=広く,廣く}} ==={{ĐM|etym}}=== [[連用形|Ren'yōkei]] của {{ja-r|ひろい|gloss=[[rộng]]}}. ==={{ĐM|adv}}=== {{ja-pos|adv}} # Một cách [[rộng rãi]]. #: {{ja-usex|'''広く'''[[知る|知ら]]れている|'''ひろく''' しられている|được biết đến '''rộng rãi'''}} # Một cách [[phổ biến]]. ==={{ĐM|see also}}=== * {{ja-r|あまねく}} qlvwk9s82dkucp5enw3i2r472yxgmq5 hiroi 0 392494 2344449 2026-04-12T08:55:12Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== ==={{ĐM|pron}}=== {{ja-romaji}} # {{ja-romanization of|ひろい}}” 2344449 wikitext text/x-wiki =={{langname|ja}}== ==={{ĐM|pron}}=== {{ja-romaji}} # {{ja-romanization of|ひろい}} e8l3ijzweoyei9x00f1xxjxvxzns86h hiroku 0 392495 2344450 2026-04-12T08:56:57Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-rom}} # {{ja-rom of|ひろく}}” 2344450 wikitext text/x-wiki =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-rom}} # {{ja-rom of|ひろく}} 4hb0ygs60p3pnzjt8j30o3u3dxtlt7k 広く 0 392496 2344451 2026-04-12T08:57:22Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろく}}” 2344451 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろく}} bvckj40ggpgnbrdlwd84ubwm6j6586v 廣く 0 392497 2344452 2026-04-12T08:58:04Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろく}}” 2344452 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|ひろ|yomi=k}} {{ja-see|ひろく}} bvckj40ggpgnbrdlwd84ubwm6j6586v あまねく 0 392498 2344453 2026-04-12T09:03:06Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|alt=遍く,普く,洽く,汎く}} ==={{ĐM|etym}}=== Từ dạng tính từ {{mention|ja|あまねし|tr=amaneshi}}. Xem mục từ này để biết thêm từ nguyên. ==={{ĐM|pron}}=== {{ja-pron|acc=3|acc_ref=DJR}} ==={{ĐM|adv}}=== {{ja-pos|adverb}} # Một cách [[rộng rãi]]; [[khắp nơi]]. ===={{ĐM|see also}}==== * {{ja-r|ひろく}} ==={{ĐM|ref}}=== <references />” 2344453 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|alt=遍く,普く,洽く,汎く}} ==={{ĐM|etym}}=== Từ dạng tính từ {{mention|ja|あまねし|tr=amaneshi}}. Xem mục từ này để biết thêm từ nguyên. ==={{ĐM|pron}}=== {{ja-pron|acc=3|acc_ref=DJR}} ==={{ĐM|adv}}=== {{ja-pos|adverb}} # Một cách [[rộng rãi]]; [[khắp nơi]]. ===={{ĐM|see also}}==== * {{ja-r|ひろく}} ==={{ĐM|ref}}=== <references /> s932opq5w3uy7v6a93ym7q8c5w7kgst amaneku 0 392499 2344454 2026-04-12T09:03:32Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-rom}} # {{ja-rom of|あまねく}}” 2344454 wikitext text/x-wiki =={{langname|ja}}== ==={{ĐM|rom}}=== {{ja-rom}} # {{ja-rom of|あまねく}} hznksuco1mt0svzxi8jpds5qsicx1l9 遍く 0 392500 2344455 2026-04-12T09:05:07Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0006273100|<sup>△</sup>遍く}}” 2344455 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0006273100|<sup>△</sup>遍く}} k0n9vrzj2k0xh8eqcocb6f2ba773hx7 普く 0 392501 2344456 2026-04-12T09:05:35Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0006056700|<sup>△</sup>普く}}” 2344456 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} ==={{ĐM|ref}}=== * {{R:Kanjipedia Kotoba|0006056700|<sup>△</sup>普く}} pp05j3m4fzlv10hc6undumuipzjw9w1 洽く 0 392502 2344457 2026-04-12T09:08:16Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}}” 2344457 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} 8scl2xj7aplgzh97e468yavuyszv0kv 汎く 0 392503 2344458 2026-04-12T09:08:35Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}}” 2344458 wikitext text/x-wiki =={{langname|ja}}== {{ja-kanjitab|あまね|yomi=k}} {{ja-see|あまねく}} 8scl2xj7aplgzh97e468yavuyszv0kv テレビばんぐみ 0 392504 2344459 2026-04-12T09:13:23Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|テレビ番組}}” 2344459 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|テレビ番組}} 16jt6z72n54dyrdx84e7p65kaul6krg テレビンゆ 0 392505 2344460 2026-04-12T09:14:44Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|テレビン油}}” 2344460 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|テレビン油}} iv73nsjkzav7d1piuxnod7p0fbmw6d0 なんかいじしん 0 392506 2344461 2026-04-12T09:15:12Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|南海地震}}” 2344461 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|南海地震}} 6s7fqohlgxzk18y0phbxtmu71743psi 南蠻烏瓜 0 392507 2344463 2026-04-12T09:16:43Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|南蛮烏瓜}}” 2344463 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|南蛮烏瓜}} 3wv71n9fovimj6u1syclndo1be4fpdf ナンバンカラスウリ 0 392508 2344464 2026-04-12T09:16:57Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|南蛮烏瓜}}” 2344464 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|南蛮烏瓜}} 3wv71n9fovimj6u1syclndo1be4fpdf なんばんからすうり 0 392509 2344465 2026-04-12T09:17:00Z WhoAlone 40420 Trang mới: “=={{langname|ja}}== {{ja-see|南蛮烏瓜}}” 2344465 wikitext text/x-wiki =={{langname|ja}}== {{ja-see|南蛮烏瓜}} 3wv71n9fovimj6u1syclndo1be4fpdf loăng 0 392510 2344466 2026-04-12T09:18:40Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]]. #:{{ux|sed|'''loăng '''pơlái|'''cây '''cối}} ==={{đm|ref}}=== {{R:VOV}}” 2344466 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]]. #:{{ux|sed|'''loăng '''pơlái|'''cây '''cối}} ==={{đm|ref}}=== {{R:VOV}} 28vj5gnxqrfy386vf5lylwi2y2zxku0 loăng plâi kâ 0 392511 2344468 2026-04-12T09:26:06Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây ăn trái]]. #:{{ux|sed|'''loăng plâi kâ''' hên hěng tung kơdrum|'''cây ăn trái''' đầy vườn}} ==={{đm|ref}}=== {{R:VOV}}” 2344468 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây ăn trái]]. #:{{ux|sed|'''loăng plâi kâ''' hên hěng tung kơdrum|'''cây ăn trái''' đầy vườn}} ==={{đm|ref}}=== {{R:VOV}} 3ean8fbolzkyuar1xt3z5aldtwaxx6s loăng tróu 0 392512 2344469 2026-04-12T09:27:28Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bằng lăng]]. #:{{ux|sed|'''loăng tróu''' hngêi ai reăng lěm ó|'''Cây bằng lăng''' có hoa rất đẹp}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344469 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bằng lăng]]. #:{{ux|sed|'''loăng tróu''' hngêi ai reăng lěm ó|'''Cây bằng lăng''' có hoa rất đẹp}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} abo93fg1ony1qgp8pki1yfeu1sjazk6 loăng plâi ƀơr 0 392513 2344470 2026-04-12T09:29:13Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bơ]]. #:{{ux|sed|'''loăng plâi ƀơr''' pêt pa ngiâ hngêi|'''cây bơ''' trồng trước nhà}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344470 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bơ]]. #:{{ux|sed|'''loăng plâi ƀơr''' pêt pa ngiâ hngêi|'''cây bơ''' trồng trước nhà}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} i4wbp10j5sf480zrwukcng28uvtyfg8 loăng chêh 0 392514 2344471 2026-04-12T09:31:17Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bút]]. #:{{ux|sed|nôu rôe '''loăng chêh''' ăm o mơhriâm|Mẹ mua '''bút '''cho em đi học}} ==={{đm|ref}}=== {{R:VOV}}” 2344471 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[bút]]. #:{{ux|sed|nôu rôe '''loăng chêh''' ăm o mơhriâm|Mẹ mua '''bút '''cho em đi học}} ==={{đm|ref}}=== {{R:VOV}} 7botoxfj6i1ndu7nluxtvzxxg2sncgr loăng ka te 0 392515 2344472 2026-04-12T09:32:42Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cà te]]. #:{{ux|sed|ai môi xiâm '''loăng ka te'''|Có một '''cây cà te'''}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344472 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cà te]]. #:{{ux|sed|ai môi xiâm '''loăng ka te'''|Có một '''cây cà te'''}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} dyw78uj8e5tucupazcnb31amaccpjow nhâ chó đẻ 0 392516 2344473 2026-04-12T09:34:39Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[chó đẻ]]. #:{{ux|sed|'''nhâ chó đẻ''' huăn xêh lâp lu|'''Cây chó đẻ''' mọc hoang khắp nơi}} ==={{đm|ref}}=== {{R:VOV}}” 2344473 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[chó đẻ]]. #:{{ux|sed|'''nhâ chó đẻ''' huăn xêh lâp lu|'''Cây chó đẻ''' mọc hoang khắp nơi}} ==={{đm|ref}}=== {{R:VOV}} tn19z99avsxxs6fhuzwkkj9oocftua3 loăng nhâ 0 392517 2344474 2026-04-12T10:24:18Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây cỏ]]. #:{{ux|sed|'''loăng nhâ''' amê tiah lâi?|'''Cây cỏ''' ở đó thế nào?}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344474 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây cỏ]]. #:{{ux|sed|'''loăng nhâ''' amê tiah lâi?|'''Cây cỏ''' ở đó thế nào?}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} n2q8ln99mjoiwd1ddtud9wsr7q8l33d nhâ loăng 0 392518 2344475 2026-04-12T10:28:07Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{alt form of|sed|loăng nhâ}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344475 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{alt form of|sed|loăng nhâ}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} kb0474dco78ngl5simanxhfs65em2r7 loăng rơxế 0 392519 2344476 2026-04-12T10:29:09Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cọ]]. #:{{ux|sed|văng ki kố ai hên '''loăng rơxế'''|Đồi này có nhiều '''cây cọ'''}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344476 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cọ]]. #:{{ux|sed|văng ki kố ai hên '''loăng rơxế'''|Đồi này có nhiều '''cây cọ'''}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} syjobkhf7vvl8c94v3dc1ssrjsowezp loăng plâi kơchâi nhâ 0 392520 2344477 2026-04-12T10:36:51Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây cối]]. #:{{ux|sed|rak ngăn '''loăng plâi kơchâi nhâ''' tung kơdrum|Bảo vệ '''cây cối''' trong vườn}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344477 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây cối]]. #:{{ux|sed|rak ngăn '''loăng plâi kơchâi nhâ''' tung kơdrum|Bảo vệ '''cây cối''' trong vườn}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} flobzo3w6djuriqjkslerk1ob6e20ta loăng plâi cơm nguội 0 392521 2344478 2026-04-12T10:37:37Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cơm]] [[nguội]]. #:{{ux|sed|'''loăng plâi cơm nguội''' a Việt Nam|'''Cây cơm nguội''' ở Việt Nam}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}}” 2344478 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # [[cây]] [[cơm]] [[nguội]]. #:{{ux|sed|'''loăng plâi cơm nguội''' a Việt Nam|'''Cây cơm nguội''' ở Việt Nam}} ==={{đm|ref}}=== {{R:VOV}} {{c|sed|Cây}} 5eyh656wvfg5hqywjqa94uklwt5z975 luông pli kă 0 392522 2344479 2026-04-12T10:42:12Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây ăn trái]]. ==={{đm|ref}}=== {{R:VOV}}” 2344479 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây ăn trái]]. ==={{đm|ref}}=== {{R:VOV}} 5b54ifjvqhyll3rphgzzz5q6zx82d2g luông trol 0 392523 2344480 2026-04-12T10:43:10Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[bằng lăng]]. ==={{đm|ref}}=== {{R:VOV}}” 2344480 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[bằng lăng]]. ==={{đm|ref}}=== {{R:VOV}} iy2b8z387h3ug2vwr9zd1caibofnwlx luông jêh 0 392524 2344481 2026-04-12T10:43:38Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[bút]]. ==={{đm|ref}}=== {{R:VOV}}” 2344481 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[bút]]. ==={{đm|ref}}=== {{R:VOV}} jwgi54tltyj04owfd0dhwa0baznpfyc luông nhă 0 392525 2344482 2026-04-12T10:48:36Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây cỏ]]. ==={{đm|ref}}=== {{R:VOV}}” 2344482 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây cỏ]]. ==={{đm|ref}}=== {{R:VOV}} i58ev03gbunudzol7364afcwh1tcs0s luông rơxế 0 392526 2344483 2026-04-12T10:48:57Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[cọ]]. ==={{đm|ref}}=== {{R:VOV}}” 2344483 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[cọ]]. ==={{đm|ref}}=== {{R:VOV}} bdcw0v76amiriweewk8umz4hcpbsx1p long rơxai 0 392527 2344484 2026-04-12T10:49:35Z WhoAlone 40420 Trang mới: “=={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[cọ]]. ==={{đm|ref}}=== {{R:VOV}}” 2344484 wikitext text/x-wiki =={{langname|sed}}== ==={{ĐM|noun}}=== {{head|sed|Danh từ}} # {{label|sed|dialectal}} [[cây]] [[cọ]]. ==={{đm|ref}}=== {{R:VOV}} bdcw0v76amiriweewk8umz4hcpbsx1p Thể loại:Danh từ có loại từ ᦀᧃ tiếng Lự 14 392528 2344486 2026-04-12T11:49:01Z Hiyuune 50834 Trang mới: “{{auto cat}}” 2344486 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx Thể loại:Danh từ có loại từ ᦐᦽᧈ tiếng Lự 14 392529 2344491 2026-04-12T11:56:43Z Hiyuune 50834 Trang mới: “{{auto cat}}” 2344491 wikitext text/x-wiki {{auto cat}} eomzlm5v4j7ond1phrju7cnue91g5qx ᦷᦂᧅᧈᦟᦻ 0 392530 2344492 2026-04-12T11:58:07Z Hiyuune 50834 + khb 2344492 wikitext text/x-wiki =={{langname|khb}}== ==={{section|etym}}=== {{affix|khb|ᦷᦂᧅᧈ|ᦟᦻ}} ==={{section|pron}}=== {{khb-pron|ᦷᦂᧅᧈ-ᦟᦻ}} ==={{section|n}}=== {{khb-noun|ᦐᦽᧈ}} # [[thùng thư|Thùng thư]], [[hòm thư]]. ==={{section|ref}}=== * {{R:khb:Hanna}} 6f8q4zwqnl3kjmqvkij209yheey2b4p