Wikikamus idwiktionary https://id.wiktionary.org/wiki/Wikikamus:Halaman_Utama MediaWiki 1.46.0-wmf.23 case-sensitive Media Istimewa Pembicaraan Pengguna Pembicaraan Pengguna Wikikamus Pembicaraan Wikikamus Berkas Pembicaraan Berkas MediaWiki Pembicaraan MediaWiki Templat Pembicaraan Templat Bantuan Pembicaraan Bantuan Kategori Pembicaraan Kategori Indeks Pembicaraan Indeks Lampiran Pembicaraan Lampiran TimedText TimedText talk Modul Pembicaraan Modul Acara Pembicaraan Acara ladang 0 1751 1348975 1210966 2026-04-08T16:12:27Z Iripseudocorus 40083 Kutipan23 1348975 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} #[[tempat]] orang [[bercocoktanam]], [[sawah]] #[[tempat]] orang [[menggarap]] sesuatu (arti yang diperluas) #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Bu, bagaimana kalau kita menanam singkong di '''ladang''' kita," usulku pada ibu. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=%22Bu%2C%20bagaimana%20kalau%20kita%20menanam%20singkong%20di%20ladang%20kita%2C%22%20usulku%20pada%20ibu. }} =={{bahasa|bjn}}== {{kepala|bjn}} #[[tempat]] orang [[berkebun]] #[[tempat]] orang [[menggarap]] sesuatu (arti yang diperluas) =={{bahasa|bug}}== {{kepala|bug}} {{-n-|bug}} *'''''Definisi :''''' [[lombok]] #: ''Mapesse ladangna tau Toraja'' #:Cabainya orang Toraja pedas {{-lafal-|bug}} * {{suara|bug|LL-Q33190 (bug)-Iripseudocorus-Ladang.wav }} [[Kategori:WikiTutur - Bugis]] [[Kategori:WikiTutur Daring Umum 11 Februari 2024]] osn7ynjeittx8lhk69ocoabt9q2ritf barangkali 0 7351 1348955 1144119 2026-04-08T13:53:57Z Losstreak 36825 1348955 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adv-|id}} # menyatakan ketidakpastian tentang sesuatu hal #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. '''Barangkali''' hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} * {{nl}} : {{trad-|nl|misschien}}, {{trad-|nl|mogelijk}}, {{trad-|nl|waarschijnlijk}} * {{en}} : {{trad-|en|maybe}}, {{trad-|en|perhaps}} {{t-bawah}} hcm1w64s3o64gvlvde66rfdhalw34ze MediaWiki:Common.css 8 9841 1348994 1345486 2026-04-08T16:38:49Z Swarabakti 18192 1348994 css text/css /*@import "//en.wiktionary.org/w/index.php?title=MediaWiki:Common.css&oldid=71426525&action=raw&ctype=text/css"; Ditulis ulang 2026-01-09 -- Swarabakti CSS yang berada di sini akan diterapkan untuk semua kulit __TOC__ == Dasar == */ /* ================================ */ /* Global color pallette */ /* ================================ */ /* Light mode */ :root, html, body, .vector-body { --white-bg: #FFF; --grey-bg: var(--background-color-neutral-subtle); --yellow-bg: #FFFFCC; --light-blue-bg: #F3F6FF; --tan-bg: #FAEBD7; --tan-border: #D2B48C; --black-font: #000; --faded-font: #333; --faded-border: #AAA; --faded-branch: #CCC; --idwikt-background-yellow: #FFFFDD; --idwikt-softblue: #F3F6FF; --idwikt-gray: #CCC; --idwikt-black: #333; } /* Night mode */ .skin-theme-clientpref-night, .skin-theme-clientpref-night body, .skin-theme-clientpref-night .vector-body { --white-bg: #000; --grey-bg: #1E1E1E; --yellow-bg: #33331A; --light-blue-bg: #1A2233; --tan-bg: #2A2522; --tan-border: #8B6F4E; --black-font: #FFF; --faded-font: #E0E0E0; --faded-border: #555; --faded-branch: #333; --idwikt-background-yellow: #222200; --idwikt-softblue: #1A2233; --idwikt-gray: #333; --idwikt-black: #E0E0E0; } /* ================================ */ /* General styling */ /* ================================ */ cite { font-style: italic !important; } /* Prevent odd line-height for raised and lowered characters */ sup, sub { line-height: 1em !important; } /* Unselectable texts */ .unselectable { cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } /* Style L2 headings */ .mw-parser-output .mw-heading2 { margin-top: 0.4em !important; padding: 1.2em 0 0.4em 0 !important; color: var(--color-base) !important; background: linear-gradient( to top, var(--background-color-base), var(--background-color-neutral-subtle) ) !important; border-bottom: none !important; border-top: 1px solid var(--border-color-base); } /* Style lists */ .mw-parser-output ol, .mw-parser-output ul, .mw-parser-output dl, .mw-parser-output li, .mw-parser-output dd { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ol > li { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ul > li::marker, .mw-parser-output ol > li::marker { font-weight: bold !important; } .mw-parser-output ol.references li::marker { font-weight: normal !important; } .mw-parser-output ol > li.has-visible-children + li { margin-top: 0.4em !important; } .mw-parser-output .syn-item, .mw-parser-output .usex-item, .mw-parser-output .quot-item { margin-top: 0 !important; margin-bottom: 0 !important; overflow: auto; } /* Style labels */ .hyphenation { font-weight: bold !important; font-size: 0.95em !important; } .ib-content { font-style: italic !important; } .usage-label-term, .usage-label-sense { color: var(--color-content-added) !important; } .usage-label-term a, .usage-label-sense a { color: inherit !important; font-style: inherit !important; text-decoration: underline dotted !important; } .usage-label-term a:hover, .usage-label-sense a:hover { text-decoration: underline !important; } /* Style usex and quotes */ .cited-source { font-size: 0.9em !important; } .h-usage-example, .h-quotation { font-size: 0.95em !important; } /* Style toggles */ .mw-collapsible-toggle, .toc-toggle, .section-toggle, .pron-toggle, .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { cursor: pointer; font-size: 0.9em; color: var(--color-link) !important; } .toc-toggle { display: block; margin: 0.2em; } .section-toggle { background: none; text-align: center; } .section-toggle + .section-collapsible-wrapper { margin-top: 0 !important; } .headword-wrapper.has-section-toggle { cursor: pointer; } .headword-wrapper.has-section-toggle .headword-inner { padding-top: 0 !important; } .infl-toggle, .content-toggle { float: right; font-weight: normal; } .pron-toggle { margin-left: 0.6em; } .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { margin-left: 0.4em; } .toggle-container { display: inline; margin-left: 0.2em; } /* Style TOC */ #toc { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; max-width: 60%; text-align: center; } #toc > .toctitle { display: none; } #toc > ul { display: flex; flex-wrap: wrap; justify-content: center; list-style: none; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; margin: 0.2em; gap: 0.4em; } #toc ul ul { display: none; } #toc > ul > li::after { content: " •"; color: var(--faded-border, #AAA); padding-left: 0.2em; } #toc > ul > li:last-child::after { content: ""; } .skin-minerva #toc { display: none; } .category-link { display: block; margin: 0.2em; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; } /* Style references */ .references { font-size: 0.9em; } ol.references > li:target, sup.reference:target, cite:target { background-color: #DEF; } /* Style catlinks */ .catlinks { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; } /* Style indents */ body dd { position: relative; margin: 0; padding-left: 0.8em; } body dd::before { content: ""; position: absolute; top: 0.2em; left: 0.2em; bottom: 0.2em; width: 1px; background: var(--faded-branch); } /* Copy and share buttons */ .mw-parser-output h3, .mw-heading > h3 { position: relative !important; padding: 0; margin: 0; } .mw-parser-output h3 > .headword-text, .mw-heading > h3 > .headword-text { display: block; padding-right: 3.2em; overflow-wrap: anywhere; word-break: normal; white-space: normal; min-width: 0; } .wikt-header-controls { display: inline-flex; align-items: center; gap: 0.2em; position: absolute; right: 0.8em; top: 0.4em; z-index: 100; opacity: 0; transition: opacity 0.15s; } .wikt-header-anchor { display: inline-flex; color: var(--color-subtle) !important; cursor: pointer; } .wikt-header-anchor:hover { color: var(--color-progressive) !important; } .mw-parser-output h3:hover > .wikt-header-controls, .mw-heading:hover > h3 > .wikt-header-controls { opacity: 1; } /* Responsive, horizontally scrollable table */ @media (max-width: 720px) { .wikitable { display: block; overflow-x: auto; width: 100% !important; } } /* ================================== */ /* Scripts styling */ /* ================================== */ /* For scripts where bolding is not used, highlight the word */ .Arab b, .Brah b, .Deva b, .Hebr b, .Lina b, .Linb b, .Mani b, .Mong b, .Ogam b, .Orkh b, .Ougr b, .Runr b, .Sogd b, .Syrc b, .Thai b, .Ugar b, .Xpeo b, .Xsux b { background: var(--yellow-bg, #FFFFCC); font-style: normal; font-weight: normal; font-size: inherit; } /* Script-specific styling */ /* Latin (default) */ .Latn { font-style: normal; } /* Arabic, right-to-left */ .Arab { font-family: 'Noto Naskh Arabic', 'Iranian Sans', Tahoma, 'Microsoft Sans Serif', 'Arial Unicode MS', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Armenian */ .Armn { font-family: Mshtakan, Arial, 'Segoe UI', Tahoma, 'Arian AMU', 'DejaVu Sans', sans-serif; } /* Balinese */ .Bali { font-family: "Noto Sans Balinese", serif; } /* Batak */ .Batk { font-family: Batak-Unicode, sans-serif; } /* Bengali */ .Beng { font-family: 'Bangla Sangam MN', UniBangla, 'Arial Unicode MS', 'Code2000', Likhan, 'UT Bengali Dhaka', Vrinda, sans-serif; font-size: 1.3em; } /* Bopomofo */ .Bopo { font-family: MOESongUN, DFKai-SB, 'Microsoft Yahei', 'Microsoft Jhenghei', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', sans-serif; } /* Braille */ .Brai { font-size: 1.5em; } /* Bugis */ .Bugi { font-family: Saweri, sans-serif; } /* Buhid */ .Buhd { font-family: 'Noto Sans Buhid', Quivira, sans-serif; font-size: 1.1em; } /* Cham */ .Cham { font-family: 'Code2000', 'JG ChamCambodia', sans-serif; font-size: 1.1em; } /* Cherokee */ .Cher { font-family: Digohweli, 'Aboriginal Sans', 'Code2000', Marin, 'Rotinonhsonni Sans', 'Everson Mono Unicode', sans-serif; font-size: 1.1em; } /* Coptic */ .Copt { font-family: Quivira, Antinoou, 'New Athena Unicode', Analecta, FreeSerifAvvaShenouda, 'Arial Coptic', 'Sophia Nubian', 'Code2000', sans-serif; font-size: 1.3em; } /* Cyrillic */ .Cyrl { font-family: Helvetica, Geneva, 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', sans-serif; } /* Old Cyrillic (Old Church Slavonic, Old East Slavic) */ .Cyrs { font-family: Monomakh, 'Monomakh Unicode', 'Monomakh Unicode TT', Menaion, 'Menaion Unicode', 'Menaion Unicode TT', Ponomar, 'Ponomar Unicode', 'Ponomar Unicode TT', Fedorovsk, 'Fedorovsk Unicode', 'Fedorovsk Unicode TT', Pochaevsk, 'Pochaevsk Unicode', 'Pochaevsk Unicode TT', Triodion, 'Triodion Unicode', 'Triodion Unicode TT', 'Acathist', 'Shafarik', Vilnius, BukyVede, 'Kliment Std', 'RomanCyrillic Std', 'Monomachus', 'Old Standard', 'Old Standard TT', Dilyana, 'Hirmos Ponomar', 'Hirmos Ponomar TT', 'Menaion Medieval', Lazov, 'Code2000', 'DejaVu Sans', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', sans-serif; font-size: 1.25em; } /* Devanagari */ .Deva { font-family: 'Adobe Devanagari', 'Noto Serif Devanagari', Utsaah, 'Devanagari MT', Raghu, Gargi, JanaSanskrit, JanaHindi, Siddhanta, sans-serif; font-size: 1.2em; } /* Dogra */ .Dogr { font-family: 'Noto Serif Dogra', sans-serif; } /* Deseret */ .Dsrt { font-family: 'Segoe UI Symbol', 'Code2001', 'MPH 2B Damase', 'Everson Mono', sans-serif; } /* Egyptian hieroglyphs */ .Egyp { font-family: 'Noto Sans Egyptian Hieroglyphs', Abydos, Aegyptus, 'Segoe UI Historic', sans-serif; font-size: 1.5em; } /* Ethiopic (Ge'ez) */ .Ethi { font-family: 'Abyssinica SIL', Nyala, 'Code2000', 'Ethiopia Jiret', 'GF Zemen Unicode', 'TITUS Cyberbit Basic', 'Visual Geez Unicode', 'Visual Geez Unicode Agazian', 'Visual Geez Unicode Title', sans-serif; font-size: 1.2em; } /* Georgian */ .Geor { font-family: 'DejaVu Sans', 'Arial Unicode MS', Sylfaen, sans-serif; } /* Glagolitic */ .Glag { font-family: Shafarik, Menaion, 'Menaion Unicode', 'Menaion Unicode TT', 'Segoe UI Historic', BukyVede, Dilyana, 'Noto Sans Glagolitic', sans-serif; font-size: 1.5em; } /* Gothic */ .Goth { font-family: 'Segoe UI Historic', 'Code2001', Skeirs, 'MPH 2B Damase', sans-serif; } /* Greek */ .Grek { font-family: 'Gentium Plus', 'Gentium', 'Lucida Sans Unicode', sans-serif; } /* Gujarati */ .Gujr { font-family: 'Noto Sans Gujarati', 'Gujarati Sangam MN', 'Gujarati MT', Shruti, 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Gurmukhi */ .Guru { font-family: 'Gurmukhi MN', 'Gurmukhi MT', 'UT Punjabi Amritsar', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Chinese (Han) .Hani = generic .Hans = simplified .Hant = traditional */ .Hans { font-family: 'PingFang SC', DengXian, 'Source Han Sans SC', 'Source Han Sans CN', 'Noto Sans CJK SC', 'Microsoft Yahei', SimHei, SimSun, NSimSun, SimSun-ExtB, Song, 'Heiti SC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hant { font-family: 'PingFang TC', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', 'Microsoft Jhenghei', MOESongUN, PMingLiU, PMingLiU-ExtB, MingLiU, MingLiU-ExtB, Ming, 'Heiti TC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hans, .Hant { font-size: 1.2em; line-height: 1; } /* Hanunoo */ .Hano { font-family: 'Noto Sans Hanunoo', Quivira, 'MPH 2B Damase', sans-serif; font-size: 1.1em; } /* Hatran */ .Hatr { font-family: 'Noto Sans Hatran', sans-serif; direction: rtl; } /* Hebrew */ .Hebr { font-family: 'SBL Hebrew', 'SBL BibLit', 'Taamey David CLM', 'Taamey Frank CLM', Alef, 'Noto Sans Hebrew', Narkisim, Miriam, Kinryu, 'Arial Hebrew', Arial, 'Adobe Hebrew', serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Hluw: Anatolian Hieroglyphs */ .Hluw { font-family: 'Noto Sans Anatolian Hieroglyphs', Anatolian; font-size: 2em; } /* Hiragana: see .Jpan */ /* Javanese */ .Java { font-family: 'Tuladha Jejeg', 'Javanese Text', adjisaka, 'Noto Sans Javanese', sans-serif; line-height: 2em; } /* Japanese scripts .Hira = Hiragana .Kana = Katakana (used for Ainu language) .Jpan = Hiragana + Katakana + Kanji */ .Hira, .Jpan, .Kana { font-family: 'Hiragino Kaku Gothic Pro', Osaka, 'Yu Gothic', Meiryo, 'Source Han Sans J', 'Source Han Sans JP', 'Noto Sans CJK JP', 'Droid Sans Japanese', 'MS PGothic', 'MS Gothic', 'MS PMincho', 'MS Mincho', HanaMinA, HanaMinB, sans-serif; font-size: 1.2em; line-height: 1; } .Jpan ruby rt { font-family: 'Yu Gothic UI', 'Meiryo UI', 'MS UI Gothic', sans-serif; font-size: 0.6em; } /* Khmer */ .Khmr { font-family: 'Khmer OS', 'Khmer OS Content', 'Leelawadee UI', 'Noto Sans Khmer', 'Code2000', 'Khmer Mondulkiri U OT ls', sans-serif; font-size: 1.25em; } /* Kannada */ .Knda { font-family: 'Kannada Sangam MN', JanaKannada, Tunga, Kedage, RaghuKannada, Sampige, 'Arial Unicode MS', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', sans-serif; font-size: 1.25em; } /* Korean */ .Kore, .Hang { font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', Dotum, Gulim, 'NanumBarunGothic YetHangul', NanumBarunGothic, UnDotum, 'Source Han Sans K', 'Source Han Sans KR', 'Noto Sans CJK KR', NanumGothic, 'NanumMyeongjo YetHangul', NanumMyeongjo, Batang, UnBatang, sans-serif; font-size: 1.2em; line-height: 1; } /* Kaithi */ .Kthi { font-family: 'Noto Sans Kaithi', sans-serif; } /* Lanna */ .Lana { font-family: 'Lanna Alif', 'Noto Sans Tai Tham', sans-serif; } /* Lao */ .Laoo { font-family: 'Phetsarath OT', 'Saysettha OT', 'JG Basic Lao Opentype', 'JG Basic2 Lao Opentype', 'JG LaoTimes Opentype', 'Phagnoum Lao Unicode Opentype', 'JG Lao Old Arial Opentype', DokChampa, 'Code2000', 'JG Lao Classic Opentype', 'Alice0 Unicode', 'Alice1 Unicode', 'Alice2 Unicode', 'Alice3 Unicode', 'Alice4 Unicode', 'Alice5 Unicode', sans-serif; font-size: 1.25em; } /* Limbu */ .Limb { font-family: 'Code2000', 'MPH 2B Damase', sans-serif; } /* Linear A */ .Lina { font-family: Aegean, 'Noto Sans Linear A', sans-serif; font-size: 1.25em; } /* Linear B */ .Linb { font-family: Aegean, 'Noto Sans Linear B', sans-serif; font-size: 1.25em; } /* Lisu */ .Lisu { font-family: 'Noto Sans Lisu', Quivira, sans-serif; } /* Makasar */ .Maka { font-family: "Noto Sans Makasar", serif; } /* Malayalam */ .Mlym { font-family: 'Malayalam Sangam MN', Kartika, 'Code2000', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Mongolian */ .Mong { font-family: 'Mongolian Baiti', 'Noto Sans Mongolian', sans-serif; font-size: 1.4em; -webkit-writing-mode: vertical-lr; -moz-writing-mode: vertical-lr; writing-mode: vertical-lr; } /* Burmese */ .Mymr { font-family: TharLon, Padauk, 'Myanmar Text', 'Myanmar3', 'Myanmar2', 'Myanmar1', ParabaikSans, 'MyMyanmar sans-serif'; font-size: 1.3em; } big.Mymr, strong.Mymr, b.Mymr, b .Mymr { font-size: 1.62em; } .Mymr b { font-size: 1.3em; } /* N’Ko */ .Nkoo { font-style: normal; direction: rtl; } /* Ogham */ .Ogam { font-family: "Noto Sans Ogham", serif; } /* Oriya */ .Orya { font-family: "Noto Sans Oriya", serif; } /* Phoenician */ .Phnx { font-family: "Noto Sans Phoenician", serif; } /* Rejang */ .Rjng { font-family: 'Noto Sans Rejang', 'Code2000', sans-serif; } /* Runic */ .Runr { font-family: 'Segoe UI Historic', Junicode, 'Free Mono', 'Caslon Roman', 'Segoe UI Symbol', 'Code2000', 'Everson Mono', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; } /* Sinhala */ .Sinh { font-family: 'Sinhala Sangam MN', KaputaUnicode, KandyUnicode, Dinamina, DinaminaUniWeb, Potha, Madhura, sans-serif; font-size: 1.25em; } /* Sundanese */ .Sund { font-family: 'Sundanese Unicode', 'Noto Sans Sundanese', sans-serif; } /* Syriac, right-to-left */ .Syrc { font-family: 'Estrangelo Edessa', 'San Francisco', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Tagbanwa */ .Tagb { font-family: Quivira, Tagbanwa, sans-serif; font-size: 1.1em; } /* Tai Le */ .Tale { font-family: 'Microsoft Tai Le', 'Tai Le Valentinium', 'MPH 2B Damase', sans-serif; } /* New Tai Lue */ .Talu { font-family: 'Noto Sans New Tai Lue', 'Microsoft New Tai Lue', 'Dai Banna SIL Book', 'Husb_New_Tai_Lue_WB', sans-serif; } /* Tamil */ .Taml { font-family: 'Tamil Sangam MN', InaiMathi, Vijaya, Akshar, JanaTamil, 'Code2000', ETTamilNew, 'Lohit Tamil', 'Arial Unicode MS', 'Free Serif', Latha, sans-serif; font-size: 1.25em; } /* Tangut */ .Tang { font-family: 'BabelStone Tangut Wenhai', 'Tangut N4694', 'Tangut Yinchuan', 'New Tangut', 'New Tangut Std', 'Tangut TWU', 'Babelstone Tangut Wenhai', sans-serif; font-size: 1.2em; } /* Tai Viet */ .Tavt { font-family: 'Tai Heritage Pro', 'Noto Sans Tai Viet', sans-serif; } /* Telugu */ .Telu { font-family: 'Telugu Sangam MN', sans-serif; font-size: 1.25em; } /* Thaana */ .Thaa { font-style: normal; direction: rtl; } /* Thai */ .Thai { font-family: 'Leelawadee UI', Leelawadee, 'Arial Unicode MS', 'Code2000', sans-serif; font-size: 1.25em; } /* Tifinagh (Berber) */ .Tfng { font-family: 'Hapax Berbère', Ebrima, 'Code2000', DejaVu, sans-serif; font-size: 1.2em; } /* Tagalog (Baybayin) */ .Tglg { font-family: 'Noto Sans Tagalog', 'Tagalog Stylized', 'Baybayin Lopez', 'Tagalog Doctrina 1593', Quivira, 'Code2000', sans-serif; } /* Tibetan */ .Tibt { font-family: 'Noto Serif Tibetan', 'Noto Sans Tibetan', Jomolhari-ID, 'Tibetan Machine Uni', 'Tibetan Machine Web', Jomolhari, 'Microsoft Himalaya', sans-serif; font-size: 1.3em; } /* Ugaritic */ .Ugar { font-family: 'Oxford Ugaritic', 'Segoe UI Historic', Aegean, 'Code2001', sans-serif; } /* Vai */ .Vaii { font-family: Ebrima, 'Code2000', sans-serif; font-size: 1.1em; } /* Old Persian cuneiform */ .Xpeo { font-family: 'Segoe UI Historic', Aegean, Xerxes, 'Code2001', sans-serif; } /* Sumero-Akkadian cuneiform */ .Xsux { font-family: Akkadian, FreeIdgSerif, CuneiformComposite, 'Segoe UI Historic', sans-serif; font-size: 1.25em; } /* Multilingual writing systems and symbols */ /* International Phonetic Alphabet */ .IPA { font-family: Gentium, 'Gentium Plus', GentiumAlt, 'DejaVu Sans', 'Segoe UI', 'Lucida Grande', 'Charis SIL', 'Doulos SIL', 'TITUS Cyberbit Basic', 'Code2000', 'Lucida Sans Unicode', sans-serif; font-size: 110%; font-variant-ligatures: no-common-ligatures; } /* Musical notation */ .Music { font-family: Musica, 'Musical Symbols', Euterpe, sans-serif; font-size: 1.4em; } /* Znamenny musical notation */ .Zname { font-family: 'Mezenets Unicode', Slavonic, Voskresensky, Smolensky, Symbola, sans-serif; } /* Symbols */ .Zsym { font-family: Symbola, sans-serif; font-size: 150%; } /* ===================================================== Legacy (list logic intentionally excluded) ===================================================== */ /* untuk category tree supaya lebar td masing-masing 1/3 Bennylin 19/8/14 */ table.mw-prefixindex-list-table td { width: 33%; } /* [[MediaWiki:Sitenotice]] */ #siteNotice { margin-top:5px; padding-left: 4px; font-style: italic; text-align: center; } /* Redirects on [[Special:Allpages]] */ .allpagesredirect { font-style: italic; } /* All tables: transparent, originally: white */ table { background: transparent; } /* User notification. You've got mail! */ .usermessage { text-decoration: blink; } /* Table of contents: redefine for printing */ .toccolours { border:1px solid var(--border-color-base); background-color:var(--background-color-neutral-subtle); padding:5px; font-size: 95%; } /* Icon link PDF (hanya untuk Mozilla dan Opera) */ #bodyContent a[href$=".pdf"].external, #bodyContent a[href*=".pdf?"].external, #bodyContent a[href*=".pdf#"].external, #bodyContent a[href$=".PDF"].external, #bodyContent a[href*=".PDF?"].external, #bodyContent a[href*=".PDF#"].external { background: url('//upload.wikimedia.org/wikipedia/commons/thumb/2/23/Icons-mini-file_acrobat.gif/15px-Icons-mini-file_acrobat.gif') center right no-repeat; padding-right: 16px; } /* Beri warna untuk jumlah bita pada [[Istimewa:Perubahanterbaru]] */ .mw-plusminus-neg { color:#FF2050; } .mw-plusminus-pos { color:#00B000; } /* /** == Tabel == CSS untuk tabel-tabel */ table.wikitable, table.prettytable { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.wikitable th, table.wikitable td, table.prettytable th, table.prettytable td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.wikitable th, table.prettytable th { background: var(--background-color-neutral); text-align: center; } table.wikitable caption, table.prettytable caption { margin-left: inherit; margin-right: inherit; } /* Digunakan oleh Templat:Tabel */ div.kolom-2 div.column { float: left; width: 50%; min-width: 300px; } div.kolom-3 div.column { float: left; width: 33.3%; min-width: 200px; } div.kolom-4 div.column { float: left; width: 25%; min-width: 150px; } div.kolom-5 div.column { float: left; width: 20%; min-width: 120px; } /* tabelcantik */ table.tabelcantik { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.tabelcantik th, table.tabelcantik td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.tabelcantik th { background: var(--background-color-neutral); text-align: center; } table.tabelcantik caption { margin-left: inherit; margin-right: inherit; } tbody tr.even td { background: var(--background-color-neutral-subtle); } tbody tr.odd td { background: var(--background-color-neutral-subtle); } /* tabelcantikcyan */ table.tabelcantikcyan { margin: 1em 1em 1em 0; background: LightCyan; border: 1px Turquoise solid; border-collapse: collapse; } table.tabelcantikcyan th, table.tabelcantikcyan td { border: 1px Turquoise solid; padding: 0.2em; } table.tabelcantikcyan th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikcyan caption { margin-left: inherit; margin-right: inherit; } tbody tr.evencyan td { background: PaleTurquoise } tbody tr.oddcyan td { background: LightCyan } /* tabelcantikmerah */ table.tabelcantikmerah { margin: 1em 1em 1em 0; background: Seashell; border: 1px LightSalmon; border-collapse: collapse; } table.tabelcantikmerah th, table.tabelcantikmerah td { border: 1px LightSalmon solid; padding: 0.2em; } table.tabelcantikmerah th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikmerah caption { margin-left: inherit; margin-right: inherit; } tbody tr.evenmerah td { background: MistyRose } tbody tr.oddmerah td { background: Seashell } /** == Kotak navigasi == */ /* Style for horizontal lists (separator following item) */ .skin-monobook .hlist dl, .skin-modern .hlist dl, .skin-vector .hlist dl { line-height: 1.5em; } .hlist dl, .hlist ol, .hlist ul { margin: 0; } .hlist dd, .hlist dt, .hlist li { display: inline; margin: 0; } /* Display nested lists inline */ .hlist dl dl, .hlist ol ol, .hlist ul ul { display: inline; } /* Generate interpuncts */ .hlist dt:after { content: " :"; } .hlist dd:after, .hlist li:after { content: " ·"; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* for IE 8 */ .hlist dd.nopunct:after, .hlist dt.nopunct:after, .hlist li.nopunct:after { content: none; } /* Add parents around nested lists */ .hlist dl dl:before, .hlist ol ol:before, .hlist ul ul:before { content: "("; } .hlist dl dl:after, .hlist ol ol:after, .hlist ul ul:after { content: ")"; } /* Put numbers in ordered lists */ .hlist.hnum ol li { counter-increment: level1; } .hlist.hnum ol li:before { content: counter(level1) " "; } .hlist.hnum ol ol li { counter-increment: level2; } .hlist.hnum ol ol li:before { content: counter(level2) " "; } /* Default style for navigation boxes */ .navbox { /* Navbox container style */ border: 1px solid #aaa; width: 100%; margin: auto; clear: both; font-size: 88%; text-align: center; padding: 1px; } .navbox-inner, .navbox-subgroup { width: 100%; } .navbox th, .navbox-title, .navbox-abovebelow { text-align: center; /* Title and above/below styles */ padding-left: 1em; padding-right: 1em; } th.navbox-group { /* Group style */ white-space: nowrap; /* @noflip */ text-align: right; } .navbox, .navbox-subgroup { background: #fdfdfd; /* Background color */ } .navbox-list { border-color: #fdfdfd; /* Must match background color */ } .navbox th, .navbox-title { background: #ccccff; /* Level 1 color */ } .navbox-abovebelow, th.navbox-group, .navbox-subgroup .navbox-title { background: #ddddff; /* Level 2 color */ } .navbox-subgroup .navbox-group, .navbox-subgroup .navbox-abovebelow { background: #e6e6ff; /* Level 3 color */ } .navbox-even { background: #f7f7f7; /* Even row striping */ } .navbox-odd { background: transparent; /* Odd row striping */ } table.navbox + table.navbox { /* Single pixel border between adjacent navboxes */ margin-top: -1px; /* (doesn't work for IE6, but that's okay) */ } .navbox .hlist td dl, .navbox .hlist td ol, .navbox .hlist td ul, .navbox td.hlist dl, .navbox td.hlist ol, .navbox td.hlist ul { padding: 0.125em 0; /* Adjust hlist padding in navboxes */ } .navbox .hlist dd, .navbox .hlist dt, .navbox .hlist li { white-space: nowrap; /* Nowrap list items in navboxes */ white-space: normal !ie; /* IE < 8 no-wraps entire list, so disable it */ } .navbox .hlist dd dl, .navbox .hlist dt dl, .navbox .hlist li ol, .navbox .hlist li ul { white-space: normal; /* But allow parent list items to be wrapped */ } ol + table.navbox, ul + table.navbox { margin-top: 0.5em; /* Prevent lists from clinging to navboxes */ } /* Default styling for Navbar template */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar ul { display: inline; white-space: nowrap; } .navbar li { word-spacing: -0.125em; } /* Navbar styling when nested in navbox */ .navbox .navbar { display: block; font-size: 100%; } .navbox-title .navbar { /* @noflip */ float: left; /* @noflip */ text-align: left; /* @noflip */ margin-right: 0.5em; width: 6em; } /* 'show'/'hide' buttons created dynamically by the CollapsibleTables javascript in [[MediaWiki:Common.js]] are styled here so they can be customised. */ .collapseButton { /* @noflip */ float: right; font-weight: normal; /* @noflip */ margin-left: 0.5em; /* @noflip */ text-align: right; width: auto; } /* In navboxes, the show/hide button balances the v·d·e links from [[Template:Navbar]], so they need to be the same width. */ .navbox .collapseButton { width: 6em; } /** == Messagebox == */ /* Berbagai ''style'' "messagebox" */ .messagebox { border: 1px solid var(--border-color-base); background-color: var(--background-color-neutral-subtle); width: 80%; margin: 0 auto 1em auto; padding: .2em; text-align: justify; } .messagebox.merge { border: 1px solid #cf9fff; background-color: #f5edf5; text-align: center; } .messagebox.cleanup { border: 1px solid #9f9fff; background-color: #efefff; text-align: center; } .messagebox.standard-talk { border: 1px solid #c0c090; background-color: #f8eaba; } /* Standard Navigationsleisten, aka box hiding thingy from .de. Documentation at [[Wikipedia:NavFrame]]. */ div.NavFrame { margin: 0; padding: 4px; border: 1px solid #aaa; text-align: center; border-collapse: collapse; font-size: 95%; } div.NavFrame + div.NavFrame { border-top-style: none; border-top-style: hidden; } div.NavPic { background-color: #fff; margin: 0; padding: 2px; /* @noflip */ float: left; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; background-color: #ccf; position: relative; } div.NavFrame p, div.NavFrame div.NavContent, div.NavFrame div.NavContent p { font-size: 100%; } div.NavEnd { margin: 0; padding: 0; line-height: 1px; clear: both; } a.NavToggle { position: absolute; top: 0; /* @noflip */ right: 3px; font-weight: normal; font-size: 90%; } /** == CommonTicker == CSS untuk CommonTickers */ /* CommonsTicker styles */ .tickerList ul, .tickerList ul li { list-style: none; text-indent:-2em; margin-left:2em; text-align:left; } .tickerList ul ul, .tickerList ul ul li { list-style: none; text-indent:0; margin-left:1.5em; text-align:left; } .tickerDiffLink { } /* diff links in ticker */ .tickerMiscLink { } /* misc links in ticker */ .tickerUsage { font-size:80%; } /* ticker usage list */ .tickerAction_deleted:before { content:" HAPUS "; color: #FF0000; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_deletedRev:before { content:" HAPUSREV "; color: #FFC0CB; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replaced:before { content:" GANTI "; color: #FF00FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replacedOwn:before { content:" GANTI+ "; color: #CC88FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedTag:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedTag:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedBad:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedBad:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedGood:before { content:" +OK "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedGood:before { content:" -OK "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerEntry_deleted { } /* entry for image deletion */ .tickerEntry_replaced { } /* entry for image replacement */ .tickerEntry_tagged { } /* entry for adding/removing problem tags */ .tickerEntry_redir { } /* entry for critical redirection (fot tag redirects) */ .tickerEntry_recat { } /* entry for critical re-categorization (for tag categories) */ .tickerEntry_notify { } /* entry for global notifications */ .tickerEntry_changed { } /* entry for generic change */ /*.tickerAction_deleted { background:#FAA; } /* action marker for image deletion */ /*.tickerAction_replaced { background:#FED; } /* action marker for image replacement */ /*.tickerAction_deletedRev { background:#FDD; } /* action marker for revision deletion */ /*.tickerAction_replacedOwn { background:#FFF4EE; } /* action marker for image replacement by uploader */ /*.tickerAction_addedBad { background:#FDD; } /* action marker for adding problem markers */ /*.tickerAction_removedBad { background:#DFD; } /* action marker for removing problem markers */ /*.tickerAction_addedGood { background:#DFD; } /* action marker for adding license markgers (for tag categories) */ /*.tickerAction_removedGood { background:#FDD; } /* action marker for removing license markers (for tag categories) */ .tickerMinorEntry { color:#666; } /* minor entry */ .tickerMinorEntry a, .tickerMinorEntry a:link, .tickerMinorEntry a:visited { color:#669; } #bodyContent .tickerMinorEntry a.extiw, #bodyContent .tickerMinorEntry a.extiw:link, #bodyContent .tickerMinorEntry a.extiw:visited { color:#669; } .tickerTemplateEntry { font-weight: bold; } /* entry applies to a template used by multiple images */ .tickerSubEntry { } /* sub-entry for multi-image entry */ /** == Lain-lain == CSS untuk berbagai jenis style */ #p-cactions #ca-edittop a { padding-left: .4em; padding-right: .4em; } /** [[Template:Coor title dm]] **/ #coordinates { position:absolute; z-index:1; border:none; background:none; right:30px; top:5.2em; float:right; margin:0.0em; padding:0.0em; line-height:1.5em; text-align:right; text-indent:0; font-size:85%; text-transform:none; white-space:nowrap; } /* [[Template:Disambig]] */ #disambigbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* [[Template:Spoiler]] */ #spoiler { border-top: 2px solid #ddd; border-bottom:2px solid #ddd; } /* [[Wikipedia:Artikel bagus]], for positioning icons at top-right */ div.topicon { position:absolute; z-index:100; top:10px; display: block !important; } /** [[Wikipedia:Kotak pengguna]] **/ .userboxdark a, .userboxdark a:visited, .userboxdark a:active { color: #ccc; } /* == Daftar isi == ''Style'' untuk variasi daftar isi: * '''horizontal''': daftar isi horizontal. Contoh penggunaan: <code><nowiki><div class="horizontal">__TOC__</div></nowiki></code>. * '''nonumtoc''': tanpa nomor. Contoh penggunaan: <code><nowiki><div class="notocnum">__TOC__</div></nowiki></code>. * '''toclimit-x''': membatasi tampilan hanya sampai level ke-x. Contoh penggunaan: <code><nowiki><div class="toclimit-3">__TOC__</div></nowiki></code>, judul subbagian tingkat 1 (tag h2), tingkat 2 (tag h3) tidak ditampilkan. */ .horizontal ul { padding: 0; margin: 0; } .horizontal li { padding: 0 0.6em 0 0.4em; display: inline; border-right: 1px solid; } .horizontal li:last-child { border-right: none; } .nonumtoc .tocnumber { display:none; } .nonumtoc #toc ul, .nonumtoc .toc ul { line-height: 1.5em; list-style: none; margin: .3em 0 0; padding: 0; } .nonumtoc #toc ul ul, .nonumtoc .toc ul ul { margin: 0 0 0 2em; } .toclimit-2 .toclevel-2 {display:none;} .toclimit-3 .toclevel-3 {display:none;} .toclimit-4 .toclevel-4 {display:none;} .toclimit-5 .toclevel-5 {display:none;} .toclimit-6 .toclevel-6 {display:none;} .toclimit-7 .toclevel-7 {display:none;} /* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */ th.mbox-text, td.mbox-text { /* The message body cell(s) */ border: none; padding: 0.25em 0.9em; /* 0.9em left/right */ width: 100%; /* Make all mboxes the same width regardless of text length */ } td.mbox-image { /* The left image cell */ border: none; padding: 2px 0 2px 0.9em; /* 0.9em left, 0px right */ text-align: center; } td.mbox-imageright { /* The right image cell */ border: none; padding: 2px 0.9em 2px 0; /* 0px left, 0.9em right */ text-align: center; } td.mbox-empty-cell { /* An empty narrow cell */ border: none; padding: 0px; width: 1px; } /* Article message box styles */ table.ambox { margin: 0px 10%; /* 10% = Will not overlap with other elements */ border: 1px solid #aaa; border-left: 10px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } table.ambox + table.ambox { /* Single border between stacked boxes. */ margin-top: -1px; } .ambox th.mbox-text, .ambox td.mbox-text { /* The message body cell(s) */ padding: 0.25em 0.5em; /* 0.5em left/right */ } .ambox td.mbox-image { /* The left image cell */ padding: 2px 0 2px 0.5em; /* 0.5em left, 0px right */ } .ambox td.mbox-imageright { /* The right image cell */ padding: 2px 0.5em 2px 0; /* 0px left, 0.5em right */ } table.ambox-notice { border-left: 10px solid #1e90ff; /* Blue */ } table.ambox-speedy { border-left: 10px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ambox-delete { border-left: 10px solid #b22222; /* Red */ } table.ambox-content { border-left: 10px solid #f28500; /* Orange */ } table.ambox-style { border-left: 10px solid #f4c430; /* Yellow */ } table.ambox-move { border-left: 10px solid #9932cc; /* Purple */ } table.ambox-protection { border-left: 10px solid #bba; /* Gray-gold */ } /* Image message box styles */ table.imbox { margin: 4px 10%; border-collapse: collapse; border: 3px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } .mbox-inside .imbox { /* For imboxes inside other templates. */ margin: 4px; } .imbox .mbox-text .imbox { /* For imboxes inside imbox-text cells. */ margin: 0 -0.5em; /* 0.9 - 0.5 = 0.4em left/right. */ } table.imbox-notice { border: 3px solid #1e90ff; /* Blue */ } table.imbox-speedy { border: 3px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.imbox-delete { border: 3px solid #b22222; /* Red */ } table.imbox-content { border: 3px solid #f28500; /* Orange */ } table.imbox-style { border: 3px solid #f4c430; /* Yellow */ } table.imbox-move { border: 3px solid #9932cc; /* Purple */ } table.imbox-protection { border: 3px solid #bba; /* Gray-gold */ } table.imbox-license { border: 3px solid #88a; /* Dark gray */ background: #f7f8ff; /* Light gray */ } table.imbox-featured { border: 3px solid #cba135; /* Brown-gold */ } /* Category message box styles */ table.cmbox { margin: 3px 10%; border-collapse: collapse; border: 1px solid #aaa; background: #DFE8FF; /* Default "notice" blue */ } table.cmbox-notice { background: #D8E8FF; /* Blue */ } table.cmbox-speedy { margin-top: 4px; margin-bottom: 4px; border: 4px solid #b22222; /* Red */ background: #FFDBDB; /* Pink */ } table.cmbox-delete { background: #FFDBDB; /* Red */ } table.cmbox-content { background: #FFE7CE; /* Orange */ } table.cmbox-style { background: #FFF9DB; /* Yellow */ } table.cmbox-move { background: #E4D8FF; /* Purple */ } table.cmbox-protection { background: #EFEFE1; /* Gray-gold */ } /* Other pages message box styles */ table.ombox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #aaa; /* Default "notice" gray */ background: var(--background-color-neutral-subtle); } table.ombox-notice { border: 1px solid #aaa; /* Gray */ } table.ombox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ombox-delete { border: 2px solid #b22222; /* Red */ } table.ombox-content { border: 1px solid #f28500; /* Orange */ } table.ombox-style { border: 1px solid #f4c430; /* Yellow */ } table.ombox-move { border: 1px solid #9932cc; /* Purple */ } table.ombox-protection { border: 2px solid #bba; /* Gray-gold */ } /* Talk page message box styles */ table.tmbox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #c0c090; /* Default "notice" gray-brown */ background: #f8eaba; } .mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The "mediawiki" */ margin: 2px 0; /* class ensures that this declaration overrides other */ width: 100%; /* For Safari and Opera */ /* styles (including mbox-small above) */ } .mbox-inside .tmbox.mbox-small { /* "small" tmboxes should not be small when */ line-height: 1.5em; /* also "nested", so reset styles that are */ font-size: 100%; /* set in "mbox-small" above. */ } table.tmbox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.tmbox-delete { border: 2px solid #b22222; /* Red */ } table.tmbox-content { border: 2px solid #f28500; /* Orange */ } table.tmbox-style { border: 2px solid #f4c430; /* Yellow */ } table.tmbox-move { border: 2px solid #9932cc; /* Purple */ } table.tmbox-protection, table.tmbox-notice { border: 1px solid #c0c090; /* Gray-brown */ } /* Disambig and set index box styles */ table.dmbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* Footer and header message box styles */ table.fmbox { clear: both; margin: 0.2em 0; width: 100%; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); /* Default "system" gray */ } table.fmbox-system { background: var(--background-color-neutral-subtle); } table.fmbox-warning { border: 1px solid #bb7070; /* Dark pink */ background: #ffdbdb; /* Pink */ } table.fmbox-editnotice { background: transparent; } /* Div based "warning" style fmbox messages. */ div.mw-warning-with-logexcerpt, div.mw-lag-warn-high, div.mw-cascadeprotectedwarning, div#mw-protect-cascadeon { clear: both; margin: 0.2em 0; border: 1px solid #bb7070; background: #ffdbdb; padding: 0.25em 0.9em; } /* Div based "system" style fmbox messages. Used in [[MediaWiki:Noarticletext]] and [[MediaWiki:Readonly lag]]. */ div.mw-lag-warn-normal, div.noarticletext, div.fmbox-system { clear: both; margin: 0.2em 0; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); padding: 0.25em 0.9em; } /* These mbox-small classes must be placed after all other ambox/tmbox/ombox etc classes. "body.mediawiki" is so they override "table.ambox + table.ambox" above. */ body.mediawiki table.mbox-small { /* For the "small=yes" option. */ clear: right; float: right; margin: 4px 0 4px 1em; width: 238px; font-size: 88%; line-height: 1.25em; } body.mediawiki table.mbox-small-left { /* For the "small=left" option. */ margin: 4px 1em 4px 0; width: 238px; border-collapse: collapse; font-size: 88%; line-height: 1.25em; } /* Styling for citations */ span.citation, cite { font-style: normal; word-wrap: break-word; } /* For linked citation numbers and document IDs, where the number need not be shown on a screen or a handheld, but should be included in the printed version */ @media screen, handheld { span.citation *.printonly { display: none; } } /* Logo pour la page d'accueil */ .fondlogo { background:url("//upload.wikimedia.org/wikipedia/commons/0/08/WiktionaryFr-barre-accueil.png"); } #HalamanBaru { background:url(//upload.wikimedia.org/wiktionary/fi/e/ef/H%C3%ACnh_n%E1%BB%81n_Trang_Ch%C3%ADnh.jpg) no-repeat top right; background-position: bottom left; background-color: #f9f9fb; color: black; border: 1px solid #cccccc; padding:20px 7px 7px 7px; margin-bottom: 20px; } #ca-edit a { background: #00C !important; color: white !important; font-weight: bold !important; } div.NavFrame { border:none; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; position: relative; min-height: 1.6em; padding-left: 10px; border-bottom: 1px solid #EAEAEA; background-color: transparent; background-image: url(//upload.wikimedia.org/wiktionary/ko/9/96/BGImage_a.jpg); background-repeat: repeat-x; } span.NavToggle { cursor: pointer; float: right; font-weight: normal; padding: 0 3px; font-size: 90%; border-top: 1px solid var(--border-color-muted); border-right: 1px solid var(--border-color-base); border-bottom: 1px solid var(--border-color-base); border-left: 1px solid var(--border-color-muted); background-color:var(--background-color-neutral-subtle); } .translationtargetstar{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: 0px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstar:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -24px 60%;} .translationtargetstarchecked{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -48px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstarchecked:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -72px 60%;} #languageLinks .unselectedTab, #languageLinks .selectedTab { line-height:1.5em; } #languageLinks .selectedTab a{ cursor:pointer; padding:6px; font-size:19px; color:#333; background-color:#fff; margin-bottom:-3px; margin-right:-6px; position:relative; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #languageLinks .unselectedTab a { cursor:pointer; padding:6px; font-size:16px; color:#AAA; background-color:#F3F3F3; margin-bottom:-3px; margin-left:15px; margin-right:-5px; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #tabstable{ clear:both; } #languageLinks tr td{ padding:0px; } tr td.languageContainer{ padding-left:8px; padding-bottom:10px; padding-right:8px; border:1px solid #AAA; vertical-align:top; width:100%; } .editlangsection{ margin-top:-13px; margin-right:5px; border:1px solid #AAA; margin-bottom:-2px; border-bottom-width:0px; -webkit-border-top-left-radius:5px; -webkit-border-top-right-radius:5px; -moz-border-radius-topleft:5px; -moz-border-radius-topright:5px; border-top-left-radius:5px; border-top-right-radius:5px; color:white; line-height:14px; font-size:12px; padding:0px 7px; text-align:center; clear:both; background-color:white; } a.mw-echo-alert { text-transform:none; } /* Main Page heading removal */ .page-Wiktionary_Halaman_Utama #lastmod, .page-Wiktionary_Halaman_Utama #siteSub, .page-Wiktionary_Halaman_Utama #contentSub, /* .page-Wiktionary_Halaman_Utama #siteNotice, */ .page-Wiktionary_Halaman_Utama h1.firstHeading, .page-Wiktionary_Halaman_Utama #firstHeading { display: none; /* NOT important */ } /* Character sample untuk tabel-tabel [[Lampiran:Unicode]] */ .character-sample { display: inline-block; min-width: 1em; font-size: 200%; text-align: center; } /* From old enwikt */ /* Shortcut box */ .shortcut-box, .category-edit-box { border: 1px solid #aaa; color: black; background: var(--background-color-neutral-subtle); margin: 0 0 .5em 1em; text-align: center; padding: 5px; float: right; clear: both; font-weight: bold; font-size: smaller; } /* default style for mentions outside of "form of" definitions. */ .mention { font-style: italic; } .mention i, i .mention { font-style: normal; } /* default style for "form of" definitions */ .use-with-mention, .form-of-definition { font-style: italic; } .use-with-mention i { font-style: normal; } .form-of-definition-link { font-style: normal; } .use-with-mention .mention, .form-of-definition-link .mention { font-style: normal; font-weight: bold; } /* See also */ .disambig-see-also, .disambig-see-also-2 { padding-left: 2em; } 7tk7q179urw7xz9ejpxau1azlc2idoa 1349128 1348994 2026-04-08T19:21:02Z Swarabakti 18192 1349128 css text/css /*@import "//en.wiktionary.org/w/index.php?title=MediaWiki:Common.css&oldid=71426525&action=raw&ctype=text/css"; Ditulis ulang 2026-01-09 -- Swarabakti CSS yang berada di sini akan diterapkan untuk semua kulit __TOC__ == Dasar == */ /* ================================ */ /* Global color pallette */ /* ================================ */ /* Light mode */ :root, html, body, .vector-body { --white-bg: #FFF; --grey-bg: var(--background-color-neutral-subtle); --yellow-bg: #FFFFCC; --light-blue-bg: #F3F6FF; --tan-bg: #FAEBD7; --tan-border: #D2B48C; --black-font: #000; --faded-font: #333; --faded-border: #AAA; --faded-branch: #CCC; --idwikt-background-yellow: #FFFFDD; --idwikt-softblue: #F3F6FF; --idwikt-gray: #CCC; --idwikt-black: #333; } /* Night mode */ .skin-theme-clientpref-night, .skin-theme-clientpref-night body, .skin-theme-clientpref-night .vector-body { --white-bg: #000; --grey-bg: #1E1E1E; --yellow-bg: #33331A; --light-blue-bg: #1A2233; --tan-bg: #2A2522; --tan-border: #8B6F4E; --black-font: #FFF; --faded-font: #E0E0E0; --faded-border: #555; --faded-branch: #333; --idwikt-background-yellow: #222200; --idwikt-softblue: #1A2233; --idwikt-gray: #333; --idwikt-black: #E0E0E0; } /* ================================ */ /* General styling */ /* ================================ */ cite { font-style: italic !important; } /* Prevent odd line-height for raised and lowered characters */ sup, sub { line-height: 1em !important; } /* Unselectable texts */ .unselectable { cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } /* Style L2 headings */ .mw-parser-output .mw-heading2 { margin-top: 0.4em !important; padding: 1.2em 0 0.4em 0 !important; color: var(--color-base) !important; background: linear-gradient( to top, var(--background-color-base), var(--background-color-neutral-subtle) ) !important; border-bottom: none !important; border-top: 1px solid var(--border-color-base); } /* Style lists */ .mw-parser-output ol, .mw-parser-output ul, .mw-parser-output dl, .mw-parser-output li, .mw-parser-output dd { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ol > li { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ul > li::marker, .mw-parser-output ol > li::marker { font-weight: bold !important; } .mw-parser-output ol.references li::marker { font-weight: normal !important; } .mw-parser-output ol > li.has-visible-children + li { margin-top: 0.4em !important; } .mw-parser-output .syn-item, .mw-parser-output .usex-item, .mw-parser-output .quot-item { margin-top: 0 !important; margin-bottom: 0 !important; overflow: auto; } /* Style labels */ .hyphenation { font-weight: bold !important; font-size: 0.95em !important; } .ib-content { font-style: italic !important; } .usage-label-term, .usage-label-sense { color: var(--color-content-added) !important; } .usage-label-term a, .usage-label-sense a { color: inherit !important; font-style: inherit !important; text-decoration: underline dotted !important; } .usage-label-term a:hover, .usage-label-sense a:hover { text-decoration: underline !important; } /* Style usex and quotes */ .cited-source { font-size: 0.9em !important; } .h-usage-example, .h-quotation { font-size: 0.95em !important; } /* Style toggles */ .mw-collapsible-toggle, .toc-toggle, .section-toggle, .pron-toggle, .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { cursor: pointer; font-size: 0.9em; color: var(--color-link) !important; } .toc-toggle { display: block; margin: 0.2em; } .section-toggle { background: none; text-align: center; } .section-toggle + .section-collapsible-wrapper { margin-top: 0 !important; } .headword-wrapper.has-section-toggle { cursor: pointer; } .headword-wrapper.has-section-toggle .headword-inner { padding-top: 0 !important; } .infl-toggle, .content-toggle { float: right; font-weight: normal; } .pron-toggle { margin-left: 0.6em; } .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { margin-left: 0.4em; } .toggle-container { display: inline; margin-left: 0.2em; } /* Style TOC */ #toc { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; max-width: 60%; text-align: center; } #toc > .toctitle { display: none; } #toc > ul { display: flex; flex-wrap: wrap; justify-content: center; list-style: none; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; margin: 0.2em; gap: 0.4em; } #toc ul ul { display: none; } #toc > ul > li::after { content: " •"; color: var(--faded-border, #AAA); padding-left: 0.2em; } #toc > ul > li:last-child::after { content: ""; } .skin-minerva #toc { display: none; } .category-link { display: block; margin: 0.2em; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; } /* Style references */ .references { font-size: 0.9em; } ol.references > li:target, sup.reference:target, cite:target { background-color: #DEF; } /* Style catlinks */ .catlinks { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; } /* Style indents */ body dd { position: relative; margin: 0; padding-left: 0.8em; } body dd::before { content: ""; position: absolute; top: 0.2em; left: 0.2em; bottom: 0.2em; width: 1px; background: var(--faded-branch); } /* Copy and share buttons */ .mw-parser-output h3, .mw-heading > h3 { position: relative !important; padding: 0; margin: 0; } .mw-parser-output h3 > .headword-text, .mw-heading > h3 > .headword-text { display: block; padding-right: 3.2em; overflow-wrap: anywhere; word-break: normal; white-space: normal; min-width: 0; } .wikt-header-controls { display: inline-flex; align-items: center; gap: 0.2em; position: absolute; right: 0.8em; top: 0.4em; z-index: 100; opacity: 0; transition: opacity 0.15s; } .wikt-header-anchor { display: inline-flex; color: var(--color-subtle) !important; cursor: pointer; } .wikt-header-anchor:hover { color: var(--color-progressive) !important; } .mw-parser-output h3:hover > .wikt-header-controls, .mw-heading:hover > h3 > .wikt-header-controls { opacity: 1; } /* Responsive, horizontally scrollable table */ @media (max-width: 720px) { .wikitable { display: block; overflow-x: auto; width: 100% !important; } } /* ================================== */ /* Scripts styling */ /* ================================== */ /* For scripts where bolding is not used, highlight the word */ .Arab b, .Brah b, .Deva b, .Hebr b, .Lina b, .Linb b, .Mani b, .Mong b, .Ogam b, .Orkh b, .Ougr b, .Runr b, .Sogd b, .Syrc b, .Thai b, .Ugar b, .Xpeo b, .Xsux b { background: var(--yellow-bg, #FFFFCC); font-style: normal; font-weight: normal; font-size: inherit; } /* Script-specific styling */ /* Latin (default) */ .Latn { font-style: normal; } /* Arabic, right-to-left */ .Arab { font-family: 'Noto Naskh Arabic', 'Iranian Sans', Tahoma, 'Microsoft Sans Serif', 'Arial Unicode MS', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Armenian */ .Armn { font-family: Mshtakan, Arial, 'Segoe UI', Tahoma, 'Arian AMU', 'DejaVu Sans', sans-serif; } /* Balinese */ .Bali { font-family: "Noto Sans Balinese", serif; } /* Batak */ .Batk { font-family: Batak-Unicode, sans-serif; } /* Bengali */ .Beng { font-family: 'Bangla Sangam MN', UniBangla, 'Arial Unicode MS', 'Code2000', Likhan, 'UT Bengali Dhaka', Vrinda, sans-serif; font-size: 1.3em; } /* Bopomofo */ .Bopo { font-family: MOESongUN, DFKai-SB, 'Microsoft Yahei', 'Microsoft Jhenghei', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', sans-serif; } /* Braille */ .Brai { font-size: 1.5em; } /* Bugis */ .Bugi { font-family: Saweri, sans-serif; } /* Buhid */ .Buhd { font-family: 'Noto Sans Buhid', Quivira, sans-serif; font-size: 1.1em; } /* Cham */ .Cham { font-family: 'Code2000', 'JG ChamCambodia', sans-serif; font-size: 1.1em; } /* Cherokee */ .Cher { font-family: Digohweli, 'Aboriginal Sans', 'Code2000', Marin, 'Rotinonhsonni Sans', 'Everson Mono Unicode', sans-serif; font-size: 1.1em; } /* Coptic */ .Copt { font-family: Quivira, Antinoou, 'New Athena Unicode', Analecta, FreeSerifAvvaShenouda, 'Arial Coptic', 'Sophia Nubian', 'Code2000', sans-serif; font-size: 1.3em; } /* Cyrillic */ .Cyrl { font-family: Helvetica, Geneva, 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', sans-serif; } /* Old Cyrillic (Old Church Slavonic, Old East Slavic) */ .Cyrs { font-family: Monomakh, 'Monomakh Unicode', 'Monomakh Unicode TT', Menaion, 'Menaion Unicode', 'Menaion Unicode TT', Ponomar, 'Ponomar Unicode', 'Ponomar Unicode TT', Fedorovsk, 'Fedorovsk Unicode', 'Fedorovsk Unicode TT', Pochaevsk, 'Pochaevsk Unicode', 'Pochaevsk Unicode TT', Triodion, 'Triodion Unicode', 'Triodion Unicode TT', 'Acathist', 'Shafarik', Vilnius, BukyVede, 'Kliment Std', 'RomanCyrillic Std', 'Monomachus', 'Old Standard', 'Old Standard TT', Dilyana, 'Hirmos Ponomar', 'Hirmos Ponomar TT', 'Menaion Medieval', Lazov, 'Code2000', 'DejaVu Sans', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', sans-serif; font-size: 1.25em; } /* Devanagari */ .Deva { font-family: 'Adobe Devanagari', 'Noto Serif Devanagari', Utsaah, 'Devanagari MT', Raghu, Gargi, JanaSanskrit, JanaHindi, Siddhanta, sans-serif; font-size: 1.2em; } i.Deva { font-style: normal; } /* Dogra */ .Dogr { font-family: 'Noto Serif Dogra', sans-serif; } /* Deseret */ .Dsrt { font-family: 'Segoe UI Symbol', 'Code2001', 'MPH 2B Damase', 'Everson Mono', sans-serif; } /* Egyptian hieroglyphs */ .Egyp { font-family: 'Noto Sans Egyptian Hieroglyphs', Abydos, Aegyptus, 'Segoe UI Historic', sans-serif; font-size: 1.5em; } /* Ethiopic (Ge'ez) */ .Ethi { font-family: 'Abyssinica SIL', Nyala, 'Code2000', 'Ethiopia Jiret', 'GF Zemen Unicode', 'TITUS Cyberbit Basic', 'Visual Geez Unicode', 'Visual Geez Unicode Agazian', 'Visual Geez Unicode Title', sans-serif; font-size: 1.2em; } /* Georgian */ .Geor { font-family: 'DejaVu Sans', 'Arial Unicode MS', Sylfaen, sans-serif; } /* Glagolitic */ .Glag { font-family: Shafarik, Menaion, 'Menaion Unicode', 'Menaion Unicode TT', 'Segoe UI Historic', BukyVede, Dilyana, 'Noto Sans Glagolitic', sans-serif; font-size: 1.5em; } /* Gothic */ .Goth { font-family: 'Segoe UI Historic', 'Code2001', Skeirs, 'MPH 2B Damase', sans-serif; } /* Greek */ .Grek { font-family: 'Gentium Plus', 'Gentium', 'Lucida Sans Unicode', sans-serif; } /* Gujarati */ .Gujr { font-family: 'Noto Sans Gujarati', 'Gujarati Sangam MN', 'Gujarati MT', Shruti, 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Gurmukhi */ .Guru { font-family: 'Gurmukhi MN', 'Gurmukhi MT', 'UT Punjabi Amritsar', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Chinese (Han) .Hani = generic .Hans = simplified .Hant = traditional */ .Hans { font-family: 'PingFang SC', DengXian, 'Source Han Sans SC', 'Source Han Sans CN', 'Noto Sans CJK SC', 'Microsoft Yahei', SimHei, SimSun, NSimSun, SimSun-ExtB, Song, 'Heiti SC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hant { font-family: 'PingFang TC', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', 'Microsoft Jhenghei', MOESongUN, PMingLiU, PMingLiU-ExtB, MingLiU, MingLiU-ExtB, Ming, 'Heiti TC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hans, .Hant { font-size: 1.2em; line-height: 1; } /* Hanunoo */ .Hano { font-family: 'Noto Sans Hanunoo', Quivira, 'MPH 2B Damase', sans-serif; font-size: 1.1em; } /* Hatran */ .Hatr { font-family: 'Noto Sans Hatran', sans-serif; direction: rtl; } /* Hebrew */ .Hebr { font-family: 'SBL Hebrew', 'SBL BibLit', 'Taamey David CLM', 'Taamey Frank CLM', Alef, 'Noto Sans Hebrew', Narkisim, Miriam, Kinryu, 'Arial Hebrew', Arial, 'Adobe Hebrew', serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Hluw: Anatolian Hieroglyphs */ .Hluw { font-family: 'Noto Sans Anatolian Hieroglyphs', Anatolian; font-size: 2em; } /* Hiragana: see .Jpan */ /* Javanese */ .Java { font-family: 'Tuladha Jejeg', 'Javanese Text', adjisaka, 'Noto Sans Javanese', sans-serif; line-height: 2em; } /* Japanese scripts .Hira = Hiragana .Kana = Katakana (used for Ainu language) .Jpan = Hiragana + Katakana + Kanji */ .Hira, .Jpan, .Kana { font-family: 'Hiragino Kaku Gothic Pro', Osaka, 'Yu Gothic', Meiryo, 'Source Han Sans J', 'Source Han Sans JP', 'Noto Sans CJK JP', 'Droid Sans Japanese', 'MS PGothic', 'MS Gothic', 'MS PMincho', 'MS Mincho', HanaMinA, HanaMinB, sans-serif; font-size: 1.2em; line-height: 1; } .Jpan ruby rt { font-family: 'Yu Gothic UI', 'Meiryo UI', 'MS UI Gothic', sans-serif; font-size: 0.6em; } /* Khmer */ .Khmr { font-family: 'Khmer OS', 'Khmer OS Content', 'Leelawadee UI', 'Noto Sans Khmer', 'Code2000', 'Khmer Mondulkiri U OT ls', sans-serif; font-size: 1.25em; } /* Kannada */ .Knda { font-family: 'Kannada Sangam MN', JanaKannada, Tunga, Kedage, RaghuKannada, Sampige, 'Arial Unicode MS', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', sans-serif; font-size: 1.25em; } /* Korean */ .Kore, .Hang { font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', Dotum, Gulim, 'NanumBarunGothic YetHangul', NanumBarunGothic, UnDotum, 'Source Han Sans K', 'Source Han Sans KR', 'Noto Sans CJK KR', NanumGothic, 'NanumMyeongjo YetHangul', NanumMyeongjo, Batang, UnBatang, sans-serif; font-size: 1.2em; line-height: 1; } /* Kaithi */ .Kthi { font-family: 'Noto Sans Kaithi', sans-serif; } /* Lanna */ .Lana { font-family: 'Lanna Alif', 'Noto Sans Tai Tham', sans-serif; } /* Lao */ .Laoo { font-family: 'Phetsarath OT', 'Saysettha OT', 'JG Basic Lao Opentype', 'JG Basic2 Lao Opentype', 'JG LaoTimes Opentype', 'Phagnoum Lao Unicode Opentype', 'JG Lao Old Arial Opentype', DokChampa, 'Code2000', 'JG Lao Classic Opentype', 'Alice0 Unicode', 'Alice1 Unicode', 'Alice2 Unicode', 'Alice3 Unicode', 'Alice4 Unicode', 'Alice5 Unicode', sans-serif; font-size: 1.25em; } /* Limbu */ .Limb { font-family: 'Code2000', 'MPH 2B Damase', sans-serif; } /* Linear A */ .Lina { font-family: Aegean, 'Noto Sans Linear A', sans-serif; font-size: 1.25em; } /* Linear B */ .Linb { font-family: Aegean, 'Noto Sans Linear B', sans-serif; font-size: 1.25em; } /* Lisu */ .Lisu { font-family: 'Noto Sans Lisu', Quivira, sans-serif; } /* Makasar */ .Maka { font-family: "Noto Sans Makasar", serif; } /* Malayalam */ .Mlym { font-family: 'Malayalam Sangam MN', Kartika, 'Code2000', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Mongolian */ .Mong { font-family: 'Mongolian Baiti', 'Noto Sans Mongolian', sans-serif; font-size: 1.4em; -webkit-writing-mode: vertical-lr; -moz-writing-mode: vertical-lr; writing-mode: vertical-lr; } /* Burmese */ .Mymr { font-family: TharLon, Padauk, 'Myanmar Text', 'Myanmar3', 'Myanmar2', 'Myanmar1', ParabaikSans, 'MyMyanmar sans-serif'; font-size: 1.3em; } big.Mymr, strong.Mymr, b.Mymr, b .Mymr { font-size: 1.62em; } .Mymr b { font-size: 1.3em; } /* N’Ko */ .Nkoo { font-style: normal; direction: rtl; } /* Ogham */ .Ogam { font-family: "Noto Sans Ogham", serif; } /* Oriya */ .Orya { font-family: "Noto Sans Oriya", serif; } /* Phoenician */ .Phnx { font-family: "Noto Sans Phoenician", serif; } /* Rejang */ .Rjng { font-family: 'Noto Sans Rejang', 'Code2000', sans-serif; } /* Runic */ .Runr { font-family: 'Segoe UI Historic', Junicode, 'Free Mono', 'Caslon Roman', 'Segoe UI Symbol', 'Code2000', 'Everson Mono', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; } /* Sinhala */ .Sinh { font-family: 'Sinhala Sangam MN', KaputaUnicode, KandyUnicode, Dinamina, DinaminaUniWeb, Potha, Madhura, sans-serif; font-size: 1.25em; } /* Sundanese */ .Sund { font-family: 'Sundanese Unicode', 'Noto Sans Sundanese', sans-serif; } /* Syriac, right-to-left */ .Syrc { font-family: 'Estrangelo Edessa', 'San Francisco', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Tagbanwa */ .Tagb { font-family: Quivira, Tagbanwa, sans-serif; font-size: 1.1em; } /* Tai Le */ .Tale { font-family: 'Microsoft Tai Le', 'Tai Le Valentinium', 'MPH 2B Damase', sans-serif; } /* New Tai Lue */ .Talu { font-family: 'Noto Sans New Tai Lue', 'Microsoft New Tai Lue', 'Dai Banna SIL Book', 'Husb_New_Tai_Lue_WB', sans-serif; } /* Tamil */ .Taml { font-family: 'Tamil Sangam MN', InaiMathi, Vijaya, Akshar, JanaTamil, 'Code2000', ETTamilNew, 'Lohit Tamil', 'Arial Unicode MS', 'Free Serif', Latha, sans-serif; font-size: 1.25em; } /* Tangut */ .Tang { font-family: 'BabelStone Tangut Wenhai', 'Tangut N4694', 'Tangut Yinchuan', 'New Tangut', 'New Tangut Std', 'Tangut TWU', 'Babelstone Tangut Wenhai', sans-serif; font-size: 1.2em; } /* Tai Viet */ .Tavt { font-family: 'Tai Heritage Pro', 'Noto Sans Tai Viet', sans-serif; } /* Telugu */ .Telu { font-family: 'Telugu Sangam MN', sans-serif; font-size: 1.25em; } /* Thaana */ .Thaa { font-style: normal; direction: rtl; } /* Thai */ .Thai { font-family: 'Leelawadee UI', Leelawadee, 'Arial Unicode MS', 'Code2000', sans-serif; font-size: 1.25em; } /* Tifinagh (Berber) */ .Tfng { font-family: 'Hapax Berbère', Ebrima, 'Code2000', DejaVu, sans-serif; font-size: 1.2em; } /* Tagalog (Baybayin) */ .Tglg { font-family: 'Noto Sans Tagalog', 'Tagalog Stylized', 'Baybayin Lopez', 'Tagalog Doctrina 1593', Quivira, 'Code2000', sans-serif; } /* Tibetan */ .Tibt { font-family: 'Noto Serif Tibetan', 'Noto Sans Tibetan', Jomolhari-ID, 'Tibetan Machine Uni', 'Tibetan Machine Web', Jomolhari, 'Microsoft Himalaya', sans-serif; font-size: 1.3em; } /* Ugaritic */ .Ugar { font-family: 'Oxford Ugaritic', 'Segoe UI Historic', Aegean, 'Code2001', sans-serif; } /* Vai */ .Vaii { font-family: Ebrima, 'Code2000', sans-serif; font-size: 1.1em; } /* Old Persian cuneiform */ .Xpeo { font-family: 'Segoe UI Historic', Aegean, Xerxes, 'Code2001', sans-serif; } /* Sumero-Akkadian cuneiform */ .Xsux { font-family: Akkadian, FreeIdgSerif, CuneiformComposite, 'Segoe UI Historic', sans-serif; font-size: 1.25em; } /* Multilingual writing systems and symbols */ /* International Phonetic Alphabet */ .IPA { font-family: Gentium, 'Gentium Plus', GentiumAlt, 'DejaVu Sans', 'Segoe UI', 'Lucida Grande', 'Charis SIL', 'Doulos SIL', 'TITUS Cyberbit Basic', 'Code2000', 'Lucida Sans Unicode', sans-serif; font-size: 110%; font-variant-ligatures: no-common-ligatures; } /* Musical notation */ .Music { font-family: Musica, 'Musical Symbols', Euterpe, sans-serif; font-size: 1.4em; } /* Znamenny musical notation */ .Zname { font-family: 'Mezenets Unicode', Slavonic, Voskresensky, Smolensky, Symbola, sans-serif; } /* Symbols */ .Zsym { font-family: Symbola, sans-serif; font-size: 150%; } /* ===================================================== Legacy (list logic intentionally excluded) ===================================================== */ /* untuk category tree supaya lebar td masing-masing 1/3 Bennylin 19/8/14 */ table.mw-prefixindex-list-table td { width: 33%; } /* [[MediaWiki:Sitenotice]] */ #siteNotice { margin-top:5px; padding-left: 4px; font-style: italic; text-align: center; } /* Redirects on [[Special:Allpages]] */ .allpagesredirect { font-style: italic; } /* All tables: transparent, originally: white */ table { background: transparent; } /* User notification. You've got mail! */ .usermessage { text-decoration: blink; } /* Table of contents: redefine for printing */ .toccolours { border:1px solid var(--border-color-base); background-color:var(--background-color-neutral-subtle); padding:5px; font-size: 95%; } /* Icon link PDF (hanya untuk Mozilla dan Opera) */ #bodyContent a[href$=".pdf"].external, #bodyContent a[href*=".pdf?"].external, #bodyContent a[href*=".pdf#"].external, #bodyContent a[href$=".PDF"].external, #bodyContent a[href*=".PDF?"].external, #bodyContent a[href*=".PDF#"].external { background: url('//upload.wikimedia.org/wikipedia/commons/thumb/2/23/Icons-mini-file_acrobat.gif/15px-Icons-mini-file_acrobat.gif') center right no-repeat; padding-right: 16px; } /* Beri warna untuk jumlah bita pada [[Istimewa:Perubahanterbaru]] */ .mw-plusminus-neg { color:#FF2050; } .mw-plusminus-pos { color:#00B000; } /* /** == Tabel == CSS untuk tabel-tabel */ table.wikitable, table.prettytable { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.wikitable th, table.wikitable td, table.prettytable th, table.prettytable td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.wikitable th, table.prettytable th { background: var(--background-color-neutral); text-align: center; } table.wikitable caption, table.prettytable caption { margin-left: inherit; margin-right: inherit; } /* Digunakan oleh Templat:Tabel */ div.kolom-2 div.column { float: left; width: 50%; min-width: 300px; } div.kolom-3 div.column { float: left; width: 33.3%; min-width: 200px; } div.kolom-4 div.column { float: left; width: 25%; min-width: 150px; } div.kolom-5 div.column { float: left; width: 20%; min-width: 120px; } /* tabelcantik */ table.tabelcantik { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.tabelcantik th, table.tabelcantik td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.tabelcantik th { background: var(--background-color-neutral); text-align: center; } table.tabelcantik caption { margin-left: inherit; margin-right: inherit; } tbody tr.even td { background: var(--background-color-neutral-subtle); } tbody tr.odd td { background: var(--background-color-neutral-subtle); } /* tabelcantikcyan */ table.tabelcantikcyan { margin: 1em 1em 1em 0; background: LightCyan; border: 1px Turquoise solid; border-collapse: collapse; } table.tabelcantikcyan th, table.tabelcantikcyan td { border: 1px Turquoise solid; padding: 0.2em; } table.tabelcantikcyan th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikcyan caption { margin-left: inherit; margin-right: inherit; } tbody tr.evencyan td { background: PaleTurquoise } tbody tr.oddcyan td { background: LightCyan } /* tabelcantikmerah */ table.tabelcantikmerah { margin: 1em 1em 1em 0; background: Seashell; border: 1px LightSalmon; border-collapse: collapse; } table.tabelcantikmerah th, table.tabelcantikmerah td { border: 1px LightSalmon solid; padding: 0.2em; } table.tabelcantikmerah th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikmerah caption { margin-left: inherit; margin-right: inherit; } tbody tr.evenmerah td { background: MistyRose } tbody tr.oddmerah td { background: Seashell } /** == Kotak navigasi == */ /* Style for horizontal lists (separator following item) */ .skin-monobook .hlist dl, .skin-modern .hlist dl, .skin-vector .hlist dl { line-height: 1.5em; } .hlist dl, .hlist ol, .hlist ul { margin: 0; } .hlist dd, .hlist dt, .hlist li { display: inline; margin: 0; } /* Display nested lists inline */ .hlist dl dl, .hlist ol ol, .hlist ul ul { display: inline; } /* Generate interpuncts */ .hlist dt:after { content: " :"; } .hlist dd:after, .hlist li:after { content: " ·"; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* for IE 8 */ .hlist dd.nopunct:after, .hlist dt.nopunct:after, .hlist li.nopunct:after { content: none; } /* Add parents around nested lists */ .hlist dl dl:before, .hlist ol ol:before, .hlist ul ul:before { content: "("; } .hlist dl dl:after, .hlist ol ol:after, .hlist ul ul:after { content: ")"; } /* Put numbers in ordered lists */ .hlist.hnum ol li { counter-increment: level1; } .hlist.hnum ol li:before { content: counter(level1) " "; } .hlist.hnum ol ol li { counter-increment: level2; } .hlist.hnum ol ol li:before { content: counter(level2) " "; } /* Default style for navigation boxes */ .navbox { /* Navbox container style */ border: 1px solid #aaa; width: 100%; margin: auto; clear: both; font-size: 88%; text-align: center; padding: 1px; } .navbox-inner, .navbox-subgroup { width: 100%; } .navbox th, .navbox-title, .navbox-abovebelow { text-align: center; /* Title and above/below styles */ padding-left: 1em; padding-right: 1em; } th.navbox-group { /* Group style */ white-space: nowrap; /* @noflip */ text-align: right; } .navbox, .navbox-subgroup { background: #fdfdfd; /* Background color */ } .navbox-list { border-color: #fdfdfd; /* Must match background color */ } .navbox th, .navbox-title { background: #ccccff; /* Level 1 color */ } .navbox-abovebelow, th.navbox-group, .navbox-subgroup .navbox-title { background: #ddddff; /* Level 2 color */ } .navbox-subgroup .navbox-group, .navbox-subgroup .navbox-abovebelow { background: #e6e6ff; /* Level 3 color */ } .navbox-even { background: #f7f7f7; /* Even row striping */ } .navbox-odd { background: transparent; /* Odd row striping */ } table.navbox + table.navbox { /* Single pixel border between adjacent navboxes */ margin-top: -1px; /* (doesn't work for IE6, but that's okay) */ } .navbox .hlist td dl, .navbox .hlist td ol, .navbox .hlist td ul, .navbox td.hlist dl, .navbox td.hlist ol, .navbox td.hlist ul { padding: 0.125em 0; /* Adjust hlist padding in navboxes */ } .navbox .hlist dd, .navbox .hlist dt, .navbox .hlist li { white-space: nowrap; /* Nowrap list items in navboxes */ white-space: normal !ie; /* IE < 8 no-wraps entire list, so disable it */ } .navbox .hlist dd dl, .navbox .hlist dt dl, .navbox .hlist li ol, .navbox .hlist li ul { white-space: normal; /* But allow parent list items to be wrapped */ } ol + table.navbox, ul + table.navbox { margin-top: 0.5em; /* Prevent lists from clinging to navboxes */ } /* Default styling for Navbar template */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar ul { display: inline; white-space: nowrap; } .navbar li { word-spacing: -0.125em; } /* Navbar styling when nested in navbox */ .navbox .navbar { display: block; font-size: 100%; } .navbox-title .navbar { /* @noflip */ float: left; /* @noflip */ text-align: left; /* @noflip */ margin-right: 0.5em; width: 6em; } /* 'show'/'hide' buttons created dynamically by the CollapsibleTables javascript in [[MediaWiki:Common.js]] are styled here so they can be customised. */ .collapseButton { /* @noflip */ float: right; font-weight: normal; /* @noflip */ margin-left: 0.5em; /* @noflip */ text-align: right; width: auto; } /* In navboxes, the show/hide button balances the v·d·e links from [[Template:Navbar]], so they need to be the same width. */ .navbox .collapseButton { width: 6em; } /** == Messagebox == */ /* Berbagai ''style'' "messagebox" */ .messagebox { border: 1px solid var(--border-color-base); background-color: var(--background-color-neutral-subtle); width: 80%; margin: 0 auto 1em auto; padding: .2em; text-align: justify; } .messagebox.merge { border: 1px solid #cf9fff; background-color: #f5edf5; text-align: center; } .messagebox.cleanup { border: 1px solid #9f9fff; background-color: #efefff; text-align: center; } .messagebox.standard-talk { border: 1px solid #c0c090; background-color: #f8eaba; } /* Standard Navigationsleisten, aka box hiding thingy from .de. Documentation at [[Wikipedia:NavFrame]]. */ div.NavFrame { margin: 0; padding: 4px; border: 1px solid #aaa; text-align: center; border-collapse: collapse; font-size: 95%; } div.NavFrame + div.NavFrame { border-top-style: none; border-top-style: hidden; } div.NavPic { background-color: #fff; margin: 0; padding: 2px; /* @noflip */ float: left; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; background-color: #ccf; position: relative; } div.NavFrame p, div.NavFrame div.NavContent, div.NavFrame div.NavContent p { font-size: 100%; } div.NavEnd { margin: 0; padding: 0; line-height: 1px; clear: both; } a.NavToggle { position: absolute; top: 0; /* @noflip */ right: 3px; font-weight: normal; font-size: 90%; } /** == CommonTicker == CSS untuk CommonTickers */ /* CommonsTicker styles */ .tickerList ul, .tickerList ul li { list-style: none; text-indent:-2em; margin-left:2em; text-align:left; } .tickerList ul ul, .tickerList ul ul li { list-style: none; text-indent:0; margin-left:1.5em; text-align:left; } .tickerDiffLink { } /* diff links in ticker */ .tickerMiscLink { } /* misc links in ticker */ .tickerUsage { font-size:80%; } /* ticker usage list */ .tickerAction_deleted:before { content:" HAPUS "; color: #FF0000; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_deletedRev:before { content:" HAPUSREV "; color: #FFC0CB; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replaced:before { content:" GANTI "; color: #FF00FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replacedOwn:before { content:" GANTI+ "; color: #CC88FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedTag:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedTag:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedBad:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedBad:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedGood:before { content:" +OK "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedGood:before { content:" -OK "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerEntry_deleted { } /* entry for image deletion */ .tickerEntry_replaced { } /* entry for image replacement */ .tickerEntry_tagged { } /* entry for adding/removing problem tags */ .tickerEntry_redir { } /* entry for critical redirection (fot tag redirects) */ .tickerEntry_recat { } /* entry for critical re-categorization (for tag categories) */ .tickerEntry_notify { } /* entry for global notifications */ .tickerEntry_changed { } /* entry for generic change */ /*.tickerAction_deleted { background:#FAA; } /* action marker for image deletion */ /*.tickerAction_replaced { background:#FED; } /* action marker for image replacement */ /*.tickerAction_deletedRev { background:#FDD; } /* action marker for revision deletion */ /*.tickerAction_replacedOwn { background:#FFF4EE; } /* action marker for image replacement by uploader */ /*.tickerAction_addedBad { background:#FDD; } /* action marker for adding problem markers */ /*.tickerAction_removedBad { background:#DFD; } /* action marker for removing problem markers */ /*.tickerAction_addedGood { background:#DFD; } /* action marker for adding license markgers (for tag categories) */ /*.tickerAction_removedGood { background:#FDD; } /* action marker for removing license markers (for tag categories) */ .tickerMinorEntry { color:#666; } /* minor entry */ .tickerMinorEntry a, .tickerMinorEntry a:link, .tickerMinorEntry a:visited { color:#669; } #bodyContent .tickerMinorEntry a.extiw, #bodyContent .tickerMinorEntry a.extiw:link, #bodyContent .tickerMinorEntry a.extiw:visited { color:#669; } .tickerTemplateEntry { font-weight: bold; } /* entry applies to a template used by multiple images */ .tickerSubEntry { } /* sub-entry for multi-image entry */ /** == Lain-lain == CSS untuk berbagai jenis style */ #p-cactions #ca-edittop a { padding-left: .4em; padding-right: .4em; } /** [[Template:Coor title dm]] **/ #coordinates { position:absolute; z-index:1; border:none; background:none; right:30px; top:5.2em; float:right; margin:0.0em; padding:0.0em; line-height:1.5em; text-align:right; text-indent:0; font-size:85%; text-transform:none; white-space:nowrap; } /* [[Template:Disambig]] */ #disambigbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* [[Template:Spoiler]] */ #spoiler { border-top: 2px solid #ddd; border-bottom:2px solid #ddd; } /* [[Wikipedia:Artikel bagus]], for positioning icons at top-right */ div.topicon { position:absolute; z-index:100; top:10px; display: block !important; } /** [[Wikipedia:Kotak pengguna]] **/ .userboxdark a, .userboxdark a:visited, .userboxdark a:active { color: #ccc; } /* == Daftar isi == ''Style'' untuk variasi daftar isi: * '''horizontal''': daftar isi horizontal. Contoh penggunaan: <code><nowiki><div class="horizontal">__TOC__</div></nowiki></code>. * '''nonumtoc''': tanpa nomor. Contoh penggunaan: <code><nowiki><div class="notocnum">__TOC__</div></nowiki></code>. * '''toclimit-x''': membatasi tampilan hanya sampai level ke-x. Contoh penggunaan: <code><nowiki><div class="toclimit-3">__TOC__</div></nowiki></code>, judul subbagian tingkat 1 (tag h2), tingkat 2 (tag h3) tidak ditampilkan. */ .horizontal ul { padding: 0; margin: 0; } .horizontal li { padding: 0 0.6em 0 0.4em; display: inline; border-right: 1px solid; } .horizontal li:last-child { border-right: none; } .nonumtoc .tocnumber { display:none; } .nonumtoc #toc ul, .nonumtoc .toc ul { line-height: 1.5em; list-style: none; margin: .3em 0 0; padding: 0; } .nonumtoc #toc ul ul, .nonumtoc .toc ul ul { margin: 0 0 0 2em; } .toclimit-2 .toclevel-2 {display:none;} .toclimit-3 .toclevel-3 {display:none;} .toclimit-4 .toclevel-4 {display:none;} .toclimit-5 .toclevel-5 {display:none;} .toclimit-6 .toclevel-6 {display:none;} .toclimit-7 .toclevel-7 {display:none;} /* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */ th.mbox-text, td.mbox-text { /* The message body cell(s) */ border: none; padding: 0.25em 0.9em; /* 0.9em left/right */ width: 100%; /* Make all mboxes the same width regardless of text length */ } td.mbox-image { /* The left image cell */ border: none; padding: 2px 0 2px 0.9em; /* 0.9em left, 0px right */ text-align: center; } td.mbox-imageright { /* The right image cell */ border: none; padding: 2px 0.9em 2px 0; /* 0px left, 0.9em right */ text-align: center; } td.mbox-empty-cell { /* An empty narrow cell */ border: none; padding: 0px; width: 1px; } /* Article message box styles */ table.ambox { margin: 0px 10%; /* 10% = Will not overlap with other elements */ border: 1px solid #aaa; border-left: 10px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } table.ambox + table.ambox { /* Single border between stacked boxes. */ margin-top: -1px; } .ambox th.mbox-text, .ambox td.mbox-text { /* The message body cell(s) */ padding: 0.25em 0.5em; /* 0.5em left/right */ } .ambox td.mbox-image { /* The left image cell */ padding: 2px 0 2px 0.5em; /* 0.5em left, 0px right */ } .ambox td.mbox-imageright { /* The right image cell */ padding: 2px 0.5em 2px 0; /* 0px left, 0.5em right */ } table.ambox-notice { border-left: 10px solid #1e90ff; /* Blue */ } table.ambox-speedy { border-left: 10px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ambox-delete { border-left: 10px solid #b22222; /* Red */ } table.ambox-content { border-left: 10px solid #f28500; /* Orange */ } table.ambox-style { border-left: 10px solid #f4c430; /* Yellow */ } table.ambox-move { border-left: 10px solid #9932cc; /* Purple */ } table.ambox-protection { border-left: 10px solid #bba; /* Gray-gold */ } /* Image message box styles */ table.imbox { margin: 4px 10%; border-collapse: collapse; border: 3px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } .mbox-inside .imbox { /* For imboxes inside other templates. */ margin: 4px; } .imbox .mbox-text .imbox { /* For imboxes inside imbox-text cells. */ margin: 0 -0.5em; /* 0.9 - 0.5 = 0.4em left/right. */ } table.imbox-notice { border: 3px solid #1e90ff; /* Blue */ } table.imbox-speedy { border: 3px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.imbox-delete { border: 3px solid #b22222; /* Red */ } table.imbox-content { border: 3px solid #f28500; /* Orange */ } table.imbox-style { border: 3px solid #f4c430; /* Yellow */ } table.imbox-move { border: 3px solid #9932cc; /* Purple */ } table.imbox-protection { border: 3px solid #bba; /* Gray-gold */ } table.imbox-license { border: 3px solid #88a; /* Dark gray */ background: #f7f8ff; /* Light gray */ } table.imbox-featured { border: 3px solid #cba135; /* Brown-gold */ } /* Category message box styles */ table.cmbox { margin: 3px 10%; border-collapse: collapse; border: 1px solid #aaa; background: #DFE8FF; /* Default "notice" blue */ } table.cmbox-notice { background: #D8E8FF; /* Blue */ } table.cmbox-speedy { margin-top: 4px; margin-bottom: 4px; border: 4px solid #b22222; /* Red */ background: #FFDBDB; /* Pink */ } table.cmbox-delete { background: #FFDBDB; /* Red */ } table.cmbox-content { background: #FFE7CE; /* Orange */ } table.cmbox-style { background: #FFF9DB; /* Yellow */ } table.cmbox-move { background: #E4D8FF; /* Purple */ } table.cmbox-protection { background: #EFEFE1; /* Gray-gold */ } /* Other pages message box styles */ table.ombox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #aaa; /* Default "notice" gray */ background: var(--background-color-neutral-subtle); } table.ombox-notice { border: 1px solid #aaa; /* Gray */ } table.ombox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ombox-delete { border: 2px solid #b22222; /* Red */ } table.ombox-content { border: 1px solid #f28500; /* Orange */ } table.ombox-style { border: 1px solid #f4c430; /* Yellow */ } table.ombox-move { border: 1px solid #9932cc; /* Purple */ } table.ombox-protection { border: 2px solid #bba; /* Gray-gold */ } /* Talk page message box styles */ table.tmbox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #c0c090; /* Default "notice" gray-brown */ background: #f8eaba; } .mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The "mediawiki" */ margin: 2px 0; /* class ensures that this declaration overrides other */ width: 100%; /* For Safari and Opera */ /* styles (including mbox-small above) */ } .mbox-inside .tmbox.mbox-small { /* "small" tmboxes should not be small when */ line-height: 1.5em; /* also "nested", so reset styles that are */ font-size: 100%; /* set in "mbox-small" above. */ } table.tmbox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.tmbox-delete { border: 2px solid #b22222; /* Red */ } table.tmbox-content { border: 2px solid #f28500; /* Orange */ } table.tmbox-style { border: 2px solid #f4c430; /* Yellow */ } table.tmbox-move { border: 2px solid #9932cc; /* Purple */ } table.tmbox-protection, table.tmbox-notice { border: 1px solid #c0c090; /* Gray-brown */ } /* Disambig and set index box styles */ table.dmbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* Footer and header message box styles */ table.fmbox { clear: both; margin: 0.2em 0; width: 100%; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); /* Default "system" gray */ } table.fmbox-system { background: var(--background-color-neutral-subtle); } table.fmbox-warning { border: 1px solid #bb7070; /* Dark pink */ background: #ffdbdb; /* Pink */ } table.fmbox-editnotice { background: transparent; } /* Div based "warning" style fmbox messages. */ div.mw-warning-with-logexcerpt, div.mw-lag-warn-high, div.mw-cascadeprotectedwarning, div#mw-protect-cascadeon { clear: both; margin: 0.2em 0; border: 1px solid #bb7070; background: #ffdbdb; padding: 0.25em 0.9em; } /* Div based "system" style fmbox messages. Used in [[MediaWiki:Noarticletext]] and [[MediaWiki:Readonly lag]]. */ div.mw-lag-warn-normal, div.noarticletext, div.fmbox-system { clear: both; margin: 0.2em 0; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); padding: 0.25em 0.9em; } /* These mbox-small classes must be placed after all other ambox/tmbox/ombox etc classes. "body.mediawiki" is so they override "table.ambox + table.ambox" above. */ body.mediawiki table.mbox-small { /* For the "small=yes" option. */ clear: right; float: right; margin: 4px 0 4px 1em; width: 238px; font-size: 88%; line-height: 1.25em; } body.mediawiki table.mbox-small-left { /* For the "small=left" option. */ margin: 4px 1em 4px 0; width: 238px; border-collapse: collapse; font-size: 88%; line-height: 1.25em; } /* Styling for citations */ span.citation, cite { font-style: normal; word-wrap: break-word; } /* For linked citation numbers and document IDs, where the number need not be shown on a screen or a handheld, but should be included in the printed version */ @media screen, handheld { span.citation *.printonly { display: none; } } /* Logo pour la page d'accueil */ .fondlogo { background:url("//upload.wikimedia.org/wikipedia/commons/0/08/WiktionaryFr-barre-accueil.png"); } #HalamanBaru { background:url(//upload.wikimedia.org/wiktionary/fi/e/ef/H%C3%ACnh_n%E1%BB%81n_Trang_Ch%C3%ADnh.jpg) no-repeat top right; background-position: bottom left; background-color: #f9f9fb; color: black; border: 1px solid #cccccc; padding:20px 7px 7px 7px; margin-bottom: 20px; } #ca-edit a { background: #00C !important; color: white !important; font-weight: bold !important; } div.NavFrame { border:none; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; position: relative; min-height: 1.6em; padding-left: 10px; border-bottom: 1px solid #EAEAEA; background-color: transparent; background-image: url(//upload.wikimedia.org/wiktionary/ko/9/96/BGImage_a.jpg); background-repeat: repeat-x; } span.NavToggle { cursor: pointer; float: right; font-weight: normal; padding: 0 3px; font-size: 90%; border-top: 1px solid var(--border-color-muted); border-right: 1px solid var(--border-color-base); border-bottom: 1px solid var(--border-color-base); border-left: 1px solid var(--border-color-muted); background-color:var(--background-color-neutral-subtle); } .translationtargetstar{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: 0px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstar:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -24px 60%;} .translationtargetstarchecked{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -48px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstarchecked:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -72px 60%;} #languageLinks .unselectedTab, #languageLinks .selectedTab { line-height:1.5em; } #languageLinks .selectedTab a{ cursor:pointer; padding:6px; font-size:19px; color:#333; background-color:#fff; margin-bottom:-3px; margin-right:-6px; position:relative; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #languageLinks .unselectedTab a { cursor:pointer; padding:6px; font-size:16px; color:#AAA; background-color:#F3F3F3; margin-bottom:-3px; margin-left:15px; margin-right:-5px; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #tabstable{ clear:both; } #languageLinks tr td{ padding:0px; } tr td.languageContainer{ padding-left:8px; padding-bottom:10px; padding-right:8px; border:1px solid #AAA; vertical-align:top; width:100%; } .editlangsection{ margin-top:-13px; margin-right:5px; border:1px solid #AAA; margin-bottom:-2px; border-bottom-width:0px; -webkit-border-top-left-radius:5px; -webkit-border-top-right-radius:5px; -moz-border-radius-topleft:5px; -moz-border-radius-topright:5px; border-top-left-radius:5px; border-top-right-radius:5px; color:white; line-height:14px; font-size:12px; padding:0px 7px; text-align:center; clear:both; background-color:white; } a.mw-echo-alert { text-transform:none; } /* Main Page heading removal */ .page-Wiktionary_Halaman_Utama #lastmod, .page-Wiktionary_Halaman_Utama #siteSub, .page-Wiktionary_Halaman_Utama #contentSub, /* .page-Wiktionary_Halaman_Utama #siteNotice, */ .page-Wiktionary_Halaman_Utama h1.firstHeading, .page-Wiktionary_Halaman_Utama #firstHeading { display: none; /* NOT important */ } /* Character sample untuk tabel-tabel [[Lampiran:Unicode]] */ .character-sample { display: inline-block; min-width: 1em; font-size: 200%; text-align: center; } /* From old enwikt */ /* Shortcut box */ .shortcut-box, .category-edit-box { border: 1px solid #aaa; color: black; background: var(--background-color-neutral-subtle); margin: 0 0 .5em 1em; text-align: center; padding: 5px; float: right; clear: both; font-weight: bold; font-size: smaller; } /* default style for mentions outside of "form of" definitions. */ .mention { font-style: italic; } .mention i, i .mention { font-style: normal; } /* default style for "form of" definitions */ .use-with-mention, .form-of-definition { font-style: italic; } .use-with-mention i { font-style: normal; } .form-of-definition-link { font-style: normal; } .use-with-mention .mention, .form-of-definition-link .mention { font-style: normal; font-weight: bold; } /* See also */ .disambig-see-also, .disambig-see-also-2 { padding-left: 2em; } p0xwly6v9s7kzghu5w63y9a5vm69vlt 1349133 1349128 2026-04-08T19:31:48Z Swarabakti 18192 1349133 css text/css /*@import "//en.wiktionary.org/w/index.php?title=MediaWiki:Common.css&oldid=71426525&action=raw&ctype=text/css"; Ditulis ulang 2026-01-09 -- Swarabakti CSS yang berada di sini akan diterapkan untuk semua kulit __TOC__ == Dasar == */ /* ================================ */ /* Global color pallette */ /* ================================ */ /* Light mode */ :root, html, body, .vector-body { --white-bg: #FFF; --grey-bg: var(--background-color-neutral-subtle); --yellow-bg: #FFFFCC; --light-blue-bg: #F3F6FF; --tan-bg: #FAEBD7; --tan-border: #D2B48C; --black-font: #000; --faded-font: #333; --faded-border: #AAA; --faded-branch: #CCC; --idwikt-background-yellow: #FFFFDD; --idwikt-softblue: #F3F6FF; --idwikt-gray: #CCC; --idwikt-black: #333; } /* Night mode */ .skin-theme-clientpref-night, .skin-theme-clientpref-night body, .skin-theme-clientpref-night .vector-body { --white-bg: #000; --grey-bg: #1E1E1E; --yellow-bg: #33331A; --light-blue-bg: #1A2233; --tan-bg: #2A2522; --tan-border: #8B6F4E; --black-font: #FFF; --faded-font: #E0E0E0; --faded-border: #555; --faded-branch: #333; --idwikt-background-yellow: #222200; --idwikt-softblue: #1A2233; --idwikt-gray: #333; --idwikt-black: #E0E0E0; } /* ================================ */ /* General styling */ /* ================================ */ cite { font-style: italic !important; } /* Prevent odd line-height for raised and lowered characters */ sup, sub { line-height: 1em !important; } /* Unselectable texts */ .unselectable { cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } /* Style L2 headings */ .mw-parser-output .mw-heading2 { margin-top: 0.4em !important; padding: 1.2em 0 0.4em 0 !important; color: var(--color-base) !important; background: linear-gradient( to top, var(--background-color-base), var(--background-color-neutral-subtle) ) !important; border-bottom: none !important; border-top: 1px solid var(--border-color-base); } /* Style lists */ .mw-parser-output ol, .mw-parser-output ul, .mw-parser-output dl, .mw-parser-output li, .mw-parser-output dd { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ol > li { margin-top: 0 !important; margin-bottom: 0 !important; } .mw-parser-output ul > li::marker, .mw-parser-output ol > li::marker { font-weight: bold !important; } .mw-parser-output ol.references li::marker { font-weight: normal !important; } .mw-parser-output ol > li.has-visible-children + li { margin-top: 0.4em !important; } .mw-parser-output .syn-item, .mw-parser-output .usex-item, .mw-parser-output .quot-item { margin-top: 0 !important; margin-bottom: 0 !important; overflow: auto; } /* Style labels */ .hyphenation { font-weight: bold !important; font-size: 0.95em !important; } .ib-content { font-style: italic !important; } .usage-label-term, .usage-label-sense { color: var(--color-content-added) !important; } .usage-label-term a, .usage-label-sense a { color: inherit !important; font-style: inherit !important; text-decoration: underline dotted !important; } .usage-label-term a:hover, .usage-label-sense a:hover { text-decoration: underline !important; } /* Style usex and quotes */ .cited-source { font-size: 0.9em !important; } .h-usage-example, .h-quotation { font-size: 0.95em !important; } /* Style toggles */ .mw-collapsible-toggle, .toc-toggle, .section-toggle, .pron-toggle, .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { cursor: pointer; font-size: 0.9em; color: var(--color-link) !important; } .toc-toggle { display: block; margin: 0.2em; } .section-toggle { background: none; text-align: center; } .section-toggle + .section-collapsible-wrapper { margin-top: 0 !important; } .headword-wrapper.has-section-toggle { cursor: pointer; } .headword-wrapper.has-section-toggle .headword-inner { padding-top: 0 !important; } .infl-toggle, .content-toggle { float: right; font-weight: normal; } .pron-toggle { margin-left: 0.6em; } .syn-toggle, .usex-toggle, .quot-toggle, .infl-toggle, .content-toggle { margin-left: 0.4em; } .toggle-container { display: inline; margin-left: 0.2em; } /* Style TOC */ #toc { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; max-width: 60%; text-align: center; } #toc > .toctitle { display: none; } #toc > ul { display: flex; flex-wrap: wrap; justify-content: center; list-style: none; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; margin: 0.2em; gap: 0.4em; } #toc ul ul { display: none; } #toc > ul > li::after { content: " •"; color: var(--faded-border, #AAA); padding-left: 0.2em; } #toc > ul > li:last-child::after { content: ""; } .skin-minerva #toc { display: none; } .category-link { display: block; margin: 0.2em; border-top: 1px solid var(--faded-border, #AAA); padding-top: 0.4em; } /* Style references */ .references { font-size: 0.9em; } ol.references > li:target, sup.reference:target, cite:target { background-color: #DEF; } /* Style catlinks */ .catlinks { background-color: var(--grey-bg, var(--background-color-neutral-subtle)); border: 1px solid var(--faded-border, #AAA); color: var(--faded-font, #333); margin: 1em auto; padding: 0.4em; font-size: 95%; } /* Style indents */ body dd { position: relative; margin: 0; padding-left: 0.8em; } body dd::before { content: ""; position: absolute; top: 0.2em; left: 0.2em; bottom: 0.2em; width: 1px; background: var(--faded-branch); } /* Copy and share buttons */ .mw-parser-output h3, .mw-heading > h3 { position: relative !important; padding: 0; margin: 0; } .mw-parser-output h3 > .headword-text, .mw-heading > h3 > .headword-text { display: block; padding-right: 3.2em; overflow-wrap: anywhere; word-break: normal; white-space: normal; min-width: 0; } .wikt-header-controls { display: inline-flex; align-items: center; gap: 0.2em; position: absolute; right: 0.8em; top: 0.4em; z-index: 100; opacity: 0; transition: opacity 0.15s; } .wikt-header-anchor { display: inline-flex; color: var(--color-subtle) !important; cursor: pointer; } .wikt-header-anchor:hover { color: var(--color-progressive) !important; } .mw-parser-output h3:hover > .wikt-header-controls, .mw-heading:hover > h3 > .wikt-header-controls { opacity: 1; } /* Responsive, horizontally scrollable table */ @media (max-width: 720px) { .wikitable { display: block; overflow-x: auto; width: 100% !important; } } /* ================================== */ /* Scripts styling */ /* ================================== */ /* For scripts where bolding is not used, highlight the word */ .Arab b, .Brah b, .Deva b, .Hebr b, .Lina b, .Linb b, .Mani b, .Mong b, .Ogam b, .Orkh b, .Ougr b, .Runr b, .Sogd b, .Syrc b, .Thai b, .Ugar b, .Xpeo b, .Xsux b { background: var(--yellow-bg, #FFFFCC); font-style: normal; font-weight: normal; font-size: inherit; } /* Script-specific styling */ /* Latin (default) */ .Latn { font-style: normal; } /* Arabic, right-to-left */ .Arab { font-family: 'Noto Naskh Arabic', 'Iranian Sans', Tahoma, 'Microsoft Sans Serif', 'Arial Unicode MS', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Armenian */ .Armn { font-family: Mshtakan, Arial, 'Segoe UI', Tahoma, 'Arian AMU', 'DejaVu Sans', sans-serif; } /* Balinese */ .Bali { font-family: "Noto Sans Balinese", serif; } /* Batak */ .Batk { font-family: Batak-Unicode, sans-serif; } /* Bengali */ .Beng { font-family: 'Bangla Sangam MN', UniBangla, 'Arial Unicode MS', 'Code2000', Likhan, 'UT Bengali Dhaka', Vrinda, sans-serif; font-size: 1.3em; } /* Bopomofo */ .Bopo { font-family: MOESongUN, DFKai-SB, 'Microsoft Yahei', 'Microsoft Jhenghei', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', sans-serif; } /* Braille */ .Brai { font-size: 1.5em; } /* Bugis */ .Bugi { font-family: Saweri, sans-serif; } /* Buhid */ .Buhd { font-family: 'Noto Sans Buhid', Quivira, sans-serif; font-size: 1.1em; } /* Cham */ .Cham { font-family: 'Code2000', 'JG ChamCambodia', sans-serif; font-size: 1.1em; } /* Cherokee */ .Cher { font-family: Digohweli, 'Aboriginal Sans', 'Code2000', Marin, 'Rotinonhsonni Sans', 'Everson Mono Unicode', sans-serif; font-size: 1.1em; } /* Coptic */ .Copt { font-family: Quivira, Antinoou, 'New Athena Unicode', Analecta, FreeSerifAvvaShenouda, 'Arial Coptic', 'Sophia Nubian', 'Code2000', sans-serif; font-size: 1.3em; } /* Cyrillic */ .Cyrl { font-family: Helvetica, Geneva, 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', sans-serif; } /* Old Cyrillic (Old Church Slavonic, Old East Slavic) */ .Cyrs { font-family: Monomakh, 'Monomakh Unicode', 'Monomakh Unicode TT', Menaion, 'Menaion Unicode', 'Menaion Unicode TT', Ponomar, 'Ponomar Unicode', 'Ponomar Unicode TT', Fedorovsk, 'Fedorovsk Unicode', 'Fedorovsk Unicode TT', Pochaevsk, 'Pochaevsk Unicode', 'Pochaevsk Unicode TT', Triodion, 'Triodion Unicode', 'Triodion Unicode TT', 'Acathist', 'Shafarik', Vilnius, BukyVede, 'Kliment Std', 'RomanCyrillic Std', 'Monomachus', 'Old Standard', 'Old Standard TT', Dilyana, 'Hirmos Ponomar', 'Hirmos Ponomar TT', 'Menaion Medieval', Lazov, 'Code2000', 'DejaVu Sans', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', sans-serif; font-size: 1.25em; } /* Devanagari */ .Deva { font-family: 'Adobe Devanagari', 'Noto Serif Devanagari', Utsaah, 'Devanagari MT', Raghu, Gargi, JanaSanskrit, JanaHindi, Siddhanta, sans-serif; font-size: 1.2em; } i.Deva { font-style: normal; } /* Dogra */ .Dogr { font-family: 'Noto Serif Dogra', sans-serif; } /* Deseret */ .Dsrt { font-family: 'Segoe UI Symbol', 'Code2001', 'MPH 2B Damase', 'Everson Mono', sans-serif; } /* Egyptian hieroglyphs */ .Egyp { font-family: 'Noto Sans Egyptian Hieroglyphs', Abydos, Aegyptus, 'Segoe UI Historic', sans-serif; font-size: 1.5em; } /* Ethiopic (Ge'ez) */ .Ethi { font-family: 'Abyssinica SIL', Nyala, 'Code2000', 'Ethiopia Jiret', 'GF Zemen Unicode', 'TITUS Cyberbit Basic', 'Visual Geez Unicode', 'Visual Geez Unicode Agazian', 'Visual Geez Unicode Title', sans-serif; font-size: 1.2em; } /* Georgian */ .Geor { font-family: 'DejaVu Sans', 'Arial Unicode MS', Sylfaen, sans-serif; } /* Glagolitic */ .Glag { font-family: Shafarik, Menaion, 'Menaion Unicode', 'Menaion Unicode TT', 'Segoe UI Historic', BukyVede, Dilyana, 'Noto Sans Glagolitic', sans-serif; font-size: 1.5em; } /* Gothic */ .Goth { font-family: 'Segoe UI Historic', 'Code2001', Skeirs, 'MPH 2B Damase', sans-serif; } /* Greek */ .Grek { font-family: 'Gentium Plus', 'Gentium', 'Lucida Sans Unicode', sans-serif; } /* Gujarati */ .Gujr { font-family: 'Noto Sans Gujarati', 'Gujarati Sangam MN', 'Gujarati MT', Shruti, 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Gurmukhi */ .Guru { font-family: 'Gurmukhi MN', 'Gurmukhi MT', 'UT Punjabi Amritsar', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'Code2000', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Chinese (Han) .Hani = generic .Hans = simplified .Hant = traditional */ .Hans { font-family: 'PingFang SC', DengXian, 'Source Han Sans SC', 'Source Han Sans CN', 'Noto Sans CJK SC', 'Microsoft Yahei', SimHei, SimSun, NSimSun, SimSun-ExtB, Song, 'Heiti SC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hant { font-family: 'PingFang TC', 'Source Han Sans TC', 'Source Han Sans TW', 'Noto Sans CJK TC', 'Microsoft Jhenghei', MOESongUN, PMingLiU, PMingLiU-ExtB, MingLiU, MingLiU-ExtB, Ming, 'Heiti TC', HanaMinA, HanaMinB, sans-serif; } .Hani, .Hans, .Hant { font-size: 1.2em; line-height: 1; } /* Hanunoo */ .Hano { font-family: 'Noto Sans Hanunoo', Quivira, 'MPH 2B Damase', sans-serif; font-size: 1.1em; } /* Hatran */ .Hatr { font-family: 'Noto Sans Hatran', sans-serif; direction: rtl; } /* Hebrew */ .Hebr { font-family: 'SBL Hebrew', 'SBL BibLit', 'Taamey David CLM', 'Taamey Frank CLM', Alef, 'Noto Sans Hebrew', Narkisim, Miriam, Kinryu, 'Arial Hebrew', Arial, 'Adobe Hebrew', serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Hluw: Anatolian Hieroglyphs */ .Hluw { font-family: 'Noto Sans Anatolian Hieroglyphs', Anatolian; font-size: 2em; } /* Hiragana: see .Jpan */ /* Javanese */ .Java { font-family: 'Tuladha Jejeg', 'Javanese Text', adjisaka, 'Noto Sans Javanese', sans-serif; line-height: 2em; } /* Japanese scripts .Hira = Hiragana .Kana = Katakana (used for Ainu language) .Jpan = Hiragana + Katakana + Kanji */ .Hira, .Jpan, .Kana { font-family: 'Hiragino Kaku Gothic Pro', Osaka, 'Yu Gothic', Meiryo, 'Source Han Sans J', 'Source Han Sans JP', 'Noto Sans CJK JP', 'Droid Sans Japanese', 'MS PGothic', 'MS Gothic', 'MS PMincho', 'MS Mincho', HanaMinA, HanaMinB, sans-serif; font-size: 1.2em; line-height: 1; } .Jpan ruby rt { font-family: 'Yu Gothic UI', 'Meiryo UI', 'MS UI Gothic', sans-serif; font-size: 0.6em; } /* Khmer */ .Khmr { font-family: 'Khmer OS', 'Khmer OS Content', 'Leelawadee UI', 'Noto Sans Khmer', 'Code2000', 'Khmer Mondulkiri U OT ls', sans-serif; font-size: 1.25em; } /* Kannada */ .Knda { font-family: 'Kannada Sangam MN', JanaKannada, Tunga, Kedage, RaghuKannada, Sampige, 'Arial Unicode MS', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', sans-serif; font-size: 1.25em; } /* Korean */ .Kore, .Hang { font-family: 'Apple SD Gothic Neo', 'Malgun Gothic', Dotum, Gulim, 'NanumBarunGothic YetHangul', NanumBarunGothic, UnDotum, 'Source Han Sans K', 'Source Han Sans KR', 'Noto Sans CJK KR', NanumGothic, 'NanumMyeongjo YetHangul', NanumMyeongjo, Batang, UnBatang, sans-serif; font-size: 1.2em; line-height: 1; } /* Kaithi */ .Kthi { font-family: 'Noto Sans Kaithi', sans-serif; } /* Lanna */ .Lana { font-family: 'Lanna Alif', 'Noto Sans Tai Tham', sans-serif; } /* Lao */ .Laoo { font-family: 'Phetsarath OT', 'Saysettha OT', 'JG Basic Lao Opentype', 'JG Basic2 Lao Opentype', 'JG LaoTimes Opentype', 'Phagnoum Lao Unicode Opentype', 'JG Lao Old Arial Opentype', DokChampa, 'Code2000', 'JG Lao Classic Opentype', 'Alice0 Unicode', 'Alice1 Unicode', 'Alice2 Unicode', 'Alice3 Unicode', 'Alice4 Unicode', 'Alice5 Unicode', sans-serif; font-size: 1.25em; } /* Limbu */ .Limb { font-family: 'Code2000', 'MPH 2B Damase', sans-serif; } /* Linear A */ .Lina { font-family: Aegean, 'Noto Sans Linear A', sans-serif; font-size: 1.25em; } /* Linear B */ .Linb { font-family: Aegean, 'Noto Sans Linear B', sans-serif; font-size: 1.25em; } /* Lisu */ .Lisu { font-family: 'Noto Sans Lisu', Quivira, sans-serif; } /* Makasar */ .Maka { font-family: "Noto Sans Makasar", serif; } /* Malayalam */ .Mlym { font-family: 'Malayalam Sangam MN', Kartika, 'Code2000', 'Lucida Grande', 'Arial Unicode MS', 'Lucida Sans Unicode', 'TITUS Cyberbit Basic', 'Chrysanthi Unicode', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'Visual Geez Unicode', sans-serif; font-size: 1.25em; } /* Mongolian */ .Mong { font-family: 'Mongolian Baiti', 'Noto Sans Mongolian', sans-serif; font-size: 1.4em; -webkit-writing-mode: vertical-lr; -moz-writing-mode: vertical-lr; writing-mode: vertical-lr; } /* Burmese */ .Mymr { font-family: TharLon, Padauk, 'Myanmar Text', 'Myanmar3', 'Myanmar2', 'Myanmar1', ParabaikSans, 'MyMyanmar sans-serif'; font-size: 1.3em; } big.Mymr, strong.Mymr, b.Mymr, b .Mymr { font-size: 1.62em; } .Mymr b { font-size: 1.3em; } /* N’Ko */ .Nkoo { font-style: normal; direction: rtl; } /* Ogham */ .Ogam { font-family: "Noto Sans Ogham", serif; } /* Oriya */ .Orya { font-family: "Noto Sans Oriya", serif; } /* Phoenician */ .Phnx { font-family: "Noto Sans Phoenician", serif; } /* Rejang */ .Rjng { font-family: 'Noto Sans Rejang', 'Code2000', sans-serif; } /* Runic */ .Runr { font-family: 'Segoe UI Historic', Junicode, 'Free Mono', 'Caslon Roman', 'Segoe UI Symbol', 'Code2000', 'Everson Mono', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; } /* Sinhala */ .Sinh { font-family: 'Sinhala Sangam MN', KaputaUnicode, KandyUnicode, Dinamina, DinaminaUniWeb, Potha, Madhura, sans-serif; font-size: 1.25em; } /* Sundanese */ .Sund { font-family: 'Sundanese Unicode', 'Noto Sans Sundanese', sans-serif; } /* Syriac, right-to-left */ .Syrc { font-family: 'Estrangelo Edessa', 'San Francisco', 'Code2000', 'Bitstream Cyberbit', 'Bitstream CyberBase', 'Bitstream Vera', 'TITUS Cyberbit Basic', sans-serif; font-size: 1.3em; direction: rtl; unicode-bidi: isolate; } /* Tagbanwa */ .Tagb { font-family: Quivira, Tagbanwa, sans-serif; font-size: 1.1em; } /* Tai Le */ .Tale { font-family: 'Microsoft Tai Le', 'Tai Le Valentinium', 'MPH 2B Damase', sans-serif; } /* New Tai Lue */ .Talu { font-family: 'Noto Sans New Tai Lue', 'Microsoft New Tai Lue', 'Dai Banna SIL Book', 'Husb_New_Tai_Lue_WB', sans-serif; } /* Tamil */ .Taml { font-family: 'Tamil Sangam MN', InaiMathi, Vijaya, Akshar, JanaTamil, 'Code2000', ETTamilNew, 'Lohit Tamil', 'Arial Unicode MS', 'Free Serif', Latha, sans-serif; font-size: 1.25em; } /* Tangut */ .Tang { font-family: 'BabelStone Tangut Wenhai', 'Tangut N4694', 'Tangut Yinchuan', 'New Tangut', 'New Tangut Std', 'Tangut TWU', 'Babelstone Tangut Wenhai', sans-serif; font-size: 1.2em; } /* Tai Viet */ .Tavt { font-family: 'Tai Heritage Pro', 'Noto Sans Tai Viet', sans-serif; } /* Telugu */ .Telu { font-family: 'Telugu Sangam MN', sans-serif; font-size: 1.25em; } /* Thaana */ .Thaa { font-style: normal; direction: rtl; } /* Thai */ .Thai { font-family: 'Leelawadee UI', Leelawadee, 'Arial Unicode MS', 'Code2000', sans-serif; font-size: 1.25em; } /* Tifinagh (Berber) */ .Tfng { font-family: 'Hapax Berbère', Ebrima, 'Code2000', DejaVu, sans-serif; font-size: 1.2em; } /* Tagalog (Baybayin) */ .Tglg { font-family: 'Noto Sans Tagalog', 'Tagalog Stylized', 'Baybayin Lopez', 'Tagalog Doctrina 1593', Quivira, 'Code2000', sans-serif; } /* Tibetan */ .Tibt { font-family: 'Noto Serif Tibetan', 'Noto Sans Tibetan', Jomolhari-ID, 'Tibetan Machine Uni', 'Tibetan Machine Web', Jomolhari, 'Microsoft Himalaya', sans-serif; font-size: 1.3em; } /* Ugaritic */ .Ugar { font-family: 'Oxford Ugaritic', 'Segoe UI Historic', Aegean, 'Code2001', sans-serif; } /* Vai */ .Vaii { font-family: Ebrima, 'Code2000', sans-serif; font-size: 1.1em; } /* Old Persian cuneiform */ .Xpeo { font-family: 'Segoe UI Historic', Aegean, Xerxes, 'Code2001', sans-serif; } /* Sumero-Akkadian cuneiform */ .Xsux { font-family: Akkadian, FreeIdgSerif, CuneiformComposite, 'Segoe UI Historic', sans-serif; font-size: 1.25em; } /* Multilingual writing systems and symbols */ /* International Phonetic Alphabet */ .IPA { font-family: Gentium, 'Gentium Plus', GentiumAlt, 'DejaVu Sans', 'Segoe UI', 'Lucida Grande', 'Charis SIL', 'Doulos SIL', 'TITUS Cyberbit Basic', 'Code2000', 'Lucida Sans Unicode', sans-serif; font-size: 110%; font-variant-ligatures: no-common-ligatures; } /* Musical notation */ .Music { font-family: Musica, 'Musical Symbols', Euterpe, sans-serif; font-size: 1.4em; } /* Znamenny musical notation */ .Zname { font-family: 'Mezenets Unicode', Slavonic, Voskresensky, Smolensky, Symbola, sans-serif; } /* Symbols */ .Zsym { font-family: Symbola, sans-serif; font-size: 150%; } /* ===================================================== Legacy (list logic intentionally excluded) ===================================================== */ /* untuk category tree supaya lebar td masing-masing 1/3 Bennylin 19/8/14 */ table.mw-prefixindex-list-table td { width: 33%; } /* [[MediaWiki:Sitenotice]] */ #siteNotice { margin-top:5px; padding-left: 4px; font-style: italic; text-align: center; } /* Redirects on [[Special:Allpages]] */ .allpagesredirect { font-style: italic; } /* All tables: transparent, originally: white */ table { background: transparent; } /* User notification. You've got mail! */ .usermessage { text-decoration: blink; } /* Table of contents: redefine for printing */ .toccolours { border:1px solid var(--border-color-base); background-color:var(--background-color-neutral-subtle); padding:5px; font-size: 95%; } /* Icon link PDF (hanya untuk Mozilla dan Opera) */ #bodyContent a[href$=".pdf"].external, #bodyContent a[href*=".pdf?"].external, #bodyContent a[href*=".pdf#"].external, #bodyContent a[href$=".PDF"].external, #bodyContent a[href*=".PDF?"].external, #bodyContent a[href*=".PDF#"].external { background: url('//upload.wikimedia.org/wikipedia/commons/thumb/2/23/Icons-mini-file_acrobat.gif/15px-Icons-mini-file_acrobat.gif') center right no-repeat; padding-right: 16px; } /* Beri warna untuk jumlah bita pada [[Istimewa:Perubahanterbaru]] */ .mw-plusminus-neg { color:#FF2050; } .mw-plusminus-pos { color:#00B000; } /* /** == Tabel == CSS untuk tabel-tabel */ table.wikitable, table.prettytable { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.wikitable th, table.wikitable td, table.prettytable th, table.prettytable td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.wikitable th, table.prettytable th { background: var(--background-color-neutral); text-align: center; } table.wikitable caption, table.prettytable caption { margin-left: inherit; margin-right: inherit; } /* Digunakan oleh Templat:Tabel */ div.kolom-2 div.column { float: left; width: 50%; min-width: 300px; } div.kolom-3 div.column { float: left; width: 33.3%; min-width: 200px; } div.kolom-4 div.column { float: left; width: 25%; min-width: 150px; } div.kolom-5 div.column { float: left; width: 20%; min-width: 120px; } /* tabelcantik */ table.tabelcantik { margin: 1em 1em 1em 0; background: var(--background-color-neutral-subtle); border: 1px var(--border-color-base) solid; border-collapse: collapse; } table.tabelcantik th, table.tabelcantik td { border: 1px var(--border-color-base) solid; padding: 0.2em; } table.tabelcantik th { background: var(--background-color-neutral); text-align: center; } table.tabelcantik caption { margin-left: inherit; margin-right: inherit; } tbody tr.even td { background: var(--background-color-neutral-subtle); } tbody tr.odd td { background: var(--background-color-neutral-subtle); } /* tabelcantikcyan */ table.tabelcantikcyan { margin: 1em 1em 1em 0; background: LightCyan; border: 1px Turquoise solid; border-collapse: collapse; } table.tabelcantikcyan th, table.tabelcantikcyan td { border: 1px Turquoise solid; padding: 0.2em; } table.tabelcantikcyan th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikcyan caption { margin-left: inherit; margin-right: inherit; } tbody tr.evencyan td { background: PaleTurquoise } tbody tr.oddcyan td { background: LightCyan } /* tabelcantikmerah */ table.tabelcantikmerah { margin: 1em 1em 1em 0; background: Seashell; border: 1px LightSalmon; border-collapse: collapse; } table.tabelcantikmerah th, table.tabelcantikmerah td { border: 1px LightSalmon solid; padding: 0.2em; } table.tabelcantikmerah th { background: var(--background-color-neutral); text-align: center; } table.tabelcantikmerah caption { margin-left: inherit; margin-right: inherit; } tbody tr.evenmerah td { background: MistyRose } tbody tr.oddmerah td { background: Seashell } /** == Kotak navigasi == */ /* Style for horizontal lists (separator following item) */ .skin-monobook .hlist dl, .skin-modern .hlist dl, .skin-vector .hlist dl { line-height: 1.5em; } .hlist dl, .hlist ol, .hlist ul { margin: 0; } .hlist dd, .hlist dt, .hlist li { display: inline; margin: 0; } /* Display nested lists inline */ .hlist dl dl, .hlist ol ol, .hlist ul ul { display: inline; } /* Generate interpuncts */ .hlist dt:after { content: " :"; } .hlist dd:after, .hlist li:after { content: " ·"; font-weight: bold; } .hlist dd:last-child:after, .hlist dt:last-child:after, .hlist li:last-child:after { content: none; } /* for IE 8 */ .hlist dd.nopunct:after, .hlist dt.nopunct:after, .hlist li.nopunct:after { content: none; } /* Add parents around nested lists */ .hlist dl dl:before, .hlist ol ol:before, .hlist ul ul:before { content: "("; } .hlist dl dl:after, .hlist ol ol:after, .hlist ul ul:after { content: ")"; } /* Put numbers in ordered lists */ .hlist.hnum ol li { counter-increment: level1; } .hlist.hnum ol li:before { content: counter(level1) " "; } .hlist.hnum ol ol li { counter-increment: level2; } .hlist.hnum ol ol li:before { content: counter(level2) " "; } /* Default style for navigation boxes */ .navbox { /* Navbox container style */ border: 1px solid #aaa; width: 100%; margin: auto; clear: both; font-size: 88%; text-align: center; padding: 1px; } .navbox-inner, .navbox-subgroup { width: 100%; } .navbox th, .navbox-title, .navbox-abovebelow { text-align: center; /* Title and above/below styles */ padding-left: 1em; padding-right: 1em; } th.navbox-group { /* Group style */ white-space: nowrap; /* @noflip */ text-align: right; } .navbox, .navbox-subgroup { background: #fdfdfd; /* Background color */ } .navbox-list { border-color: #fdfdfd; /* Must match background color */ } .navbox th, .navbox-title { background: #ccccff; /* Level 1 color */ } .navbox-abovebelow, th.navbox-group, .navbox-subgroup .navbox-title { background: #ddddff; /* Level 2 color */ } .navbox-subgroup .navbox-group, .navbox-subgroup .navbox-abovebelow { background: #e6e6ff; /* Level 3 color */ } .navbox-even { background: #f7f7f7; /* Even row striping */ } .navbox-odd { background: transparent; /* Odd row striping */ } table.navbox + table.navbox { /* Single pixel border between adjacent navboxes */ margin-top: -1px; /* (doesn't work for IE6, but that's okay) */ } .navbox .hlist td dl, .navbox .hlist td ol, .navbox .hlist td ul, .navbox td.hlist dl, .navbox td.hlist ol, .navbox td.hlist ul { padding: 0.125em 0; /* Adjust hlist padding in navboxes */ } .navbox .hlist dd, .navbox .hlist dt, .navbox .hlist li { white-space: nowrap; /* Nowrap list items in navboxes */ white-space: normal !ie; /* IE < 8 no-wraps entire list, so disable it */ } .navbox .hlist dd dl, .navbox .hlist dt dl, .navbox .hlist li ol, .navbox .hlist li ul { white-space: normal; /* But allow parent list items to be wrapped */ } ol + table.navbox, ul + table.navbox { margin-top: 0.5em; /* Prevent lists from clinging to navboxes */ } /* Default styling for Navbar template */ .navbar { display: inline; font-size: 88%; font-weight: normal; } .navbar ul { display: inline; white-space: nowrap; } .navbar li { word-spacing: -0.125em; } /* Navbar styling when nested in navbox */ .navbox .navbar { display: block; font-size: 100%; } .navbox-title .navbar { /* @noflip */ float: left; /* @noflip */ text-align: left; /* @noflip */ margin-right: 0.5em; width: 6em; } /* 'show'/'hide' buttons created dynamically by the CollapsibleTables javascript in [[MediaWiki:Common.js]] are styled here so they can be customised. */ .collapseButton { /* @noflip */ float: right; font-weight: normal; /* @noflip */ margin-left: 0.5em; /* @noflip */ text-align: right; width: auto; } /* In navboxes, the show/hide button balances the v·d·e links from [[Template:Navbar]], so they need to be the same width. */ .navbox .collapseButton { width: 6em; } /** == Messagebox == */ /* Berbagai ''style'' "messagebox" */ .messagebox { border: 1px solid var(--border-color-base); background-color: var(--background-color-neutral-subtle); width: 80%; margin: 0 auto 1em auto; padding: .2em; text-align: justify; } .messagebox.merge { border: 1px solid #cf9fff; background-color: #f5edf5; text-align: center; } .messagebox.cleanup { border: 1px solid #9f9fff; background-color: #efefff; text-align: center; } .messagebox.standard-talk { border: 1px solid #c0c090; background-color: #f8eaba; } /* Standard Navigationsleisten, aka box hiding thingy from .de. Documentation at [[Wikipedia:NavFrame]]. */ div.NavFrame { margin: 0; padding: 4px; border: 1px solid #aaa; text-align: center; border-collapse: collapse; font-size: 95%; } div.NavFrame + div.NavFrame { border-top-style: none; border-top-style: hidden; } div.NavPic { background-color: #fff; margin: 0; padding: 2px; /* @noflip */ float: left; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; background-color: #ccf; position: relative; } div.NavFrame p, div.NavFrame div.NavContent, div.NavFrame div.NavContent p { font-size: 100%; } div.NavEnd { margin: 0; padding: 0; line-height: 1px; clear: both; } a.NavToggle { position: absolute; top: 0; /* @noflip */ right: 3px; font-weight: normal; font-size: 90%; } /** == CommonTicker == CSS untuk CommonTickers */ /* CommonsTicker styles */ .tickerList ul, .tickerList ul li { list-style: none; text-indent:-2em; margin-left:2em; text-align:left; } .tickerList ul ul, .tickerList ul ul li { list-style: none; text-indent:0; margin-left:1.5em; text-align:left; } .tickerDiffLink { } /* diff links in ticker */ .tickerMiscLink { } /* misc links in ticker */ .tickerUsage { font-size:80%; } /* ticker usage list */ .tickerAction_deleted:before { content:" HAPUS "; color: #FF0000; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_deletedRev:before { content:" HAPUSREV "; color: #FFC0CB; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replaced:before { content:" GANTI "; color: #FF00FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_replacedOwn:before { content:" GANTI+ "; color: #CC88FF; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedTag:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedTag:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedBad:before { content:" +TAG "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedBad:before { content:" -TAG "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_addedGood:before { content:" +OK "; color: #00BB00; font-family:monospace; font-weight:bold; font-size:100%; } .tickerAction_removedGood:before { content:" -OK "; color: #FF8800; font-family:monospace; font-weight:bold; font-size:100%; } .tickerEntry_deleted { } /* entry for image deletion */ .tickerEntry_replaced { } /* entry for image replacement */ .tickerEntry_tagged { } /* entry for adding/removing problem tags */ .tickerEntry_redir { } /* entry for critical redirection (fot tag redirects) */ .tickerEntry_recat { } /* entry for critical re-categorization (for tag categories) */ .tickerEntry_notify { } /* entry for global notifications */ .tickerEntry_changed { } /* entry for generic change */ /*.tickerAction_deleted { background:#FAA; } /* action marker for image deletion */ /*.tickerAction_replaced { background:#FED; } /* action marker for image replacement */ /*.tickerAction_deletedRev { background:#FDD; } /* action marker for revision deletion */ /*.tickerAction_replacedOwn { background:#FFF4EE; } /* action marker for image replacement by uploader */ /*.tickerAction_addedBad { background:#FDD; } /* action marker for adding problem markers */ /*.tickerAction_removedBad { background:#DFD; } /* action marker for removing problem markers */ /*.tickerAction_addedGood { background:#DFD; } /* action marker for adding license markgers (for tag categories) */ /*.tickerAction_removedGood { background:#FDD; } /* action marker for removing license markers (for tag categories) */ .tickerMinorEntry { color:#666; } /* minor entry */ .tickerMinorEntry a, .tickerMinorEntry a:link, .tickerMinorEntry a:visited { color:#669; } #bodyContent .tickerMinorEntry a.extiw, #bodyContent .tickerMinorEntry a.extiw:link, #bodyContent .tickerMinorEntry a.extiw:visited { color:#669; } .tickerTemplateEntry { font-weight: bold; } /* entry applies to a template used by multiple images */ .tickerSubEntry { } /* sub-entry for multi-image entry */ /** == Lain-lain == CSS untuk berbagai jenis style */ #p-cactions #ca-edittop a { padding-left: .4em; padding-right: .4em; } /** [[Template:Coor title dm]] **/ #coordinates { position:absolute; z-index:1; border:none; background:none; right:30px; top:5.2em; float:right; margin:0.0em; padding:0.0em; line-height:1.5em; text-align:right; text-indent:0; font-size:85%; text-transform:none; white-space:nowrap; } /* [[Template:Disambig]] */ #disambigbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* [[Template:Spoiler]] */ #spoiler { border-top: 2px solid #ddd; border-bottom:2px solid #ddd; } /* [[Wikipedia:Artikel bagus]], for positioning icons at top-right */ div.topicon { position:absolute; z-index:100; top:10px; display: block !important; } /** [[Wikipedia:Kotak pengguna]] **/ .userboxdark a, .userboxdark a:visited, .userboxdark a:active { color: #ccc; } /* == Daftar isi == ''Style'' untuk variasi daftar isi: * '''horizontal''': daftar isi horizontal. Contoh penggunaan: <code><nowiki><div class="horizontal">__TOC__</div></nowiki></code>. * '''nonumtoc''': tanpa nomor. Contoh penggunaan: <code><nowiki><div class="notocnum">__TOC__</div></nowiki></code>. * '''toclimit-x''': membatasi tampilan hanya sampai level ke-x. Contoh penggunaan: <code><nowiki><div class="toclimit-3">__TOC__</div></nowiki></code>, judul subbagian tingkat 1 (tag h2), tingkat 2 (tag h3) tidak ditampilkan. */ .horizontal ul { padding: 0; margin: 0; } .horizontal li { padding: 0 0.6em 0 0.4em; display: inline; border-right: 1px solid; } .horizontal li:last-child { border-right: none; } .nonumtoc .tocnumber { display:none; } .nonumtoc #toc ul, .nonumtoc .toc ul { line-height: 1.5em; list-style: none; margin: .3em 0 0; padding: 0; } .nonumtoc #toc ul ul, .nonumtoc .toc ul ul { margin: 0 0 0 2em; } .toclimit-2 .toclevel-2 {display:none;} .toclimit-3 .toclevel-3 {display:none;} .toclimit-4 .toclevel-4 {display:none;} .toclimit-5 .toclevel-5 {display:none;} .toclimit-6 .toclevel-6 {display:none;} .toclimit-7 .toclevel-7 {display:none;} /* Cell sizes for ambox/tmbox/imbox/cmbox/ombox/fmbox/dmbox message boxes */ th.mbox-text, td.mbox-text { /* The message body cell(s) */ border: none; padding: 0.25em 0.9em; /* 0.9em left/right */ width: 100%; /* Make all mboxes the same width regardless of text length */ } td.mbox-image { /* The left image cell */ border: none; padding: 2px 0 2px 0.9em; /* 0.9em left, 0px right */ text-align: center; } td.mbox-imageright { /* The right image cell */ border: none; padding: 2px 0.9em 2px 0; /* 0px left, 0.9em right */ text-align: center; } td.mbox-empty-cell { /* An empty narrow cell */ border: none; padding: 0px; width: 1px; } /* Article message box styles */ table.ambox { margin: 0px 10%; /* 10% = Will not overlap with other elements */ border: 1px solid #aaa; border-left: 10px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } table.ambox + table.ambox { /* Single border between stacked boxes. */ margin-top: -1px; } .ambox th.mbox-text, .ambox td.mbox-text { /* The message body cell(s) */ padding: 0.25em 0.5em; /* 0.5em left/right */ } .ambox td.mbox-image { /* The left image cell */ padding: 2px 0 2px 0.5em; /* 0.5em left, 0px right */ } .ambox td.mbox-imageright { /* The right image cell */ padding: 2px 0.5em 2px 0; /* 0px left, 0.5em right */ } table.ambox-notice { border-left: 10px solid #1e90ff; /* Blue */ } table.ambox-speedy { border-left: 10px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ambox-delete { border-left: 10px solid #b22222; /* Red */ } table.ambox-content { border-left: 10px solid #f28500; /* Orange */ } table.ambox-style { border-left: 10px solid #f4c430; /* Yellow */ } table.ambox-move { border-left: 10px solid #9932cc; /* Purple */ } table.ambox-protection { border-left: 10px solid #bba; /* Gray-gold */ } /* Image message box styles */ table.imbox { margin: 4px 10%; border-collapse: collapse; border: 3px solid #1e90ff; /* Default "notice" blue */ background: #fbfbfb; } .mbox-inside .imbox { /* For imboxes inside other templates. */ margin: 4px; } .imbox .mbox-text .imbox { /* For imboxes inside imbox-text cells. */ margin: 0 -0.5em; /* 0.9 - 0.5 = 0.4em left/right. */ } table.imbox-notice { border: 3px solid #1e90ff; /* Blue */ } table.imbox-speedy { border: 3px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.imbox-delete { border: 3px solid #b22222; /* Red */ } table.imbox-content { border: 3px solid #f28500; /* Orange */ } table.imbox-style { border: 3px solid #f4c430; /* Yellow */ } table.imbox-move { border: 3px solid #9932cc; /* Purple */ } table.imbox-protection { border: 3px solid #bba; /* Gray-gold */ } table.imbox-license { border: 3px solid #88a; /* Dark gray */ background: #f7f8ff; /* Light gray */ } table.imbox-featured { border: 3px solid #cba135; /* Brown-gold */ } /* Category message box styles */ table.cmbox { margin: 3px 10%; border-collapse: collapse; border: 1px solid #aaa; background: #DFE8FF; /* Default "notice" blue */ } table.cmbox-notice { background: #D8E8FF; /* Blue */ } table.cmbox-speedy { margin-top: 4px; margin-bottom: 4px; border: 4px solid #b22222; /* Red */ background: #FFDBDB; /* Pink */ } table.cmbox-delete { background: #FFDBDB; /* Red */ } table.cmbox-content { background: #FFE7CE; /* Orange */ } table.cmbox-style { background: #FFF9DB; /* Yellow */ } table.cmbox-move { background: #E4D8FF; /* Purple */ } table.cmbox-protection { background: #EFEFE1; /* Gray-gold */ } /* Other pages message box styles */ table.ombox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #aaa; /* Default "notice" gray */ background: var(--background-color-neutral-subtle); } table.ombox-notice { border: 1px solid #aaa; /* Gray */ } table.ombox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.ombox-delete { border: 2px solid #b22222; /* Red */ } table.ombox-content { border: 1px solid #f28500; /* Orange */ } table.ombox-style { border: 1px solid #f4c430; /* Yellow */ } table.ombox-move { border: 1px solid #9932cc; /* Purple */ } table.ombox-protection { border: 2px solid #bba; /* Gray-gold */ } /* Talk page message box styles */ table.tmbox { margin: 4px 10%; border-collapse: collapse; border: 1px solid #c0c090; /* Default "notice" gray-brown */ background: #f8eaba; } .mediawiki .mbox-inside .tmbox { /* For tmboxes inside other templates. The "mediawiki" */ margin: 2px 0; /* class ensures that this declaration overrides other */ width: 100%; /* For Safari and Opera */ /* styles (including mbox-small above) */ } .mbox-inside .tmbox.mbox-small { /* "small" tmboxes should not be small when */ line-height: 1.5em; /* also "nested", so reset styles that are */ font-size: 100%; /* set in "mbox-small" above. */ } table.tmbox-speedy { border: 2px solid #b22222; /* Red */ background: #fee; /* Pink */ } table.tmbox-delete { border: 2px solid #b22222; /* Red */ } table.tmbox-content { border: 2px solid #f28500; /* Orange */ } table.tmbox-style { border: 2px solid #f4c430; /* Yellow */ } table.tmbox-move { border: 2px solid #9932cc; /* Purple */ } table.tmbox-protection, table.tmbox-notice { border: 1px solid #c0c090; /* Gray-brown */ } /* Disambig and set index box styles */ table.dmbox { clear: both; margin: 0.9em 1em; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; background: transparent; } /* Footer and header message box styles */ table.fmbox { clear: both; margin: 0.2em 0; width: 100%; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); /* Default "system" gray */ } table.fmbox-system { background: var(--background-color-neutral-subtle); } table.fmbox-warning { border: 1px solid #bb7070; /* Dark pink */ background: #ffdbdb; /* Pink */ } table.fmbox-editnotice { background: transparent; } /* Div based "warning" style fmbox messages. */ div.mw-warning-with-logexcerpt, div.mw-lag-warn-high, div.mw-cascadeprotectedwarning, div#mw-protect-cascadeon { clear: both; margin: 0.2em 0; border: 1px solid #bb7070; background: #ffdbdb; padding: 0.25em 0.9em; } /* Div based "system" style fmbox messages. Used in [[MediaWiki:Noarticletext]] and [[MediaWiki:Readonly lag]]. */ div.mw-lag-warn-normal, div.noarticletext, div.fmbox-system { clear: both; margin: 0.2em 0; border: 1px solid #aaa; background: var(--background-color-neutral-subtle); padding: 0.25em 0.9em; } /* These mbox-small classes must be placed after all other ambox/tmbox/ombox etc classes. "body.mediawiki" is so they override "table.ambox + table.ambox" above. */ body.mediawiki table.mbox-small { /* For the "small=yes" option. */ clear: right; float: right; margin: 4px 0 4px 1em; width: 238px; font-size: 88%; line-height: 1.25em; } body.mediawiki table.mbox-small-left { /* For the "small=left" option. */ margin: 4px 1em 4px 0; width: 238px; border-collapse: collapse; font-size: 88%; line-height: 1.25em; } /* Styling for citations */ span.citation, cite { font-style: normal; word-wrap: break-word; } /* For linked citation numbers and document IDs, where the number need not be shown on a screen or a handheld, but should be included in the printed version */ @media screen, handheld { span.citation *.printonly { display: none; } } /* Logo pour la page d'accueil */ .fondlogo { background:url("//upload.wikimedia.org/wikipedia/commons/0/08/WiktionaryFr-barre-accueil.png"); } #HalamanBaru { background:url(//upload.wikimedia.org/wiktionary/fi/e/ef/H%C3%ACnh_n%E1%BB%81n_Trang_Ch%C3%ADnh.jpg) no-repeat top right; background-position: bottom left; background-color: #f9f9fb; color: black; border: 1px solid #cccccc; padding:20px 7px 7px 7px; margin-bottom: 20px; } #ca-edit a { background: #00C !important; color: white !important; font-weight: bold !important; } div.NavFrame { border:none; } div.NavFrame div.NavHead { height: 1.6em; font-weight: bold; position: relative; min-height: 1.6em; padding-left: 10px; border-bottom: 1px solid #EAEAEA; background-color: transparent; background-image: url(//upload.wikimedia.org/wiktionary/ko/9/96/BGImage_a.jpg); background-repeat: repeat-x; } span.NavToggle { cursor: pointer; float: right; font-weight: normal; padding: 0 3px; font-size: 90%; border-top: 1px solid var(--border-color-muted); border-right: 1px solid var(--border-color-base); border-bottom: 1px solid var(--border-color-base); border-left: 1px solid var(--border-color-muted); background-color:var(--background-color-neutral-subtle); } .translationtargetstar{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: 0px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstar:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -24px 60%;} .translationtargetstarchecked{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -48px 60%;position:absolute;margin-top:3px;margin-left:-17px;cursor:pointer;width:16px;height:16px;} .translationtargetstarchecked:hover{background-image: url(/w/skins/Vector/images/watch-icons.png); background-position: -72px 60%;} #languageLinks .unselectedTab, #languageLinks .selectedTab { line-height:1.5em; } #languageLinks .selectedTab a{ cursor:pointer; padding:6px; font-size:19px; color:#333; background-color:#fff; margin-bottom:-3px; margin-right:-6px; position:relative; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #languageLinks .unselectedTab a { cursor:pointer; padding:6px; font-size:16px; color:#AAA; background-color:#F3F3F3; margin-bottom:-3px; margin-left:15px; margin-right:-5px; display:block; border-left:1px solid #AAA; border-top:1px solid #AAA; border-bottom:1px solid #AAA; white-space:nowrap; } #tabstable{ clear:both; } #languageLinks tr td{ padding:0px; } tr td.languageContainer{ padding-left:8px; padding-bottom:10px; padding-right:8px; border:1px solid #AAA; vertical-align:top; width:100%; } .editlangsection{ margin-top:-13px; margin-right:5px; border:1px solid #AAA; margin-bottom:-2px; border-bottom-width:0px; -webkit-border-top-left-radius:5px; -webkit-border-top-right-radius:5px; -moz-border-radius-topleft:5px; -moz-border-radius-topright:5px; border-top-left-radius:5px; border-top-right-radius:5px; color:white; line-height:14px; font-size:12px; padding:0px 7px; text-align:center; clear:both; background-color:white; } a.mw-echo-alert { text-transform:none; } /* Main Page heading removal */ .page-Wiktionary_Halaman_Utama #lastmod, .page-Wiktionary_Halaman_Utama #siteSub, .page-Wiktionary_Halaman_Utama #contentSub, /* .page-Wiktionary_Halaman_Utama #siteNotice, */ .page-Wiktionary_Halaman_Utama h1.firstHeading, .page-Wiktionary_Halaman_Utama #firstHeading { display: none; /* NOT important */ } /* Character sample untuk tabel-tabel [[Lampiran:Unicode]] */ .character-sample { display: inline-block; min-width: 1em; font-size: 200%; text-align: center; } /* From old enwikt */ /* Shortcut box */ .shortcut-box, .category-edit-box { border: 1px solid #aaa; color: black; background: var(--background-color-neutral-subtle); margin: 0 0 .5em 1em; text-align: center; padding: 5px; float: right; clear: both; font-weight: bold; font-size: smaller; } /* default style for mentions outside of "form of" definitions. */ .mention { font-style: italic; } .mention[lang$="-pro"], .mention i, i .mention { font-style: normal; } /* default style for "form of" definitions */ .use-with-mention, .form-of-definition { font-style: italic; } .use-with-mention i { font-style: normal; } .form-of-definition-link { font-style: normal; } .use-with-mention .mention, .form-of-definition-link .mention { font-style: normal; font-weight: bold; } /* See also */ .disambig-see-also, .disambig-see-also-2 { padding-left: 2em; } c6b18c2efh9r05xs5z7dtxwzri0fnsv Ogos 0 14509 1348961 1133399 2026-04-08T15:31:30Z Swarabakti 18192 1348961 wikitext text/x-wiki =={{bahasa|ms}}== {{wikipedia|lang=ms}} {{kepala|ms|alt=اوݢوس}} : {{pemenggalan|ms|Ogos}} {{AFI|ms|/ɔgos/}} {{-etimologi-}} : Dari [[bahasa Inggris]] ''[[August]]'' {{-n-|ms}} # [[Agustus]] tlps2fcqdh6wn7s6uzyhy8f4e2etuvm 1348962 1348961 2026-04-08T15:32:17Z Swarabakti 18192 /* {{bahasa|ms}} */ 1348962 wikitext text/x-wiki =={{bahasa|ms}}== {{wikipedia|lang=ms}} {{kepala|ms|alt=اوݢوس}} : {{pemenggalan|ms|Ogos}} {{AFI|ms|/ɔgos/}} {{-etimologi-}} : {{dipinjam dari+|en|August}} {{-n-|ms}} # [[Agustus]] rdcm31g6wkqobynvkcv04ohry9hu9kc 1348963 1348962 2026-04-08T15:32:28Z Swarabakti 18192 1348963 wikitext text/x-wiki =={{bahasa|ms}}== {{wikipedia|lang=ms}} {{kepala|ms|alt=اوݢوس}} : {{pemenggalan|ms|Ogos}} {{AFI|ms|/ɔgos/}} {{-etimologi-}} : {{dipinjam dari+|ms|en|August}}. {{-n-|ms}} # [[Agustus]] etkkp4j2bcdzez9sbuane6el1sy8mi1 1348964 1348963 2026-04-08T15:32:58Z Swarabakti 18192 1348964 wikitext text/x-wiki =={{bahasa|ms}}== {{wikipedia|lang=ms}} {{kepala|ms|alt=اوݢوس}} : {{pemenggalan|ms|Ogos}} {{AFI|ms|/ɔgos/}} {{-etimologi-}} : {{bor+|ms|en|August}}. {{-n-|ms}} # [[Agustus]] 4vbc8bnvjovomfn9pmkkhoqsqz6cn8g butuh 0 18230 1348956 1284827 2026-04-08T13:55:24Z Losstreak 36825 1348956 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-v-|id}} # [[perlu]] #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih '''butuh''' sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-etimologi-}} * Berasal dari ''[[bahasa Jawa Kuno]]'' ''"butuh"'' 'dalam kesukaran, dalam kesulitan, dalam kebingungan' {{-rujukan-}} * Zoetmulder, P.J., dan Robson, S.O. (2006). Kamus Jawa Kuna-Indonesia. (Darusuprapta dan Sumarti Suprayitna, Penerjemah). Jakarta: Gramedia Pustaka Utama. * Stevens, A. M., Schmidgall-Tellings, A. E., & American Indonesian Chamber of Commerce. (2004). A comprehensive Indonesian-English dictionary (Second edition). Ohio University Press. http://sealang.net/indonesia/dictionary.htm * {{R:KBBI Daring}} {{-turunan-|id}} *[[kebutuhan]] =={{bahasa|bjn}}== {{kepala|bjn}} {{-n-|bjn}} *[[alat kelamin lelaki]]/[[penis]] {{-turunan-}} * [[kapala butuh]] (glans penis) * [[butuh rakungan]] {{-sinonim-}} * [[peler]]---> Dialek Banjar Kuala * [[palir]]---> Dialek Banjar Hulu =={{bahasa|jv}}== {{kepala|jv}} {{-v-|jv}} {{jvword|k=butuh|n=butuh}} # {{ngoko}} {{label|jv|krama}} butuh (perlu) =={{malaysia}}== {{-n-|jv}} * {{kas}} [[penis]] {{-terjemahan-}} {{t-atas}} *{{mg}}: [[vutu]] *{{jv}}: [[kontol]] *{{bjn}}: butuh *{{rej}}: [[botoak]] {{t-bawah}} to28gp6s2u7pq1ei5o3m6x0bl8afdc1 pu 0 19862 1349121 1290105 2026-04-08T19:10:44Z Swarabakti 18192 1349121 wikitext text/x-wiki =={{bahasa|kaw}}== {{kepala|kaw}} {{-etimologi-}} {{clipping|kaw|ḍapunta}}. {{doublet|kaw|mpu}}. {{cog+|sa|rājputa|tr={{l|sa|राजपुत्र|tr=-}}|t=putra raja; pangeran}}. {{-n-|kaw}} # {{l|id|empu|t=gelar kehormatan klasik Jawa}} {{-turunan-}} {{-frasa-|kaw}} {{-ragam-}} * {{alter|kaw|ḍapu|ḍapuṅku|ḍapunta}} {{-rujukan-}} {{R:OJED}} t98lqta1cxb4rfkqsi6nbimhw2t5npf 1349122 1349121 2026-04-08T19:11:19Z Swarabakti 18192 1349122 wikitext text/x-wiki =={{bahasa|kaw}}== {{kepala|kaw}} {{-ragam-}} * {{alter|kaw|ḍapu|ḍapuṅku|ḍapunta}} {{-etimologi-}} {{clipping|kaw|ḍapunta}}. {{doublet|kaw|mpu}}. {{cog+|sa|rājputa|tr={{l|sa|राजपुत्र|tr=-}}|t=putra raja; pangeran}}. {{-n-|kaw}} # {{l|id|empu|t=gelar kehormatan klasik Jawa}} {{-rujukan-}} * {{R:OJED}} bl14zudxhst2na64brjglc2ii20b4lm 1349127 1349122 2026-04-08T19:18:28Z Swarabakti 18192 /* {{bahasa|kaw}} */ 1349127 wikitext text/x-wiki =={{bahasa|kaw}}== {{kepala|kaw}} {{-ragam-}} * {{alter|kaw|ḍapu|ḍapuṅku|ḍapunta}} {{-etimologi-}} : {{clipping|kaw|ḍapunta}}. {{doublet|kaw|mpu}}. {{cog+|sa|rājputa|tr={{l|sa|राजपुत्र|tr=-}}|t=putra raja; pangeran}}. {{-n-|kaw}} # {{l|id|empu|t=gelar kehormatan klasik Jawa}} {{-rujukan-}} * {{R:OJED}} 87h2vnmwk2b16cy6scyg08vyu1lgtpl α 0 19954 1349162 1051424 2026-04-09T05:43:17Z ~2026-21887-62 47532 α 1349162 wikitext text/x-wiki Wann ==Translingua== ===Lambang=== '''α''' # Huruf kecil dari huruf [[alpha]], huruf pertama dari [[alfabet Yunani]] moderen. # ''elektrodinamika'' [[Konstanta struktur halus]]. # ''mekanika klasik'' Melambangkan [[percepatan sudut]]. # ''kimia'' Digunakan dalam [[penamaan rumus molekul kimia]]. # ''bintang'' Digunakan untuk membedakan kecemerlangan [[bintang]] dalam suatu [[konstelasi]], sebagai contoh [[α-Centauri]]. # Digunakan dalam penandaan (''marking scheme''): α, β, γ or α+, α, α-, β, dsb; misalnya saja dalam sudut suatu bangun geometri. '''α'''' # Angka pertama dalam [[w:Angka Yunani|angka Yunani]]. ''',α''' # Angka 1000 dalam angka Yunani [[Kategori:Bahasa Yunani]] lwj5hc5ww1rnlsiyoc7itjubuux4x8p akhirnya 0 21110 1348954 1137314 2026-04-08T13:51:34Z Losstreak 36825 1348954 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|akhir|kelas=adv}} # kesudahannya: <br />''akhirnya kita juga yang harus menderita rugi'' #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, '''akhirnya''' aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} * {{fr}} : {{trad-|fr|finalement}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} f0ttb6dlpunp2f8tulb9blgu1z13vxn apel 0 21372 1349164 1348059 2026-04-09T08:03:34Z Swarabakti 18192 1349164 wikitext text/x-wiki =={{bahasa|id}}== [[Berkas:Red Apple.jpg|thumb|apel (makna 2)]] {{kepala|id}} : {{AFI|id|/apəl/}} {{-etimologi-}} : Pinjaman dari bahasa Belanda {{sebut|nl|appel|t=apel}}, dari bahasa Belanda Kuna ''*appel'', dari bahasa Proto-Jermanik Barat *applu, dari bahasa Proto-Jermanik *aplaz, dari bahasa Proto-Indo-Eropa {{sebut|ine-pro|*h₂ébōl|t=apel, pohon apel}}. {{-n-|id}} # pohon berbuah bulat dengan daging berair dan kulit lunak yang berwarna hijau, kekuningan, atau kemerahan; {{species|Malus domestica}} # buah dari pohon apel {{-terjemahan-}} {{t-atas}} * {{bhs|fi}}: {{t|fi|omena}} * {{bhs|en}}: {{t|en|apple}} * {{bhs|fr}}: {{t|fr|pomme}} * {{bhs|pt}}: {{t|pt|maçã|f}} * {{bhs|ru}}: {{t|ru|яблоко|n}} * {{bhs|es}}: {{t|es|manzana|f}} {{t-bawah}} {{kepala|id|num=1}} : {{AFI|id|/apɛl/}} {{-etimologi-}} : Pinjaman dari bahasa Belanda {{sebut|nl|appel|t=upacara, banding}}, dulunya dieja {{sebut|nl|appèl}}, dari bahasa Belanda Pertengahan ''appeel'', dari bahasa Prancis Kuna ''apel''. {{-v-|id}} # {{label|id|hukum}} naik banding kepada pengadilan yang lebih tinggi; permohonan pemeriksaan ulang pada pengadilan tingkat kedua (pengadilan tinggi) terhadap keputusan pengadilan tingkat pertama (pengadilan negeri) # {{label|id|militer}} wajib hadir dalam suatu upacara resmi (bersifat kemiliteran) untuk diketahui hadir tidaknya atau untuk mendengar amanat # {{label|id|cakapan}} mengunjungi pacar {{-n-|id}} # [[upacara]] {{-turunan-}} {{kotak|id|title=Gabungan kata |apel bendera |apel besar |apel paripurna |apel siaga |naik apel }} {{kepala|id|num=2}} {{-n-|id}} # kepala kampung; bawahan kepala desa {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:id:Buah]] kaninbzpwy2i52yp7eqgp44sa0otws7 taruhan 0 21767 1349192 1129299 2026-04-09T10:16:07Z Sofi Solihah 23681 1349192 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # uang dsb yang dipasang dalam perjudian; tagan # tanggungan uang dsb; cagar # yang dipertaruhkan (kalau perlu dikorbankan dsb): <br />''kalau engkau tidak berhasil, nyawalah taruhannya'' # yang disuruh simpan (rawat, selenggarakan, dsb); titipan; rawatan, dsb: <br />''ketika peti taruhannya dibuka, terperanjatlah orang-orang melihat banyaknya surat yang diikat dengan sutra berwarna-warni'' # (pakaian, cincin, permadani, dsb) yang hanya dipakai apabila ada keperluan (pesta, perayaan, dsb) # hadiah yang dijanjikan (kepada mereka yang dapat menangkap penjahat dsb) # {{cak}} bertaruh #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Sedangkan bagi pemain yang kurang mahir dalam melemparkan akan banyak kehilangan karet gelang sebagai alat '''taruhan'''. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Sedangkan%20bagi%20pemain%20yang%20kurang%20mahir%20dalam%20melemparkan%20akan%20banyak%20kehilangan%20karet%20gelang%20sebagai%20alat%20taruhan. }} {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|bet}} * {{fr}} : {{trad-|fr|pari}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} pf0nz269orxm0h8fkkubptzjut1u6up perbandingan 0 21829 1349177 1232813 2026-04-09T09:41:23Z Sofi Solihah 23681 1349177 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan per-an|banding|kelas=n}} # perbedaan (selisih) kesamaan: <br />''perbandingan pasukan musuh dengan pasukan kita adalah lima lawan dua'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Dari '''perbandingan''' jumlah peserta jelas sekali bahwa regu A kalah dan regu B menang. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Dari%20perbandingan%20jumlah%20peserta%20jelas%20sekali%20bahwa%20regu%20A%20kalah%20dan%20regu%20B%20menang. }} # persamaan; ibarat: <br />''perbandingan bulan dengan putri malam kurang tepat'' # pedoman pertimbangan: <br />''pengalaman dapat dijadikan perbandingan dalam memecahkan masalah rumah tangga'' {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|comparison}} * {{fr}} : {{trad-|fr|comparaison}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} afyfchcy8wxf823mtet4nu1i8peir6n kunci 0 22640 1348917 1341626 2026-04-08T12:05:26Z Losstreak 36825 1348917 wikitext text/x-wiki [[Berkas:Key_ring.jpg|thumb|beberapa jenis kunci]] =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # [[alat]] dari [[logam]] untuk mem[[buka]] atau untuk me[[tutup|nutup]] pintu, peti, dsb, dengan cara memasukkannya ke dalam lubang yang ada pada induk kunci #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya '''kunci''' cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} # alat yang digunakan untuk membuka dan memasang [[sekrup]], dsb # alat untuk menghidupkan atau menjalankan mesin ([[mobil]], dsb) # sendi (pertemuan) tulang # jawaban yang disediakan atas pertanyaan ujian, dsb {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} *{{id}}: {{t+|id|kunci}} *{{gor}}: {{t+|gor|u'unti}} *{{en}}: {{trad-|en|key}} *{{fr}}: {{trad-|fr|clé}}, {{trad-|fr|clef}} {{t-bawah}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|mqg}}== {{kepala|mqg}} :{{suara|mqg|LL-Q12952778 (mqg)-Tamti (Silvitirtasari04)-Kunci.wav}} {{-n-|mqg}} # {{label|mqg|Kutai Adat Lawas}} {{l|id|kunci}} [[Kategori:Edit-a-thon WikiKathā Maret 2026]] gr32k7k97tfy598zu35n5gzecolsevj kuat 0 23030 1349023 1333536 2026-04-08T17:06:50Z Sofi Solihah 23681 1349023 wikitext text/x-wiki [[File:Kuat.webm|thumb|250px|start=1|end=4|Bahasa isyarat kata "Kuat" ]] =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # banyak tenaga # tahan; awet # tidak mudah goyah #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Permainan ini memerlukan daya berfikir yang '''kuat''', sehingga anak - anak kecil jarang dan hampir tidak pernah diikut sertakan. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Permainan%20ini%20memerlukan%20daya%20berfikir%20yang%20kuat%2C%20sehingga%20anak%20%2D%20anak%20kecil%20jarang%20dan%20hampir%20tidak%20pernah%20diikut%20sertakan. }} # ketat # kencang # berat # keras; nyaring # erat # mampu dan kuasa # mempunyai keunggulan; cakap {{-etimologi-}} Dari {{bor|id|ar|عقُوَّة|t=kekuasaan, tenaga, daya}}. {{-rujukan-}} * {{R:KBBI Daring}} {{-turunan-|id}} {{-antonim-|id}} * {{l|id|lemah}} {{-terjemahan-}} {{t-atas}} * {{nl}} : {{trad-|nl|sterk}} * {{en}} : {{trad-|en|strong}} * {{pt}} : {{trad-|pt|forte}} * {{fr}} : {{trad-|fr|fort}} {{t-bawah}} [[Kategori:Kata dengan unsur serapan -at]] =={{bahasa|bew}}== {{kepala|bew}} : {{suara|bew|LL-Q33014 (bew)-Pitchrigi-kuat.wav}} {{-v-|bew}} # {{l|id|kuat}} =={{bahasa|su}}== {{kepala|su}} {{-adj-|su}} # {{loma}} memiliki banyak tenaga #: ''manéhna kuat sanajan ditabrak'' #:dia kuat meskipun ditabrak {{-lafal-|su}} * {{suara|su|LL-Q34002 (sun)-Kepadalisna-kuat.wav }} [[Kategori:WikiTutur - Sunda]] [[Kategori:WikiTutur Daring 10 Maret 2024]] =={{bahasa|dun}}== {{kepala|dun}} {{-v-|dun}} # bangun #: '' setiap pita isé kuat pukul opat '' #: setiap pagi ia bangun pukul empat [[Kategori:Barurumba]] [[Kategori:WikiBalalah II]] =={{bahasa|pgu}}== {{kepala|pgu}} {{-a-|pgu}} # kuat #: ''o ngeweka gena mo-kuat-a o kilo mo-litoa ma-ka-ma-golaoka'' #: perempuan itu kuat, mampu mengangkat 50 kilo {{-rujukan-}} * Perangin-Angin, Dalan. (2023). ''[https://penerbit.brin.go.id/press/catalog/view/640/628/14703 Kamus Pagu-Indonesia-Inggris]''. Jakarta: Badan Riset dan Inovasi Nasional. [[Kategori:Edit-a-thon WikiKathā Maret 2026]] g1mwvzwpsjkwror4da25hsgxjz8qgtt gula 0 23056 1349150 1326701 2026-04-09T04:00:48Z Swarabakti 18192 kutipan ganda dari satu sumber 1349150 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # bahan [[pemanis]] dalam bentuk [[padatan]] atau [[butiran]] yang dibuat dari air [[tebu]], [[aren]], atau [[kelapa]] #* {{RQ:Mustikarasa |page= 58 |text= '''Gula''' ini dibuat dari sari tebu, jang setelah disaring lalu dikristalkan dengan dimasak |norm= '''Gula''' ini dibuat dari sari tebu, yang setelah disaring lalu dikristalkan dengan dimasak |url= https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Gula%20ini%20dibuat%20dari%20sari%20tebu%2C%20jang%20setelah%20disaring%20lalu%20dikristalkan%20dengan%20dimasak }} {{-etimologi-}} * Sanskerta ''guḍa'' (गुड) {{-terjemahan-}} {{t-atas}} *{{de}}: {{t+|de|Zucker}} *{{en}}: {{t+|en|sugar}} *{{fr}}: {{t+|fr|sucre}} *{{th}}: {{t+|th|น้ำตาล}} {{t-bawah}} {{id-cat|Food}} =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # [[Gula]] #: ''Nggawa '''gula''' sak kilo' #:Membawa gula satu kilo {{-lafal-|jv}} * {{suara|jv|LL-Q33549 (jav)-Tetheow-gula.wav}} [[Kategori:WikiTutur Daring Umum 11 Februari 2024]] [[Kategori:WikiTutur - Jawa]] =={{bahasa|tes}}== {{kepala|tes}} {{-n-|tes}} # {{l|id|gula}} {{-lafal-|tes}} * {{suara|tes|LL-Q12473479 (tes)-Resmi (Bangrapip)-gula.wav}} [[Kategori:Kopdar WikiTutur 2.0 Jakarta 20 April 2025]] [[Kategori:WikiTutur 2.0 - Tengger]] [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] =={{bahasa|xmm}}== {{kepala|xmm}} : {{suara|xmm|LL-Q9240 (ind)-Manadonese-Gula.wav}} {{-n-|xmm}} # gula, bahan pemanis [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] 33m3pq5ji0n33bd473wyfhw5z4orn4s 1349151 1349150 2026-04-09T04:01:30Z Swarabakti 18192 1349151 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # bahan [[pemanis]] dalam bentuk [[padatan]] atau [[butiran]] yang dibuat dari air [[tebu]], [[aren]], atau [[kelapa]] #* {{RQ:Mustikarasa |page= 58 |text= '''Gula''' ini dibuat dari sari tebu, jang setelah disaring lalu dikristalkan dengan dimasak |norm= '''Gula''' ini dibuat dari sari tebu, yang setelah disaring lalu dikristalkan dengan dimasak |url= https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Gula%20ini%20dibuat%20dari%20sari%20tebu%2C%20jang%20setelah%20disaring%20lalu%20dikristalkan%20dengan%20dimasak }} {{-etimologi-}} * Sanskerta ''guḍa'' (गुड) {{-terjemahan-}} {{t-atas}} * {{bhs|de}}: {{t|de|Zucker}} * {{bhs|en}}: {{t|en|sugar}} * {{bhs|fr}}: {{t|fr|sucre}} * {{bhs|th}}: {{t|th|น้ำตาล}} {{t-bawah}} {{id-cat|Food}} =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # [[Gula]] #: ''Nggawa '''gula''' sak kilo' #:Membawa gula satu kilo {{-lafal-|jv}} * {{suara|jv|LL-Q33549 (jav)-Tetheow-gula.wav}} [[Kategori:WikiTutur Daring Umum 11 Februari 2024]] [[Kategori:WikiTutur - Jawa]] =={{bahasa|tes}}== {{kepala|tes}} {{-n-|tes}} # {{l|id|gula}} {{-lafal-|tes}} * {{suara|tes|LL-Q12473479 (tes)-Resmi (Bangrapip)-gula.wav}} [[Kategori:Kopdar WikiTutur 2.0 Jakarta 20 April 2025]] [[Kategori:WikiTutur 2.0 - Tengger]] [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] =={{bahasa|xmm}}== {{kepala|xmm}} : {{suara|xmm|LL-Q9240 (ind)-Manadonese-Gula.wav}} {{-n-|xmm}} # gula, bahan pemanis [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] brt3ndur9vfiefm7nnz2ihhckp6nqh0 1349152 1349151 2026-04-09T04:02:09Z Swarabakti 18192 1349152 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-etimologi-}} : Sanskerta ''guḍa'' (गुड) {{-n-|id}} # bahan [[pemanis]] dalam bentuk [[padatan]] atau [[butiran]] yang dibuat dari air [[tebu]], [[aren]], atau [[kelapa]] #* {{RQ:Mustikarasa |page= 58 |text= '''Gula''' ini dibuat dari sari tebu, jang setelah disaring lalu dikristalkan dengan dimasak |norm= '''Gula''' ini dibuat dari sari tebu, yang setelah disaring lalu dikristalkan dengan dimasak |url= https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Gula%20ini%20dibuat%20dari%20sari%20tebu%2C%20jang%20setelah%20disaring%20lalu%20dikristalkan%20dengan%20dimasak }} {{-terjemahan-}} {{t-atas}} * {{bhs|de}}: {{t|de|Zucker}} * {{bhs|en}}: {{t|en|sugar}} * {{bhs|fr}}: {{t|fr|sucre}} * {{bhs|th}}: {{t|th|น้ำตาล}} {{t-bawah}} {{id-cat|Food}} =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # [[Gula]] #: ''Nggawa '''gula''' sak kilo' #:Membawa gula satu kilo {{-lafal-|jv}} * {{suara|jv|LL-Q33549 (jav)-Tetheow-gula.wav}} [[Kategori:WikiTutur Daring Umum 11 Februari 2024]] [[Kategori:WikiTutur - Jawa]] =={{bahasa|tes}}== {{kepala|tes}} {{-n-|tes}} # {{l|id|gula}} {{-lafal-|tes}} * {{suara|tes|LL-Q12473479 (tes)-Resmi (Bangrapip)-gula.wav}} [[Kategori:Kopdar WikiTutur 2.0 Jakarta 20 April 2025]] [[Kategori:WikiTutur 2.0 - Tengger]] [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] =={{bahasa|xmm}}== {{kepala|xmm}} : {{suara|xmm|LL-Q9240 (ind)-Manadonese-Gula.wav}} {{-n-|xmm}} # gula, bahan pemanis [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] g5wpdcicd94wt28nib8chla4212mkb1 sulit 0 25055 1348951 1239776 2026-04-08T13:48:39Z Losstreak 36825 1348951 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # tidak mudah; susah (diselesaikan, dikerjakan, dsb.): #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, '''sulit''' kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} #: ''Pekerjaan yang '''sulit''' diselesaikan'' #: ''Rasanya '''sulit''' baginya untuk memberitahukan hal itu kepadamu'' # dalam keadaan yang sukar (genting, gawat, dsb.): #: ''Penghidupan yang '''sulit''' itu dihadapi dengan sabar dan tawakal.'' #: ''Keadaan ekonomi yang makin '''sulit''' # susah dicari; jarang terdapat: #: ''Obat semacam itu '''sulit'''.'' # dirahasiakan (sukar diketahui dsb.); tersembunyi; tidak terang-terangan: #: ''Tempat yang '''sulit''' pun ia tahu.'' #: ''Ia dapat mengetahui hal yang '''sulit'''.'' #: ''Apa yang mereka lakukan itu merupakan perbuatan yang '''sulit'''.'' {{-turunan-|id}} {{-terjemahan-}} {{t-atas|tidak mudah}} * {{en}}: {{t+|en|difficult}}, {{t+|en|hard}}, {{t+|en|complex}} * {{fr}}: {{t+|fr|difficile}}, {{trad-|fr|compliqué}} {{t-bawah}} {{t-atas|keadaan susah}} * {{en}}: {{t+|en|difficult}}, {{t+|en|hard}} * {{fr}}: {{t+|fr|difficile}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 8snxsxrugg070eb0a02eqh70zg6s1uc setiap 0 25067 1348968 1238657 2026-04-08T16:04:13Z Iripseudocorus 40083 Kutipan23 1348968 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan se-|tiap|kelas=num}} # tiap #* {{RQ:Perahu Tulis | page = 132 | author = Balai Bahasa Sumatera Barat | chapter = | text = Terbayang di pikiranku wajah ibu yang kerjanya '''setiap''' pagi mencari pinang di ladang orang, hal yang harus kuubah semestinya. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/144#:~:text=Terbayang%20di%20pikiranku%20wajah%20ibu%20yang%20kerjanya%20setiap%20pagi%20mencari%20pinang%20di%20ladang%20orang%2C%20hal%20yang%20harus%20kuubah%20semestinya. }} {{-sinonim-}} * [[masing-masing]] {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|each}} * {{fr}} : {{trad-|fr|chaque}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} okqkbyd80542xnfkgc4to52x780n0s0 pedas 0 27357 1349145 1232228 2026-04-08T20:46:03Z Alfiyah Rizzy Afdiquni 40651 1349145 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # rasa cabai #* {{RQ:Mustikarasa |page= 59 |text=Rasa pedas disebabkan oleh piperin. Lada hitam lebih banjak mengadung zat ini daripada lada putih. |norm=Rasa pedas disebabkan oleh piperin. Lada hitam lebih banyak mengadung zat ini daripada lada putih. |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/67#:~:text=Rasa%20pedas%20disebabkan%20oleh%20piperin.%20Lada%20hitam%20lebih%20banjak%20mengadung%20zat%20ini%20daripada%20lada%20putih.}} =={{bahasa|btx}}== {{kepala|btx}} {{-adj-|btx}} # cepat #: ''ia pedas galang'' #:dia cepat besar [[Kategori:WikiTutur - Karo]] [[Kategori:WikiTutur Daring 25 Februari 2024]] {{-terjemahan-}} {{t-atas}} * {{bjn}} : {{trad-|ebjn|padas}} * {{en}} : {{trad-|en|spicy}} * {{fr}} : {{trad-|fr|épicé}} {{t-bawah}} t0diilu18sptirmd5duzuavknbc4e7u kurang 0 31703 1349160 1209348 2026-04-09T05:31:04Z Iripseudocorus 40083 Kutipan24 1349160 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} (komparatif: [[lebih kurang]], superlatif: [[paling]] kurang) #belum atau tidak [[cukup]] #:''Tenaganya masih '''kurang''' untuk mengangkat beban.'' #* {{RQ:Perahu Tulis | page = 136 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Yang menyuruh Kemal menasihatimu adalah bapak sendiri, sayangnya Kemal '''kurang''' mampu mengarahkanmu, mungkin ia terlalu keras dan kurang lihai berkata-kata." | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/148#:~:text=%22Yang%20menyuruh%20Kemal%20menasihatimu%20adalah%20bapak%20sendiri%2C%20sayangnya%20Kemal%20kurang%20mampu%20mengarahkanmu%2C%20mungkin%20ia%20terlalu%20keras%20dan%20kurang%20lihai%20berkata%2Dkata.%22 }} #tidak berapa; [[sedikit]] #:''Meskipun telah bekerja keras, penghasilannya masih '''kurang'''.'' {{-adv-|id}} #tidak [[lebih]] dari #:''Banyak pembaca kamus hari ini '''kurang''' dari kemarin.'' #belum atau tidak [[sama]] dengan yang seharusnya #:''Makanannya '''kurang''' pedas.'' {{-prep-|id}} #(untuk menyatakan bilangan, ukuran, dan sebagainya yang) sedikit lagi menjadi bilangan bulat #:''Sekarang jam enam '''kurang''' seperempat.'' {{-antonim-|id}} * [[lebih]] {{-turunan-|id}} * [[kekurangan]] {{-terjemahan-}} {{t-atas|Tidak lebih}} * {{en}} : {{t|en|less}} * {{fr}} : {{t|fr|moins}} * {{sv}} : {{t|sv|mindre}} {{t-bawah}} =={{bahasa|mak}}== {{kepala|mak}} {{-adv-|mak}} /ku.raŋ/ '''ᨀᨘᨑ''' # [[kurang]] ==== Contoh kalimat ==== *'''ᨕᨊᨙ ᨄᨗᨑᨗᨂ ᨀᨘᨑ ᨔᨙᨑᨙ ᨊ ᨔᨗᨒᨚᨔᨗ'''<br>''anne piringa kurang se're silosing''<br>piring ini kurang satu buah selusin ==== Kata turunan ==== * [[a'kurang]] * [[kurangi]] * [[kakurangang]] * [[kurang ajara']] * [[kurang pangngali']] * [[kurang pacce]] * [[kurang siri']] lqydpqgv23n1f6qqe94svda6gxv8qqf merancang 0 34340 1349186 1229881 2026-04-09T09:59:12Z Sofi Solihah 23681 1349186 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|rancang|kelas=v}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Meskipun permainan ini melatih orang berfikir, yaitu '''merancang''' atau mengatur siasat, tetapi masih lebih sederhana kalau dibandingkan dengan permainan catur. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Meskipun%20permainan%20ini%20melatih%20orang%20berfikir%2C%20yaitu%20merancang%20atau%20mengatur%20siasat%2C%20tetapi%20masih%20lebih%20sederhana%20kalau%20dibandingkan%20dengan%20permainan%20catur. }} # mencucukkan rancang ke tanah (untuk tanda, batas, atau untuk mengetahui sesuatu yang ada di dalam tanah) # tampak mencuar (runcing-runcing) {{-terjemahan-}} {{t-atas}} * {{fr}} : {{trad-|fr|projeter}}, {{trad-|fr|planifier}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} cwgnvlxfk9b834benjvqsyo8c8rn97y menjual 0 38087 1349194 1229640 2026-04-09T10:22:31Z Sofi Solihah 23681 1349194 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|jual|kelas=v}} # memberikan sesuatu kepada orang lain untuk memperoleh uang pembayaran atau menerima uang: <br />''ia menjual cincinnya seharga Rp350.000,00'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Selama masih ada orang atau warung yang '''menjual''' karet gelang maka permainan ini kemungkinan akan tetap masih berkembang. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Selama%20masih%20ada%20orang%20atau%20warung%20yang%20menjual%20karet%20gelang%20maka%20permainan%20ini%20kemungkinan%20akan%20tetap%20masih%20berkembang. }} # {{ki}} menggunakan cara-cara jahat untuk kepentingan pribadi: <br />''dengan cara menjual koperasi kantornya, ia berhasil meminjam uang dari bank untuk membangun rumah'' # {{ki}} mengkhianati: <br />''menjual bangsa'' {{-terjemahan-}} {{t-atas|dagang}} *{{de}}: {{t+|de|verkaufen}} *{{en}}: {{t+|en|sell}} *{{fr}}: {{t+|fr|vendre}} *{{ja}}: {{t+|ja|売る}}, {{t+|ja|売却}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} j5py7vnx68x1p3azno8r60ci17z5kgw banjir 0 38826 1349043 1300704 2026-04-08T17:22:48Z Swarabakti 18192 1349043 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-etimologi-}} : {{bor+|id|jv|banjir|t=banjir}}. {{-n-|id}} # berair banyak dan deras, kadang-kadang meluap (tentang kali dan sebagainya) # air yang banyak dan mengalir deras; air bah # peristiwa terbenamnya daratan (yang biasanya kering) karena volume air yang meningkat # (kiasan) datang (ada) banyak sekali {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|flood}} * {{fr}} : {{trad-|fr|inondation}} {{t-bawah}} =={{bahasa|jv}}== {{kepala|jv}} {{-etimologi-}} :{{unknown|jv}} secara pasti. :*Kemungkinan 1, dari {{der|jv|sa|-}}. :*Kemungkinan 2, dari pengimbuhan {{kat-afiks|jv|{{sebut|jv|ba}} + {{sebut|jv|anjir}}}}; bandingkan dengan {{cog|bjn|anjir|t=saluran air, kanal}}. :*Kemungkinan 3, dari pengimbuhan dengan akhiran penanda kesopanan (seperti ''arep'' menjadi ''ajeng'', ''ésuk'' menjadi ''énjing'') dari {{inh|jv|kaw|wah|wāh}}, dari {{inh|jv|poz-pro|*bahaq}}, dari {{inh|jv|map-pro|*baSaq|t=banjir}}. {{-n-|jv}} # {{l|id|banjir}} =={{bahasa|ms}}== {{kepala|ms}} {{-n-|ms}} # {{l|id|banjir}} =={{bahasa|bew}}== {{kepala|bew}} {{-n-|bew}} # {{l|id|banjir}} t3bsjs7mizkrusnvvx0lf8jwc320mpw mengelola 0 38909 1348981 1229329 2026-04-08T16:16:29Z Iripseudocorus 40083 Kutipan23 1348981 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|kelola|kelas=v}} # mengendalikan; menyelenggarakan (pemerintahan dsb) # mengurus (perusahaan, proyek, dsb); menjalankan: <br />''sudah 45 tahun beliau mengelola yayasan yang bergerak dalam bidang pendidikan itu'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Aku mulai '''mengelola''' ladang baruku. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Aku%20mulai%20mengelola%20ladang%20baruku. }} {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|manage}} * {{fr}} : {{trad-|fr|gérer}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} pedlg5n656t1tr0j42fz47cdn4viai7 menyatakan 0 38916 1349176 1328889 2026-04-09T09:37:57Z Sofi Solihah 23681 1349176 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-kan|nyata|kelas=v}} # menerangkan; menjadikan nyata; menjelaskan #:''ucapannya belum '''menyatakan''' siapa di antara mereka yang bersalah'' # menunjukkan; memperlihatkan; menandakan #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Untuk mempercepat proses jalannya permainan, kadang - kadang pemain yang sudah dapat mamastikan akan kalah juga, '''menyatakan''' langsung menyerah dan memulai permainan baru lagi. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Untuk%20mempercepat%20proses%20jalannya%20permainan%2C%20kadang%20%2D%20kadang%20pemain%20yang%20sudah%20dapat%20mamastikan%20akan%20kalah%20juga%2C%20menyatakan%20langsung%20menyerah%20dan%20memulai%20permainan%20baru%20lagi. }} #:''daftar itu '''menyatakan''' betapa banyaknya korban yang jatuh'' # mengatakan; mengemukakan (pikiran, isi hati); melahirkan (isi hati, perasaan, dsb); mempermaklumkan (perang) #:''anak cucunya '''menyatakan''' setuju; ia '''menyatakan''' terima kasihnya kepada pengurus'' {{-terjemahan-}} {{t-atas}} * {{fr}} :{{trad-|fr|afficher}}, {{trad-|fr|affirmer}}, {{trad-|fr|clarifier}}, {{trad-|fr|constater}}, {{trad-|fr|déclarer}}, {{trad-|fr|énoncer}}, {{trad-|fr|exprimer}}, {{trad-|fr|expliquer}} {{trad-|fr|plaider}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} sj1l0aflhorvm42lqwge4pdfyboz268 buah 0 40363 1349137 1335455 2026-04-08T20:04:07Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349137 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # hasil dari [[bunga]] #* {{RQ:Mustikarasa |page=58 |text=Asam kandis jang banjak dipakai di Sumatera tengah, berasal dari '''buah''' jang sekeluarga dengan manggis |norm=Asam kandis yang banjak dipakai di Sumatera tengah, berasal dari '''buah''' yang sekeluarga dengan manggis |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Asam%20kandis%20jang%20banjak%20dipakai%20di%20Sumatera%20tengah%2C%20berasal%20dari%20buah%20jang%20sekeluarga%20dengan%20manggis }} =={{bahasa|bkr}}== {{kepala|bkr}} {{-n-|bkr}} # {{l|id|buah}} [[Kategori:WikiTutur - Bakumpai]] [[Kategori:WikiTutur Kopdar Banjarmasin 30 Juni 2024]] =={{bahasa|knl}}== {{kepala|knl}} {{-lafal-}} * {{suara|knl|LL-Q6389309 (knl)-Mario Manggit (Neyana999)-buah.wav}} {{-n-|knl}} # {{l|id|buah}} [[Kategori:WikiTutur 2.0 - Keninjal]] [[Kategori:Kolaborasi Tim WikiTutur 2.0]] =={{bahasa|mui}}== {{kepala|mui}} {{-n-|mui}} # {{l|id|buah}} #: {{ux|mui|'''buah''' rambutan|'''buah''' rambutan}} {{-lafal-|mui}} * {{suara|mui|LL-Q615660 (mui)-Dpratiwi-buah.wav }} [[Kategori:WikiTutur - Musi]] [[Kategori:WikiTutur Kopdar Palembang 19 Mei 2024]] =={{bahasa|kvb}}== {{kepala|kvb}} : {{suara|kvb|LL-Q6441341_(kvb)-Nugraha_(Djordi_Andai)-buah.wav}} {{-nomina-|kvb}} # {{l|id|asal}} # [[buah]] {{-n-|kvb}} # '''buah belaki'''= angin yang datang setelah musim hujan sebelum musim kemarau, biasanya membantu penyerbukan # '''buah belakong'''= ginjal # '''buah botiy'''= betis bagian belakang # '''buah kepalo'''= buah batu yang berdaging kuning muda kehijau-hijauan untuk dibuat manisan, berbentuk bulat lonjong, dan beralur memanjang, bijinya dibuat bumbu penyedap atau ramuan obat # '''buah sebelik sumpah'''= buah yang dapat dijadikan penangkal berbentuk kalung atau gelang [[Kategori:Edit-a-thon WikiKathā Maret 2026]] =={{bahasa|su}}== {{kepala|su}} {{-n-|su}} # [[mangga.]] # [[buah.]] {{-terjemahan-}} {{t-atas}} * {{en}} : {{trad-|en|fruit}} * {{fr}} : {{trad-|fr|fruit}} {{m}} {{t-bawah}} =={{bahasa|bjn}}== {{kepala|bjn}} {{-lafal-|bjn}} * {{suara|bjn| LL-Q33151 (bjn)-Wadaihangit-buah.wav}} {{-n-|bjn}} # {{l|id|buah}} #: {{ux|bjn|''Pabila jar musim buah kuini di banua?''|Kapan kah kira-kira musim buah Kweni di Kalimantan Selatan?}} [[Kategori:WikiTutur 3.0 - Banjar]] [[Kategori:WikiTutur 3.0 Banjarmasin 15 Februari 2026]] 0f7pkqws71hwpin4ub8tcslwqu3cr9f Kategori:Kata yang belum dituliskan artinya dalam bahasa Indonesia 14 43080 1349136 1070472 2026-04-08T20:02:48Z Andreass972212A 47526 1349136 wikitext text/x-wiki [[Kategori: Wikimedia]] 4k0gz7os8clzt6nup92cb5iss4ydu4g kepentingan 0 45583 1349185 1279830 2026-04-09T09:58:04Z Sofi Solihah 23681 1349185 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ke-an|penting|kelas=n}} # keperluan; kebutuhan: <br />''mendahulukan kepentingan umum'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Tetapi karena peranannya kecil sekali untuk '''kepentingan''' perkembangan permainan atau pendidikan pada umumnya, maka masyarakat tampaknya tidak merasa dirugikan kalau permainan ini tidak berkembang lagi. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Tetapi%20karena%20peranannya%20kecil%20sekali%20untuk%20kepentingan%20perkembangan%20permainan%20atau%20pendidikan%20pada%20umumnya%2C%20maka%20masyarakat%20tampaknya%20tidak%20merasa%20dirugikan%20kalau%20permainan%20ini%20tidak%20berkembang%20lagi. }} # interes {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} p6tt8een6zjgc1mscgfl5cyptr43yrc walaupun 0 47400 1349045 1244547 2026-04-08T17:24:29Z Sofi Solihah 23681 1349045 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-p-|id}} # [[walau]] {{-turunan-|id}} {{-sinonim-}} * [[walaupun demikian]] #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= '''Walaupun''' pengertian cit itu berarti membuat anak cit tersusun berjajar 3 dan kepada pemain yang dapat melakukannya berhak mengambil satu biji milik lawan yang sudah tersusun dalam papan cit, dalam tahap pertama ini ( tahap penyusunan anak cit ) hak mengambil anak cit lawan itu tidak berlaku. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Walaupun%20pengertian%20cit%20itu%20berarti%20membuat%20anak%20cit%20tersusun%20berjajar%203%20dan%20kepada%20pemain%20yang%20dapat%20melakukannya%20berhak%20mengambil%20satu%20biji%20milik%20lawan%20yang%20sudah%20tersusun%20dalam%20papan%20cit%2C%20dalam%20tahap%20pertama%20ini%20(%20tahap%20penyusunan%20anak%20cit%20)%20hak%20mengambil%20anak%20cit%20lawan%20itu%20tidak%20berlaku. }} {{-terjemahan-}} {{t-atas}} * {{id}} : {{t+|id|meski}}, {{t+|id|meskipun}}, {{t+|id|walau}}, {{t+|id|walaupun}} * {{gor}} : {{t+|gor|eleponu}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:Turunan kata walau]] p0gmm3nbjen88vzq271f0ud9wtw51nl salat 0 47920 1348923 1125630 2026-04-08T12:23:32Z Losstreak 36825 1348923 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # {{Isl}} rukun Islam kedua, berupa ibadah kepada Allah Swt., wajib dilakukan oleh setiap muslim mukalaf, dengan syarat, rukun, dan bacaan tertentu, dimulai dengan takbir dan diakhiri dengan salam #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap jadwal. Setelah '''salat''' isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} # doa kepada Allah {{-turunan-|id}} {{-ragam-}} * [[solat]], [[sholat]] {{-terjemahan-}} <!--Anda dapat menyalin templat {{t-atas}} -- {{t-bawah}} di bawah berulang kali untuk masing masing arti kata, masing-masing dibedakan melalui parameter pertamanya (misalkan {{t-atas|arti 1}} dan {{t-atas|arti 2}} dst). Lihat [[Wiktionary:Terjemahan]] untuk panduan membuat lebih dari satu kolom terjemahan--> {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} e57jnijl7f86pn17gt2xkp28zyuie93 semenjak 0 48572 1348971 1237783 2026-04-08T16:07:45Z Iripseudocorus 40083 Kutipan23 1348971 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-prep-|id}} # sejak; mulai dari: <br>''semenjak ibunya meninggal, ia kelihatan murung'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = '''Semenjak''' aku sering diskusi dengan Pak Bidin, semakin terpatri kuat di hatiku untuk merubah profesi ibu sebagai pencari pinang. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Semenjak%20aku%20sering%20diskusi%20dengan%20Pak%20Bidin%2C%20semakin%20terpatri%20kuat%20di%20hatiku%20untuk%20merubah%20profesi%20ibu%20sebagai%20pencari%20pinang. }} {{-turunan-|id}} {{-terjemahan-}} <!--Anda dapat menyalin templat {{t-atas}} -- {{t-bawah}} di bawah berulang kali untuk masing masing arti kata, masing-masing dibedakan melalui parameter pertamanya (misalkan {{t-atas|arti 1}} dan {{t-atas|arti 2}} dst). Lihat [[Wiktionary:Terjemahan]] untuk panduan membuat lebih dari satu kolom terjemahan--> {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:id:Sisipan (em)]] gukt59c7zzad17euai40h27eh4as2an seri 0 48918 1349129 1345291 2026-04-08T19:22:13Z Swarabakti 18192 /* {{bahasa|id}} */ 1349129 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id|num=1}} : {{pemenggalan|id|se|ri}} {{AFI|id|/səri/}} {{-etimologi-}} : Dari {{inh|id|ms|seri}}, dari {{der|id|sa|श्री}}.<ref>Jones, R. (2008) [2007], “seri”, dalam ''Loan-words in Indonesian and Malay'', Indonesian imprints edition, Jakarta* Yayasan Pustaka Obor Indonesia.</ref> {{-n-|id}} # yang [[mulia]]; [[sri]] # [[keelokan]] yang menandakan [[kemuliaan]] # [[cahaya]] atau [[kecerahan]] yang [[menguar]] {{-adj-|id}} # [[elok]]; [[bagus]] {{-turunan-}} {{kotak|id|title=Kata turunan |berseri |berseri-seri |menyerikan |perserian }} {{kotak|id|title=Gabungan kata |seri balai |seri gunung |seri muka |seri panggung |seri pantai |seri wajah }} {{-terjemahan-}} {{t-atas|yang mulia|lihat=sri}} {{t-atas|cahaya}} * {{bahasa|en}}: {{t|en|radiance}} {{t-bawah}} {{kepala|id|num=2}} {{-etimologi-}} : Dari {{inh|id|ms|seri}}, kemungkinan dari {{der|id|jv|-}}. {{-adj-|id}} # [[seimbang]]; sama kuat # [[sepadan]]; tidak [[untung]] dan tidak [[rugi]] {{-terjemahan-}} {{t-atas|sama kuat}} * {{bahasa|en}}: {{t|en|tie}} {{t-bawah}} {{kepala|id|num=3}} {{-n-|id}} # {{ragam bentuk dari|id|sari}} {{-turunan-}} * {{l|id|menyeri}} {{kepala|id|num=1}} : {{pemenggalan|id|se|ri}} {{AFI|id|/seri/}} {{-etimologi-}} : {{bor+|id|nl|serie}}.<ref name="seri">Jones, R. (2008) [2007], “séri”, dalam ''Loan-words in Indonesian and Malay'', Indonesian imprints edition, Jakarta* Yayasan Pustaka Obor Indonesia.</ref> {{-n-|id}} # [[rangkaian]] yang [[berturut-turut]] {{-turunan-}} * {{l|id|berseri}} {{-terjemahan-}} {{t-atas|rangkaian}} * {{bahasa|nl}}: {{t|nl|serie}} * {{bahasa|en}}: {{t|nl|series}} {{t-bawah}} {{kepala|id|num=2}} {{-etimologi-}} : {{bor+|id|en|cherry}}.<ref name="seri"/> {{-n-|id}} # {{ragam bentuk dari|id|ceri}} {{-rujukan-}} <references/> {{-bacaan-}} * {{R:KBBI Daring}} =={{bahasa|mhy}}== {{kepala|mhy}} {{-adj-|mhy}} # [[sama]] =={{bahasa|ms}}== {{kepala|ms|num=1}} {{-n-|ms}} # {{l|id|seri}} {{gloss|yang mulia, keelokan, cahaya}} {{kepala|ms|num=2}} {{-adj-|ms}} # {{l|id|seri}} {{gloss|seimbang, sepadan}} nu0o5x0mrj6iinkftd5rjpz21opqbti sportif 0 49745 1349180 1239495 2026-04-09T09:48:08Z Sofi Solihah 23681 1349180 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-a-|id}} # bersifat kesatria, jujur, dsb.: <br>''jadilah penonton dan pemain yang sportif, jangan emosional'' # tegap; gagah: <br>''sosok mereka pada umumnya sportif'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Yang kalah terpaksa harus menerima kekalahannya dengan secara '''sportif''' serta harus mengakui keunggulan lawannya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Yang%20kalah%20terpaksa%20harus%20menerima%20kekalahannya%20dengan%20secara%20sportif%20serta%20harus%20mengakui%20keunggulan%20lawannya. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} o05ln3v5g8ciow229te1za0ioh9qi3x sumur 0 50074 1349156 1294882 2026-04-09T05:19:06Z Iripseudocorus 40083 Kutipan24 1349156 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # sumber air buatan, dengan cara menggali tanah; perigi: <br>''sumur bor'' #* {{RQ:Perahu Tulis | page = 135 | author = Balai Bahasa Sumatera Barat | chapter = | text = '''Tergesa-gesa''' kupergi ke sumur mengambil wuduk, mungkin dengan berwuduk hatiku menjadi tenang. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Tergesa%2Dgesa%20kupergi%20ke%20sumur%20mengambil%20wuduk%2C%20mungkin%20dengan%20berwuduk%20hatiku%20menjadi%20tenang. }} # lubang yang sengaja dibuat menembus lapisan tanah untuk memperoleh air, minyak, atau gas # lubang hasil pengeboran, baik dalam tahap eksplorasi maupun eksploitasi # {{Geo}} bangunan hidraulis berupa lubang yang digali ke dalam bumi yang memungkinkan penyadapan air secara ekonomis dari akuifer {{-etimologi-}} * Pinjaman dari [[bahasa Jawa]] ''sumur'', dari [[bahasa Jawa Kuno]] ''sumur'' 'sumur' {{-rujukan-}} * Zoetmulder, P.J., dan Robson, S.O. (2006). Kamus Jawa Kuna-Indonesia. (Darusuprapta dan Sumarti Suprayitna, Penerjemah). Jakarta: Gramedia Pustaka Utama. * Zoetmulder, P.J. 1982. Old Javanese-English dictionary. 2 vols. Koninklijk Instituut voor Taal-, Land- en Volkenkunde. 's Gravenhage: Nijhoff. * Wilkinson, R.J. 1959 A Malay-English dictionary (Romanised). 2 vols. London: Macmillan. http://sealang.net/malay/dictionary.htm * Klinkert, H.C. 1892. Nieuw Maleisch-Nederlandsch zawoordenboek, ten behoove van hen, die het Maleisch met Latijnsch karakter beoefenen. Leiden, E.J. Brill. * Gericke, J.F.C. en T. Roorda 1901 Javaansch-Nederlandsch Handwoordenboek. 2 vols. Amsterdam / Leiden. https://www.sastra.org/leksikon * {{R:KBBI Daring}} {{-turunan-|id}} {{-terjemahan-}} <!--Anda dapat menyalin templat {{kotak awal}} -- {{t-bawah}} di bawah berulang kali untuk masing masing arti kata, masing-masing dibedakan melalui parameter pertamanya (misalkan {{kotak awal|arti 1}} dan {{kotak awal|arti 2}} dst). Lihat [[Wiktionary:Terjemahan]] untuk panduan membuat lebih dari satu kolom terjemahan--> {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:jv]] =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} {{jvword|k=sumur|n=sumur}} # {{ngoko}} {{label|jv|krama}} sumur t7jhqdg76s6foyv8hyixkyrxjmu7hwu Templat:-var- 10 55770 1348959 1051735 2026-04-08T15:28:10Z Swarabakti 18192 1348959 wikitext text/x-wiki [[Kategori:Halaman dengan templat usang]]<div style="font-size:120%; margin:10px 0;">[[Berkas:Fairytale viewmag-.png|x16px|link=]] <span title="Variasi dari kata {{PAGENAME}}"><b class="error">Tukar dengan {{temp|-ragam-}}</b></span> </div>{{#ifeq:{{#expr:{{PAGESINCATEGORY:Variasi kata {{PAGENAME}}}}>{{#ifexist:Kategori:Variasi kata {{PAGENAME}}|1|0}}}}|1|<nowiki /> <div class="NavFrame collapsible uncollapsed"> <div class="NavHead" align="left">[[:Kategori:Variasi kata {{PAGENAME}}|Daftar variasi kata {{PAGENAME}}]] ({{#ifexist:Kategori:Variasi kata {{PAGENAME}}|{{#expr:{{PAGESINCATEGORY:Variasi kata {{PAGENAME}}}}-1}}|{{PAGESINCATEGORY:Variasi kata {{PAGENAME}}}}}})</div> <div class="NavContent"> {{col|3}} {{#categorytree:Variasi kata {{PAGENAME}}|hideroot=true|namespaces=-}} {{end-col}} </div></div> }}<noinclude> ---- [[Kategori:Templat umum]] </noinclude> dicwlbb59m5e7xtq39pv22cqm1fh9xa telah 0 61616 1349149 1340403 2026-04-09T01:08:26Z ~2026-21684-76 47529 Suamiku selingkuh dan keluarga suamiku cintanya ya aja keluarga suamiku tidak pernah ngomong kosong aku tidak tahu sifat rekam Suamiku gahib gosipnya sama keluarga besar tapi tidak bilang kosong aku ga tau jadi sedih wajah mulut putih benci suami menipu isyarat beda dengan suka fitnah seperti biasa ngomong bohong jadi tidak jujur 1349149 wikitext text/x-wiki Assalamu'alaikum saya baru pertama mengerti sifat suamiku buruk bohong jadi rahasia tentang tidak bilang jadi fitnah aku tau pernah sifat suami menipu isyarat beda menipu banyak 3 tahun depan nanti diam ku tenang maklum ikhlas suami tidak positif ada negatif terhadap karena suami takut gawet kalah seperti selingkuh cewe siapa dari Indonesia ya buruk menipu sahabat kasih aku menolak pesanan suami buruk fitnah.. =={{bahasa|id}}== {{kepala|id}} {{-adv-|id}} # sudah (untuk menyatakan perbuatan, keadaan dsb. yang sempurna, lampau, atau selesai): #*{{RQ:Mustikarasa |page=42 |text=Ajam jang '''telah''' dibului |norm=Ajam yang '''telah''' dibului |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/50#:~:text=Ajam%20jang%20telah%20dibului}} <br />''Ia telah pergi dan tidak akan kembali lagi; mereka telah membeli karcis'' {{-turunan-|id}} {{-sinonim-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} g17pz2ln2c3l5yrg7t2q83euqesnfwn persegi 0 93013 1349034 1123755 2026-04-08T17:12:39Z Sofi Solihah 23681 1349034 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan per-|segi|kelas=v|plain=y|aktif=no}} # bersegi {{-n-|id}} # segi empat sama sisi; bujur sangkar # kuadrat: <br />''Lima meter persegi (5 m2)'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kadang - kadang papan kecil berukuran kurang lebih 40 cm '''persegi''' atau lantai biasa yang dapat ditulisi untuk papannya sudah cukup memadai, sedangkan pemainnya cukup duduk di lantai saja. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kadang%20%2D%20kadang%20papan%20kecil%20berukuran%20kurang%20lebih%2040%20cm%20persegi%20atau%20lantai%20biasa%20yang%20dapat%20ditulisi%20untuk%20papannya%20sudah%20cukup%20memadai%2C%20sedangkan%20pemainnya%20cukup%20duduk%20di%20lantai%20saja. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} cdcynomternc84p5vivy4g4lgevnhuy pinang 0 93235 1348969 1338981 2026-04-08T16:04:56Z Iripseudocorus 40083 Kutipan23 1348969 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # tumbuhan berumpun, berbatang lurus seperti lilin, tangkai daun yang melekat pada batang berbentuk seperti lembaran kulit, buah yang tua berwarna kuning kemerah-merahan untuk kawan makan sirih dsb.; "[[:species:Areca catechu|Areca catechu]]" # buah pinang; biji pinang #* {{RQ:Perahu Tulis | page = 132 | author = Balai Bahasa Sumatera Barat | chapter = | text = Terbayang di pikiranku wajah ibu yang kerjanya setiap pagi mencari '''pinang''' di ladang orang, hal yang harus kuubah semestinya. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/144#:~:text=Terbayang%20di%20pikiranku%20wajah%20ibu%20yang%20kerjanya%20setiap%20pagi%20mencari%20pinang%20di%20ladang%20orang%2C%20hal%20yang%20harus%20kuubah%20semestinya. }} {{-v-|id}} # meminang {{-etimologi-}} * Pinjaman dari [[bahasa Jawa]] ''pinang'', dari [[bahasa Jawa Kuno]] ''pinaṅ'' (''pinang'') 'memohon datang, mengundang, meminta bantuan' {{-rujukan-}} * Zoetmulder, P.J., dan Robson, S.O. (2006). Kamus Jawa Kuna-Indonesia. (Darusuprapta dan Sumarti Suprayitna, Penerjemah). Jakarta: Gramedia Pustaka Utama. * Zoetmulder, P.J. 1982. Old Javanese-English dictionary. 2 vols. Koninklijk Instituut voor Taal-, Land- en Volkenkunde. 's Gravenhage: Nijhoff. http://sealang.net/ojed/ * Gericke, J.F.C. en T. Roorda 1901 Javaansch-Nederlandsch Handwoordenboek. 2 vols. Amsterdam / Leiden. https://www.sastra.org/leksikon *Pigeaud, Th. 1938. Javaans-Nederlands handwoordenboek. Groningen: J.B. Wolters. *Jansz, P. 1899. Nederlandsch-Javaansch Woordenboek. Vijfde weder vermeerderde druk. *Juynboll, H.H. 1923. Oudjavaansch-Nederlandsche Woordenlijst. E.J. Brill. Leiden. * {{R:KBBI Daring}} * {{R:KBBI Daring}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|bjn}}== {{kepala|bjn}} {{-lafal-|bjn}} * {{suara|bjn|LL-Q33151 (bjn)-Wadaihangit-pinang.wav }} {{-n-|bjn}} # pinang #: {{ux|bjn|Bagawi manguyak pinang pulang kami ari ini.|Kerja mengupas pinang lagi hari ini}} [[Kategori:WikiTutur 3.0 - Banjar]] [[Kategori:WikiTutur 3.0 Banjarmasin 15 Februari 2026]] =={{bahasa|kvb}}== {{kepala|kvb}} : {{pemenggalan|kvb|pi|nang}} {{-n-|kvb}} # {{l|id|pinang}} [[Kategori:Edit-a-thon WikiKathā Maret 2026]] ojp1k6lh9avmi63m77lyv4c7cqd0w2m niat 0 94855 1348976 1328681 2026-04-08T16:13:57Z Iripseudocorus 40083 Kutipan23 1348976 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # maksud atau tujuan suatu perbuatan: <br />''mudah-mudahan niat baik Anda terwujud'' # kehendak (keinginan dalam hati) akan melakukan sesuatu: <br />''Timbul lagi niatnya untuk menyelesaikan studinya yang terhenti itu; niatnya hendak berziarah ke Tanah Suci tahun ini, sudah bulat'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = '''Niat''' hatiku ingin mengalihkan kebiasaan ibu mengambil barang orang, malah menjadi pembuka peluang bagi ibu untuk mengambil punya orang. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Niat%20hatiku%20ingin%20mengalihkan%20kebiasaan%20ibu%20mengambil%20barang%20orang%2C%20malah%20menjadi%20pembuka%20peluang%20bagi%20ibu%20untuk%20mengambil%20punya%20orang. }} # janji untuk melakukan sesuatu jika cita-cita atau harapan terkabul; kaul; nazar: <br />''Janji ditepati, niat harus dibayar'' {{-turunan-|id}} {{-sinonim-}} * [[memasang niat]], berkaul; bernazar {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|pgu}}== {{kepala|pgu}} : {{suara|pgu|LL-Q7124462_(pgu)-Abednego_Lasa-niat.wav}} {{-verba-|pgu|epentetik|niata}} # [[berdoa]] [[Kategori:Edit-a-thon WikiKathā Maret 2026]] grohrkix8lohjhzk7vpii7oqrus00uh marah 0 95528 1348950 1331231 2026-04-08T13:46:34Z Losstreak 36825 1348950 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adj-|id}} # sangat tidak senang (karena dihina, diperlakukan tidak sepantasnya, dsb.); berang; gusar: <br />''Aku marah mendengar ucapannya yang kasar itu'' #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan '''marah'''. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-etimologi-}} * Dari ''[[Jawa Kuno]]'' '''''rah''''' ['darah; marah; berdarah'] {{-rujukan-}} * {{R:KBBI Daring}} {{-turunan-|id}} {{-n-|id}} # gelar anak sutan yang menikah dengan perempuan biasa atau anak putri (bangsawan) dengan laki-laki biasa {{-sinonim-}} * [[amarah]] (''n'') {{-terjemahan-}} {{t-atas}} *{{id}}: {{t+|id|marah}} *{{gor}}: {{t+|gor|yingo}} *{{de}}: {{t+|de|verärgert}} *{{en}}: {{t+|en|angry}} *{{fr}}: {{t+|fr|fâché}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:id:Emosi]] =={{bahasa|jv}}== {{kepala|jv}} {{-adj-|jv}} # marah (berang; gusar) =={{bahasa|kvb}}== {{kepala|kvb}} : {{pemenggalan|kvb|ma|rah}} {{-a-|kvb}} # {{l|id|marah}} c5oqj41i5vbx70wmyjy37x4xsplzrjp lidi 0 101093 1349015 1215077 2026-04-08T17:03:50Z Sofi Solihah 23681 1349015 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # tulang daun nyiur (enau dsb.) #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dibandingkan dengan permainan catur, jelas sekali orang lebih menyukai catur dari pada bacit walaupun bacit alatnya sembarang saja misalnya batu - batu kerikil yang kecil atau potongan bilah lidi yang dipatah - patah. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dibandingkan%20dengan%20permainan%20catur%2C%20jelas%20sekali%20orang%20lebih%20menyukai%20catur%20dari%20pada%20bacit%20walaupun%20bacit%20alatnya%20sembarang%20saja%20misalnya%20batu%20%2D%20batu%20kerikil%20yang%20kecil%20atau%20potongan%20bilah%20lidi%20yang%20dipatah%20%2D%20patah. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} *{{id}}: {{t+|id|lidi}} *{{gor}}: {{t+|gor|hiyo}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} bj0o23uwyz0i2y132ioagcwdd535myq 1349016 1349015 2026-04-08T17:04:08Z Sofi Solihah 23681 1349016 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # tulang daun nyiur (enau dsb.) #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dibandingkan dengan permainan catur, jelas sekali orang lebih menyukai catur dari pada bacit walaupun bacit alatnya sembarang saja misalnya batu - batu kerikil yang kecil atau potongan bilah '''lidi''' yang dipatah - patah. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dibandingkan%20dengan%20permainan%20catur%2C%20jelas%20sekali%20orang%20lebih%20menyukai%20catur%20dari%20pada%20bacit%20walaupun%20bacit%20alatnya%20sembarang%20saja%20misalnya%20batu%20%2D%20batu%20kerikil%20yang%20kecil%20atau%20potongan%20bilah%20lidi%20yang%20dipatah%20%2D%20patah. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} *{{id}}: {{t+|id|lidi}} *{{gor}}: {{t+|gor|hiyo}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 7ol1ow595plz3k7cdfmwmxcuu59thve lihai 0 101106 1349161 1215121 2026-04-09T05:31:58Z Iripseudocorus 40083 Kutipan24 1349161 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-a-|id}} # pintar; cerdik; cekatan; pandai (menipu dsb.): <br />''Dia sangat lihai memperdayakan lawannya'' # tajam (tentang senjata) #* {{RQ:Perahu Tulis | page = 136 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Yang menyuruh Kemal menasihatimu adalah bapak sendiri, sayangnya Kemal kurang mampu mengarahkanmu, mungkin ia terlalu keras dan kurang '''lihai''' berkata-kata." | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/148#:~:text=%22Yang%20menyuruh%20Kemal%20menasihatimu%20adalah%20bapak%20sendiri%2C%20sayangnya%20Kemal%20kurang%20mampu%20mengarahkanmu%2C%20mungkin%20ia%20terlalu%20keras%20dan%20kurang%20lihai%20berkata%2Dkata.%22 }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} n3aun0nyjc1005395cku8502cexvpvz lombok 0 101347 1349142 1286504 2026-04-08T20:28:35Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349142 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # cabai #* {{RQ:Mustikarasa |page=59 |text=Rasa pedas ditimbulkan oleh lada, '''lombok''', djae, dan laos, tjuma pedasnja lain² |norm=Rasa pedas ditimbulkan oleh lada, '''lombok''', jae, dan laos, cuma pedasnya lain-lain |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/67#:~:text=Rasa%20pedas%20ditimbulkan%20oleh%20lada%2C%20lombok%2C%20djae%2C%20dan%20laos%2C%20tjuma%20pedasnja%20lain%C2%B2}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|bjn}}== {{kepala|bjn}} {{-lafal-|bjn}} * {{suara|bjn|LL-Q33151 (bjn)-Wadaihangit-lombok.wav}} {{-n-|bjn}} # cabe #: {{ux|bjn|Naikan haraga lombok wayah ini|Harga cabe naik sekarang}} [[Kategori:WikiTutur 3.0 - Banjar]] [[Kategori:WikiTutur 3.0 Banjarmasin 15 Februari 2026]] rm4bo0os0v2tmt0hkukf9iyerrfn6hp kaba 0 101525 1348924 1117499 2026-04-08T12:36:47Z ~2026-21632-04 47521 1348924 wikitext text/x-wiki kaba indang =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # sastra tradisional Minangkabau yang berbentuk prosa berirama, kalimatnya sederhana dengan 3-5 kata sehingga dapat diucapkan secara berirama atau didendangkan, tema ceritanya bermacam-macam, seperti kepahlawanan, petualangan, pelipur lara, dan kisah cinta {{-etimologi-}} * {{lbor|id|min|kaba}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|pse}}== {{kepala|pse}} {{-p-|pse}} # [[kamu]] #: ''kaba jeme mane'' #: kamu orang mana {{-lafal-|pse}} * {{suara|pse|LL-Q3367751 (pse)-Cloudy (Losstreak)-kaba.wav |q={{besemah}}}} * {{suara|pse| LL-Q3367751 (pse)-Rezzzyy-kaba.wav |q={{enim}}}} * {{suara|pse|LL-Q3367751 (pse)-Tarijushi-kaba.wav |q={{semende}}}} {{-ragam-}} * [[kabah]] * {{l|pse|kaban}} (''Lintang'') [[Kategori:WikiTutur - Besemah]] [[Kategori:WikiTutur - Semende]] [[Kategori:WikiTutur Palembang 18 Februari 2024]] =={{bahasa|min}}== {{kepala|min}} {{-n-|min}} # [[kabar]] #: ''baa kaba kini, sanak?'' #: gimana kabarnya sekarang, kawan? [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] =={{bahasa|mui-plm}}== {{kepala|mui-plm}} {{-pron-|mui-plm}} # [[kamu]]; yang diajak bicara; yang disapa (dalam ragam akrab atau kasar) r39p2yvfwja634yh1eezod1u311qbv9 1348935 1348924 2026-04-08T12:59:51Z Ardzun 8096 Batalkan revisi [[Special:Diff/1348924|1348924]] oleh [[Special:Contributions/~2026-21632-04|~2026-21632-04]] ([[User talk:~2026-21632-04|bicara]]) 1348935 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # sastra tradisional Minangkabau yang berbentuk prosa berirama, kalimatnya sederhana dengan 3-5 kata sehingga dapat diucapkan secara berirama atau didendangkan, tema ceritanya bermacam-macam, seperti kepahlawanan, petualangan, pelipur lara, dan kisah cinta {{-etimologi-}} * {{lbor|id|min|kaba}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|pse}}== {{kepala|pse}} {{-p-|pse}} # [[kamu]] #: ''kaba jeme mane'' #: kamu orang mana {{-lafal-|pse}} * {{suara|pse|LL-Q3367751 (pse)-Cloudy (Losstreak)-kaba.wav |q={{besemah}}}} * {{suara|pse| LL-Q3367751 (pse)-Rezzzyy-kaba.wav |q={{enim}}}} * {{suara|pse|LL-Q3367751 (pse)-Tarijushi-kaba.wav |q={{semende}}}} {{-ragam-}} * [[kabah]] * {{l|pse|kaban}} (''Lintang'') [[Kategori:WikiTutur - Besemah]] [[Kategori:WikiTutur - Semende]] [[Kategori:WikiTutur Palembang 18 Februari 2024]] =={{bahasa|min}}== {{kepala|min}} {{-n-|min}} # [[kabar]] #: ''baa kaba kini, sanak?'' #: gimana kabarnya sekarang, kawan? [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] =={{bahasa|mui-plm}}== {{kepala|mui-plm}} {{-pron-|mui-plm}} # [[kamu]]; yang diajak bicara; yang disapa (dalam ragam akrab atau kasar) ob0zud2vd7lvhe16r4zwvw5cs5dpx2b kerikil 0 102872 1349018 1118581 2026-04-08T17:04:49Z Sofi Solihah 23681 1349018 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # butiran batu lebih besar daripada pasir dan lebih kecil daripada kerakal (kira-kira sebesar biji kacang tanah atau biji nangka) # {{Geo}} endapan batuan yang komponennya bulat, biasanya bercampur dengan tanah liat dan pasir #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dibandingkan dengan permainan catur, jelas sekali orang lebih menyukai catur dari pada bacit walaupun bacit alatnya sembarang saja misalnya batu - batu '''kerikil''' yang kecil atau potongan bilah lidi yang dipatah - patah. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dibandingkan%20dengan%20permainan%20catur%2C%20jelas%20sekali%20orang%20lebih%20menyukai%20catur%20dari%20pada%20bacit%20walaupun%20bacit%20alatnya%20sembarang%20saja%20misalnya%20batu%20%2D%20batu%20kerikil%20yang%20kecil%20atau%20potongan%20bilah%20lidi%20yang%20dipatah%20%2D%20patah. }} {{-etimologi-}} * Dari [[bahasa Jawa|Jawa Modern]] ''k(ê)rikil'', dari [[Jawa Kuno]] ''karikil'' ['kerikil'] {{-rujukan-}} * Zoetmulder, P.J., dan Robson, S.O. (2006). Kamus Jawa Kuna-Indonesia. (Darusuprapta dan Sumarti Suprayitna, Penerjemah). Jakarta: Gramedia Pustaka Utama. * Zoetmulder, P.J. 1982. Old Javanese-English dictionary. (Koninklijk Instituut voor Taal-, Land- en Volkenkunde.) The Hague: Martinus Nijhoff. (2 vols). * Robson, S.O & Wibisono, S. 1941. Old Javanese-English Dictionary. Periplus Editions, Ltd. Hongkong. * Gericke, J.F.C. en T. Roorda 1901 Javaansch-Nederlandsch Handwoordenboek. 2 vols. Amsterdam / Leiden. * Gericke, J.F.C., T. Roorda. 1847. Javaansch-Nederduitsch Woordenboek. Johannes Müller, Amsterdam & Brill. Leiden. * L'Abbé P. Favre. 1870. Dictionnaire Javanais-Français. Imprimerie Impériale et Royale. *Jansz, P. 1899. Nederlandsch-Javaansch Woordenboek. Vijfde weder vermeerderde druk. Semarang. * Juynboll, H.H. 1923. Oudjavaansch-Nederlandsche Woordenlijst. E.J. Brill. Leiden * Pigeaud, Th. 1938. Javaans-Nederlands handwoordenboek. Groningen: J.B. Wolters. * Poerwadarminta, W.J.S. 1939. Bausastra Jawa. Batavia: J.B Wolters Uitgevers Maatschappij N.V Groningen. * {{R:KBBI Daring}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} *{{id}}: {{t+|id|kerikil}} *{{gor}}: {{t+|gor|biilato}} *{{de}}: {{t+|de|Kies}}, {{t+|de|Schotter}}, {{t+|de|Kiesel}} *{{en}}: {{t+|en|gravel}} *{{fr}}: {{t+|fr|gravier}} *{{zh}}: {{t+|zh|礫石}} *{{ja}}: {{t+|ja|砂利}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # kerikil oxpg988fmeu7cciwcwwb0vryracwfzz jadwal 0 104565 1348922 1117101 2026-04-08T12:16:38Z Losstreak 36825 1348922 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # pembagian waktu berdasarkan rencana pengaturan urutan kerja; daftar atau tabel kegiatan atau rencana kegiatan dengan pembagian waktu pelaksanaan yang terperinci: #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap '''jadwal'''. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} <br />''Jadwal penataran itu sudah disetujui oleh pimpinan'' {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} ptmd22u5tzh7kpapdor18738dwsx5ic jongkok 0 105060 1349007 1194179 2026-04-08T16:58:12Z Sofi Solihah 23681 1349007 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-v-|id}} # menempatkan badan dengan cara melipat kedua lutut, bertumpu pada telapak kaki, dengan pantat tidak menjejak tanah; bercangkung; berjongkok # {{kiasan}} rendah (tentang inteligensi); bebal: <br>''Orang itu jongkok inteligensinya sehingga tidak dapat memahami persoalan yang sederhana sekalipun'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Agar anggota badannya tidak kelihatan maka cara berjalan dengan jongkok sehingga seluruh tubuhnya tertutup dengan sarung. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Baburungan#:~:text=Agar%20anggota%20badannya%20tidak%20kelihatan%20maka%20cara%20berjalan%20dengan%20jongkok%20sehingga%20seluruh%20tubuhnya%20tertutup%20dengan%20sarung. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} t7zjyiasua7m0jhgsouqk59efwvcfil 1349009 1349007 2026-04-08T16:58:27Z Sofi Solihah 23681 1349009 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-v-|id}} # menempatkan badan dengan cara melipat kedua lutut, bertumpu pada telapak kaki, dengan pantat tidak menjejak tanah; bercangkung; berjongkok # {{kiasan}} rendah (tentang inteligensi); bebal: <br>''Orang itu jongkok inteligensinya sehingga tidak dapat memahami persoalan yang sederhana sekalipun'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Agar anggota badannya tidak kelihatan maka cara berjalan dengan '''jongkok''' sehingga seluruh tubuhnya tertutup dengan sarung. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Baburungan#:~:text=Agar%20anggota%20badannya%20tidak%20kelihatan%20maka%20cara%20berjalan%20dengan%20jongkok%20sehingga%20seluruh%20tubuhnya%20tertutup%20dengan%20sarung. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} sywycuy05fsefkrubknam05esuyxjw5 istirahat 0 105896 1348929 1273070 2026-04-08T12:54:31Z Losstreak 36825 1348929 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} [[File:Istirahat.webm|thumb|250px|start=1|end=4|BISINDO "Istirahat" ]] # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, '''istirahat''' untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} {{lihat 2|v=y}} {{-etimologi-}} * Dari [''[[Arab]]'' '''''اِسْتِرَاحَةٌ istirāḥah''''' 'waktu berhenti sejenak dari suatu kegiatan', dari ''[[Arab]]'' '''''اِسْتَرَاحَ istarāḥa''''' 'mengaso sejenak dari suatu kegiatan (untuk melepaskan lelah)' dari ''[[Arab]] '''''رَاحَ rāḥa''''' 'merasa semangat; senang; bugar; tenang'] {{-rujukan-}} * Russell Jones, Loan-words in Indonesian and Malay, (Jakarta: Yayasan Obor Indonesia, 2008) * Ibn Manẓūr, Lisan al-'Arab, (Cairo: Dār al-Ma‘ārif, 1431 H) * {{R:KBBI Daring}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} dwbf1iysfs8zeltdyebrcjj56gevfss halal 0 105976 1349154 1280104 2026-04-09T05:16:05Z Iripseudocorus 40083 Kutipan24 1349154 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-a-|id}} # diizinkan (tidak dilarang oleh syarak): <br />''Makanan ini halal'' {{-a-|id}} # (yang diperoleh atau diperbuat dengan) sah: <br />''Uang halal'' #* {{RQ:Perahu Tulis | page = 135 | author = Balai Bahasa Sumatera Barat | chapter = | text = Seharusnya Kau bersabar dan berusaha mencari rezeki yang '''halal'''. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Seharusnya%20Kau%20bersabar%20dan%20berusaha%20mencari%20rezeki%20yang%20halal. }} {{-n-|id}} # {{ark}} izin; ampun: <br />''Menyembah minta halal akan segala pengajarannya'' {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} asrk6clmd5pyoj6rt6yyb8jz6wefjrw ganda 0 106767 1348982 1325290 2026-04-08T16:17:51Z Iripseudocorus 40083 Kutipan23 1348982 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # (tentang hitungan) kali; lipat: <br />''Dua ganda'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Semenjak kepergian sang ayah di keluarga kami, ibu berperan '''ganda''', selain sebagai ibu, ibu juga merangkap sebagai ayah. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Semenjak%20kepergian%20sang%20ayah%20di%20keluarga%20kami%2C%20ibu%20berperan%20ganda%2C%20selain%20sebagai%20ibu%2C%20ibu%20juga%20merangkap%20sebagai%20ayah. }} # berbayang (seakan-akan ada dua): <br />''Dengan teknik pemotretan tertentu kita dapat menghasilkan gambar ganda'' # berpasangan (terdiri atas dua); berpasangan dua-dua (dalam bulu tangkis, tenis, dsb.): <br />''Pemain ganda'' {{-a-|id}} # berani melawan (meskipun tidak seimbang) # sanggup mengerjakan sesuatu dengan tenaga yang lebih sedikit (meremehkan) {{-n-|id}} # [[bau]] {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 2e8wm3ztryidod83x98692365midj0c eugenol 0 109098 1349148 1114907 2026-04-08T20:51:25Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349148 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # {{Kim}} zat cair tanpa warna, konstituen utama minyak bunga cengkih, digunakan sebagai bahan wangi-wangian dan bakterisida; C10H12O2 #* {{RQ:Mustikarasa |page= 60 |text= Tjengkeh mengandung minjak '''eugenol''' jang harum baunja |norm= Cengkeh mengandung minyak '''eugenol''' yang harum baunya |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/68#:~:text=Tjengkeh%20mengandung%20minjak%20eugenol%20jang%20harum%20baunja.}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} obrw6opmtw7bb13pod86w2sm92u8vdw disiplin 0 110017 1348920 1113984 2026-04-08T12:11:25Z Losstreak 36825 1348920 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # tata tertib (di sekolah, kemiliteran, dsb.) # ketaatan (kepatuhan) kepada peraturan (tata tertib dsb.) #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling '''disiplin''' terhadap jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} # bidang studi yang memiliki objek, sistem, dan metode tertentu {{-etimologi-}} * Dari {{en}} [[discipline]] {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} mrxq7vfo1ar4676dex5e49pcdinx8bf bilah 0 112074 1349013 1112205 2026-04-08T17:02:56Z Sofi Solihah 23681 1349013 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # belahan bambu (kayu dsb.) yang tipis dan panjang #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dibandingkan dengan permainan catur, jelas sekali orang lebih menyukai catur dari pada bacit walaupun bacit alatnya sembarang saja misalnya batu - batu kerikil yang kecil atau potongan '''bilah''' lidi yang dipatah - patah. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dibandingkan%20dengan%20permainan%20catur%2C%20jelas%20sekali%20orang%20lebih%20menyukai%20catur%20dari%20pada%20bacit%20walaupun%20bacit%20alatnya%20sembarang%20saja%20misalnya%20batu%20%2D%20batu%20kerikil%20yang%20kecil%20atau%20potongan%20bilah%20lidi%20yang%20dipatah%20%2D%20patah. }} #:''Pagar dari '''bilah''' buluh'' # sesuatu yang menyerupai bilah (terutama pisau, pedang, dsb.) #:''Didapatnya '''bilah''' keris tua di dalam gua itu'' # kata penggolong bagi sesuatu yang tipis dan panjang #:''Dua '''bilah''' pedang; dua '''bilah''' papan'' {{-n-|id}} # bagian buldoser yang berfungsi sebagai alat gali dan dorong {{lihat v}} # ''lihat [[membilah-bilah]]''. {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} fm1wpv1457ek52qdouxmvd955k4jr0c bissu 0 112221 1349172 1112328 2026-04-09T09:17:29Z Swarabakti 18192 1349172 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # [[pemuka agama]] [[Bugis]] [[klasik]] pada [[tataran]] [[diraja]] yang dianggap [[melampaui]] penggolongan [[gender]], bertugas sebagai [[perantara]] [[dewata]] dan [[manusia]] dalam berbagai [[ritual]] #* {{kutip buku|id|year=2004|author=Halilintar Lathief|title=Bissu: Pergulatan dan peranannya di masyarakat Bugis|location=Depok|publisher=Desantara|page=38–39|text=Para '''bissu''' menganggap harkat mereka lebih tinggi dan lebih suci dari waria (''calabai'') biasa. ''Calabai'' biasa kadang menjadi bahan ejekan pemuda, sedang para '''bissu''' disegani karena kesaktian dan fungsinya dalam setiap upacara adat.}} =={{bahasa|bug}}== {{kepala|bug}} {{-n-|bug}} # {{l|id|bissu}} 8ajl8gqeallyhxevzofb3p14xne5n2y acar 0 112659 1348925 1291996 2026-04-08T12:51:51Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1348925 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-etimologi-}} Dari {{der|id|fa|آچار|tr=āchār|t=acar, rendaman bumbu}} {{-n-|id}} # makanan bercuka dari irisan buah mentimun, wortel, bawang, cabai, nanas, bengkuang, atau daun sawi, biasa dimakan bersama nasi #* {{RQ:Mustikarasa |page= 58 |text=Tjuka ini terdiri dari asam asetat, jang punja rasa chas untuk '''atjar'''² dan sajur lain²nja |norm=Cuka ini terdiri dari asam asetat, yang punya rasa khas untuk '''acar'''-acar dan sayur lain-lainnya |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Tjuka%20ini%20terdiri%20dari%20asam%20asetat%2C%20jang%20punja%20rasa%20chas%20untuk%20atjar%C2%B2%20dan%20sajur%20lain%C2%B2nja}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|bjn}}== {{kepala|bjn}} {{-n-|bjn}} # {{l|id|acar}} =={{bahasa|bts}}== {{kepala|bts}} {{-n-|bts}} # {{l|id|acar}} =={{bahasa|bkr}}== {{kepala|bkr}} {{-n-|bkr}} # {{l|id|acar}} #: ''kuman dengan acar'' #: makan dengan acar [[Kategori:WikiBalalah - Bakumpai]] h2548gma893x1sxvagb0zj330qp7nrc cengkeh 0 114365 1349147 1314484 2026-04-08T20:49:28Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349147 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} '''cengkeh''' # {{ragam dari|id|cengkih}} #* {{RQ:Mustikarasa |page= 60 |text= '''Tjengkeh''' mengandung minjak eugenol jang harum baunja |norm= '''Cengkeh''' mengandung minyak eugenol yang harum baunya |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/68#:~:text=Tjengkeh%20mengandung%20minjak%20eugenol%20jang%20harum%20baunja.}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|jax}}== {{kepala|jax}} : {{suara|jax|LL-Q3915769 (jax)-YOGI NUGRAHA PUTRA-kayu manis.wav}} {{-n-|jax}} # [[cengkih]] [[Kategori:WikiMaknyus Jambi]] =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # {{l|id|cengkeh}} [[Kategori:WikiMaknyus]] [[Kategori:WikiMaknyus Banjarnegara]] [[Kategori:WikiMaknyus]] 7ya7qeuayssgnyyj68jju2xbxolgewg kayu manis 0 127398 1349146 1286019 2026-04-08T20:46:36Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349146 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} #pohon yang tingginya 10-15 m, kulit batangnya berwarna abu-abu tua dan berbau manis yang tajam, merupakan bahan ekspor yang penting, manis jangan; keningar; ''[[:species:Cinnamomum burmani|Cinnamomum burmani]]'' #* {{RQ:Mustikarasa |page=61 |text='''Kaju manis''', adalah kulit dari pohon Cinnamomum zeylanicam jang didjemur kering |norm='''Kayu manis''', adalah kulit dari pohon Cinnamomum zeylanicam yang dijemur kering |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/69#:~:text=Kaju%20manis%2C%20adalah%20kulit%20dari%20pohon%20Cinnamomum%20zeylanicam%20jang%20didjemur%20kering}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|xmm}}== {{kepala|xmm}} : {{suara|xmm|LL-Q9240 (ind)-Manadonese-Kayu Manis.wav}} {{-n-|xmm}} # kayu manis. jenis tanaman rempah, biasa digunakan untuk bumbu dapur =={{bahasa|jv}}== {{kepala|jv}} {{-n-|jv}} # [[kayu manis]] [[Kategori:WikiMaknyus]] [[Kategori:WikiMaknyus Banjarnegara]] [[Category:WikiMaknyus Manado]] [[Category:WikiMaknyus]] jbe7vkjg6by83fyrb9ircpau82eamgg belimbing wuluh 0 130379 1349135 1345788 2026-04-08T19:51:44Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349135 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # belimbing yang buahnya kecil-kecil, rasanya sangat masam; ''[[:species:Averrhoa belimbi|Averrhoa belimbi]]'' #* {{RQ:Mustikarasa |page= 58 |text='''Belimbing wuluh''' menimbulkan rasa asam jang enak djuga, disebabkan oleh asam oxalat. |norm='''Belimbing wuluh''' menimbulkan rasa asam yang enak juga, disebabkan oleh asam oxalat. |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Belimbing%20wuluh%20menimbulkan%20rasa%20asam%20jang%20enak%20djuga%2C%20disebabkan%20oleh%20asam%20oxalat.a}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} =={{bahasa|osi}}== {{kepala|osi}} {{-n-|osi}} # {{l|id|belimbing wuluh}} {{-rujukan-}} * Ali, Hasan. (2002). ''[https://web.archive.org/web/20260115111844/https://ebookbanyuwangi.id/assets/2022/kamus_using.pdf Kamus Bahasa Daerah Using-Indonesia]''. Banyuwangi: Pemerintah Kabupaten Banyuwangi. [[Kategori:Edit-a-thon WikiKathā Maret 2026]] 8wf5eiq7a8rdlfm11i3eigclfdn2rff gula jawa 0 131624 1349141 1186670 2026-04-08T20:20:53Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349141 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} #gula dari nira, nyiur, atau aren #* {{RQ:Mustikarasa |page=59 |text='''Gula djawa''' dibikin dari sari bunga kelapa jang dikentalkan dengan djalan direbus |norm='''Gula jawa''' dibikin dari sari bunga kelapa yang dikentalkan dengan jalan direbus |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/67#:~:text=Gula%20djawa%20dibikin%20dari%20sari%20bunga%20kelapa%20jang%20dikentalkan%20dengan%20djalan%20direbus}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} ssejs8gj63ebl2sf4o6tib7yz0uduhk gula pasir 0 131648 1349140 1186674 2026-04-08T20:12:28Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349140 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} #gula dari tebu yang bentuknya halus-halus seperti pasir #* {{RQ:Mustikarasa |page= 58 |text=Rasa manis diberikan oleh gula. Jang paling banjak dipakai adalah '''gula pasir''' asal dari pabrik gula |norm=Rasa manis diberikan oleh gula. Yang paling banyak dipakai adalah '''gula pasir''' asal dari pabrik gula |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Rasa%20manis%20diberikan%20oleh%20gula.%20Jang%20paling%20banjak%20dipakai%20adalah%20gula%20pasir%20asal%20dari%20pabrik%20gula}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1xwpqsittwzoyjnkte73a8fvtbcgk58 minta maaf 0 132631 1349158 1264578 2026-04-09T05:25:19Z Iripseudocorus 40083 Kutipan24 1349158 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} #mengharap agar diberi maaf (dimaafkan) #* {{RQ:Perahu Tulis | page = 136 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Pen, sebelumnya bapak '''minta maaf''' padamu, mungkin telah banyak yang menyinggung perasaanmu." | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/148#:~:text=%22Pen%2C%20sebelumnya%20bapak%20minta%20maaf%20padamu%2C%20mungkin%20telah%20banyak%20yang%20menyinggung%20perasaanmu.%22 }} {{-terjemahan-}} {{t-atas}} * bahasa Esperanto: {{t|eo|pardonpeti}} * bahasa Swedia: {{t+|sv|be om ursäkt}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1hjdz27m8cck3ouv59hdytkqjki53bf lada hitam 0 135252 1349143 1210957 2026-04-08T20:34:01Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349143 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} #rempah-rempah jenis lada berwarna hitam; ''[[:species:Piper nigrum|Piper nigrum]]'' #* {{RQ:Mustikarasa |page= 58 |text=Rasa pedas disebabkan oleh piperin. '''Lada hitam''' lebih banjak mengadung zat ini daripada lada putih. |norm=Rasa pedas disebabkan oleh piperin. '''Lada hitam''' lebih banjak mengadung zat ini daripada lada putih. |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/67#:~:text=Rasa%20pedas%20disebabkan%20oleh%20piperin.%20Lada%20hitam%20lebih%20banjak%20mengadung%20zat%20ini%20daripada%20lada%20putih.}} {{-terjemahan-}} {{t-atas}} * bahasa Finlandia: {{t+|fi|mustapippuri}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 86btujyspxw80jfie8fazyb23t5vhy1 mengabaikan 0 136466 1348937 1221645 2026-04-08T13:12:27Z Losstreak 36825 1348937 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{suara|id|LL-Q9240 (ind)-Dvnfit-mengabaikan.wav}} {{imbuhan me-kan|abai}} # memandang rendah (hina, mudah): <br>''jangan mengabaikan kemampuan lawan'' # tidak mengindahkan (perintah, nasihat): <br>''orang itu mengabaikan perintah agama'' # melalaikan (kewajiban, tugas, pekerjaan) # tidak menggunakan baik-baik; menyia-nyiakan: <br>''Adik menyesal telah mengabaikan peluang yang ada; dia telah mengabaikan kesempatan yang baik'' # tidak memedulikan (kritik, celaan): <br>''ia mengabaikan segala macam kritik yang ditujukan kepadanya'' #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, '''mengabaikan''' jadwalnya. Aku tahu, anduang sedang menungguku. Aku mendekat pelan, anduang membuka matanya. Setelah lima jam yang terasa lambat, ingin sekali rasanya aku memeluk anduang, mengucap maaf yang deras padanya. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang%20masih%20duduk%20di%20kursi%20goyangnya%2C%20mengabaikan%20jadwalnya.%20Aku%20tahu%2C%20anduang%20sedang%20menungguku.%20Aku%20mendekat%20pelan%2C%20anduang%20membuka%20matanya.%20Setelah%20lima%20jam%20yang%20terasa%20lambat%2C%20ingin%20sekali%20rasanya%20aku%20memeluk%20anduang%2C%20mengucap%20maaf%20yang%20deras%20padanya. }} # membiarkan telantar (terbengkalai dsb): <br>''orang itu mengabaikan anaknya dan tidak mengurusnya lagi'' # tidak memegang teguh (adat istiadat, aturan, janji): <br>''negara itu mengabaikan ketentuan yang telah disepakati bersama'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 2d8zso3yyjk4z7pfpyponoe6agbrwko musiman 0 136525 1349193 1230526 2026-04-09T10:21:11Z Sofi Solihah 23681 1349193 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|musim|kelas=verb}} # pada musim tertentu: <br>''banjir musiman datang ketika musim hujan; buruh musiman hanya bekerja pada musim-musim tertentu (misal setelah selesai menanam padi)'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Permainan ini sampai sekarang merupakan permainan yang tetap digemari oleh anak-anak meskipun kadang - kadang bersifat '''musiman'''. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Permainan%20ini%20sampai%20sekarang%20merupakan%20permainan%20yang%20tetap%20digemari%20oleh%20anak%2Danak%20meskipun%20kadang%20%2D%20kadang%20bersifat%20musiman. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} jxwdhkghjzwg9eyo49lme4lcgvbcppi menceburkan 0 136604 1349157 1229114 2026-04-09T05:20:40Z Iripseudocorus 40083 Kutipan24 1349157 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-kan|cebur}} # menjatuhkan (membuang) ke dalam air; mencemplungkan (ke dalam air): <br>''ia menceburkan mayat orang yang terbunuh itu ke laut; ia menceburkan diri ke laut'' #* {{RQ:Perahu Tulis | page = 135 | author = Balai Bahasa Sumatera Barat | chapter = | text = Hampir saja aku '''menceburkan''' diri ke sumur itu, untuk bercerita pada katak-katak sumur. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Hampir%20saja%20aku%20menceburkan%20diri%20ke%20sumur%20itu%2C%20untuk%20bercerita%20pada%20katak%2Dkatak%20sumur. }} # {{kiasan}} ikut berkecimpung dalam suatu kegiatan atau usaha: <br>''ia belum lama menceburkan diri dalam dunia perfilman'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} hd3q6383bbxjhftpex5a1iatlu1c6sb tersusun 0 136676 1349047 1240086 2026-04-08T17:27:05Z Sofi Solihah 23681 1349047 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|susun}} # sudah disusun (diatur baik-baik, ditumpuk, dsb): <br>''penyelundupan cengkih dilakukan oleh organisasi penyelundupan yang tersusun rapi'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= '''Walaupun''' pengertian cit itu berarti membuat anak cit tersusun berjajar 3 dan kepada pemain yang dapat melakukannya berhak mengambil satu biji milik lawan yang sudah '''tersusun''' dalam papan cit, dalam tahap pertama ini (tahap penyusunan anak cit) hak mengambil anak cit lawan itu tidak berlaku. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Walaupun%20pengertian%20cit%20itu%20berarti%20membuat%20anak%20cit%20tersusun%20berjajar%203%20dan%20kepada%20pemain%20yang%20dapat%20melakukannya%20berhak%20mengambil%20satu%20biji%20milik%20lawan%20yang%20sudah%20tersusun%20dalam%20papan%20cit%2C%20dalam%20tahap%20pertama%20ini%20(%20tahap%20penyusunan%20anak%20cit%20)%20hak%20mengambil%20anak%20cit%20lawan%20itu%20tidak%20berlaku. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} brfisnklvakwk0iz5tj8jzotb8oauty 1349048 1349047 2026-04-08T17:27:24Z Sofi Solihah 23681 1349048 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|susun}} # sudah disusun (diatur baik-baik, ditumpuk, dsb): <br>''penyelundupan cengkih dilakukan oleh organisasi penyelundupan yang tersusun rapi'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Walaupun pengertian cit itu berarti membuat anak cit tersusun berjajar 3 dan kepada pemain yang dapat melakukannya berhak mengambil satu biji milik lawan yang sudah '''tersusun''' dalam papan cit, dalam tahap pertama ini (tahap penyusunan anak cit) hak mengambil anak cit lawan itu tidak berlaku. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Walaupun%20pengertian%20cit%20itu%20berarti%20membuat%20anak%20cit%20tersusun%20berjajar%203%20dan%20kepada%20pemain%20yang%20dapat%20melakukannya%20berhak%20mengambil%20satu%20biji%20milik%20lawan%20yang%20sudah%20tersusun%20dalam%20papan%20cit%2C%20dalam%20tahap%20pertama%20ini%20(%20tahap%20penyusunan%20anak%20cit%20)%20hak%20mengambil%20anak%20cit%20lawan%20itu%20tidak%20berlaku. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 4totk363a0v5bkjiv41n8qr9i1g5sbh penyusunan 0 136697 1349049 1240083 2026-04-08T17:29:00Z Sofi Solihah 23681 1349049 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan peng-an|susun}} # proses, cara, perbuatan menyusun (seperti penyusunan kamus, ensiklopedia) #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Walaupun pengertian cit itu berarti membuat anak cit tersusun berjajar 3 dan kepada pemain yang dapat melakukannya berhak mengambil satu biji milik lawan yang sudah tersusun dalam papan cit, dalam tahap pertama ini (tahap '''penyusunan''' anak cit) hak mengambil anak cit lawan itu tidak berlaku. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Walaupun%20pengertian%20cit%20itu%20berarti%20membuat%20anak%20cit%20tersusun%20berjajar%203%20dan%20kepada%20pemain%20yang%20dapat%20melakukannya%20berhak%20mengambil%20satu%20biji%20milik%20lawan%20yang%20sudah%20tersusun%20dalam%20papan%20cit%2C%20dalam%20tahap%20pertama%20ini%20(%20tahap%20penyusunan%20anak%20cit%20)%20hak%20mengambil%20anak%20cit%20lawan%20itu%20tidak%20berlaku. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} lpbtxgsfm826yizkpjvxhe43u22105e terhadap 0 137538 1348921 1225463 2026-04-08T12:15:30Z Losstreak 36825 1348921 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|hadap}} {{-prep-|id}} # kata depan untuk menandai arah; kepada; lawan: <br>''ia segan terhadap ayahku; tindakan terhadap musuh sangat kejam'' #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin '''terhadap''' jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1u6mq3k55kurdgebvhb3pxaxltm3407 tercenung 0 137888 1348990 1223611 2026-04-08T16:27:41Z Iripseudocorus 40083 Kutipan23 1348990 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|cenung|kelas=adj}} # (duduk dsb) diam-diam tafakaur karena memikirkan sesuatu dalam-dalam; termenung-menung; termangu-mangu: <br>''dia tercenung saja di mulut pintu sejak kepergian suaminya pagi tadi'' #* {{RQ:Perahu Tulis | page = 135 | author = Balai Bahasa Sumatera Barat | chapter = | text = Aku '''tercenung''' lama, terpikir olehku kenapa hidupku selalu miskin. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Aku%20tercenung%20lama%2C%20terpikir%20olehku%20kenapa%20hidupku%20selalu%20miskin. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1a5tleatd0pmv3jut71js9kds9kqyb9 perorangan 0 138805 1349024 1231303 2026-04-08T17:08:40Z Sofi Solihah 23681 1349024 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan per-an|orang}} # perihal orang seorang #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Karena permainan ini bersifat '''perorangan''', maka jumlah pemainnya biasanya tidak lebih dari 2 orang. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Karena%20permainan%20ini%20bersifat%20perorangan%2C%20maka%20jumlah%20pemainnya%20biasanya%20tidak%20lebih%20dari%202%20orang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} bhksludoaixm3lowlxiid11le4ldaah mengalihkan 0 138824 1348977 1221857 2026-04-08T16:14:35Z Iripseudocorus 40083 Kutipan23 1348977 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-kan|alih}} # memindahkan: <br>''ia mengalihkan percakapannya ke soal lain'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Niat hatiku ingin '''mengalihkan''' kebiasaan ibu mengambil barang orang, malah menjadi pembuka peluang bagi ibu untuk mengambil punya orang. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Niat%20hatiku%20ingin%20mengalihkan%20kebiasaan%20ibu%20mengambil%20barang%20orang%2C%20malah%20menjadi%20pembuka%20peluang%20bagi%20ibu%20untuk%20mengambil%20punya%20orang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 6rmmdkfifgcsgdu2mlkl35wu6j4um34 menanam 0 138863 1348974 1240652 2026-04-08T16:11:36Z Iripseudocorus 40083 Kutipan23 1348974 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|tanam}} # menaruh (bibit, benih, setek, dsb) di dalam tanah supaya tumbuh: <br>''menanam pohon buah-buahan'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Bu, bagaimana kalau kita '''menanam''' singkong di ladang kita," usulku pada ibu. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=%22Bu%2C%20bagaimana%20kalau%20kita%20menanam%20singkong%20di%20ladang%20kita%2C%22%20usulku%20pada%20ibu. }} # menaruh di dalam tanah yang dilubangi, lalu ditimbuni dengan tanah; memendam; menguburkan (mayat, bangkai): <br>''ia harta bendanya di kolong tempat tidur; ia menanam bangkai kucing di pekarangan'' # menaburkan (paham, ajaran, dsb); memasukkan, membangkitkan, atau memelihara (perasaan, cinta kasih, semangat, dsb): <br>''perguruan Taman Siswa menanam semangat kebangsaan pada para siswa'' # menyertakan (modal, uang, dsb) ke dalam perusahaan dsb: <br>''banyak pengusaha asing ingin menanam modal di Indonesia'' # menegakkan (kekuasaan); menempatkan (pengaruh, kepentingan, dsb): <br>''ia hendak menanam pengaruhnya kepada orang itu melalui orang lain'' # mempertumbuhkan atau membiakkan (benih penyakit dsb): <br>''dokter hewan menanam benih penyakit cacar pada tubuh kuda'' # mengandung (niat dsb): <br>''ia menanam niat untuk berontak'' # mengangkat atau menempatkan (wakil, tenaga, agen, dsb): <br>''gerakan separatis itu menanam agen-agennya di seluruh negara'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} o5ch21qztddhy9v2gjeov7blv9l5z2b berdakwah 0 141101 1348985 1148390 2026-04-08T16:21:15Z Iripseudocorus 40083 Kutipan23 1348985 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|dakwah}} # mengajak (menyerukan) untuk mempelajari dan mengamalkan ajaran agama #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Maafkan aku ya, kala itu aku baru belajar '''berdakwah''', jadi aku belum tahu harus memulai dengan apa, lagian waktu itu Kau main emosi saja | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Maafkan%20aku%20ya%2C%20kala%20itu%20aku%20baru%20belajar%20berdakwah%2C%20jadi%20aku%20belum%20tahu%20harus%20memulai%20dengan%20apa%2C%20lagian%20waktu%20itu%20Kau%20main%20emosi%20saja }} # berkhotbah (memberi penerangan) tentang agama: <br />''sekali seminggu datanglah seorang mubalig untuk berdakwah di desa itu'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1m9jgc6hcom5in60rxleu1j643j5x6j sasaran 0 141594 1349196 1236724 2026-04-09T10:26:00Z Sofi Solihah 23681 1349196 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|sasar}} # bulan-bulanan; yang disasarkan; hasil menyasar #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Meskipun sebenarnya dalam permainan ini terdapat unsur taruhan, namun sebenarnya terdapat pula unsur-unsur positif yang dapat dipetik yaitu antara lain merupakan latihan ketepatan melempar suatu '''sasaran''' di samping merupakan latihan kemahiran menentukan strategi dalam melempar tahapan pertama. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Meskipun%20sebenarnya%20dalam%20permainan%20ini%20terdapat%20unsur%20taruhan%2C%20namun%20sebenarnya%20terdapat%20pula%20unsur%2Dunsur%20positif%20yang%20dapat%20dipetik%20yaitu%20antara%20lain%20merupakan%20latihan%20ketepatan%20melempar%20suatu%20sasaran%20di%20samping%20merupakan%20latihan%20kemahiran%20menentukan%20strategi%20dalam%20melempar%20tahapan%20pertama. }} # sesuatu yang menjadi tujuan (yang dikritik, dimarahi, dsb) # {{Olr}} bagian tubuh di atas garis khayal pada pusar sampai batas telinga, tidak termasuk lengan atau bahu {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} i84cu29zcrkhous3adap97z0jbjm6pe mendapat 0 141638 1349188 1223996 2026-04-09T10:02:59Z Sofi Solihah 23681 1349188 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|dapat}} # beroleh; memperoleh #:''juara pertama '''mendapat''' medali emas; dalam setahun perusahaan itu mendapat laba lima puluh juta rupiah'' # menerima #:''ia '''mendapat''' kabar buruk kemarin'' # menemukan; memperoleh #:''penjelajah hutan '''mendapat''' harta karun dalam gua'' # mengalami; memperoleh #:''berkali-kali ia '''mendapat''' kesulitan'' # menerima; dikenai #:''ia '''mendapat''' hukuman yang setimpal dengan kesalahannya'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Pemain ini berarti akan '''mendapat''' giliran main pada urutan paling belakang (durit) untuk tahap berikutnya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Pemain%20ini%20berarti%20akan%20mendapat%20giliran%20main%20pada%20urutan%20paling%20belakang%20(%20durit%20)%20untuk%20tahap%20berikutnya. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} gjdnzbfc5c98wkqzcrwyf41qrayjrst berasal 0 142007 1349138 1146711 2026-04-08T20:04:27Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349138 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|asal}} # bermula: <br />''peperangan itu berasal dari sengketa perbatasan'' # bersumber: <br />''berita itu dapat dipercayai karena berasal dari pihak resmi'' # bertempat asal (dibuat, dilahirkan, dsb): #* {{RQ:Mustikarasa |page= 58 |text=Asam kandis jang banjak dipakai di Sumatera tengah, '''berasal''' dari buah jang sekeluarga dengan manggis |norm=Asam kandis yang banjak dipakai di Sumatera tengah, '''berasal''' dari buah yang sekeluarga dengan manggis |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Asam%20kandis%20jang%20banjak%20dipakai%20di%20Sumatera%20tengah%2C%20berasal%20dari%20buah%20jang%20sekeluarga%20dengan%20manggis}} <br />''barang-barang yang berasal dari Jepang terdapat di mana-mana; dia berasal dari Jawa Timur'' # keturunan: <br />''dia berasal dari orang baik-baik'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} brci6k8z5yqoeue4bv239p2vtlf9w2q setelah 0 142085 1348953 1241312 2026-04-08T13:49:47Z Losstreak 36825 1348953 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan se-|telah}} {{-adv-|id}} # sesudah: <br>''setelah makan, ia langsung berangkat ke sekolah'' #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. '''Setelah''' diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} jyomrawvvwqjvkzqvgabxw0umjvwqma lagian 0 142154 1348988 1211032 2026-04-08T16:23:39Z Iripseudocorus 40083 Kutipan23 1348988 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|lagi}} {{-adv-|id}} # {{cak}} lagi pula; tambahan lagi: <br>''lagian apa gunanya aku datang'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Maafkan aku ya, kala itu aku baru belajar berdakwah jadi aku belum tahu harus memulai dengan apa, '''lagian''' waktu itu Kau main emosi saja | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Maafkan%20aku%20ya%2C%20kala%20itu%20aku%20baru%20belajar%20berdakwah%2C%20jadi%20aku%20belum%20tahu%20harus%20memulai%20dengan%20apa%2C%20lagian%20waktu%20itu%20Kau%20main%20emosi%20saja }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} afyy3wqkfpgdlsazvs4xzflkwr8mhge terpatri 0 142282 1348972 1242034 2026-04-08T16:09:04Z Iripseudocorus 40083 Kutipan23 1348972 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|patri}} # dalam keadaan dipatri(kan) # {{kiasan}} terlekat erat-erat; sudah ditetapkan (diteguhkan dsb): <br>''sukar melupakan cinta yang telah terpatri sekian lama'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Semenjak aku sering diskusi dengan Pak Bidin, semakin '''terpatri''' kuat di hatiku untuk merubah profesi ibu sebagai pencari pinang. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Semenjak%20aku%20sering%20diskusi%20dengan%20Pak%20Bidin%2C%20semakin%20terpatri%20kuat%20di%20hatiku%20untuk%20merubah%20profesi%20ibu%20sebagai%20pencari%20pinang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} lav3k5sbpjml08fpqxwrhdg2bdvmrqv sedangkan 0 142302 1349036 1236942 2026-04-08T17:14:29Z Sofi Solihah 23681 1349036 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -kan|sedang}} {{-conj-|id}} # kata penghubung untuk menandai perlawanan; meski ... (sekalipun); selagi ... (sekalipun): <br>''sedangkan Tuan tidak sanggup mengerjakannya, apalagi saya'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kadang - kadang papan kecil berukuran kurang lebih 40 cm persegi atau lantai biasa yang dapat ditulisi untuk papannya sudah cukup memadai, '''sedangkan''' pemainnya cukup duduk di lantai saja. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kadang%20%2D%20kadang%20papan%20kecil%20berukuran%20kurang%20lebih%2040%20cm%20persegi%20atau%20lantai%20biasa%20yang%20dapat%20ditulisi%20untuk%20papannya%20sudah%20cukup%20memadai%2C%20sedangkan%20pemainnya%20cukup%20duduk%20di%20lantai%20saja. }} # padahal: <br>''bagaimana aku dapat menolongmu, sedangkan aku sendiri kekurangan'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 4115mn37e74sovaamu1g0i234qrbamk berlaku 0 142463 1349046 1280407 2026-04-08T17:25:45Z Sofi Solihah 23681 1349046 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|laku}} # ''bentuk [[pasif]] dari'' '''[[mem{{PAGENAME}}kan]]''' # masih berjalan (sedang dikerjakan dsb); berlangsung; terjadi: <br />''jam malam berlaku dari pukul 18.00 sampai pukul 06.00 WIB; penahanan para sandera masih berlaku; peraturan itu sudah dinyatakan tidak berlaku lagi'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Walaupun pengertian cit itu berarti membuat anak cit tersusun berjajar 3 dan kepada pemain yang dapat melakukannya berhak mengambil satu biji milik lawan yang sudah tersusun dalam papan cit, dalam tahap pertama ini (tahap penyusunan anak cit) hak mengambil anak cit lawan itu tidak '''berlaku'''. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Walaupun%20pengertian%20cit%20itu%20berarti%20membuat%20anak%20cit%20tersusun%20berjajar%203%20dan%20kepada%20pemain%20yang%20dapat%20melakukannya%20berhak%20mengambil%20satu%20biji%20milik%20lawan%20yang%20sudah%20tersusun%20dalam%20papan%20cit%2C%20dalam%20tahap%20pertama%20ini%20(%20tahap%20penyusunan%20anak%20cit%20)%20hak%20mengambil%20anak%20cit%20lawan%20itu%20tidak%20berlaku. }} # berbuat; bertindak: <br />''ia suka berlaku kasar terhadap istrinya'' # bertindak menjadi; menjalankan tugas menjadi: <br />''dalam pemilihan umum, presiden pun berlaku sebagai warga negara biasa'' # boleh dipakai (tentang surat, uang, dsb); sah: <br />''surat keterangan Saudara tidak berlaku lagi karena sudah habis masa berlakunya'' # dikenakan untuk atau pada: <br />''aturan ini berlaku bagi sekalian warga negara Indonesia; peraturan lalu lintas itu berlaku bagi semua pemakai jalan'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} choheem6n1f554l55uj4h0hz5en5v57 mengatur 0 142588 1349187 1222252 2026-04-09T10:00:03Z Sofi Solihah 23681 1349187 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|atur}} # membuat (menyusun) sesuatu menjadi teratur (rapi); menata #:''dialah yang '''mengatur''' ruangan ini'' # mengurus #:''siapa yang '''mengatur''' rumah tanggamu?'' # merangkai; menyusun (tentang bunga) #:''ia ahli dalam hal '''mengatur''' bunga'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Meskipun permainan ini melatih orang berfikir, yaitu merancang atau '''mengatur''' siasat, tetapi masih lebih sederhana kalau dibandingkan dengan permainan catur. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Meskipun%20permainan%20ini%20melatih%20orang%20berfikir%2C%20yaitu%20merancang%20atau%20mengatur%20siasat%2C%20tetapi%20masih%20lebih%20sederhana%20kalau%20dibandingkan%20dengan%20permainan%20catur. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} m183bz4r29whfqykzkkino8xfgkgqba mendekat 0 142605 1348938 1224090 2026-04-08T13:16:48Z Losstreak 36825 1348938 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|dekat}} # datang menghampiri: <br>''tentara musuh sudah mendekat'' #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, mengabaikan jadwalnya. Aku tahu, anduang sedang menungguku. Aku '''mendekat''' pelan, anduang membuka matanya. Setelah lima jam yang terasa lambat, ingin sekali rasanya aku memeluk anduang, mengucap maaf yang deras padanya. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang%20masih%20duduk%20di%20kursi%20goyangnya%2C%20mengabaikan%20jadwalnya.%20Aku%20tahu%2C%20anduang%20sedang%20menungguku.%20Aku%20mendekat%20pelan%2C%20anduang%20membuka%20matanya.%20Setelah%20lima%20jam%20yang%20terasa%20lambat%2C%20ingin%20sekali%20rasanya%20aku%20memeluk%20anduang%2C%20mengucap%20maaf%20yang%20deras%20padanya. }} # hampir akan tiba: <br>''kereta dari Surabaya sudah mendekat'' # mau berdamai (bersahabat, bergaul): <br>''kedua belah pihak telah mendekat dan segera akan tercapai persetujuan'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} trdyguetii6xov6wgcycc4xlqs5zd7c menempati 0 142846 1349166 1241507 2026-04-09T08:18:13Z Sofi Solihah 23681 1349166 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-i|tempat}} # bertempat di; menduduki; mendiami: <br>''yang berhak menempati rumah dinas adalah karyawan yang belum memiliki rumah'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Pada giliran berikutnya A memindahkan anak citnya nomor 9 A '''menempati''' bekas kedudukan anak cit nomor 6 B dan langsung cit. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Pada%20giliran%20berikutnya%20A%20memindahkan%20anak%20citnya%20nomor%209%20A%20menempati%20bekas%20kedudukan%20anak%20cit%20nomor%206%20B%20dan%20langsung%20cit. }} # memangku jabatan (pangkat, pekerjaan, dsb): <br>''lebih lima tahun ia menempati jabatan yang penting itu'' # memberi tempat: <br>''dibawanya pundi-pundi besar untuk menempati uang emas itu'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 8r2vox575kk83apmg23fss5cymsatjk berjajar 0 143645 1349044 1154191 2026-04-08T17:23:32Z Sofi Solihah 23681 1349044 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|jajar}} # merupakan baris (banjar, deret); membentuk jajaran (banjar, dsb): <br />''penduduk berdiri berjajar sepanjang jalan yang dilalui pawai pembangunan'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Dalam tahap pertama ini bisa terjadi susunan anak cit milik langsung '''berjajar''' tiga seperti 4A, 7 A dan 3 A atau anak cit milik B seperti 9 B, 5 B dan 11 B. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Dalam%20tahap%20pertama%20ini%20bisa%20terjadi%20susunan%20anak%20cit%20milik%20langsung%20berjajar%20tiga%20seperti%204A%2C%207%20A%20dan%203%20A%20atau%20anak%20cit%20milik%20B%20seperti%209%20B%2C%205%20B%20dan%2011%20B }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} nzl3lbmdlp3jbkx0nv19l06pn0kq02s berperan 0 144096 1349183 1158912 2026-04-09T09:54:56Z Sofi Solihah 23681 1349183 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|peran}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Waiau pengaruh positifnya ada, tapi kurang berperan untuk masa kini, sehingga permainan ini cepat sekali menghilangnya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Waiau%20pengaruh%20positifnya%20ada%2C%20tapi%20kurang%20berperan%20untuk%20masa%20kini%2C%20sehingga%20permainan%20ini%20cepat%20sekali%20menghilangnya. }} # bermain sebagai (dalam sandiwara, film): <br />''di film itu ia berperan sebagai pahlawan'' # bertindak sebagai: <br />''Jimmy Carter berperan sebagai pendamai dalam peperangan di Timur Tengah'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} m1bndasbreykjogf3q109hlltf0dmxh 1349184 1349183 2026-04-09T09:55:48Z Sofi Solihah 23681 1349184 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|peran}} # bermain sebagai (dalam sandiwara, film): <br />''di film itu ia berperan sebagai pahlawan'' # bertindak sebagai: <br />''Jimmy Carter berperan sebagai pendamai dalam peperangan di Timur Tengah'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Waiau pengaruh positifnya ada, tapi kurang '''berperan''' untuk masa kini, sehingga permainan ini cepat sekali menghilangnya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Waiau%20pengaruh%20positifnya%20ada%2C%20tapi%20kurang%20berperan%20untuk%20masa%20kini%2C%20sehingga%20permainan%20ini%20cepat%20sekali%20menghilangnya. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1ha53ko2b7ms9tfov7vsdxcb8u7u6yi terdiri 0 144543 1348927 1224270 2026-04-08T12:52:46Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1348927 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|diri}} # tiba-tiba berdiri: #* {{RQ:Mustikarasa |page= 57 |text=Tjuka ini '''terdiri''' dari asam asetat, jang punja rasa chas untuk atjar² dan sajur lain²nja |norm=Cuka ini '''terdiri''' dari asam asetat, yang punya rasa khas untuk acar-acar dan sayur lain-lainnya |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/66#:~:text=Tjuka%20ini%20terdiri%20dari%20asam%20asetat%2C%20jang%20punja%20rasa%20chas%20untuk%20atjar%C2%B2%20dan%20sajur%20lain%C2%B2nja}} <br>''tahanan itu terdiri hendak menyerang penjaganya'' # telah berdiri; sudah didirikan: <br>''gedung itu terdiri sejak tahun 1928'' # terjadi: <br>''para penyandera itu terdiri atas lima orang'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 2j8nafvfesjtwkm1739r3tmy81aaxwh latihan 0 144777 1349195 1212163 2026-04-09T10:24:44Z Sofi Solihah 23681 1349195 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|latih}} # hasil berlatih: <br>''latihan yang diikutinya sudah memadai'' # {{cak}} pelatihan: <br>''untuk mencapai prestasi yang baik latihan perlu diperbanyak'' # {{cak}} pendidikan untuk memperoleh kemahiran atau kecakapan: <br>''latihan yang diberikan tanpa teori itu kurang bermanfaat'' # {{cak}} berlatih #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Meskipun sebenarnya dalam permainan ini terdapat unsur taruhan, namun sebenarnya terdapat pula unsur-unsur positif yang dapat dipetik yaitu antara lain merupakan '''latihan''' ketepatan melempar suatu sasaran di samping merupakan '''latihan''' kemahiran menentukan strategi dalam melempar tahapan pertama. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Meskipun%20sebenarnya%20dalam%20permainan%20ini%20terdapat%20unsur%20taruhan%2C%20namun%20sebenarnya%20terdapat%20pula%20unsur%2Dunsur%20positif%20yang%20dapat%20dipetik%20yaitu%20antara%20lain%20merupakan%20latihan%20ketepatan%20melempar%20suatu%20sasaran%20di%20samping%20merupakan%20latihan%20kemahiran%20menentukan%20strategi%20dalam%20melempar%20tahapan%20pertama. }} {{-terjemahan-}} {{t-atas}} * bahasa Inggris: {{t+|en|exercise}}, {{t+|en|training}} * bahasa Esperanto: {{t+|eo|ekzerco}} * bahasa Svenska: {{t+|sv|övning}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 1rksgbxr3pp8x7fnekxkfh8dbwmsxoc tersendiri 0 145841 1349190 1237929 2026-04-09T10:08:28Z Sofi Solihah 23681 1349190 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|sendiri}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Di samping itu bagi anak yang selalu tepat melempar bilah pasangan dikatakan anak yang bidik dan ini merupakan kebanggaan '''tersendiri''' bagi pemain tersebut. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Di%20samping%20itu%20bagi%20anak%20yang%20selalu%20tepat%20melempar%20bilah%20pasangan%20dikatakan%20anak%20yang%20bidik%20dan%20ini%20merupakan%20kebanggaan%20tersendiri%20bagi%20pemain%20tersebut. }} # terpisah dari yang lain; terasing; terpencil; teristimewa: <br>''bapaknya selalu mendapat menu makanan tersendiri agar tetap kuat; ia merasa tersendiri di tengah kawan-kawannya'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} fby74li3uzx14gkpuv6p0d076xwe3uj terbayang 0 146226 1348966 1222628 2026-04-08T15:57:54Z Iripseudocorus 40083 Kutipan23 1348966 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ter-|bayang}} # seakan-akan tampak: <br>''wajah kekasihnya terbayang dalam pandangannya'' # tampak bayang-bayangnya: <br>''keelokan tubuh tuan putri itu terbayang dari balik pakaiannya'' # sudah ada tanda-tandanya (akan berhasil dsb): <br>''sudah terbayang bahwa lamarannya akan diterima'' # dapat dilihat; tampak: <br>''pada mukanya terbayang kesedihan yang merisaukan batinnya'' #* {{RQ:Perahu Tulis | page = 132 | author = Balai Bahasa Sumatera Barat | chapter = | text = '''Terbayang''' di pikiranku wajah ibu yang kerjanya setiap pagi mencari pinang di ladang orang, hal yang harus kuubah semestinya. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/144#:~:text=Terbayang%20di%20pikiranku%20wajah%20ibu%20yang%20kerjanya%20setiap%20pagi%20mencari%20pinang%20di%20ladang%20orang%2C%20hal%20yang%20harus%20kuubah%20semestinya. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 6f8ym8ny6zb2d30q80ppnr1nwxcsx4f pemindahan 0 146250 1349173 1233374 2026-04-09T09:33:05Z Sofi Solihah 23681 1349173 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan peng-an|pindah}} # proses, cara, perbuatan memindahkan: <br>''besar kecilnya bantuan Pemerintah terhadap rencana pemindahan itu bergantung pada besar kecilnya dana'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Gerakan '''pemindahan''' anak cit pulang balik ini disebut "arikan". |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Gerakan%20pemindahan%20anak%20cit%20pulang%20balik%20ini%20disebut%20%22arikan%22. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 4yb24jiqc88v2lo8w39hfahzxax19mr menyerah 0 147206 1349175 1229787 2026-04-09T09:35:19Z Sofi Solihah 23681 1349175 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|serah|pasif=intransitif}} # berserah; pasrah: <br>''kita tidak mampu berbuat apa-apa selain dari menyerah kepada Tuhan Yang Mahakuasa'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Untuk mempercepat proses jalannya permainan, kadang - kadang pemain yang sudah dapat mamastikan akan kalah juga, menyatakan langsung '''menyerah''' dan memulai permainan baru lagi. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Untuk%20mempercepat%20proses%20jalannya%20permainan%2C%20kadang%20%2D%20kadang%20pemain%20yang%20sudah%20dapat%20mamastikan%20akan%20kalah%20juga%2C%20menyatakan%20langsung%20menyerah%20dan%20memulai%20permainan%20baru%20lagi. }} # memberikan dirinya kepada yang berwenang: <br>''anggota gerombolan yang menyerah akan diampuni'' # menurut saja (sekehendak orang); tidak melawan: <br>''pendek kata saya menyerah saja, disuruh apa pun baiklah'' # {{kiasan}} mengaku kalah; tunduk (tidak akan melawan lagi): <br>''mereka tidak mau menyerah mentah-mentah; sesudah habis pelurunya, barulah mereka menyerah kalah'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} iqtfrazbf0ynsjjt0d6p49t36h02v5p bersifat 0 149540 1349028 1160803 2026-04-08T17:09:25Z Sofi Solihah 23681 1349028 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|sifat}} # mempunyai sifat (dalam berbagai-bagai arti): <br />''aksi militer itu bersifat menyerang'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Karena permainan ini '''bersifat''' perorangan, maka jumlah pemainnya biasanya tidak lebih dari 2 orang. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Karena%20permainan%20ini%20bersifat%20perorangan%2C%20maka%20jumlah%20pemainnya%20biasanya%20tidak%20lebih%20dari%202%20orang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} g6asize9a0kwzebun7aquif2ps6zl7g mengucap 0 150410 1348947 1243355 2026-04-08T13:36:52Z Losstreak 36825 1348947 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|ucap}} # mengeluarkan ucapan (perkataan): <br>''ia selalu mengucap "bismillah" ketika hendak memulai suatu kegiatan'' #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, mengabaikan jadwalnya. Aku tahu, anduang sedang menungguku. Aku mendekat pelan, anduang membuka matanya. Setelah lima jam yang terasa lambat, ingin sekali rasanya aku memeluk anduang, '''mengucap''' maaf yang deras padanya. Tapi entah mengapa tubuhku kaku. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang,mengapa%20tubuhku%20kaku. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} qwdwf9bmdz9bqrdmt30zbz4g8llx2ag menyinggung 0 150647 1349159 1229813 2026-04-09T05:26:17Z Iripseudocorus 40083 Kutipan24 1349159 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|singgung}} # menyodok (mendesak, menolak, dsb) dengan siku: <br>''petinju itu menyinggung perut lawannya hingga jatuh'' # menyentuh; menjamah; menyenggol: <br>''beliaulah yang menyinggung gelas itu hingga pecah'' # mengenai (sedikit); membicarakan (sedikit): <br>''bab pendahuluan telah menyinggung soal itu'' # melanggar (kehormatan, kekuasaan, dsb): <br>''tulisannya dianggap menyinggung kehormatan Bapak Gubernur'' # {{kiasan}} menyakiti (melukai) hati (perasaan): <br>''kata-katanya menyinggung perasaan'' #* {{RQ:Perahu Tulis | page = 136 | author = Balai Bahasa Sumatera Barat | chapter = | text = "Pen, sebelumnya bapak minta maaf padamu, mungkin telah banyak yang '''menyinggung''' perasaanmu." | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/148#:~:text=%22Pen%2C%20sebelumnya%20bapak%20minta%20maaf%20padamu%2C%20mungkin%20telah%20banyak%20yang%20menyinggung%20perasaanmu.%22 }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} iak3089hd9bae9h4j7y2gc0r13p0kei bergelimang 0 151077 1348992 1149888 2026-04-08T16:28:34Z Iripseudocorus 40083 Kutipan23 1348992 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|gelimang}} # berlumuran lumpur dsb # {{kiasan}} mengandung; penuh dengan: <br />''langit bergelimang awan hitam seperti kapas kena abu dapur'' #* {{RQ:Perahu Tulis | page = 134 | author = Balai Bahasa Sumatera Barat | chapter = | text = Ah, tapi kenapa banyak juga orang yang maling tapi bergelimang dengan harta. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Ah%2C%20tapi%20kenapa%20banyak%20juga%20orang%20yang%20maling%20tapi%20bergelimang%20dengan%20harta. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} saj3k2mz0m6fabid3blgnq6vmjth6mv rasanya 0 151189 1348945 1234755 2026-04-08T13:34:04Z Losstreak 36825 1348945 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|rasa}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, mengabaikan jadwalnya. Aku tahu, anduang sedang menungguku. Aku mendekat pelan, anduang membuka matanya. Setelah lima jam yang terasa lambat, ingin sekali '''rasanya''' aku memeluk anduang, mengucap maaf yang deras padanya. Tapi entah mengapa tubuhku kaku. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang,mengapa%20tubuhku%20kaku. }} {{-adv-|id}} # kiranya {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} i19rpvewntblc4afkeav5mw3j820nlb menggelora 0 151410 1349155 1224985 2026-04-09T05:17:37Z Iripseudocorus 40083 Kutipan24 1349155 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|gelora}} # bergelora #* {{RQ:Perahu Tulis | page = 135 | author = Balai Bahasa Sumatera Barat | chapter = | text = Amarah yang tadi '''menggelora''', berangsur-angsur hilang. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/147#:~:text=Amarah%20yang%20tadi%20menggelora%2C%20berangsur%2Dangsur%20hilang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 8dfd8yvktyaskaakblz7tbk7ktckaso keunggulan 0 151498 1349181 1203930 2026-04-09T09:50:09Z Sofi Solihah 23681 1349181 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ke-an|unggul}} # keadaan (lebih) unggul; keutamaan; kepandaian (kecakapan, kebaikan, kekuatan, dsb) yang lebih daripada yang lain: <br>''keunggulan mesin-mesin kami justru dapat dilihat di lapangan dan di hutan-hutan'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 45 |text= Yang kalah terpaksa harus menerima kekalahannya dengan secara sportif serta harus mengakui keunggulan lawannya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Yang%20kalah%20terpaksa%20harus%20menerima%20kekalahannya%20dengan%20secara%20sportif%20serta%20harus%20mengakui%20keunggulan%20lawannya. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 7ry7zecuizu9uovcz7mqcnonimfb5ys pembuka 0 151650 1348979 1223181 2026-04-08T16:15:26Z Iripseudocorus 40083 Kutipan23 1348979 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan peng-|buka}} # alat untuk membuka: <br>''pembuka kaleng'' # orang yang membuka # pendahuluan: <br>''pembuka kata'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Niat hatiku ingin mengalihkan kebiasaan ibu mengambil barang orang, malah menjadi '''pembuka''' peluang bagi ibu untuk mengambil punya orang. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Niat%20hatiku%20ingin%20mengalihkan%20kebiasaan%20ibu%20mengambil%20barang%20orang%2C%20malah%20menjadi%20pembuka%20peluang%20bagi%20ibu%20untuk%20mengambil%20punya%20orang. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} q3cko4473izgn1yh84nuqvsnenxh2ea beregu 0 152181 1349029 1149274 2026-04-08T17:10:22Z Sofi Solihah 23681 1349029 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-|regu}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dikompetesikan maka permainan menjadi '''beregu''' dan pemainnya bisa menjadi 4 atau 5 satu regunya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dikompetesikan%20maka%20permainan%20menjadi%20beregu%20dan%20pemainnya%20bisa%20menjadi%204%20atau%205%20satu%20regunya. }} # berupa regu; berkelompok yang terdiri atas beberapa orang: <br />''balap sepeda beregu diadakan di jalan raya bebas hambatan'' {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} qs2oix7z0bc9z4gxaprotj82g9s71ox menggerakkan 0 152542 1349168 1229404 2026-04-09T08:59:00Z Sofi Solihah 23681 1349168 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-kan|gerak}} # menjadikan bergerak: <br>''dialah yang menggerakkan buruh untuk mengadakan aksi itu'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Waktu A '''menggerakkan''' biji 9 A ke tempat 6 B yang sudah kosong, A bersuara cit. Kedudukan cit terjadi pada anak cit milik A nomor 5 A, 6 A dan 9 A. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Waktu%20A%20menggerakkan%20biji%209%20A%20ke%20tempat%206%20B%20yang%20sudah%20kosong%2C%20A%20bersuara%20cit.%20Kedudukan%20cit%20terjadi%20pada%20anak%20cit%20milik%20A%20nomor%205%20A%2C%206%20A%20dan%209%20A. }} # {{kiasan}} membangkitkan atau membangunkan (perasaan hati dsb): <br>''rintihannyalah yang menggerakkan hati saya untuk memberi pertolongan'' # {{kiasan}} mengubah kedudukan (untuk armada, pasukan, dsb) {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} iudbdd18kr3j0f0i6ywt90pi7fd9tmf bersuara 0 152798 1349170 1161212 2026-04-09T09:13:44Z Sofi Solihah 23681 1349170 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-}} # mengeluarkan suara #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Waktu A menggerakkan biji 9 A ke tempat 6 B yang sudah kosong, A '''bersuara''' cit. Kedudukan cit terjadi pada anak cit milik A nomor 5 A, 6 A dan 9 A. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Waktu%20A%20menggerakkan%20biji%209%20A%20ke%20tempat%206%20B%20yang%20sudah%20kosong%2C%20A%20bersuara%20cit.%20Kedudukan%20cit%20terjadi%20pada%20anak%20cit%20milik%20A%20nomor%205%20A%2C%206%20A%20dan%209%20A. }} # turut menentukan sesuatu (dalam pemerintahan) # {{kiasan}} mengemukakan pendapat # {{Ling}} dihasilkan dengan getaran pita suara, misal bunyi [b], [d], [g] {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} sukjbmc2du6v2a61jtsvjks6hrqf7xa cadangan 0 153151 1348918 1167178 2026-04-08T12:06:47Z Losstreak 36825 1348918 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|cadang}} # anjuran; usul: <br>''cadangan balasan'' # persediaan; serep: <br>''uang cadangan; hutan cadangan'' #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci '''cadangan''' sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar tidurnya, istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} # {{arkais}} rancangan; rencana: <br>''cadangan lima tahun'' # penyisihan dana yang berasal dari kelebihan atau dari laba yang tidak dibagi-bagikan dsb # {{Komp}} salinan (berkas, dsb.) sebagai jaga-jaga kalau yang asli hilang/rusak {{-terjemahan-}} {{t-atas}} * bahasa Inggris: {{t+|en|backup}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} pazk6xb9gmh30s2w334q7ho2vgz4vpt bergiliran 0 153886 1349050 1153162 2026-04-08T17:30:16Z Sofi Solihah 23681 1349050 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ber-an|gilir}} # secara berganti; bergantian; berganti-ganti: <br />''secara bergiliran anak-anak itu menunggu ibunya yang sakit keras'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Tahap I berakhir setelah semua anak cit tersusun di papan cit, baik milik A maupun milik B. Prinsip cara meletakkan anak cit tersebut harus bergantian / '''bergiliran''' yaitu A, B ; A, B ; A, B dan seterusnya sampai anak cit yang ke 12. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Tahap%20I%20berakhir%20setelah%20semua%20anak%20cit%20tersusun%20di%20papan%20cit%2C%20baik%20milik%20A%20maupun%20milik%20B.%20Prinsip%20cara%20meletakkan%20anak%20cit%20tersebut%20harus%20bergantian%20/%20bergiliran%20yaitu%20A%2C%20B%C2%A0%3B%20A%2C%20B%C2%A0%3B%20A%2C%20B%20dan%20seterusnya%20sampai%20anak%20cit%20yang%20ke%2012. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} aaalc3glzx5hife5wwx9ezf4rdc4xj3 giliran 0 153897 1349042 1185863 2026-04-08T17:20:49Z Sofi Solihah 23681 1349042 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -an|gilir}} # waktu (saat) atau kesempatan untuk mengerjakan (menjalankan) atau menerima sesuatu: <br>''sekarang tibalah giliranku untuk menyanyi; kapal-kapal sedang menunggu giliran dibongkar muatannya'' # pertukaran (pergantian) dengan teratur (tentang sesuatu yang beredar atau yang berlaku berganti-ganti) # hasil menggilir #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kedudukan anak cit A dan B sesudah dua '''giliran''' masing - masing. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Gambar%20diagram%20II%20(%20kedudukan%20anak%20cit%20A%20dan%20B%20sesudah%20dua%20giliran%20masing%20%2D%20masing%20) }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} jwi4el0wmc03s70jlayxpcqmykd6ndj kumengerti 0 173246 1348949 1208749 2026-04-08T13:45:25Z Losstreak 36825 1348949 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan ku-|erti}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak '''kumengerti'''. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} [[Kategori:Turunan kata mengerti]] otx7jwofswijct6pxwel3omfb0uw43k tubuhku 0 174237 1348948 1242824 2026-04-08T13:39:50Z Losstreak 36825 1348948 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -ku|tubuh}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, mengabaikan jadwalnya. Aku tahu, anduang sedang menungguku. Aku mendekat pelan, anduang membuka matanya. Setelah lima jam yang terasa lambat, ingin sekali rasanya aku memeluk anduang, mengucap maaf yang deras padanya. Tapi entah mengapa '''tubuhku''' kaku. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang,mengapa%20tubuhku%20kaku. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} n2sbxkhjupyd7qjiu2wmii0evum8fs2 dasarnya 0 174296 1349189 1172391 2026-04-09T10:05:35Z Sofi Solihah 23681 1349189 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|dasar}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Karena permainan ini pada '''dasarnya''' adalah permainan perorangan maka konsekuensi kalah menang dalam permainan ini adalah bagi pemain yang selalu menang berarti akan banyak mendapatkan karet gelang. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Karena%20permainan%20ini%20pada%20dasarnya%20adalah%20permainan%20perorangan%20maka%20konsekuensi%20kalah%20menang%20dalam%20permainan%20ini%20adalah%20bagi%20pemain%20yang%20selalu%20menang%20berarti%20akan%20banyak%20mendapatkan%20karet%20gelang. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} rmyxcvtoj02kggkfyfhxkeedakht8qd gilirannya 0 174408 1349171 1185866 2026-04-09T09:15:08Z Sofi Solihah 23681 1349171 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|giliran}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Sesudah A memenuhi '''gilirannya''' dan ternyata melakukan cit, maka A mendapat hak mengambil biji / anak cit B sebiji. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Sesudah%20A%20memenuhi%20gilirannya%20dan%20ternyata%20melakukan%20cit%2C%20maka%20A%20mendapat%20hak%20mengambil%20biji%20/%20anak%20cit%20B%20sebiji. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} frualbach2tvslpwmscu2n9v4qifa3f jalannya 0 174538 1349174 1192887 2026-04-09T09:34:12Z Sofi Solihah 23681 1349174 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|jalan}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Untuk mempercepat proses '''jalannya''' permainan, kadang - kadang pemain yang sudah dapat mamastikan akan kalah juga, menyatakan langsung menyerah dan memulai permainan baru lagi. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Untuk%20mempercepat%20proses%20jalannya%20permainan%2C%20kadang%20%2D%20kadang%20pemain%20yang%20sudah%20dapat%20mamastikan%20akan%20kalah%20juga%2C%20menyatakan%20langsung%20menyerah%20dan%20memulai%20permainan%20baru%20lagi. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} hlx6v79mn9fh3bjidk0ibj9rr5k2eht matanya 0 174684 1348940 1220657 2026-04-08T13:18:34Z Losstreak 36825 1348940 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|mata}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Tapi sekarang, anduang masih duduk di kursi goyangnya, mengabaikan jadwalnya. Aku tahu, anduang sedang menungguku. Aku mendekat pelan, anduang membuka '''matanya'''. Setelah lima jam yang terasa lambat, ingin sekali rasanya aku memeluk anduang, mengucap maaf yang deras padanya. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Tapi%20sekarang%2C%20anduang%20masih%20duduk%20di%20kursi%20goyangnya%2C%20mengabaikan%20jadwalnya.%20Aku%20tahu%2C%20anduang%20sedang%20menungguku.%20Aku%20mendekat%20pelan%2C%20anduang%20membuka%20matanya.%20Setelah%20lima%20jam%20yang%20terasa%20lambat%2C%20ingin%20sekali%20rasanya%20aku%20memeluk%20anduang%2C%20mengucap%20maaf%20yang%20deras%20padanya. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} 344ma1pl2ym44esf60j7flrmseuiaxw tidurnya 0 174927 1348926 1242214 2026-04-08T12:52:37Z Losstreak 36825 1348926 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|tidur}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Gelap. Berarti anduang sudah pulang ke rumah. Aku masuk ke rumah, aku memang punya kunci cadangan sendiri. Kudapati anduang sedang tertidur di atas kursi goyangnya. Anduang adalah orang yang paling disiplin terhadap jadwal. Setelah salat isya usai, anduang akan langsung menuju kamar '''tidurnya''', istirahat untuk kemudian bangun lagi tengah malam nanti. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Gelap.%20Berarti%20anduang,tengah%20malam%20nanti. }} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} 3rox31n4zcfysdrfkgs9z1j591f90ri batu-batu 0 186117 1349019 1144634 2026-04-08T17:05:18Z Sofi Solihah 23681 1349019 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{ulang|batu}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Kalau dibandingkan dengan permainan catur, jelas sekali orang lebih menyukai catur dari pada bacit walaupun bacit alatnya sembarang saja misalnya '''batu - batu''' kerikil yang kecil atau potongan bilah lidi yang dipatah - patah. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Kalau%20dibandingkan%20dengan%20permainan%20catur%2C%20jelas%20sekali%20orang%20lebih%20menyukai%20catur%20dari%20pada%20bacit%20walaupun%20bacit%20alatnya%20sembarang%20saja%20misalnya%20batu%20%2D%20batu%20kerikil%20yang%20kecil%20atau%20potongan%20bilah%20lidi%20yang%20dipatah%20%2D%20patah. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} byt6hx4p0gve9p66hqeuybav1h9vn0a dipalsukan 0 188402 1349144 1319944 2026-04-08T20:37:12Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349144 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan di-kan|palsu}} # {{rfdef|id}} #* {{RQ:Mustikarasa |page=30 |text=Didalam perdagangan lada dapat '''dipalsukan''' dengan djagung |norm=Di dalam perdagangan lada dapat '''dipalsukan''' dengan djagung |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/67#:~:text=Didalam%20perdagangan%20lada%20dapat%20dipalsukan%20dengan%20djagung}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} bsn6znt2cykep3p9slfjq1jh4cvencu dipindahkan 0 188526 1349055 1320121 2026-04-08T17:33:58Z Sofi Solihah 23681 1349055 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan di-kan|pindah}} # {{rfdef|id}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Setelah A mengambil 3 biji anak cit milik B, permainan diteruskan oleh B untuk giliran ke dua. B memungut anak citnya 5 B dipindahkan ke tempat bekas 11 B, dengan maksud membuka kemungkinan agar anak citnya bisa cit yaitu apabila anak nomor 7 B '''dipindahkan''' ke tempat bekas biji 5 B. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Setelah%20A%20mengambil%203%20biji%20anak%20cit%20milik%20B%2C%20permainan%20diteruskan%20oleh%20B%20untuk%20giliran%20ke%20dua.%20B%20memungut%20anak%20citnya%205%20B%20dipindahkan%20ke%20tempat%20bekas%2011%20B%2C%20dengan%20maksud%20membuka%20kemungkinan%20agar%20anak%20citnya%20bisa%20cit%20yaitu%20apabila%20anak%20nomor%207%20B%20dipindahkan%20ke%20tempat%20bekas%20biji%205%20B. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} 3pdgppbuckjtlfk16532nkrxkprw31y kujelaskan 0 190179 1348952 1208082 2026-04-08T13:49:20Z Losstreak 36825 1348952 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{verba ku-kan|jelas}} # {{rfdef|id}} #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit '''kujelaskan'''. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk benar-benar berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} p9x3qbpo3ybu19yje65tlpxso4po3b9 misalkan 0 196447 1349037 1230132 2026-04-08T17:16:35Z Sofi Solihah 23681 1349037 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -kan|misal}} # #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= '''Misalkan''' pemain A memegang 12 anak cit dari batu kerikil dan pemain B memegang anak cit dari potongan bilah lidi kira kira 1 cm panjangnya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Misalkan%20pemain%20A%20memegang%2012%20anak%20cit%20dari%20batu%20kerikil%20dan%20pemain%20B%20memegang%20anak%20cit%20dari%20potongan%20bilah%20lidi%20kira%20kira%201%20cm%20panjangnya }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} 96k9dvg5ivs49n2zlc3u6u3uo45shqt merubah 0 198955 1348973 1235739 2026-04-08T16:10:21Z Iripseudocorus 40083 Kutipan23 1348973 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|rubah}} '''merubah''' # {{ragam dari|id|mengubah}}, salah kaprah yang sangat umum dilakukan, kemungkinan dari "robah", "berobah", dan "merobah" (ejaan lama). Bedakan dengan [[rubah]] #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Semenjak aku sering diskusi dengan Pak Bidin, semakin terpatri kuat di hatiku untuk '''merubah''' profesi ibu sebagai pencari pinang. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Semenjak%20aku%20sering%20diskusi%20dengan%20Pak%20Bidin%2C%20semakin%20terpatri%20kuat%20di%20hatiku%20untuk%20merubah%20profesi%20ibu%20sebagai%20pencari%20pinang. }} :"Kini keadaan telah kita robah. Kini kita telah mempunyai Dewan Perwakilan Rakyat pilihan rakyat sendiri. ... :Mental kita harus berobah! Mental kita harus ber-revolusi! " :: -- Soekarno, ''[[:s:Berilah Isi kepada Hidupmu!|Berilah Isi kepada Hidupmu!]]'' 9w7iwt1rw4gljjf2tmhbiluxkzouf0k Modul:languages 828 200722 1348991 1111014 2026-04-08T16:28:32Z Swarabakti 18192 1348991 Scribunto text/plain --[==[ intro: This module implements fetching of language-specific information and processing text in a given language. ===Types of languages=== There are two types of languages: full languages and etymology-only languages. The essential difference is that only full languages appear in L2 headings in vocabulary entries, and hence categories like [[:Category:French nouns]] exist only for full languages. Etymology-only languages have either a full language or another etymology-only language as their parent (in the parent-child inheritance sense), and for etymology-only languages with another etymology-only language as their parent, a full language can always be derived by following the parent links upwards. For example, "Canadian French", code `fr-CA`, is an etymology-only language whose parent is the full language "French", code `fr`. An example of an etymology-only language with another etymology-only parent is "Northumbrian Old English", code `ang-nor`, which has "Anglian Old English", code `ang-ang` as its parent; this is an etymology-only language whose parent is "Old English", code `ang`, which is a full language. (This is because Northumbrian Old English is considered a variety of Anglian Old English.) Sometimes the parent is the "Undetermined" language, code `und`; this is the case, for example, for "substrate" languages such as "Pre-Greek", code `qsb-grc`, and "the BMAC substrate", code `qsb-bma`. It is important to distinguish language ''parents'' from language ''ancestors''. The parent-child relationship is one of containment, i.e. if X is a child of Y, X is considered a variety of Y. On the other hand, the ancestor-descendant relationship is one of descent in time. For example, "Classical Latin", code `la-cla`, and "Late Latin", code `la-lat`, are both etymology-only languages with "Latin", code `la`, as their parents, because both of the former are varieties of Latin. However, Late Latin does *NOT* have Classical Latin as its parent because Late Latin is *not* a variety of Classical Latin; rather, it is a descendant. There is in fact a separate `ancestors` field that is used to express the ancestor-descendant relationship, and Late Latin's ancestor is given as Classical Latin. It is also important to note that sometimes an etymology-only language is actually the conceptual ancestor of its parent language. This happens, for example, with "Old Italian" (code `roa-oit`), which is an etymology-only variant of full language "Italian" (code `it`), and with "Old Latin" (code `itc-ola`), which is an etymology-only variant of Latin. In both cases, the full language has the etymology-only variant listed as an ancestor. This allows a Latin term to inherit from Old Latin using the {{tl|inh}} template (where in this template, "inheritance" refers to ancestral inheritance, i.e. inheritance in time, rather than in the parent-child sense); likewise for Italian and Old Italian. Full languages come in three subtypes: * {regular}: This indicates a full language that is attested according to [[WT:CFI]] and therefore permitted in the main namespace. There may also be reconstructed terms for the language, which are placed in the {Reconstruction} namespace and must be prefixed with * to indicate a reconstruction. Most full languages are natural (not constructed) languages, but a few constructed languages (e.g. Esperanto and Volapük, among others) are also allowed in the mainspace and considered regular languages. * {reconstructed}: This language is not attested according to [[WT:CFI]], and therefore is allowed only in the {Reconstruction} namespace. All terms in this language are reconstructed, and must be prefixed with *. Languages such as Proto-Indo-European and Proto-Germanic are in this category. * {appendix-constructed}: This language is attested but does not meet the additional requirements set out for constructed languages ([[WT:CFI#Constructed languages]]). Its entries must therefore be in the Appendix namespace, but they are not reconstructed and therefore should not have * prefixed in links. Most constructed languages are of this subtype. Both full languages and etymology-only languages have a {Language} object associated with them, which is fetched using the {getByCode} function in [[Module:languages]] to convert a language code to a {Language} object. Depending on the options supplied to this function, etymology-only languages may or may not be accepted, and family codes may be accepted (returning a {Family} object as described in [[Module:families]]). There are also separate {getByCanonicalName} functions in [[Module:languages]] and [[Module:etymology languages]] to convert a language's canonical name to a {Language} object (depending on whether the canonical name refers to a full or etymology-only language). ===Textual representations=== Textual strings belonging to a given language come in several different ''text variants'': # The ''input text'' is what the user supplies in wikitext, in the parameters to {{tl|m}}, {{tl|l}}, {{tl|ux}}, {{tl|t}}, {{tl|lang}} and the like. # The ''corrected input text'' is the input text with some corrections and/or normalizations applied, such as bad-character replacements for certain languages, like replacing `l` or `1` to [[palochka]] in some languages written in Cyrillic. (FIXME: This currently goes under the name ''display text'' but that will be repurposed below. Also, [[User:Surjection]] suggests renaming this to ''normalized input text'', but "normalized" is used in a different sense in [[Module:usex]].) # The ''display text'' is the text in the form as it will be displayed to the user. This is what appears in headwords, in usexes, in displayed internal links, etc. This can include accent marks that are removed to form the stripped display text (see below), as well as embedded bracketed links that are variously processed further. The display text is generated from the corrected input text by applying language-specific transformations; for most languages, there will be no such transformations. The general reason for having a difference between input and display text is to allow for extra information in the input text that is not displayed to the user but is sent to the transliteration module. Note that having different display and input text is only supported currently through special-casing but will be generalized. Examples of transformations are: (1) Removing the {{cd|^}} that is used in certain East Asian (and possibly other unicameral) languages to indicate capitalization of the transliteration (which is currently special-cased); (2) for Korean, removing or otherwise processing hyphens (which is currently special-cased); (3) for Arabic, removing a ''sukūn'' diacritic placed over a ''tāʔ marbūṭa'' (like this: ةْ) to indicate that the ''tāʔ marbūṭa'' is pronounced and transliterated as /t/ instead of being silent [NOTE, NOT IMPLEMENTED YET]; (4) for Thai and Khmer, converting space-separated words to bracketed words and resolving respelling substitutions such as `[กรีน/กฺรีน]`, which indicate how to transliterate given words [NOTE, NOT IMPLEMENTED YET except in language-specific templates like {{tl|th-usex}}]. ## The ''right-resolved display text'' is the result of removing brackets around one-part embedded links and resolving two-part embedded links into their right-hand components (i.e. converting two-part links into the displayed form). The process of right-resolution is what happens when you call {{cd|remove_links()}} in [[Module:links]] on some text. When applied to the display text, it produces exactly what the user sees, without any link markup. # The ''stripped display text'' is the result of applying diacritic-stripping to the display text. ## The ''left-resolved stripped display text'' [NEED BETTER NAME] is the result of applying left-resolution to the stripped display text, i.e. similar to right-resolution but resolving two-part embedded links into their left-hand components (i.e. the linked-to page). If the display text refers to a single page, the resulting of applying diacritic stripping and left-resolution produces the ''logical pagename''. # The ''physical pagename text'' is the result of converting the stripped display text into physical page links. If the stripped display text contains embedded links, the left side of those links is converted into physical page links; otherwise, the entire text is considered a pagename and converted in the same fashion. The conversion does three things: (1) converts characters not allowed in pagenames into their "unsupported title" representation, e.g. {{cd|Unsupported titles/`gt`}} in place of the logical name {{cd|>}}; (2) handles certain special-cased unsupported-title logical pagenames, such as {{cd|Unsupported titles/Space}} in place of {{cd|[space]}} and {{cd|Unsupported titles/Ancient Greek dish}} in place of a very long Greek name for a gourmet dish as found in Aristophanes; (3) converts "mammoth" pagenames such as [[a]] into their appropriate split component, e.g. [[a/languages A to L]]. # The ''source translit text'' is the text as supplied to the language-specific {{cd|transliterate()}} method. The form of the source translit text may need to be language-specific, e.g Thai and Khmer will need the corrected input text, whereas other languages may need to work off the display text. [FIXME: It's still unclear to me how embedded bracketed links are handled in the existing code.] In general, embedded links need to be right-resolved (see above), but when this happens is unclear to me [FIXME]. Some languages have a chop-up-and-paste-together scheme that sends parts of the text through the transliterate mechanism, and for others (those listed with "cont" in {{cd|substitution}} in [[Module:languages/data]]) they receive the full input text, but preprocessed in certain ways. (The wisdom of this is still unclear to me.) # The ''transliterated text'' (or ''transliteration'') is the result of transliterating the source translit text. Unlike for all the other text variants except the transcribed text, it is always in the Latin script. # The ''transcribed text'' (or ''transcription'') is the result of transcribing the source translit text, where "transcription" here means a close approximation to the phonetic form of the language in languages (e.g. Akkadian, Sumerian, Ancient Egyptian, maybe Tibetan) that have a wide difference between the written letters and spoken form. Unlike for all the other text variants other than the transliterated text, it is always in the Latin script. Currently, the transcribed text is always supplied manually be the user; there is no such thing as a {{cd|transcribe()}} method on language objects. # The ''sort key'' is the text used in sort keys for determining the placing of pages in categories they belong to. The sort key is generated from the pagename or a specified ''sort base'' by lowercasing, doing language-specific transformations and then uppercasing the result. If the sort base is supplied and is generated from input text, it needs to be converted to display text, have embedded links removed through right-resolution and have diacritic-stripping applied. # There are other text variants that occur in usexes (specifically, there are normalized variants of several of the above text variants), but we can skip them for now. The following methods exist on {Language} objects to convert between different text variants: # {correctInputText} (currently called {makeDisplayText}): This converts input text to corrected input text. # {stripDiacritics}: This converts to stripped display text. [FIXME: This needs some rethinking. In particular, {stripDiacritics} is sometimes called on input text, corrected input text or display text (in various paths inside of [[Module:links]], and, in the case of input text, usually from other modules). We need to make sure we don't try to convert input text to display text twice, but at the same time we need to support calling it directly on input text since so many modules do this. This means we need to add a parameter indicating whether the passed-in text is input, corrected input, or display text; if the former two, we call {correctInputText} ourselves.] # {logicalToPhysical}: This converts logical pagenames to physical pagenames. # {transliterate}: This appears to convert input text with embedded brackets removed into a transliteration. [FIXME: This needs some rethinking. In particular, it calls {processDisplayText} on its input, which won't work for Thai and Khmer, so we may need language-specific flags indicating whether to pass the input text directly to the language transliterate method. In addition, I'm not sure how embedded links are handled in the existing translit code; a lot of callers remove the links themselves before calling {transliterate()}, which I assume is wrong.] # {makeSortKey}: This converts display text (?) to a sort key. [FIXME: Clarify this.] ]==] local export = {} local debug_track_module = "Module:debug/track" local etymology_languages_data_module = "Module:etymology languages/data" local families_module = "Module:families" local headword_page_module = "Module:headword/page" local json_module = "Module:JSON" local language_like_module = "Module:language-like" local languages_data_module = "Module:languages/data" local languages_data_patterns_module = "Module:languages/data/patterns" local links_data_module = "Module:links/data" local load_module = "Module:load" local scripts_module = "Module:scripts" local scripts_data_module = "Module:scripts/data" local string_encode_entities_module = "Module:string/encode entities" local string_pattern_escape_module = "Module:string/patternEscape" local string_replacement_escape_module = "Module:string/replacementEscape" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local wikimedia_languages_module = "Module:wikimedia languages" local mw = mw local string = string local table = table local char = string.char local concat = table.concat local find = string.find local floor = math.floor local get_by_code -- Defined below. local get_data_module_name -- Defined below. local get_extra_data_module_name -- Defined below. local getmetatable = getmetatable local gmatch = string.gmatch local gsub = string.gsub local insert = table.insert local ipairs = ipairs local is_known_language_tag = mw.language.isKnownLanguageTag local make_object -- Defined below. local match = string.match local next = next local pairs = pairs local remove = table.remove local require = require local select = select local setmetatable = setmetatable local sub = string.sub local type = type local unstrip = mw.text.unstrip -- Loaded as needed by findBestScript. local Hans_chars local Hant_chars local function check_object(...) check_object = require(utilities_module).check_object return check_object(...) 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 local function deep_copy(...) deep_copy = require(table_module).deepCopy return deep_copy(...) end local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function get_L2_sort_key(...) get_L2_sort_key = require(headword_page_module).get_L2_sort_key return get_L2_sort_key(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) 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 get_family(...) get_family = require(families_module).getByCode return get_family(...) end local function get_plaintext(...) get_plaintext = require(utilities_module).get_plaintext return get_plaintext(...) end local function get_wikimedia_lang(...) get_wikimedia_lang = require(wikimedia_languages_module).getByCode return get_wikimedia_lang(...) end local function keys_to_list(...) keys_to_list = require(table_module).keysToList return keys_to_list(...) end local function list_to_set(...) list_to_set = require(table_module).listToSet return list_to_set(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function make_family_object(...) make_family_object = require(families_module).makeObject return make_family_object(...) end local function pattern_escape(...) pattern_escape = require(string_pattern_escape_module) return pattern_escape(...) end local function replacement_escape(...) replacement_escape = require(string_replacement_escape_module) return replacement_escape(...) end local function safe_require(...) safe_require = require(load_module).safe_require return safe_require(...) 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 to_json(...) to_json = require(json_module).toJSON return to_json(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function ulen(...) ulen = require(string_utilities_module).len return ulen(...) 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 function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end local function track(page) debug_track("languages/" .. page) return true end local function normalize_code(code) return load_data(languages_data_module).aliases[code] or code end local function check_inputs(self, check, default, ...) local n = select("#", ...) if n == 0 then return false end local ret = check(self, (...)) if ret ~= nil then return ret elseif n > 1 then local inputs = {...} for i = 2, n do ret = check(self, inputs[i]) if ret ~= nil then return ret end end end return default end local function make_link(self, target, display) local prefix, main if self:getFamilyCode() == "qfa-sub" then prefix, main = display:match("^(the )(.*)") if not prefix then prefix, main = display:match("^(a )(.*)") end end return (prefix or "") .. "[[" .. target .. "|" .. (main or display) .. "]]" end -- Convert risky characters to HTML entities, which minimizes interference once returned (e.g. for "sms:a", "<!-- -->" etc.). local function escape_risky_characters(text) -- Spacing characters in isolation generally need to be escaped in order to be properly processed by the MediaWiki software. if umatch(text, "^%s*$") then return encode_entities(text, text) end return encode_entities(text, "!#%&*+/:;<=>?@[\\]_{|}") end -- Temporarily convert various formatting characters to PUA to prevent them from being disrupted by the substitution process. local function doTempSubstitutions(text, subbedChars, keepCarets, noTrim) -- Clone so that we don't insert any extra patterns into the table in package.loaded. For some reason, using require seems to keep memory use down; probably because the table is always cloned. local patterns = shallow_copy(require(languages_data_patterns_module)) if keepCarets then insert(patterns, "((\\+)%^)") insert(patterns, "((%^))") end -- Ensure any whitespace at the beginning and end is temp substituted, to prevent it from being accidentally trimmed. We only want to trim any final spaces added during the substitution process (e.g. by a module), which means we only do this during the first round of temp substitutions. if not noTrim then insert(patterns, "^([\128-\191\244]*(%s+))") insert(patterns, "((%s+)[\128-\191\244]*)$") end -- Pre-substitution, of "[[" and "]]", which makes pattern matching more accurate. text = gsub(text, "%f[%[]%[%[", "\1"):gsub("%f[%]]%]%]", "\2") local i = #subbedChars for _, pattern in ipairs(patterns) do -- Patterns ending in \0 stand are for things like "[[" or "]]"), so the inserted PUA are treated as breaks between terms by modules that scrape info from pages. local term_divider pattern = gsub(pattern, "%z$", function(divider) term_divider = divider == "\0" return "" end) text = gsub(text, pattern, function(...) local m = {...} local m1New = m[1] for k = 2, #m do local n = i + k - 1 subbedChars[n] = m[k] local byte2 = floor(n / 4096) % 64 + (term_divider and 128 or 136) local byte3 = floor(n / 64) % 64 + 128 local byte4 = n % 64 + 128 m1New = gsub(m1New, pattern_escape(m[k]), "\244" .. char(byte2) .. char(byte3) .. char(byte4), 1) end i = i + #m - 1 return m1New end) end text = gsub(text, "\1", "%[%["):gsub("\2", "%]%]") return text, subbedChars end -- Reinsert any formatting that was temporarily substituted. local function undoTempSubstitutions(text, subbedChars) for i = 1, #subbedChars do local byte2 = floor(i / 4096) % 64 + 128 local byte3 = floor(i / 64) % 64 + 128 local byte4 = i % 64 + 128 text = gsub(text, "\244[" .. char(byte2) .. char(byte2+8) .. "]" .. char(byte3) .. char(byte4), replacement_escape(subbedChars[i])) end text = gsub(text, "\1", "%[%["):gsub("\2", "%]%]") return text end -- Check if the raw text is an unsupported title, and if so return that. Otherwise, remove HTML entities. We do the pre-conversion to avoid loading the unsupported title list unnecessarily. local function checkNoEntities(self, text) local textNoEnc = decode_entities(text) if textNoEnc ~= text and load_data(links_data_module).unsupported_titles[text] then return text else return textNoEnc end end -- If no script object is provided (or if it's invalid or None), get one. local function checkScript(text, self, sc) if not check_object("script", true, sc) or sc:getCode() == "None" then return self:findBestScript(text) end return sc end local function normalize(text, sc) text = sc:fixDiscouragedSequences(text) return sc:toFixedNFD(text) end -- Subfunction of iterateSectionSubstitutions(). Process an individual chunk of text according to the specifications in -- `substitution_data`. The input parameters are all as in the documentation of iterateSectionSubstitutions() except for -- `recursed`, which is set to true if we called ourselves recursively to process a script-specific setting or -- script-wide fallback. Returns two values: the processed text and the actual substitution data used to do the -- substitutions (same as the `actual_substitution_data` return value to iterateSectionSubstitutions()). local function doSubstitutions(self, text, sc, substitution_data, data_field, function_name, recursed) -- BE CAREFUL in this function because the value at any level can be `false`, which causes no processing to be done -- and blocks any further fallback processing. local actual_substitution_data = substitution_data -- If there are language-specific substitutes given in the data module, use those. if type(substitution_data) == "table" then -- If a script is specified, run this function with the script-specific data before continuing. local sc_code = sc:getCode() local has_substitution_data = false if substitution_data[sc_code] ~= nil then has_substitution_data = true if substitution_data[sc_code] then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data[sc_code], data_field, function_name, true) end -- Hant, Hans and Hani are usually treated the same, so add a special case to avoid having to specify each one -- separately. elseif sc_code:match("^Han") and substitution_data.Hani ~= nil then has_substitution_data = true if substitution_data.Hani then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data.Hani, data_field, function_name, true) end -- Substitution data with key 1 in the outer table may be given as a fallback. elseif substitution_data[1] ~= nil then has_substitution_data = true if substitution_data[1] then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data[1], data_field, function_name, true) end end -- Iterate over all strings in the "from" subtable, and gsub with the corresponding string in "to". We work with -- the NFD decomposed forms, as this simplifies many substitutions. if substitution_data.from then has_substitution_data = true for i, from in ipairs(substitution_data.from) do -- Normalize each loop, to ensure multi-stage substitutions work correctly. text = sc:toFixedNFD(text) text = ugsub(text, sc:toFixedNFD(from), substitution_data.to[i] or "") end end if substitution_data.remove_diacritics then has_substitution_data = true text = sc:toFixedNFD(text) -- Convert exceptions to PUA. local remove_exceptions, substitutes = substitution_data.remove_exceptions if remove_exceptions then substitutes = {} local i = 0 for _, exception in ipairs(remove_exceptions) do exception = sc:toFixedNFD(exception) text = ugsub(text, exception, function(m) i = i + 1 local subst = u(0x80000 + i) substitutes[subst] = m return subst end) end end -- Strip diacritics. text = ugsub(text, "[" .. substitution_data.remove_diacritics .. "]", "") -- Convert exceptions back. if remove_exceptions then text = text:gsub("\242[\128-\191]*", substitutes) end end if not has_substitution_data and sc._data[data_field] then -- If language-specific sort key (etc.) is nil, fall back to script-wide sort key (etc.). text, actual_substitution_data = doSubstitutions(self, text, sc, sc._data[data_field], data_field, function_name, true) end elseif type(substitution_data) == "string" then -- If there is a dedicated function module, use that. local module = safe_require("Module:" .. substitution_data) if module then -- TODO: translit functions should take objects, not codes. -- TODO: translit functions should be called with form NFD. if function_name == "tr" then if not module[function_name] then error(("Internal error: Module [[%s]] has no function named 'tr'"):format(substitution_data)) end text = module[function_name](text, self._code, sc:getCode()) elseif function_name == "stripDiacritics" then -- FIXME, get rid of this arm after renaming makeEntryName -> stripDiacritics. if module[function_name] then text = module[function_name](sc:toFixedNFD(text), self, sc) elseif module.makeEntryName then text = module.makeEntryName(sc:toFixedNFD(text), self, sc) else error(("Internal error: Module [[%s]] has no function named 'stripDiacritics' or 'makeEntryName'" ):format(substitution_data)) end else if not module[function_name] then error(("Internal error: Module [[%s]] has no function named '%s'"):format( substitution_data, function_name)) end text = module[function_name](sc:toFixedNFD(text), self, sc) end else error("Substitution data '" .. substitution_data .. "' does not match an existing module.") end elseif substitution_data == nil and sc._data[data_field] then -- If language-specific sort key (etc.) is nil, fall back to script-wide sort key (etc.). text, actual_substitution_data = doSubstitutions(self, text, sc, sc._data[data_field], data_field, function_name, true) end -- Don't normalize to NFC if this is the inner loop or if a module returned nil. if recursed or not text then return text, actual_substitution_data end -- Fix any discouraged sequences created during the substitution process, and normalize into the final form. return sc:toFixedNFC(sc:fixDiscouragedSequences(text)), actual_substitution_data end -- Split the text into sections, based on the presence of temporarily substituted formatting characters, then iterate -- over each section to apply substitutions (e.g. transliteration or diacritic stripping). This avoids putting PUA -- characters through language-specific modules, which may be unequipped for them. This function is passed the following -- values: -- * `self` (the Language object); -- * `text` (the text to process); -- * `sc` (the script of the text, which must be specified; callers should call checkScript() as needed to autodetect the -- script of the text if not given explicitly by the user); -- * `subbedChars` (an array of the same length as the text, indicating which characters have been substituted and by -- what, or {nil} if no substitutions are to happen); -- * `keepCarets` (DOCUMENT ME); -- * `substitution_data` (the data indicating which substitutions to apply, taken directly from `data_field` in the -- language's data structure in a submodule of [[Module:languages/data]]); -- * `data_field` (the data field from which `substitution_data` was fetched, such as "sort_key" or "strip_diacritics"); -- * `function_name` (the name of the function to call to do the substitution, in case `substitution_data` specifies a -- module to do the substitution); -- * `notrim` (don't trim whitespace at the edges of `text`; set when computing the sort key, because whitespace at the -- beginning of a sort key is significant and causes the resulting page to be sorted at the beginning of the category -- it's in). -- Returns three values: -- (1) the processed text; -- (2) the value of `subbedChars` that was passed in, possibly modified with additional character substitutions; will be -- {nil} if {nil} was passed in; -- (3) the actual substitution data that was used to apply substitutions to `text`; this may be different from the value -- of `substitution_data` passed in if that value recursively specified script-specific substitutions or if no -- substitution data could be found in the language-specific data (e.g. {nil} was passed in or a structure was passed -- in that had no setting for the script given in `sc`), but a script-wide fallback value was set; currently it is -- only used by makeSortKey(). local function iterateSectionSubstitutions(self, text, sc, subbedChars, keepCarets, substitution_data, data_field, function_name, notrim) local sections -- See [[Module:languages/data]]. if not find(text, "\244") or load_data(languages_data_module).substitution[self._code] == "cont" then sections = {text} else sections = split(text, "\244[\128-\143][\128-\191]*", true) end local actual_substitution_data for _, section in ipairs(sections) do -- Don't bother processing empty strings or whitespace (which may also not be handled well by dedicated -- modules). if gsub(section, "%s+", "") ~= "" then local sub, this_actual_substitution_data = doSubstitutions(self, section, sc, substitution_data, data_field, function_name) actual_substitution_data = this_actual_substitution_data -- Second round of temporary substitutions, in case any formatting was added by the main substitution -- process. However, don't do this if the section contains formatting already (as it would have had to have -- been escaped to reach this stage, and therefore should be given as raw text). if sub and subbedChars then local noSub for _, pattern in ipairs(require(languages_data_patterns_module)) do if match(section, pattern .. "%z?") then noSub = true end end if not noSub then sub, subbedChars = doTempSubstitutions(sub, subbedChars, keepCarets, true) end end if not sub then text = sub break end text = sub and gsub(text, pattern_escape(section), replacement_escape(sub), 1) or text end end if not notrim then -- Trim, unless there are only spacing characters, while ignoring any final formatting characters. -- Do not trim sort keys because spaces at the beginning are significant. text = text and text:gsub("^([\128-\191\244]*)%s+(%S)", "%1%2"):gsub("(%S)%s+([\128-\191\244]*)$", "%1%2") or nil end return text, subbedChars, actual_substitution_data end -- Process carets (and any escapes). Default to simple removal, if no pattern/replacement is given. local function processCarets(text, pattern, repl) local rep repeat text, rep = gsub(text, "\\\\(\\*^)", "\3%1") until rep == 0 return (text:gsub("\\^", "\4") :gsub(pattern or "%^", repl or "") :gsub("\3", "\\") :gsub("\4", "^")) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). local function removeCarets(text, sc) if not sc:hasCapitalization() and sc:isTransliterated() and text:find("^", 1, true) then return processCarets(text) else return text end end local Language = {} local Bahasa = require("Module:bahasa") --[==[Returns the language code of the language. Example: {{code|lua|"fr"}} for French.]==] function Language:getCode() return Bahasa.getLangCodeByCode(self._code) or self._code end --[==[Returns the canonical name of the language. This is the name used to represent that language on Wiktionary, and is guaranteed to be unique to that language alone. Example: {{code|lua|"French"}} for French.]==] function Language:getCanonicalName() local canonical = Bahasa.getLangNameByCode(self._code) if canonical then self._name = canonical return canonical end local name = self._name if name == nil then name = self._data[1] self._name = name end return name end --lowercase version function Language:getCanonicalNameLower() local name = self:getCanonicalName() local first = mw.ustring.sub(name, 1, 1) local rest = mw.ustring.sub(name, 2) return mw.ustring.lower(first) .. rest end --[==[ Return the display form of the language. The display form of a language, family or script is the form it takes when appearing as the <code><var>source</var></code> in categories such as <code>English terms derived from <var>source</var></code> or <code>English given names from <var>source</var></code>, and is also the displayed text in {makeCategoryLink()} links. For full and etymology-only languages, this is the same as the canonical name, but for families, it reads <code>"<var>name</var> languages"</code> (e.g. {"Indo-Iranian languages"}), and for scripts, it reads <code>"<var>name</var> script"</code> (e.g. {"Arabic script"}). ]==] function Language:getDisplayForm() local form = self._displayForm if form == nil then form = self:getCanonicalName() -- Add article and " substrate" to substrates that lack them. if self:getFamilyCode() == "qfa-sub" then if not (sub(form, 1, 4) == "the " or sub(form, 1, 2) == "a ") then form = "a " .. form end if not match(form, " [Ss]ubstrate") then form = form .. " substrate" end end self._displayForm = form end return form end --[==[Returns the value which should be used in the HTML lang= attribute for tagged text in the language.]==] function Language:getHTMLAttribute(sc, region) local code = self._code if not find(code, "-", 1, true) then return code .. "-" .. sc:getCode() .. (region and "-" .. region or "") end local parent = self:getParent() region = region or match(code, "%f[%u][%u-]+%f[%U]") if parent then return parent:getHTMLAttribute(sc, region) end -- TODO: ISO family codes can also be used. return "mis-" .. sc:getCode() .. (region and "-" .. region or "") end --[==[Returns a table of the aliases that the language is known by, excluding the canonical name. Aliases are synonyms for the language in question. The names are not guaranteed to be unique, in that sometimes more than one language is known by the same name. Example: {{code|lua|{"High German", "New High German", "Deutsch"} }} for [[:Category:German language|German]].]==] function Language:getAliases() self:loadInExtraData() return require(language_like_module).getAliases(self) end --[==[ Return a table of the known subvarieties of a given language, excluding subvarieties that have been given explicit etymology-only language codes. The names are not guaranteed to be unique, in that sometimes a given name refers to a subvariety of more than one language. Example: {{code|lua|{"Southern Aymara", "Central Aymara"} }} for [[:Category:Aymara language|Aymara]]. Note that the returned value can have nested tables in it, when a subvariety goes by more than one name. Example: {{code|lua|{"North Azerbaijani", "South Azerbaijani", {"Afshar", "Afshari", "Afshar Azerbaijani", "Afchar"}, {"Qashqa'i", "Qashqai", "Kashkay"}, "Sonqor"} }} for [[:Category:Azerbaijani language|Azerbaijani]]. Here, for example, Afshar, Afshari, Afshar Azerbaijani and Afchar all refer to the same subvariety, whose preferred name is Afshar (the one listed first). To avoid a return value with nested tables in it, specify a non-{{code|lua|nil}} value for the <code>flatten</code> parameter; in that case, the return value would be {{code|lua|{"North Azerbaijani", "South Azerbaijani", "Afshar", "Afshari", "Afshar Azerbaijani", "Afchar", "Qashqa'i", "Qashqai", "Kashkay", "Sonqor"} }}. ]==] function Language:getVarieties(flatten) self:loadInExtraData() return require(language_like_module).getVarieties(self, flatten) end --[==[Returns a table of the "other names" that the language is known by, which are listed in the <code>otherNames</code> field. It should be noted that the <code>otherNames</code> field itself is deprecated, and entries listed there should eventually be moved to either <code>aliases</code> or <code>varieties</code>.]==] function Language:getOtherNames() -- To be eventually removed, once there are no more uses of the `otherNames` field. self:loadInExtraData() return require(language_like_module).getOtherNames(self) end --[==[ Return a combined table of the canonical name, aliases, varieties and other names of a given language.]==] function Language:getAllNames() self:loadInExtraData() return require(language_like_module).getAllNames(self) end --[==[Returns a table of types as a lookup table (with the types as keys). The possible types are * {language}: This is a language, either full or etymology-only. * {full}: This is a "full" (not etymology-only) language, i.e. the union of {regular}, {reconstructed} and {appendix-constructed}. Note that the types {full} and {etymology-only} also exist for families, so if you want to check specifically for a full language and you have an object that might be a family, you should use {{lua|hasType("language", "full")}} and not simply {{lua|hasType("full")}}. * {etymology-only}: This is an etymology-only (not full) language, whose parent is another etymology-only language or a full language. Note that the types {full} and {etymology-only} also exist for families, so if you want to check specifically for an etymology-only language and you have an object that might be a family, you should use {{lua|hasType("language", "etymology-only")}} and not simply {{lua|hasType("etymology-only")}}. * {regular}: This indicates a full language that is attested according to [[WT:CFI]] and therefore permitted in the main namespace. There may also be reconstructed terms for the language, which are placed in the {Reconstruction} namespace and must be prefixed with * to indicate a reconstruction. Most full languages are natural (not constructed) languages, but a few constructed languages (e.g. Esperanto and Volapük, among others) are also allowed in the mainspace and considered regular languages. * {reconstructed}: This language is not attested according to [[WT:CFI]], and therefore is allowed only in the {Reconstruction} namespace. All terms in this language are reconstructed, and must be prefixed with *. Languages such as Proto-Indo-European and Proto-Germanic are in this category. * {appendix-constructed}: This language is attested but does not meet the additional requirements set out for constructed languages ([[WT:CFI#Constructed languages]]). Its entries must therefore be in the Appendix namespace, but they are not reconstructed and therefore should not have * prefixed in links. ]==] function Language:getTypes() local types = self._types if types == nil then types = {language = true} if self:getFullCode() == self._code then types.full = true else types["etymology-only"] = true end for t in gmatch(self._data.type, "[^,]+") do types[t] = true end self._types = types end return types end --[==[Given a list of types as strings, returns true if the language has all of them.]==] function Language:hasType(...) Language.hasType = require(language_like_module).hasType return self:hasType(...) end --[==[Returns a table containing <code>WikimediaLanguage</code> objects (see [[Module:wikimedia languages]]), which represent languages and their codes as they are used in Wikimedia projects for interwiki linking and such. More than one object may be returned, as a single Wiktionary language may correspond to multiple Wikimedia languages. For example, Wiktionary's single code <code>sh</code> (Serbo-Croatian) maps to four Wikimedia codes: <code>sh</code> (Serbo-Croatian), <code>bs</code> (Bosnian), <code>hr</code> (Croatian) and <code>sr</code> (Serbian). The code for the Wikimedia language is retrieved from the <code>wikimedia_codes</code> property in the data modules. If that property is not present, the code of the current language is used. If none of the available codes is actually a valid Wikimedia code, an empty table is returned.]==] function Language:getWikimediaLanguages() local wm_langs = self._wikimediaLanguageObjects if wm_langs == nil then local codes = self:getWikimediaLanguageCodes() wm_langs = {} for i = 1, #codes do wm_langs[i] = get_wikimedia_lang(codes[i]) end self._wikimediaLanguageObjects = wm_langs end return wm_langs end function Language:getWikimediaLanguageCodes() local wm_langs = self._wikimediaLanguageCodes if wm_langs == nil then wm_langs = self._data.wikimedia_codes if wm_langs then wm_langs = split(wm_langs, ",", true, true) else local code = self._code if is_known_language_tag(code) then wm_langs = {code} else -- Inherit, but only if no codes are specified in the data *and* -- the language code isn't a valid Wikimedia language code. local parent = self:getParent() wm_langs = parent and parent:getWikimediaLanguageCodes() or {} end end self._wikimediaLanguageCodes = wm_langs end return wm_langs end --[==[ Returns the name of the Wikipedia article for the language. `project` specifies the language and project to retrieve the article from, defaulting to {"enwiki"} for the English Wikipedia. Normally if specified it should be the project code for a specific-language Wikipedia e.g. "zhwiki" for the Chinese Wikipedia, but it can be any project, including non-Wikipedia ones. If the project is the English Wikipedia and the property {wikipedia_article} is present in the data module it will be used first. In all other cases, a sitelink will be generated from {:getWikidataItem} (if set). The resulting value (or lack of value) is cached so that subsequent calls are fast. If no value could be determined, and `noCategoryFallback` is {false}, {:getCategoryName} is used as fallback; otherwise, {nil} is returned. Note that if `noCategoryFallback` is {nil} or omitted, it defaults to {false} if the project is the English Wikipedia, otherwise to {true}. In other words, under normal circumstances, if the English Wikipedia article couldn't be retrieved, the return value will fall back to a link to the language's category, but this won't normally happen for any other project. ]==] function Language:getWikipediaArticle(noCategoryFallback, project) Language.getWikipediaArticle = require(language_like_module).getWikipediaArticle return self:getWikipediaArticle(noCategoryFallback, project) end function Language:makeWikipediaLink() return make_link(self, "w:id:" .. self:getWikipediaArticle(), self:getCanonicalNameLower()) end --[==[Returns the name of the Wikimedia Commons category page for the language.]==] function Language:getCommonsCategory() Language.getCommonsCategory = require(language_like_module).getCommonsCategory return self:getCommonsCategory() end --[==[Returns the Wikidata item id for the language or <code>nil</code>. This corresponds to the the second field in the data modules.]==] function Language:getWikidataItem() Language.getWikidataItem = require(language_like_module).getWikidataItem return self:getWikidataItem() end --[==[Returns a table of <code>Script</code> objects for all scripts that the language is written in. See [[Module:scripts]].]==] function Language:getScripts() local scripts = self._scriptObjects if scripts == nil then local codes = self:getScriptCodes() if codes[1] == "All" then scripts = load_data(scripts_data_module) else scripts = {} for i = 1, #codes do scripts[i] = get_script(codes[i]) end end self._scriptObjects = scripts end return scripts end --[==[Returns the table of script codes in the language's data file.]==] function Language:getScriptCodes() local scripts = self._scriptCodes if scripts == nil then scripts = self._data[4] if scripts then local codes, n = {}, 0 for code in gmatch(scripts, "[^,]+") do n = n + 1 -- Special handling of "Hants", which represents "Hani", "Hant" and "Hans" collectively. if code == "Hants" then codes[n] = "Hani" codes[n + 1] = "Hant" codes[n + 2] = "Hans" n = n + 2 else codes[n] = code end end scripts = codes else scripts = {"None"} end self._scriptCodes = scripts end return scripts end --[==[Given some text, this function iterates through the scripts of a given language and tries to find the script that best matches the text. It returns a {{code|lua|Script}} object representing the script. If no match is found at all, it returns the {{code|lua|None}} script object.]==] function Language:findBestScript(text, forceDetect) if not text or text == "" or text == "-" then return get_script("None") end -- Differs from table returned by getScriptCodes, as Hants is not normalized into its constituents. local codes = self._bestScriptCodes if codes == nil then codes = self._data[4] codes = codes and split(codes, ",", true, true) or {"None"} self._bestScriptCodes = codes end local first_sc = codes[1] if first_sc == "All" then return find_best_script_without_lang(text) end local codes_len = #codes if not (forceDetect or first_sc == "Hants" or codes_len > 1) then first_sc = get_script(first_sc) local charset = first_sc.characters return charset and umatch(text, "[" .. charset .. "]") and first_sc or get_script("None") end -- Remove all formatting characters. text = get_plaintext(text) -- Remove all spaces and any ASCII punctuation. Some non-ASCII punctuation is script-specific, so can't be removed. text = ugsub(text, "[%s!\"#%%&'()*,%-./:;?@[\\%]_{}]+", "") if #text == 0 then return get_script("None") end -- Try to match every script against the text, -- and return the one with the most matching characters. local bestcount, bestscript, length = 0 for i = 1, codes_len do local sc = codes[i] -- Special case for "Hants", which is a special code that represents whichever of "Hant" or "Hans" best matches, or "Hani" if they match equally. This avoids having to list all three. In addition, "Hants" will be treated as the best match if there is at least one matching character, under the assumption that a Han script is desirable in terms that contain a mix of Han and other scripts (not counting those which use Jpan or Kore). if sc == "Hants" then local Hani = get_script("Hani") if not Hant_chars then Hant_chars = load_data("Module:zh/data/ts") Hans_chars = load_data("Module:zh/data/st") end local t, s, found = 0, 0 -- This is faster than using mw.ustring.gmatch directly. for ch in gmatch((ugsub(text, "[" .. Hani.characters .. "]", "\255%0")), "\255(.[\128-\191]*)") do found = true if Hant_chars[ch] then t = t + 1 if Hans_chars[ch] then s = s + 1 end elseif Hans_chars[ch] then s = s + 1 else t, s = t + 1, s + 1 end end if found then if t == s then return Hani end return get_script(t > s and "Hant" or "Hans") end else sc = get_script(sc) if not length then length = ulen(text) end -- Count characters by removing everything in the script's charset and comparing to the original length. local charset = sc.characters local count = charset and length - ulen((ugsub(text, "[" .. charset .. "]+", ""))) or 0 if count >= length then return sc elseif count > bestcount then bestcount = count bestscript = sc end end end -- Return best matching script, or otherwise None. return bestscript or get_script("None") end --[==[Returns a <code>Family</code> object for the language family that the language belongs to. See [[Module:families]].]==] function Language:getFamily() local family = self._familyObject if family == nil then family = self:getFamilyCode() -- If the value is nil, it's cached as false. family = family and get_family(family) or false self._familyObject = family end return family or nil end --[==[Returns the family code in the language's data file.]==] function Language:getFamilyCode() local family = self._familyCode if family == nil then -- If the value is nil, it's cached as false. family = self._data[3] or false self._familyCode = family end return family or nil end function Language:getFamilyName() local family = self._familyName if family == nil then family = self:getFamily() -- If the value is nil, it's cached as false. family = family and family:getCanonicalName() or false self._familyName = family end return family or nil end do local function check_family(self, family) if type(family) == "table" then family = family:getCode() end if self:getFamilyCode() == family then return true end local self_family = self:getFamily() if self_family:inFamily(family) then return true -- If the family isn't a real family (e.g. creoles) check any ancestors. elseif self_family:inFamily("qfa-not") then local ancestors = self:getAncestors() for _, ancestor in ipairs(ancestors) do if ancestor:inFamily(family) then return true end end end end --[==[Check whether the language belongs to `family` (which can be a family code or object). A list of objects can be given in place of `family`; in that case, return true if the language belongs to any of the specified families. Note that some languages (in particular, certain creoles) can have multiple immediate ancestors potentially belonging to different families; in that case, return true if the language belongs to any of the specified families.]==] function Language:inFamily(...) if self:getFamilyCode() == nil then return false end return check_inputs(self, check_family, false, ...) end end function Language:getParent() local parent = self._parentObject if parent == nil then parent = self:getParentCode() -- If the value is nil, it's cached as false. parent = parent and get_by_code(parent, nil, true, true) or false self._parentObject = parent end return parent or nil end function Language:getParentCode() local parent = self._parentCode if parent == nil then -- If the value is nil, it's cached as false. parent = self._data.parent or false self._parentCode = parent end return parent or nil end function Language:getParentName() local parent = self._parentName if parent == nil then parent = self:getParent() -- If the value is nil, it's cached as false. parent = parent and parent:getCanonicalName() or false self._parentName = parent end return parent or nil end function Language:getParentChain() local chain = self._parentChain if chain == nil then chain = {} local parent, n = self:getParent(), 0 while parent do n = n + 1 chain[n] = parent parent = parent:getParent() end self._parentChain = chain end return chain end do local function check_lang(self, lang) for _, parent in ipairs(self:getParentChain()) do if (type(lang) == "string" and lang or lang:getCode()) == parent:getCode() then return true end end end function Language:hasParent(...) return check_inputs(self, check_lang, false, ...) end end --[==[ If the language is etymology-only, this iterates through parents until a full language or family is found, and the corresponding object is returned. If the language is a full language, then it simply returns itself. ]==] function Language:getFull() local full = self._fullObject if full == nil then full = self:getFullCode() full = full == self._code and self or get_by_code(full) self._fullObject = full end return full end --[==[ If the language is an etymology-only language, this iterates through parents until a full language or family is found, and the corresponding code is returned. If the language is a full language, then it simply returns the language code. ]==] function Language:getFullCode() return self._fullCode or self._code end --[==[ If the language is an etymology-only language, this iterates through parents until a full language or family is found, and the corresponding canonical name is returned. If the language is a full language, then it simply returns the canonical name of the language. ]==] function Language:getFullName() local full = self._fullName if full == nil then full = self:getFull():getCanonicalName() self._fullName = full end return full end --[==[Returns a table of <code class="nf">Language</code> objects for all languages that this language is directly descended from. Generally this is only a single language, but creoles, pidgins and mixed languages can have multiple ancestors.]==] function Language:getAncestors() local ancestors = self._ancestorObjects if ancestors == nil then ancestors = {} local ancestor_codes = self:getAncestorCodes() if #ancestor_codes > 0 then for _, ancestor in ipairs(ancestor_codes) do insert(ancestors, get_by_code(ancestor, nil, true)) end else local fam = self:getFamily() local protoLang = fam and fam:getProtoLanguage() or nil -- For the cases where the current language is the proto-language -- of its family, or an etymology-only language that is ancestral to that -- proto-language, we need to step up a level higher right from the -- start. if protoLang and ( protoLang:getCode() == self._code or (self:hasType("etymology-only") and protoLang:hasAncestor(self)) ) then fam = fam:getFamily() protoLang = fam and fam:getProtoLanguage() or nil end while not protoLang and not (not fam or fam:getCode() == "qfa-not") do fam = fam:getFamily() protoLang = fam and fam:getProtoLanguage() or nil end insert(ancestors, protoLang) end self._ancestorObjects = ancestors end return ancestors end do -- Avoid a language being its own ancestor via class inheritance. We only need to check for this if the language has inherited an ancestor table from its parent, because we never want to drop ancestors that have been explicitly set in the data. -- Recursively iterate over ancestors until we either find self or run out. If self is found, return true. local function check_ancestor(self, lang) local codes = lang:getAncestorCodes() if not codes then return nil end for i = 1, #codes do local code = codes[i] if code == self._code then return true end local anc = get_by_code(code, nil, true) if check_ancestor(self, anc) then return true end end end --[==[Returns a table of <code class="nf">Language</code> codes for all languages that this language is directly descended from. Generally this is only a single language, but creoles, pidgins and mixed languages can have multiple ancestors.]==] function Language:getAncestorCodes() if self._ancestorCodes then return self._ancestorCodes end local data = self._data local codes = data.ancestors if codes == nil then codes = {} self._ancestorCodes = codes return codes end codes = split(codes, ",", true, true) self._ancestorCodes = codes -- If there are no codes or the ancestors weren't inherited data, there's nothing left to check. if #codes == 0 or self:getData(false, "raw").ancestors ~= nil then return codes end local i, code = 1 while i <= #codes do code = codes[i] if check_ancestor(self, self) then remove(codes, i) else i = i + 1 end end return codes end end --[==[Given a list of language objects or codes, returns true if at least one of them is an ancestor. This includes any etymology-only children of that ancestor. If the language's ancestor(s) are etymology-only languages, it will also return true for those language parent(s) (e.g. if Vulgar Latin is the ancestor, it will also return true for its parent, Latin). However, a parent is excluded from this if the ancestor is also ancestral to that parent (e.g. if Classical Persian is the ancestor, Persian would return false, because Classical Persian is also ancestral to Persian).]==] function Language:hasAncestor(...) local function iterateOverAncestorTree(node, func, parent_check) local ancestors = node:getAncestors() local ancestorsParents = {} for _, ancestor in ipairs(ancestors) do -- When checking the parents of the other language, and the ancestor is also a parent, skip to the next ancestor, so that we exclude any etymology-only children of that parent that are not directly related (see below). local ret = (parent_check or not node:hasParent(ancestor)) and func(ancestor) or iterateOverAncestorTree(ancestor, func, parent_check) if ret then return ret end end -- Check the parents of any ancestors. We don't do this if checking the parents of the other language, so that we exclude any etymology-only children of those parents that are not directly related (e.g. if the ancestor is Vulgar Latin and we are checking New Latin, we want it to return false because they are on different ancestral branches. As such, if we're already checking the parent of New Latin (Latin) we don't want to compare it to the parent of the ancestor (Latin), as this would be a false positive; it should be one or the other). if not parent_check then return nil end for _, ancestor in ipairs(ancestors) do local ancestorParents = ancestor:getParentChain() for _, ancestorParent in ipairs(ancestorParents) do if ancestorParent:getCode() == self._code or ancestorParent:hasAncestor(ancestor) then break else insert(ancestorsParents, ancestorParent) end end end for _, ancestorParent in ipairs(ancestorsParents) do local ret = func(ancestorParent) if ret then return ret end end end local function do_iteration(otherlang, parent_check) -- otherlang can't be self if (type(otherlang) == "string" and otherlang or otherlang:getCode()) == self._code then return false end repeat if iterateOverAncestorTree( self, function(ancestor) return ancestor:getCode() == (type(otherlang) == "string" and otherlang or otherlang:getCode()) end, parent_check ) then return true elseif type(otherlang) == "string" then otherlang = get_by_code(otherlang, nil, true) end otherlang = otherlang:getParent() parent_check = false until not otherlang end local parent_check = true for _, otherlang in ipairs{...} do local ret = do_iteration(otherlang, parent_check) if ret then return true end end return false end do local function construct_node(lang, memo) local branch, ancestors = {lang = lang:getCode()} memo[lang:getCode()] = branch for _, ancestor in ipairs(lang:getAncestors()) do if ancestors == nil then ancestors = {} end insert(ancestors, memo[ancestor:getCode()] or construct_node(ancestor, memo)) end branch.ancestors = ancestors return branch end function Language:getAncestorChain() local chain = self._ancestorChain if chain == nil then chain = construct_node(self, {}) self._ancestorChain = chain end return chain end end function Language:getAncestorChainOld() local chain = self._ancestorChain if chain == nil then chain = {} local step = self while true do local ancestors = step:getAncestors() step = #ancestors == 1 and ancestors[1] or nil if not step then break end insert(chain, step) end self._ancestorChain = chain end return chain end local function fetch_descendants(self, fmt) local descendants, family = {}, self:getFamily() -- Iterate over all three datasets. for _, data in ipairs{ require("Module:languages/code to canonical name"), require("Module:etymology languages/code to canonical name"), require("Module:families/code to canonical name"), } do for code in pairs(data) do local lang = get_by_code(code, nil, true, true) -- Test for a descendant. Earlier tests weed out most candidates, while the more intensive tests are only used sparingly. if ( code ~= self._code and -- Not self. lang:inFamily(family) and -- In the same family. ( family:getProtoLanguageCode() == self._code or -- Self is the protolanguage. self:hasDescendant(lang) or -- Full hasDescendant check. (lang:getFullCode() == self._code and not self:hasAncestor(lang)) -- Etymology-only child which isn't an ancestor. ) ) then if fmt == "object" then insert(descendants, lang) elseif fmt == "code" then insert(descendants, code) elseif fmt == "name" then insert(descendants, lang:getCanonicalName()) end end end end return descendants end function Language:getDescendants() local descendants = self._descendantObjects if descendants == nil then descendants = fetch_descendants(self, "object") self._descendantObjects = descendants end return descendants end function Language:getDescendantCodes() local descendants = self._descendantCodes if descendants == nil then descendants = fetch_descendants(self, "code") self._descendantCodes = descendants end return descendants end function Language:getDescendantNames() local descendants = self._descendantNames if descendants == nil then descendants = fetch_descendants(self, "name") self._descendantNames = descendants end return descendants end do local function check_lang(self, lang) if type(lang) == "string" then lang = get_by_code(lang, nil, true) end if lang:hasAncestor(self) then return true end end function Language:hasDescendant(...) return check_inputs(self, check_lang, false, ...) end end local function fetch_children(self, fmt) local m_etym_data = require(etymology_languages_data_module) local self_code, children = self._code, {} for code, lang in pairs(m_etym_data) do local _lang = lang repeat local parent = _lang.parent if parent == self_code then if fmt == "object" then insert(children, get_by_code(code, nil, true)) elseif fmt == "code" then insert(children, code) elseif fmt == "name" then insert(children, lang[1]) end break end _lang = m_etym_data[parent] until not _lang end return children end function Language:getChildren() local children = self._childObjects if children == nil then children = fetch_children(self, "object") self._childObjects = children end return children end function Language:getChildrenCodes() local children = self._childCodes if children == nil then children = fetch_children(self, "code") self._childCodes = children end return children end function Language:getChildrenNames() local children = self._childNames if children == nil then children = fetch_children(self, "name") self._childNames = children end return children end function Language:hasChild(...) local lang = ... if not lang then return false elseif type(lang) == "string" then lang = get_by_code(lang, nil, true) end if lang:hasParent(self) then return true end return self:hasChild(select(2, ...)) end --[==[Returns the name of the main category of that language. Example: {{code|lua|"French language"}} for French, whose category is at [[:Category:French language]]. Unless optional argument <code>nocap</code> is given, the language name at the beginning of the returned value will be capitalized. This capitalization is correct for category names, but not if the language name is lowercase and the returned value of this function is used in the middle of a sentence.]==] function Language:getCategoryName(nocap) local name = self._categoryName if name == nil then name = self:getCanonicalName() -- If a substrate, omit any leading article. if self:getFamilyCode() == "qfa-sub" then name = name:gsub("^the ", ""):gsub("^a ", "") end -- Only add " language" if a full language. if self:hasType("full") then -- Unless the canonical name already ends with "language", "lect" or their derivatives, add " language". if not (match(name, "[Ll]anguage$") or match(name, "[Ll]ect$")) then name = name .. " language" end end self._categoryName = name end if nocap then return name end return mw.getContentLanguage():ucfirst(name) end --[==[Creates a link to the category; the link text is the canonical name.]==] function Language:makeCategoryLink() return make_link(self, ":Category:" .. self:getCategoryName(), self:getDisplayForm()) end function Language:getStandardCharacters(sc) local standard_chars = self._data.standardChars if type(standard_chars) ~= "table" then return standard_chars elseif sc and type(sc) ~= "string" then check_object("script", nil, sc) sc = sc:getCode() end if (not sc) or sc == "None" then local scripts = {} for _, script in pairs(standard_chars) do insert(scripts, script) end return concat(scripts) end if standard_chars[sc] then return standard_chars[sc] .. (standard_chars[1] or "") end end --[==[ Strip diacritics from display text `text` (in a language-specific fashion), which is in the script `sc`. If `sc` is omitted or {nil}, the script is autodetected. This also strips certain punctuation characters from the end and (in the case of Spanish upside-down question mark and exclamation points) from the beginning; strips any whitespace at the end of the text or between the text and final stripped punctuation characters; and applies some language-specific Unicode normalizations to replace discouraged characters with their prescribed alternatives. Return the stripped text. ]==] function Language:stripDiacritics(text, sc) if (not text) or text == "" then return text end sc = checkScript(text, self, sc) text = normalize(text, sc) -- FIXME, rename makeEntryName to stripDiacritics and get rid of second and third return values -- everywhere text, _, _ = iterateSectionSubstitutions(self, text, sc, nil, nil, self._data.strip_diacritics or self._data.entry_name, "strip_diacritics", "stripDiacritics") text = umatch(text, "^[¿¡]?(.-[^%s%p].-)%s*[؟?!;՛՜ ՞ ՟?!︖︕।॥။၊་།]?$") or text return text end --[==[ Convert a ''logical'' pagename (the pagename as it appears to the user, after diacritics and punctuation have been stripped) to a ''physical'' pagename (the pagename as it appears in the MediaWiki database). Reasons for a difference between the two are (a) unsupported titles such as `[ ]` (with square brackets in them), `#` (pound/hash sign) and `¯\_(ツ)_/¯` (with underscores), as well as overly long titles of various sorts; (b) "mammoth" pages that are split into parts (e.g. `a`, which is split into physical pagenames `a/languages A to L` and `a/languages M to Z`). For almost all purposes, you should work with logical and not physical pagenames. But there are certain use cases that require physical pagenames, such as checking the existence of a page or retrieving a page's contents. `pagename` is the logical pagename to be converted. `is_reconstructed_or_appendix` indicates whether the page is in the `Reconstruction` or `Appendix` namespaces. If it is omitted or has the value {nil}, the pagename is checked for an initial asterisk, and if found, the page is assumed to be a `Reconstruction` page. Setting a value of `false` or `true` to `is_reconstructed_or_appendix` disables this check and allows for mainspace pagenames that begin with an asterisk. ]==] function Language:logicalToPhysical(pagename, is_reconstructed_or_appendix) -- FIXME: This probably shouldn't happen but it happens when makeEntryName() receives nil. if pagename == nil then track("nil-passed-to-logicalToPhysical") return nil end local initial_asterisk if is_reconstructed_or_appendix == nil then local pagename_minus_initial_asterisk initial_asterisk, pagename_minus_initial_asterisk = pagename:match("^(%*)(.*)$") if pagename_minus_initial_asterisk then is_reconstructed_or_appendix = true pagename = pagename_minus_initial_asterisk elseif self:hasType("appendix-constructed") then is_reconstructed_or_appendix = true end end if not is_reconstructed_or_appendix then -- Check if the pagename is a listed unsupported title. local unsupportedTitles = load_data(links_data_module).unsupported_titles if unsupportedTitles[pagename] then return "Unsupported titles/" .. unsupportedTitles[pagename] end end -- Set `unsupported` as true if certain conditions are met. local unsupported -- Check if there's an unsupported character. \239\191\189 is the replacement character U+FFFD, which can't be typed -- directly here due to an abuse filter. Unix-style dot-slash notation is also unsupported, as it is used for -- relative paths in links, as are 3 or more consecutive tildes. Note: match is faster with magic -- characters/charsets; find is faster with plaintext. if ( match(pagename, "[#<>%[%]_{|}]") or find(pagename, "\239\191\189") or match(pagename, "%f[^%z/]%.%.?%f[%z/]") or find(pagename, "~~~") ) then unsupported = true -- If it looks like an interwiki link. elseif find(pagename, ":") then local prefix = gsub(pagename, "^:*(.-):.*", ulower) if ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then unsupported = true end end -- Escape unsupported characters so they can be used in titles. ` is used as a delimiter for this, so a raw use of -- it in an unsupported title is also escaped here to prevent interference; this is only done with unsupported -- titles, though, so inclusion won't in itself mean a title is treated as unsupported (which is why it's excluded -- from the earlier test). if unsupported then -- FIXME: This conversion needs to be different for reconstructed pages with unsupported characters. There -- aren't any currently, but if there ever are, we need to fix this e.g. to put them in something like -- Reconstruction:Proto-Indo-European/Unsupported titles/`lowbar``num`. local unsupported_characters = load_data(links_data_module).unsupported_characters pagename = pagename:gsub("[#<>%[%]_`{|}\239]\191?\189?", unsupported_characters) :gsub("%f[^%z/]%.%.?%f[%z/]", function(m) return (gsub(m, "%.", "`period`")) end) :gsub("~~~+", function(m) return (gsub(m, "~", "`tilde`")) end) pagename = "Unsupported titles/" .. pagename elseif not is_reconstructed_or_appendix then -- Check if this is a mammoth page. If so, which subpage should we link to? local m_links_data = load_data(links_data_module) local mammoth_page_type = m_links_data.mammoth_pages[pagename] if mammoth_page_type then local canonical_name = self:getFullName() if canonical_name ~= "Translingual" and canonical_name ~= "English" then local this_subpage local L2_sort_key = get_L2_sort_key(canonical_name) for _, subpage_spec in ipairs(m_links_data.mammoth_page_subpage_types[mammoth_page_type]) do -- unpack() fails utterly on data loaded using mw.loadData() even if offsets are given local subpage, pattern = subpage_spec[1], subpage_spec[2] if pattern == true or L2_sort_key:match(pattern) then this_subpage = subpage break end end if not this_subpage then error(("Internal error: Bad data in mammoth_page_subpage_pages in [[Module:links/data]] for mammoth page %s, type %s; last entry didn't have 'true' in it"):format( pagename, mammoth_page_type)) end pagename = pagename .. "/" .. this_subpage end end end return (initial_asterisk or "") .. pagename end --[==[ Strip the diacritics from a display pagename and convert the resulting logical pagename into a physical pagename. This allows you, for example, to retrieve the contents of the page or check its existence. WARNING: This is deprecated and will be going away. It is a simple composition of `self:stripDiacritics` and `self:logicalToPhysical`; most callers only want the former, and if you need both, call them both yourself. `text` and `sc` are as in `self:stripDiacritics`, and `is_reconstructed_or_appendix` is as in `self:logicalToPhysical`. ]==] function Language:makeEntryName(text, sc, is_reconstructed_or_appendix) return self:logicalToPhysical(self:stripDiacritics(text, sc), is_reconstructed_or_appendix) end --[==[Generates alternative forms using a specified method, and returns them as a table. If no method is specified, returns a table containing only the input term.]==] function Language:generateForms(text, sc) local generate_forms = self._data.generate_forms if generate_forms == nil then return {text} end sc = checkScript(text, self, sc) return require("Module:" .. self._data.generate_forms).generateForms(text, self, sc) end --[==[Creates a sort key for the given stripped text, following the rules appropriate for the language. This removes diacritical marks from the stripped text if they are not considered significant for sorting, and may perform some other changes. Any initial hyphen is also removed, and anything in parentheses is removed as well. The <code>sort_key</code> setting for each language in the data modules defines the replacements made by this function, or it gives the name of the module that takes the stripped text and returns a sortkey.]==] function Language:makeSortKey(text, sc) if (not text) or text == "" then return text end if match(text, "<[^<>]+>") then track("track HTML tag") end -- Remove directional characters, bold, italics, soft hyphens, strip markers and HTML tags. -- FIXME: Partly duplicated with remove_formatting() in [[Module:links]]. text = ugsub(text, "[\194\173\226\128\170-\226\128\174\226\129\166-\226\129\169]", "") text = text:gsub("('*)'''(.-'*)'''", "%1%2"):gsub("('*)''(.-'*)''", "%1%2") text = gsub(unstrip(text), "<[^<>]+>", "") text = decode_uri(text, "PATH") text = checkNoEntities(self, text) -- Remove initial hyphens and * unless the term only consists of spacing + punctuation characters. text = ugsub(text, "^([􀀀-􏿽]*)[-־ـ᠊*]+([􀀀-􏿽]*)(.*[^%s%p].*)", "%1%2%3") sc = checkScript(text, self, sc) text = normalize(text, sc) text = removeCarets(text, sc) -- For languages with dotted dotless i, ensure that "İ" is sorted as "i", and "I" is sorted as "ı". if self:hasDottedDotlessI() then text = gsub(text, "I\204\135", "i") -- decomposed "İ" :gsub("I", "ı") text = sc:toFixedNFD(text) end -- Convert to lowercase, make the sortkey, then convert to uppercase. Where the language has dotted dotless i, it is -- usually not necessary to convert "i" to "İ" and "ı" to "I" first, because "I" will always be interpreted as -- conventional "I" (not dotless "İ") by any sorting algorithms, which will have been taken into account by the -- sortkey substitutions themselves. However, if no sortkey substitutions have been specified, then conversion is -- necessary so as to prevent "i" and "ı" both being sorted as "I". -- -- An exception is made for scripts that (sometimes) sort by scraping page content, as that means they are sensitive -- to changes in capitalization (as it changes the target page). if not sc:sortByScraping() then text = ulower(text) end local actual_substitution_data -- Don't trim whitespace here because it's significant at the beginning of a sort key or sort base. text, _, actual_substitution_data = iterateSectionSubstitutions(self, text, sc, nil, nil, self._data.sort_key, "sort_key", "makeSortKey", "notrim") if not sc:sortByScraping() then if self:hasDottedDotlessI() and not actual_substitution_data then text = text:gsub("ı", "I"):gsub("i", "İ") text = sc:toFixedNFC(text) end text = uupper(text) end -- Remove parentheses, as long as they are either preceded or followed by something. text = gsub(text, "(.)[()]+", "%1"):gsub("[()]+(.)", "%1") text = escape_risky_characters(text) return text end --[==[Create the form used as as a basis for display text and transliteration. FIXME: Rename to correctInputText().]==] local function processDisplayText(text, self, sc, keepCarets, keepPrefixes) local subbedChars = {} text, subbedChars = doTempSubstitutions(text, subbedChars, keepCarets) text = decode_uri(text, "PATH") text = checkNoEntities(self, text) sc = checkScript(text, self, sc) text = normalize(text, sc) text, subbedChars = iterateSectionSubstitutions(self, text, sc, subbedChars, keepCarets, self._data.display_text, "display_text", "makeDisplayText") text = removeCarets(text, sc) -- Remove any interwiki link prefixes (unless they have been escaped or this has been disabled). if find(text, ":") and not keepPrefixes then local rep repeat text, rep = gsub(text, "\\\\(\\*:)", "\3%1") until rep == 0 text = gsub(text, "\\:", "\4") while true do local prefix = gsub(text, "^(.-):.+", function(m1) return (gsub(m1, "\244[\128-\191]*", "")) end) -- Check if the prefix is an interwiki, though ignore capitalised Wiktionary:, which is a namespace. if not prefix or prefix == text or prefix == "Wiktionary" or not (load_data("Module:data/interwikis")[ulower(prefix)] or prefix == "") then break end text = gsub(text, "^(.-):(.*)", function(m1, m2) local ret = {} for subbedChar in gmatch(m1, "\244[\128-\191]*") do insert(ret, subbedChar) end return concat(ret) .. m2 end) end text = gsub(text, "\3", "\\"):gsub("\4", ":") end return text, subbedChars end --[==[Make the display text (i.e. what is displayed on the page).]==] function Language:makeDisplayText(text, sc, keepPrefixes) if not text or text == "" then return text end local subbedChars text, subbedChars = processDisplayText(text, self, sc, nil, keepPrefixes) text = escape_risky_characters(text) return undoTempSubstitutions(text, subbedChars) end --[==[Transliterates the text from the given script into the Latin script (see [[Wiktionary:Transliteration and romanization]]). The language must have the <code>translit</code> property for this to work; if it is not present, {{code|lua|nil}} is returned. The <code>sc</code> parameter is handled by the transliteration module, and how it is handled is specific to that module. Some transliteration modules may tolerate {{code|lua|nil}} as the script, others require it to be one of the possible scripts that the module can transliterate, and will throw an error if it's not one of them. For this reason, the <code>sc</code> parameter should always be provided when writing non-language-specific code. The <code>module_override</code> parameter is used to override the default module that is used to provide the transliteration. This is useful in cases where you need to demonstrate a particular module in use, but there is no default module yet, or you want to demonstrate an alternative version of a transliteration module before making it official. It should not be used in real modules or templates, only for testing. All uses of this parameter are tracked by [[Wiktionary:Tracking/languages/module_override]]. '''Known bugs''': * This function assumes {tr(s1) .. tr(s2) == tr(s1 .. s2)}. When this assertion fails, wikitext markups like <nowiki>'''</nowiki> can cause wrong transliterations. * HTML entities like <code>&amp;apos;</code>, often used to escape wikitext markups, do not work. ]==] function Language:transliterate(text, sc, module_override) -- If there is no text, or the language doesn't have transliteration data and there's no override, return nil. if not text or text == "" or text == "-" then return text end -- If the script is not transliteratable (and no override is given), return nil. sc = checkScript(text, self, sc) if not (sc:isTransliterated() or module_override) then -- temporary tracking to see if/when this gets triggered track("non-transliterable") track("non-transliterable/" .. self._code) track("non-transliterable/" .. sc:getCode()) track("non-transliterable/" .. sc:getCode() .. "/" .. self._code) return nil end -- Remove any strip markers. text = unstrip(text) -- Do not process the formatting into PUA characters for certain languages. local processed = load_data(languages_data_module).substitution[self._code] ~= "none" -- Get the display text with the keepCarets flag set. local subbedChars if processed then text, subbedChars = processDisplayText(text, self, sc, true) end -- Transliterate (using the module override if applicable). text, subbedChars = iterateSectionSubstitutions(self, text, sc, subbedChars, true, module_override or self._data.translit, "translit", "tr") if not text then return nil end -- Incomplete transliterations return nil. local charset = sc.characters if charset and umatch(text, "[" .. charset .. "]") then -- Remove any characters in Latin, which includes Latin characters also included in other scripts (as these are -- false positives), as well as any PUA substitutions. Anything remaining should only be script code "None" -- (e.g. numerals). local check_text = ugsub(text, "[" .. get_script("Latn").characters .. "􀀀-􏿽]+", "") -- Set none_is_last_resort_only flag, so that any non-None chars will cause a script other than "None" to be -- returned. if find_best_script_without_lang(check_text, true):getCode() ~= "None" then return nil end end if processed then text = escape_risky_characters(text) text = undoTempSubstitutions(text, subbedChars) end -- If the script does not use capitalization, then capitalize any letters of the transliteration which are -- immediately preceded by a caret (and remove the caret). if text and not sc:hasCapitalization() and text:find("^", 1, true) then text = processCarets(text, "%^([\128-\191\244]*%*?)([^\128-\191\244][\128-\191]*)", function(m1, m2) return m1 .. uupper(m2) end) end -- Track module overrides. if module_override ~= nil then track("module_override") end return text end do local function handle_language_spec(self, spec, sc) local ret = self["_" .. spec] if ret == nil then ret = self._data[spec] if type(ret) == "string" then ret = list_to_set(split(ret, ",", true, true)) end self["_" .. spec] = ret end if type(ret) == "table" then ret = ret[sc:getCode()] end return not not ret end function Language:overrideManualTranslit(sc) return handle_language_spec(self, "override_translit", sc) end function Language:link_tr(sc) return handle_language_spec(self, "link_tr", sc) end end --[==[Returns {{code|lua|true}} if the language has a transliteration module, or {{code|lua|false}} if it doesn't.]==] function Language:hasTranslit() return not not self._data.translit end --[==[Returns {{code|lua|true}} if the language uses the letters I/ı and İ/i, or {{code|lua|false}} if it doesn't.]==] function Language:hasDottedDotlessI() return not not self._data.dotted_dotless_i end function Language:toJSON(opts) local strip_diacritics, strip_diacritics_patterns, strip_diacritics_remove_diacritics = self._data.strip_diacritics if strip_diacritics then if strip_diacritics.from then strip_diacritics_patterns = {} for i, from in ipairs(strip_diacritics.from) do insert(strip_diacritics_patterns, {from = from, to = strip_diacritics.to[i] or ""}) end end strip_diacritics_remove_diacritics = strip_diacritics.remove_diacritics end -- mainCode should only end up non-nil if dontCanonicalizeAliases is passed to make_object(). -- props should either contain zero-argument functions to compute the value, or the value itself. local props = { ancestors = function() return self:getAncestorCodes() end, canonicalName = function() return self:getCanonicalName() end, categoryName = function() return self:getCategoryName("nocap") end, code = self._code, mainCode = self._mainCode, parent = function() return self:getParentCode() end, full = function() return self:getFullCode() end, stripDiacriticsPatterns = strip_diacritics_patterns, stripDiacriticsRemoveDiacritics = strip_diacritics_remove_diacritics, family = function() return self:getFamilyCode() end, aliases = function() return self:getAliases() end, varieties = function() return self:getVarieties() end, otherNames = function() return self:getOtherNames() end, scripts = function() return self:getScriptCodes() end, type = function() return keys_to_list(self:getTypes()) end, wikimediaLanguages = function() return self:getWikimediaLanguageCodes() end, wikidataItem = function() return self:getWikidataItem() end, wikipediaArticle = function() return self:getWikipediaArticle(true) end, } local ret = {} for prop, val in pairs(props) do if not opts.skip_fields or not opts.skip_fields[prop] then if type(val) == "function" then ret[prop] = val() else ret[prop] = val end end end -- Use `deep_copy` when returning a table, so that there are no editing restrictions imposed by `mw.loadData`. return opts and opts.lua_table and deep_copy(ret) or to_json(ret, opts) end function export.getDataModuleName(code) local letter = match(code, "^(%l)%l%l?$") return "Module:" .. ( letter == nil and "languages/data/exceptional" or #code == 2 and "languages/data/2" or "languages/data/3/" .. letter ) end get_data_module_name = export.getDataModuleName function export.getExtraDataModuleName(code) return get_data_module_name(code) .. "/extra" end get_extra_data_module_name = export.getExtraDataModuleName do local function make_stack(data) local key_types = { [2] = "unique", aliases = "unique", otherNames = "unique", type = "append", varieties = "unique", wikipedia_article = "unique", wikimedia_codes = "unique" } local function __index(self, k) local stack, key_type = getmetatable(self), key_types[k] -- Data that isn't inherited from the parent. if key_type == "unique" then local v = stack[stack[make_stack]][k] if v == nil then local layer = stack[0] if layer then -- Could be false if there's no extra data. v = layer[k] end end return v -- Data that is appended by each generation. elseif key_type == "append" then local parts, offset, n = {}, 0, stack[make_stack] for i = 1, n do local part = stack[i][k] if part == nil then offset = offset + 1 else parts[i - offset] = part end end return offset ~= n and concat(parts, ",") or nil end local n = stack[make_stack] while true do local layer = stack[n] if not layer then -- Could be false if there's no extra data. return nil end local v = layer[k] if v ~= nil then return v end n = n - 1 end end local function __newindex() error("table is read-only") end local function __pairs(self) -- Iterate down the stack, caching keys to avoid duplicate returns. local stack, seen = getmetatable(self), {} local n = stack[make_stack] local iter, state, k, v = pairs(stack[n]) return function() repeat repeat k = iter(state, k) if k == nil then n = n - 1 local layer = stack[n] if not layer then -- Could be false if there's no extra data. return nil end iter, state, k = pairs(layer) end until not (k == nil or seen[k]) -- Get the value via a lookup, as the one returned by the -- iterator will be the raw value from the current layer, -- which may not be the one __index will return for that -- key. Also memoize the key in `seen` (even if the lookup -- returns nil) so that it doesn't get looked up again. -- TODO: store values in `self`, avoiding the need to create -- the `seen` table. The iterator will need to iterate over -- `self` with `next` first to find these on future loops. v, seen[k] = self[k], true until v ~= nil return k, v end end local __ipairs = require(table_module).indexIpairs function make_stack(data) local stack = { data, [make_stack] = 1, -- stores the length and acts as a sentinel to confirm a given metatable is a stack. __index = __index, __newindex = __newindex, __pairs = __pairs, __ipairs = __ipairs, } stack.__metatable = stack return setmetatable({}, stack), stack end return make_stack(data) end local function get_stack(data) local stack = getmetatable(data) return stack and type(stack) == "table" and stack[make_stack] and stack or nil end --[==[ <span style="color: var(--wikt-palette-red,#BA0000)">This function is not for use in entries or other content pages.</span> Returns a blob of data about the language. The format of this blob is undocumented, and perhaps unstable; it's intended for things like the module's own unit-tests, which are "close friends" with the module and will be kept up-to-date as the format changes. If `extra` is set, any extra data in the relevant `/extra` module will be included. (Note that it will be included anyway if it has already been loaded into the language object.) If `raw` is set, then the returned data will not contain any data inherited from parent objects. -- Do NOT use these methods! -- All uses should be pre-approved on the talk page! ]==] function Language:getData(extra, raw) if extra then self:loadInExtraData() end local data = self._data -- If raw is not set, just return the data. if not raw then return data end local stack = get_stack(data) -- If there isn't a stack or its length is 1, return the data. Extra data (if any) will be included, as it's stored at key 0 and doesn't affect the reported length. if stack == nil then return data end local n = stack[make_stack] if n == 1 then return data end local extra = stack[0] -- If there isn't any extra data, return the top layer of the stack. if extra == nil then return stack[n] end -- If there is, return a new stack which has the top layer at key 1 and the extra data at key 0. data, stack = make_stack(stack[n]) stack[0] = extra return data end function Language:loadInExtraData() -- Only full languages have extra data. if not self:hasType("language", "full") then return end local data = self._data -- If there's no stack, create one. local stack = get_stack(self._data) if stack == nil then data, stack = make_stack(data) -- If already loaded, return. elseif stack[0] ~= nil then return end self._data = data -- Load extra data from the relevant module and add it to the stack at key 0, so that the __index and __pairs metamethods will pick it up, since they iterate down the stack until they run out of layers. local code = self._code local modulename = get_extra_data_module_name(code) -- No data cached as false. stack[0] = modulename and load_data(modulename)[code] or false end --[==[Returns the name of the module containing the language's data. Currently, this is always [[Module:scripts/data]].]==] function Language:getDataModuleName() local name = self._dataModuleName if name == nil then name = self:hasType("etymology-only") and etymology_languages_data_module or get_data_module_name(self._mainCode or self._code) self._dataModuleName = name end return name end --[==[Returns the name of the module containing the language's data. Currently, this is always [[Module:scripts/data]].]==] function Language:getExtraDataModuleName() local name = self._extraDataModuleName if name == nil then name = not self:hasType("etymology-only") and get_extra_data_module_name(self._mainCode or self._code) or false self._extraDataModuleName = name end return name or nil end function export.makeObject(code, data, dontCanonicalizeAliases) local data_type = type(data) if data_type ~= "table" then error(("bad argument #2 to 'makeObject' (table expected, got %s)"):format(data_type)) end -- Convert any aliases. local input_code = code code = normalize_code(code) input_code = dontCanonicalizeAliases and input_code or code local parent if data.parent then parent = get_by_code(data.parent, nil, true, true) else parent = Language end parent.__index = parent local lang = {_code = input_code} -- This can only happen if dontCanonicalizeAliases is passed to make_object(). if code ~= input_code then lang._mainCode = code end local parent_data = parent._data if parent_data == nil then -- Full code is the same as the code. lang._fullCode = parent._code or code else -- Copy full code. lang._fullCode = parent._fullCode local stack = get_stack(parent_data) if stack == nil then parent_data, stack = make_stack(parent_data) end -- Insert the input data as the new top layer of the stack. local n = stack[make_stack] + 1 data, stack[n], stack[make_stack] = parent_data, data, n end lang._data = data return setmetatable(lang, parent) end make_object = export.makeObject end --[==[Finds the language whose code matches the one provided. If it exists, it returns a <code class="nf">Language</code> object representing the language. Otherwise, it returns {{code|lua|nil}}, unless <code class="n">paramForError</code> is given, in which case an error is generated. If <code class="n">paramForError</code> is {{code|lua|true}}, a generic error message mentioning the bad code is generated; otherwise <code class="n">paramForError</code> should be a string or number specifying the parameter that the code came from, and this parameter will be mentioned in the error message along with the bad code. If <code class="n">allowEtymLang</code> is specified, etymology-only language codes are allowed and looked up along with normal language codes. If <code class="n">allowFamily</code> is specified, language family codes are allowed and looked up along with normal language codes.]==] function export.getByCode(code, paramForError, allowEtymLang, allowFamily) -- Track uses of paramForError, ultimately so it can be removed, as error-handling should be done by [[Module:parameters]], not here. if paramForError ~= nil then track("paramForError") end if type(code) ~= "string" then local typ if not code then typ = "nil" elseif check_object("language", true, code) then typ = "a language object" elseif check_object("family", true, code) then typ = "a family object" else typ = "a " .. type(code) end error("The function getByCode expects a string as its first argument, but received " .. typ .. ".") end local m_data = load_data(languages_data_module) if m_data.aliases[code] or m_data.track[code] then track(code) end local norm_code = normalize_code(code) -- Get the data, checking for etymology-only languages if allowEtymLang is set. local data = load_data(get_data_module_name(norm_code))[norm_code] or allowEtymLang and load_data(etymology_languages_data_module)[norm_code] -- If no data was found and allowFamily is set, check the family data. If the main family data was found, make the object with [[Module:families]] instead, as family objects have different methods. However, if it's an etymology-only family, use make_object in this module (which handles object inheritance), and the family-specific methods will be inherited from the parent object. if data == nil and allowFamily then data = load_data("Module:families/data")[norm_code] if data ~= nil then if data.parent == nil then return make_family_object(norm_code, data) elseif not allowEtymLang then data = nil end end end local retval = code and data and make_object(code, data) if not retval and paramForError then require("Module:languages/errorGetBy").code(code, paramForError, allowEtymLang, allowFamily) end return retval end get_by_code = export.getByCode --[==[Finds the language whose canonical name (the name used to represent that language on Wiktionary) or other name matches the one provided. If it exists, it returns a <code class="nf">Language</code> object representing the language. Otherwise, it returns {{code|lua|nil}}, unless <code class="n">paramForError</code> is given, in which case an error is generated. If <code class="n">allowEtymLang</code> is specified, etymology-only language codes are allowed and looked up along with normal language codes. If <code class="n">allowFamily</code> is specified, language family codes are allowed and looked up along with normal language codes. The canonical name of languages should always be unique (it is an error for two languages on Wiktionary to share the same canonical name), so this is guaranteed to give at most one result. This function is powered by [[Module:languages/canonical names]], which contains a pre-generated mapping of full-language canonical names to codes. It is generated by going through the [[:Category:Language data modules]] for full languages. When <code class="n">allowEtymLang</code> is specified for the above function, [[Module:etymology languages/canonical names]] may also be used, and when <code class="n">allowFamily</code> is specified for the above function, [[Module:families/canonical names]] may also be used.]==] function export.getByCanonicalName(name, errorIfInvalid, allowEtymLang, allowFamily) local byName = load_data("Module:languages/canonical names") local code = byName and byName[name] if not code and allowEtymLang then byName = load_data("Module:etymology languages/canonical names") code = byName and byName[name] or byName[gsub(name, " [Ss]ubstrate$", "")] or byName[gsub(name, "^a ", "")] or byName[gsub(name, "^a ", ""):gsub(" [Ss]ubstrate$", "")] or -- For etymology families like "ira-pro". -- FIXME: This is not ideal, as it allows " languages" to be appended to any etymology-only language, too. byName[match(name, "^(.*) languages$")] end if not code and allowFamily then byName = load_data("Module:families/canonical names") code = byName[name] or byName[match(name, "^(.*) languages$")] end local retval = code and get_by_code(code, errorIfInvalid, allowEtymLang, allowFamily) if not retval and errorIfInvalid then require("Module:languages/errorGetBy").canonicalName(name, allowEtymLang, allowFamily) end return retval end --[==[Used by [[Module:languages/data/2]] (et al.) and [[Module:etymology languages/data]], [[Module:families/data]], [[Module:scripts/data]] and [[Module:writing systems/data]] to finalize the data into the format that is actually returned.]==] function export.finalizeData(data, main_type, variety) local fields = {"type"} if main_type == "language" then insert(fields, 4) -- script codes insert(fields, "ancestors") insert(fields, "link_tr") insert(fields, "override_translit") insert(fields, "wikimedia_codes") elseif main_type == "script" then insert(fields, 3) -- writing system codes end -- Families and writing systems have no extra fields to process. local fields_len = #fields for _, entity in next, data do if variety then -- Move parent from 3 to "parent" and family from "family" to 3. These are different for the sake of convenience, since very few varieties have the family specified, whereas all of them have a parent. entity.parent, entity[3], entity.family = entity[3], entity.family -- Give the type "regular" iff not a variety and no other types are assigned. elseif not (entity.type or entity.parent) then entity.type = "regular" end for i = 1, fields_len do local key = fields[i] local field = entity[key] if field and type(field) == "string" then entity[key] = gsub(field, "%s*,%s*", ",") end end end return data end --[==[For backwards compatibility only; modules should require the error themselves.]==] function export.err(lang_code, param, code_desc, template_tag, not_real_lang) return require("Module:languages/error")(lang_code, param, code_desc, template_tag, not_real_lang) end return export t1ou72wdctal9ncl6e3aoed4oxo3bw4 1348993 1348991 2026-04-08T16:32:55Z Swarabakti 18192 1348993 Scribunto text/plain --[==[ intro: This module implements fetching of language-specific information and processing text in a given language. ===Types of languages=== There are two types of languages: full languages and etymology-only languages. The essential difference is that only full languages appear in L2 headings in vocabulary entries, and hence categories like [[:Category:French nouns]] exist only for full languages. Etymology-only languages have either a full language or another etymology-only language as their parent (in the parent-child inheritance sense), and for etymology-only languages with another etymology-only language as their parent, a full language can always be derived by following the parent links upwards. For example, "Canadian French", code `fr-CA`, is an etymology-only language whose parent is the full language "French", code `fr`. An example of an etymology-only language with another etymology-only parent is "Northumbrian Old English", code `ang-nor`, which has "Anglian Old English", code `ang-ang` as its parent; this is an etymology-only language whose parent is "Old English", code `ang`, which is a full language. (This is because Northumbrian Old English is considered a variety of Anglian Old English.) Sometimes the parent is the "Undetermined" language, code `und`; this is the case, for example, for "substrate" languages such as "Pre-Greek", code `qsb-grc`, and "the BMAC substrate", code `qsb-bma`. It is important to distinguish language ''parents'' from language ''ancestors''. The parent-child relationship is one of containment, i.e. if X is a child of Y, X is considered a variety of Y. On the other hand, the ancestor-descendant relationship is one of descent in time. For example, "Classical Latin", code `la-cla`, and "Late Latin", code `la-lat`, are both etymology-only languages with "Latin", code `la`, as their parents, because both of the former are varieties of Latin. However, Late Latin does *NOT* have Classical Latin as its parent because Late Latin is *not* a variety of Classical Latin; rather, it is a descendant. There is in fact a separate `ancestors` field that is used to express the ancestor-descendant relationship, and Late Latin's ancestor is given as Classical Latin. It is also important to note that sometimes an etymology-only language is actually the conceptual ancestor of its parent language. This happens, for example, with "Old Italian" (code `roa-oit`), which is an etymology-only variant of full language "Italian" (code `it`), and with "Old Latin" (code `itc-ola`), which is an etymology-only variant of Latin. In both cases, the full language has the etymology-only variant listed as an ancestor. This allows a Latin term to inherit from Old Latin using the {{tl|inh}} template (where in this template, "inheritance" refers to ancestral inheritance, i.e. inheritance in time, rather than in the parent-child sense); likewise for Italian and Old Italian. Full languages come in three subtypes: * {regular}: This indicates a full language that is attested according to [[WT:CFI]] and therefore permitted in the main namespace. There may also be reconstructed terms for the language, which are placed in the {Reconstruction} namespace and must be prefixed with * to indicate a reconstruction. Most full languages are natural (not constructed) languages, but a few constructed languages (e.g. Esperanto and Volapük, among others) are also allowed in the mainspace and considered regular languages. * {reconstructed}: This language is not attested according to [[WT:CFI]], and therefore is allowed only in the {Reconstruction} namespace. All terms in this language are reconstructed, and must be prefixed with *. Languages such as Proto-Indo-European and Proto-Germanic are in this category. * {appendix-constructed}: This language is attested but does not meet the additional requirements set out for constructed languages ([[WT:CFI#Constructed languages]]). Its entries must therefore be in the Appendix namespace, but they are not reconstructed and therefore should not have * prefixed in links. Most constructed languages are of this subtype. Both full languages and etymology-only languages have a {Language} object associated with them, which is fetched using the {getByCode} function in [[Module:languages]] to convert a language code to a {Language} object. Depending on the options supplied to this function, etymology-only languages may or may not be accepted, and family codes may be accepted (returning a {Family} object as described in [[Module:families]]). There are also separate {getByCanonicalName} functions in [[Module:languages]] and [[Module:etymology languages]] to convert a language's canonical name to a {Language} object (depending on whether the canonical name refers to a full or etymology-only language). ===Textual representations=== Textual strings belonging to a given language come in several different ''text variants'': # The ''input text'' is what the user supplies in wikitext, in the parameters to {{tl|m}}, {{tl|l}}, {{tl|ux}}, {{tl|t}}, {{tl|lang}} and the like. # The ''corrected input text'' is the input text with some corrections and/or normalizations applied, such as bad-character replacements for certain languages, like replacing `l` or `1` to [[palochka]] in some languages written in Cyrillic. (FIXME: This currently goes under the name ''display text'' but that will be repurposed below. Also, [[User:Surjection]] suggests renaming this to ''normalized input text'', but "normalized" is used in a different sense in [[Module:usex]].) # The ''display text'' is the text in the form as it will be displayed to the user. This is what appears in headwords, in usexes, in displayed internal links, etc. This can include accent marks that are removed to form the stripped display text (see below), as well as embedded bracketed links that are variously processed further. The display text is generated from the corrected input text by applying language-specific transformations; for most languages, there will be no such transformations. The general reason for having a difference between input and display text is to allow for extra information in the input text that is not displayed to the user but is sent to the transliteration module. Note that having different display and input text is only supported currently through special-casing but will be generalized. Examples of transformations are: (1) Removing the {{cd|^}} that is used in certain East Asian (and possibly other unicameral) languages to indicate capitalization of the transliteration (which is currently special-cased); (2) for Korean, removing or otherwise processing hyphens (which is currently special-cased); (3) for Arabic, removing a ''sukūn'' diacritic placed over a ''tāʔ marbūṭa'' (like this: ةْ) to indicate that the ''tāʔ marbūṭa'' is pronounced and transliterated as /t/ instead of being silent [NOTE, NOT IMPLEMENTED YET]; (4) for Thai and Khmer, converting space-separated words to bracketed words and resolving respelling substitutions such as `[กรีน/กฺรีน]`, which indicate how to transliterate given words [NOTE, NOT IMPLEMENTED YET except in language-specific templates like {{tl|th-usex}}]. ## The ''right-resolved display text'' is the result of removing brackets around one-part embedded links and resolving two-part embedded links into their right-hand components (i.e. converting two-part links into the displayed form). The process of right-resolution is what happens when you call {{cd|remove_links()}} in [[Module:links]] on some text. When applied to the display text, it produces exactly what the user sees, without any link markup. # The ''stripped display text'' is the result of applying diacritic-stripping to the display text. ## The ''left-resolved stripped display text'' [NEED BETTER NAME] is the result of applying left-resolution to the stripped display text, i.e. similar to right-resolution but resolving two-part embedded links into their left-hand components (i.e. the linked-to page). If the display text refers to a single page, the resulting of applying diacritic stripping and left-resolution produces the ''logical pagename''. # The ''physical pagename text'' is the result of converting the stripped display text into physical page links. If the stripped display text contains embedded links, the left side of those links is converted into physical page links; otherwise, the entire text is considered a pagename and converted in the same fashion. The conversion does three things: (1) converts characters not allowed in pagenames into their "unsupported title" representation, e.g. {{cd|Unsupported titles/`gt`}} in place of the logical name {{cd|>}}; (2) handles certain special-cased unsupported-title logical pagenames, such as {{cd|Unsupported titles/Space}} in place of {{cd|[space]}} and {{cd|Unsupported titles/Ancient Greek dish}} in place of a very long Greek name for a gourmet dish as found in Aristophanes; (3) converts "mammoth" pagenames such as [[a]] into their appropriate split component, e.g. [[a/languages A to L]]. # The ''source translit text'' is the text as supplied to the language-specific {{cd|transliterate()}} method. The form of the source translit text may need to be language-specific, e.g Thai and Khmer will need the corrected input text, whereas other languages may need to work off the display text. [FIXME: It's still unclear to me how embedded bracketed links are handled in the existing code.] In general, embedded links need to be right-resolved (see above), but when this happens is unclear to me [FIXME]. Some languages have a chop-up-and-paste-together scheme that sends parts of the text through the transliterate mechanism, and for others (those listed with "cont" in {{cd|substitution}} in [[Module:languages/data]]) they receive the full input text, but preprocessed in certain ways. (The wisdom of this is still unclear to me.) # The ''transliterated text'' (or ''transliteration'') is the result of transliterating the source translit text. Unlike for all the other text variants except the transcribed text, it is always in the Latin script. # The ''transcribed text'' (or ''transcription'') is the result of transcribing the source translit text, where "transcription" here means a close approximation to the phonetic form of the language in languages (e.g. Akkadian, Sumerian, Ancient Egyptian, maybe Tibetan) that have a wide difference between the written letters and spoken form. Unlike for all the other text variants other than the transliterated text, it is always in the Latin script. Currently, the transcribed text is always supplied manually be the user; there is no such thing as a {{cd|transcribe()}} method on language objects. # The ''sort key'' is the text used in sort keys for determining the placing of pages in categories they belong to. The sort key is generated from the pagename or a specified ''sort base'' by lowercasing, doing language-specific transformations and then uppercasing the result. If the sort base is supplied and is generated from input text, it needs to be converted to display text, have embedded links removed through right-resolution and have diacritic-stripping applied. # There are other text variants that occur in usexes (specifically, there are normalized variants of several of the above text variants), but we can skip them for now. The following methods exist on {Language} objects to convert between different text variants: # {correctInputText} (currently called {makeDisplayText}): This converts input text to corrected input text. # {stripDiacritics}: This converts to stripped display text. [FIXME: This needs some rethinking. In particular, {stripDiacritics} is sometimes called on input text, corrected input text or display text (in various paths inside of [[Module:links]], and, in the case of input text, usually from other modules). We need to make sure we don't try to convert input text to display text twice, but at the same time we need to support calling it directly on input text since so many modules do this. This means we need to add a parameter indicating whether the passed-in text is input, corrected input, or display text; if the former two, we call {correctInputText} ourselves.] # {logicalToPhysical}: This converts logical pagenames to physical pagenames. # {transliterate}: This appears to convert input text with embedded brackets removed into a transliteration. [FIXME: This needs some rethinking. In particular, it calls {processDisplayText} on its input, which won't work for Thai and Khmer, so we may need language-specific flags indicating whether to pass the input text directly to the language transliterate method. In addition, I'm not sure how embedded links are handled in the existing translit code; a lot of callers remove the links themselves before calling {transliterate()}, which I assume is wrong.] # {makeSortKey}: This converts display text (?) to a sort key. [FIXME: Clarify this.] ]==] local export = {} local debug_track_module = "Module:debug/track" local etymology_languages_data_module = "Module:etymology languages/data" local families_module = "Module:families" local headword_page_module = "Module:headword/page" local json_module = "Module:JSON" local language_like_module = "Module:language-like" local languages_data_module = "Module:languages/data" local languages_data_patterns_module = "Module:languages/data/patterns" local links_data_module = "Module:links/data" local load_module = "Module:load" local scripts_module = "Module:scripts" local scripts_data_module = "Module:scripts/data" local string_encode_entities_module = "Module:string/encode entities" local string_pattern_escape_module = "Module:string/patternEscape" local string_replacement_escape_module = "Module:string/replacementEscape" local string_utilities_module = "Module:string utilities" local table_module = "Module:table" local utilities_module = "Module:utilities" local wikimedia_languages_module = "Module:wikimedia languages" local mw = mw local string = string local table = table local char = string.char local concat = table.concat local find = string.find local floor = math.floor local get_by_code -- Defined below. local get_data_module_name -- Defined below. local get_extra_data_module_name -- Defined below. local getmetatable = getmetatable local gmatch = string.gmatch local gsub = string.gsub local insert = table.insert local ipairs = ipairs local is_known_language_tag = mw.language.isKnownLanguageTag local make_object -- Defined below. local match = string.match local next = next local pairs = pairs local remove = table.remove local require = require local select = select local setmetatable = setmetatable local sub = string.sub local type = type local unstrip = mw.text.unstrip -- Loaded as needed by findBestScript. local Hans_chars local Hant_chars local function check_object(...) check_object = require(utilities_module).check_object return check_object(...) 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 local function deep_copy(...) deep_copy = require(table_module).deepCopy return deep_copy(...) end local function encode_entities(...) encode_entities = require(string_encode_entities_module) return encode_entities(...) end local function get_L2_sort_key(...) get_L2_sort_key = require(headword_page_module).get_L2_sort_key return get_L2_sort_key(...) end local function get_script(...) get_script = require(scripts_module).getByCode return get_script(...) 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 get_family(...) get_family = require(families_module).getByCode return get_family(...) end local function get_plaintext(...) get_plaintext = require(utilities_module).get_plaintext return get_plaintext(...) end local function get_wikimedia_lang(...) get_wikimedia_lang = require(wikimedia_languages_module).getByCode return get_wikimedia_lang(...) end local function keys_to_list(...) keys_to_list = require(table_module).keysToList return keys_to_list(...) end local function list_to_set(...) list_to_set = require(table_module).listToSet return list_to_set(...) end local function load_data(...) load_data = require(load_module).load_data return load_data(...) end local function make_family_object(...) make_family_object = require(families_module).makeObject return make_family_object(...) end local function pattern_escape(...) pattern_escape = require(string_pattern_escape_module) return pattern_escape(...) end local function replacement_escape(...) replacement_escape = require(string_replacement_escape_module) return replacement_escape(...) end local function safe_require(...) safe_require = require(load_module).safe_require return safe_require(...) 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 to_json(...) to_json = require(json_module).toJSON return to_json(...) end local function u(...) u = require(string_utilities_module).char return u(...) end local function ugsub(...) ugsub = require(string_utilities_module).gsub return ugsub(...) end local function ulen(...) ulen = require(string_utilities_module).len return ulen(...) 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 function uupper(...) uupper = require(string_utilities_module).upper return uupper(...) end local function track(page) debug_track("languages/" .. page) return true end local function normalize_code(code) return load_data(languages_data_module).aliases[code] or code end local function check_inputs(self, check, default, ...) local n = select("#", ...) if n == 0 then return false end local ret = check(self, (...)) if ret ~= nil then return ret elseif n > 1 then local inputs = {...} for i = 2, n do ret = check(self, inputs[i]) if ret ~= nil then return ret end end end return default end local function make_link(self, target, display) local prefix, main if self:getFamilyCode() == "qfa-sub" then prefix, main = display:match("^(the )(.*)") if not prefix then prefix, main = display:match("^(a )(.*)") end end return (prefix or "") .. "[[" .. target .. "|" .. (main or display) .. "]]" end -- Convert risky characters to HTML entities, which minimizes interference once returned (e.g. for "sms:a", "<!-- -->" etc.). local function escape_risky_characters(text) -- Spacing characters in isolation generally need to be escaped in order to be properly processed by the MediaWiki software. if umatch(text, "^%s*$") then return encode_entities(text, text) end return encode_entities(text, "!#%&*+/:;<=>?@[\\]_{|}") end -- Temporarily convert various formatting characters to PUA to prevent them from being disrupted by the substitution process. local function doTempSubstitutions(text, subbedChars, keepCarets, noTrim) -- Clone so that we don't insert any extra patterns into the table in package.loaded. For some reason, using require seems to keep memory use down; probably because the table is always cloned. local patterns = shallow_copy(require(languages_data_patterns_module)) if keepCarets then insert(patterns, "((\\+)%^)") insert(patterns, "((%^))") end -- Ensure any whitespace at the beginning and end is temp substituted, to prevent it from being accidentally trimmed. We only want to trim any final spaces added during the substitution process (e.g. by a module), which means we only do this during the first round of temp substitutions. if not noTrim then insert(patterns, "^([\128-\191\244]*(%s+))") insert(patterns, "((%s+)[\128-\191\244]*)$") end -- Pre-substitution, of "[[" and "]]", which makes pattern matching more accurate. text = gsub(text, "%f[%[]%[%[", "\1"):gsub("%f[%]]%]%]", "\2") local i = #subbedChars for _, pattern in ipairs(patterns) do -- Patterns ending in \0 stand are for things like "[[" or "]]"), so the inserted PUA are treated as breaks between terms by modules that scrape info from pages. local term_divider pattern = gsub(pattern, "%z$", function(divider) term_divider = divider == "\0" return "" end) text = gsub(text, pattern, function(...) local m = {...} local m1New = m[1] for k = 2, #m do local n = i + k - 1 subbedChars[n] = m[k] local byte2 = floor(n / 4096) % 64 + (term_divider and 128 or 136) local byte3 = floor(n / 64) % 64 + 128 local byte4 = n % 64 + 128 m1New = gsub(m1New, pattern_escape(m[k]), "\244" .. char(byte2) .. char(byte3) .. char(byte4), 1) end i = i + #m - 1 return m1New end) end text = gsub(text, "\1", "%[%["):gsub("\2", "%]%]") return text, subbedChars end -- Reinsert any formatting that was temporarily substituted. local function undoTempSubstitutions(text, subbedChars) for i = 1, #subbedChars do local byte2 = floor(i / 4096) % 64 + 128 local byte3 = floor(i / 64) % 64 + 128 local byte4 = i % 64 + 128 text = gsub(text, "\244[" .. char(byte2) .. char(byte2+8) .. "]" .. char(byte3) .. char(byte4), replacement_escape(subbedChars[i])) end text = gsub(text, "\1", "%[%["):gsub("\2", "%]%]") return text end -- Check if the raw text is an unsupported title, and if so return that. Otherwise, remove HTML entities. We do the pre-conversion to avoid loading the unsupported title list unnecessarily. local function checkNoEntities(self, text) local textNoEnc = decode_entities(text) if textNoEnc ~= text and load_data(links_data_module).unsupported_titles[text] then return text else return textNoEnc end end -- If no script object is provided (or if it's invalid or None), get one. local function checkScript(text, self, sc) if not check_object("script", true, sc) or sc:getCode() == "None" then return self:findBestScript(text) end return sc end local function normalize(text, sc) text = sc:fixDiscouragedSequences(text) return sc:toFixedNFD(text) end -- Subfunction of iterateSectionSubstitutions(). Process an individual chunk of text according to the specifications in -- `substitution_data`. The input parameters are all as in the documentation of iterateSectionSubstitutions() except for -- `recursed`, which is set to true if we called ourselves recursively to process a script-specific setting or -- script-wide fallback. Returns two values: the processed text and the actual substitution data used to do the -- substitutions (same as the `actual_substitution_data` return value to iterateSectionSubstitutions()). local function doSubstitutions(self, text, sc, substitution_data, data_field, function_name, recursed) -- BE CAREFUL in this function because the value at any level can be `false`, which causes no processing to be done -- and blocks any further fallback processing. local actual_substitution_data = substitution_data -- If there are language-specific substitutes given in the data module, use those. if type(substitution_data) == "table" then -- If a script is specified, run this function with the script-specific data before continuing. local sc_code = sc:getCode() local has_substitution_data = false if substitution_data[sc_code] ~= nil then has_substitution_data = true if substitution_data[sc_code] then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data[sc_code], data_field, function_name, true) end -- Hant, Hans and Hani are usually treated the same, so add a special case to avoid having to specify each one -- separately. elseif sc_code:match("^Han") and substitution_data.Hani ~= nil then has_substitution_data = true if substitution_data.Hani then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data.Hani, data_field, function_name, true) end -- Substitution data with key 1 in the outer table may be given as a fallback. elseif substitution_data[1] ~= nil then has_substitution_data = true if substitution_data[1] then text, actual_substitution_data = doSubstitutions(self, text, sc, substitution_data[1], data_field, function_name, true) end end -- Iterate over all strings in the "from" subtable, and gsub with the corresponding string in "to". We work with -- the NFD decomposed forms, as this simplifies many substitutions. if substitution_data.from then has_substitution_data = true for i, from in ipairs(substitution_data.from) do -- Normalize each loop, to ensure multi-stage substitutions work correctly. text = sc:toFixedNFD(text) text = ugsub(text, sc:toFixedNFD(from), substitution_data.to[i] or "") end end if substitution_data.remove_diacritics then has_substitution_data = true text = sc:toFixedNFD(text) -- Convert exceptions to PUA. local remove_exceptions, substitutes = substitution_data.remove_exceptions if remove_exceptions then substitutes = {} local i = 0 for _, exception in ipairs(remove_exceptions) do exception = sc:toFixedNFD(exception) text = ugsub(text, exception, function(m) i = i + 1 local subst = u(0x80000 + i) substitutes[subst] = m return subst end) end end -- Strip diacritics. text = ugsub(text, "[" .. substitution_data.remove_diacritics .. "]", "") -- Convert exceptions back. if remove_exceptions then text = text:gsub("\242[\128-\191]*", substitutes) end end if not has_substitution_data and sc._data[data_field] then -- If language-specific sort key (etc.) is nil, fall back to script-wide sort key (etc.). text, actual_substitution_data = doSubstitutions(self, text, sc, sc._data[data_field], data_field, function_name, true) end elseif type(substitution_data) == "string" then -- If there is a dedicated function module, use that. local module = safe_require("Module:" .. substitution_data) if module then -- TODO: translit functions should take objects, not codes. -- TODO: translit functions should be called with form NFD. if function_name == "tr" then if not module[function_name] then error(("Internal error: Module [[%s]] has no function named 'tr'"):format(substitution_data)) end text = module[function_name](text, self._code, sc:getCode()) elseif function_name == "stripDiacritics" then -- FIXME, get rid of this arm after renaming makeEntryName -> stripDiacritics. if module[function_name] then text = module[function_name](sc:toFixedNFD(text), self, sc) elseif module.makeEntryName then text = module.makeEntryName(sc:toFixedNFD(text), self, sc) else error(("Internal error: Module [[%s]] has no function named 'stripDiacritics' or 'makeEntryName'" ):format(substitution_data)) end else if not module[function_name] then error(("Internal error: Module [[%s]] has no function named '%s'"):format( substitution_data, function_name)) end text = module[function_name](sc:toFixedNFD(text), self, sc) end else error("Substitution data '" .. substitution_data .. "' does not match an existing module.") end elseif substitution_data == nil and sc._data[data_field] then -- If language-specific sort key (etc.) is nil, fall back to script-wide sort key (etc.). text, actual_substitution_data = doSubstitutions(self, text, sc, sc._data[data_field], data_field, function_name, true) end -- Don't normalize to NFC if this is the inner loop or if a module returned nil. if recursed or not text then return text, actual_substitution_data end -- Fix any discouraged sequences created during the substitution process, and normalize into the final form. return sc:toFixedNFC(sc:fixDiscouragedSequences(text)), actual_substitution_data end -- Split the text into sections, based on the presence of temporarily substituted formatting characters, then iterate -- over each section to apply substitutions (e.g. transliteration or diacritic stripping). This avoids putting PUA -- characters through language-specific modules, which may be unequipped for them. This function is passed the following -- values: -- * `self` (the Language object); -- * `text` (the text to process); -- * `sc` (the script of the text, which must be specified; callers should call checkScript() as needed to autodetect the -- script of the text if not given explicitly by the user); -- * `subbedChars` (an array of the same length as the text, indicating which characters have been substituted and by -- what, or {nil} if no substitutions are to happen); -- * `keepCarets` (DOCUMENT ME); -- * `substitution_data` (the data indicating which substitutions to apply, taken directly from `data_field` in the -- language's data structure in a submodule of [[Module:languages/data]]); -- * `data_field` (the data field from which `substitution_data` was fetched, such as "sort_key" or "strip_diacritics"); -- * `function_name` (the name of the function to call to do the substitution, in case `substitution_data` specifies a -- module to do the substitution); -- * `notrim` (don't trim whitespace at the edges of `text`; set when computing the sort key, because whitespace at the -- beginning of a sort key is significant and causes the resulting page to be sorted at the beginning of the category -- it's in). -- Returns three values: -- (1) the processed text; -- (2) the value of `subbedChars` that was passed in, possibly modified with additional character substitutions; will be -- {nil} if {nil} was passed in; -- (3) the actual substitution data that was used to apply substitutions to `text`; this may be different from the value -- of `substitution_data` passed in if that value recursively specified script-specific substitutions or if no -- substitution data could be found in the language-specific data (e.g. {nil} was passed in or a structure was passed -- in that had no setting for the script given in `sc`), but a script-wide fallback value was set; currently it is -- only used by makeSortKey(). local function iterateSectionSubstitutions(self, text, sc, subbedChars, keepCarets, substitution_data, data_field, function_name, notrim) local sections -- See [[Module:languages/data]]. if not find(text, "\244") or load_data(languages_data_module).substitution[self._code] == "cont" then sections = {text} else sections = split(text, "\244[\128-\143][\128-\191]*", true) end local actual_substitution_data for _, section in ipairs(sections) do -- Don't bother processing empty strings or whitespace (which may also not be handled well by dedicated -- modules). if gsub(section, "%s+", "") ~= "" then local sub, this_actual_substitution_data = doSubstitutions(self, section, sc, substitution_data, data_field, function_name) actual_substitution_data = this_actual_substitution_data -- Second round of temporary substitutions, in case any formatting was added by the main substitution -- process. However, don't do this if the section contains formatting already (as it would have had to have -- been escaped to reach this stage, and therefore should be given as raw text). if sub and subbedChars then local noSub for _, pattern in ipairs(require(languages_data_patterns_module)) do if match(section, pattern .. "%z?") then noSub = true end end if not noSub then sub, subbedChars = doTempSubstitutions(sub, subbedChars, keepCarets, true) end end if not sub then text = sub break end text = sub and gsub(text, pattern_escape(section), replacement_escape(sub), 1) or text end end if not notrim then -- Trim, unless there are only spacing characters, while ignoring any final formatting characters. -- Do not trim sort keys because spaces at the beginning are significant. text = text and text:gsub("^([\128-\191\244]*)%s+(%S)", "%1%2"):gsub("(%S)%s+([\128-\191\244]*)$", "%1%2") or nil end return text, subbedChars, actual_substitution_data end -- Process carets (and any escapes). Default to simple removal, if no pattern/replacement is given. local function processCarets(text, pattern, repl) local rep repeat text, rep = gsub(text, "\\\\(\\*^)", "\3%1") until rep == 0 return (text:gsub("\\^", "\4") :gsub(pattern or "%^", repl or "") :gsub("\3", "\\") :gsub("\4", "^")) end -- Remove carets if they are used to capitalize parts of transliterations (unless they have been escaped). local function removeCarets(text, sc) if not sc:hasCapitalization() and sc:isTransliterated() and text:find("^", 1, true) then return processCarets(text) else return text end end local Language = {} local Bahasa = require("Module:bahasa") --[==[Returns the language code of the language. Example: {{code|lua|"fr"}} for French.]==] function Language:getCode() return Bahasa.getLangCodeByCode(self._code) or self._code end --[==[Returns the canonical name of the language. This is the name used to represent that language on Wiktionary, and is guaranteed to be unique to that language alone. Example: {{code|lua|"French"}} for French.]==] function Language:getCanonicalName() local canonical = Bahasa.getLangNameByCode(self._code) if canonical then self._name = canonical return canonical end local name = self._name if name == nil then name = self._data[1] self._name = name end return name end --lowercase version function Language:getCanonicalNameLower() local name = self:getCanonicalName() local first = mw.ustring.sub(name, 1, 1) local rest = mw.ustring.sub(name, 2) return mw.ustring.lower(first) .. rest end --[==[ Return the display form of the language. The display form of a language, family or script is the form it takes when appearing as the <code><var>source</var></code> in categories such as <code>English terms derived from <var>source</var></code> or <code>English given names from <var>source</var></code>, and is also the displayed text in {makeCategoryLink()} links. For full and etymology-only languages, this is the same as the canonical name, but for families, it reads <code>"<var>name</var> languages"</code> (e.g. {"Indo-Iranian languages"}), and for scripts, it reads <code>"<var>name</var> script"</code> (e.g. {"Arabic script"}). ]==] function Language:getDisplayForm() local form = self._displayForm if form == nil then form = self:getCanonicalNameLower() -- Add article and " substrate" to substrates that lack them. if self:getFamilyCode() == "qfa-sub" then if not (sub(form, 1, 4) == "the " or sub(form, 1, 2) == "a ") then form = "a " .. form end if not match(form, " [Ss]ubstrate") then form = form .. " substrate" end end self._displayForm = form end return form end --[==[Returns the value which should be used in the HTML lang= attribute for tagged text in the language.]==] function Language:getHTMLAttribute(sc, region) local code = self._code if not find(code, "-", 1, true) then return code .. "-" .. sc:getCode() .. (region and "-" .. region or "") end local parent = self:getParent() region = region or match(code, "%f[%u][%u-]+%f[%U]") if parent then return parent:getHTMLAttribute(sc, region) end -- TODO: ISO family codes can also be used. return "mis-" .. sc:getCode() .. (region and "-" .. region or "") end --[==[Returns a table of the aliases that the language is known by, excluding the canonical name. Aliases are synonyms for the language in question. The names are not guaranteed to be unique, in that sometimes more than one language is known by the same name. Example: {{code|lua|{"High German", "New High German", "Deutsch"} }} for [[:Category:German language|German]].]==] function Language:getAliases() self:loadInExtraData() return require(language_like_module).getAliases(self) end --[==[ Return a table of the known subvarieties of a given language, excluding subvarieties that have been given explicit etymology-only language codes. The names are not guaranteed to be unique, in that sometimes a given name refers to a subvariety of more than one language. Example: {{code|lua|{"Southern Aymara", "Central Aymara"} }} for [[:Category:Aymara language|Aymara]]. Note that the returned value can have nested tables in it, when a subvariety goes by more than one name. Example: {{code|lua|{"North Azerbaijani", "South Azerbaijani", {"Afshar", "Afshari", "Afshar Azerbaijani", "Afchar"}, {"Qashqa'i", "Qashqai", "Kashkay"}, "Sonqor"} }} for [[:Category:Azerbaijani language|Azerbaijani]]. Here, for example, Afshar, Afshari, Afshar Azerbaijani and Afchar all refer to the same subvariety, whose preferred name is Afshar (the one listed first). To avoid a return value with nested tables in it, specify a non-{{code|lua|nil}} value for the <code>flatten</code> parameter; in that case, the return value would be {{code|lua|{"North Azerbaijani", "South Azerbaijani", "Afshar", "Afshari", "Afshar Azerbaijani", "Afchar", "Qashqa'i", "Qashqai", "Kashkay", "Sonqor"} }}. ]==] function Language:getVarieties(flatten) self:loadInExtraData() return require(language_like_module).getVarieties(self, flatten) end --[==[Returns a table of the "other names" that the language is known by, which are listed in the <code>otherNames</code> field. It should be noted that the <code>otherNames</code> field itself is deprecated, and entries listed there should eventually be moved to either <code>aliases</code> or <code>varieties</code>.]==] function Language:getOtherNames() -- To be eventually removed, once there are no more uses of the `otherNames` field. self:loadInExtraData() return require(language_like_module).getOtherNames(self) end --[==[ Return a combined table of the canonical name, aliases, varieties and other names of a given language.]==] function Language:getAllNames() self:loadInExtraData() return require(language_like_module).getAllNames(self) end --[==[Returns a table of types as a lookup table (with the types as keys). The possible types are * {language}: This is a language, either full or etymology-only. * {full}: This is a "full" (not etymology-only) language, i.e. the union of {regular}, {reconstructed} and {appendix-constructed}. Note that the types {full} and {etymology-only} also exist for families, so if you want to check specifically for a full language and you have an object that might be a family, you should use {{lua|hasType("language", "full")}} and not simply {{lua|hasType("full")}}. * {etymology-only}: This is an etymology-only (not full) language, whose parent is another etymology-only language or a full language. Note that the types {full} and {etymology-only} also exist for families, so if you want to check specifically for an etymology-only language and you have an object that might be a family, you should use {{lua|hasType("language", "etymology-only")}} and not simply {{lua|hasType("etymology-only")}}. * {regular}: This indicates a full language that is attested according to [[WT:CFI]] and therefore permitted in the main namespace. There may also be reconstructed terms for the language, which are placed in the {Reconstruction} namespace and must be prefixed with * to indicate a reconstruction. Most full languages are natural (not constructed) languages, but a few constructed languages (e.g. Esperanto and Volapük, among others) are also allowed in the mainspace and considered regular languages. * {reconstructed}: This language is not attested according to [[WT:CFI]], and therefore is allowed only in the {Reconstruction} namespace. All terms in this language are reconstructed, and must be prefixed with *. Languages such as Proto-Indo-European and Proto-Germanic are in this category. * {appendix-constructed}: This language is attested but does not meet the additional requirements set out for constructed languages ([[WT:CFI#Constructed languages]]). Its entries must therefore be in the Appendix namespace, but they are not reconstructed and therefore should not have * prefixed in links. ]==] function Language:getTypes() local types = self._types if types == nil then types = {language = true} if self:getFullCode() == self._code then types.full = true else types["etymology-only"] = true end for t in gmatch(self._data.type, "[^,]+") do types[t] = true end self._types = types end return types end --[==[Given a list of types as strings, returns true if the language has all of them.]==] function Language:hasType(...) Language.hasType = require(language_like_module).hasType return self:hasType(...) end --[==[Returns a table containing <code>WikimediaLanguage</code> objects (see [[Module:wikimedia languages]]), which represent languages and their codes as they are used in Wikimedia projects for interwiki linking and such. More than one object may be returned, as a single Wiktionary language may correspond to multiple Wikimedia languages. For example, Wiktionary's single code <code>sh</code> (Serbo-Croatian) maps to four Wikimedia codes: <code>sh</code> (Serbo-Croatian), <code>bs</code> (Bosnian), <code>hr</code> (Croatian) and <code>sr</code> (Serbian). The code for the Wikimedia language is retrieved from the <code>wikimedia_codes</code> property in the data modules. If that property is not present, the code of the current language is used. If none of the available codes is actually a valid Wikimedia code, an empty table is returned.]==] function Language:getWikimediaLanguages() local wm_langs = self._wikimediaLanguageObjects if wm_langs == nil then local codes = self:getWikimediaLanguageCodes() wm_langs = {} for i = 1, #codes do wm_langs[i] = get_wikimedia_lang(codes[i]) end self._wikimediaLanguageObjects = wm_langs end return wm_langs end function Language:getWikimediaLanguageCodes() local wm_langs = self._wikimediaLanguageCodes if wm_langs == nil then wm_langs = self._data.wikimedia_codes if wm_langs then wm_langs = split(wm_langs, ",", true, true) else local code = self._code if is_known_language_tag(code) then wm_langs = {code} else -- Inherit, but only if no codes are specified in the data *and* -- the language code isn't a valid Wikimedia language code. local parent = self:getParent() wm_langs = parent and parent:getWikimediaLanguageCodes() or {} end end self._wikimediaLanguageCodes = wm_langs end return wm_langs end --[==[ Returns the name of the Wikipedia article for the language. `project` specifies the language and project to retrieve the article from, defaulting to {"enwiki"} for the English Wikipedia. Normally if specified it should be the project code for a specific-language Wikipedia e.g. "zhwiki" for the Chinese Wikipedia, but it can be any project, including non-Wikipedia ones. If the project is the English Wikipedia and the property {wikipedia_article} is present in the data module it will be used first. In all other cases, a sitelink will be generated from {:getWikidataItem} (if set). The resulting value (or lack of value) is cached so that subsequent calls are fast. If no value could be determined, and `noCategoryFallback` is {false}, {:getCategoryName} is used as fallback; otherwise, {nil} is returned. Note that if `noCategoryFallback` is {nil} or omitted, it defaults to {false} if the project is the English Wikipedia, otherwise to {true}. In other words, under normal circumstances, if the English Wikipedia article couldn't be retrieved, the return value will fall back to a link to the language's category, but this won't normally happen for any other project. ]==] function Language:getWikipediaArticle(noCategoryFallback, project) Language.getWikipediaArticle = require(language_like_module).getWikipediaArticle return self:getWikipediaArticle(noCategoryFallback, project) end function Language:makeWikipediaLink() return make_link(self, "w:id:" .. self:getWikipediaArticle(), self:getCanonicalNameLower()) end --[==[Returns the name of the Wikimedia Commons category page for the language.]==] function Language:getCommonsCategory() Language.getCommonsCategory = require(language_like_module).getCommonsCategory return self:getCommonsCategory() end --[==[Returns the Wikidata item id for the language or <code>nil</code>. This corresponds to the the second field in the data modules.]==] function Language:getWikidataItem() Language.getWikidataItem = require(language_like_module).getWikidataItem return self:getWikidataItem() end --[==[Returns a table of <code>Script</code> objects for all scripts that the language is written in. See [[Module:scripts]].]==] function Language:getScripts() local scripts = self._scriptObjects if scripts == nil then local codes = self:getScriptCodes() if codes[1] == "All" then scripts = load_data(scripts_data_module) else scripts = {} for i = 1, #codes do scripts[i] = get_script(codes[i]) end end self._scriptObjects = scripts end return scripts end --[==[Returns the table of script codes in the language's data file.]==] function Language:getScriptCodes() local scripts = self._scriptCodes if scripts == nil then scripts = self._data[4] if scripts then local codes, n = {}, 0 for code in gmatch(scripts, "[^,]+") do n = n + 1 -- Special handling of "Hants", which represents "Hani", "Hant" and "Hans" collectively. if code == "Hants" then codes[n] = "Hani" codes[n + 1] = "Hant" codes[n + 2] = "Hans" n = n + 2 else codes[n] = code end end scripts = codes else scripts = {"None"} end self._scriptCodes = scripts end return scripts end --[==[Given some text, this function iterates through the scripts of a given language and tries to find the script that best matches the text. It returns a {{code|lua|Script}} object representing the script. If no match is found at all, it returns the {{code|lua|None}} script object.]==] function Language:findBestScript(text, forceDetect) if not text or text == "" or text == "-" then return get_script("None") end -- Differs from table returned by getScriptCodes, as Hants is not normalized into its constituents. local codes = self._bestScriptCodes if codes == nil then codes = self._data[4] codes = codes and split(codes, ",", true, true) or {"None"} self._bestScriptCodes = codes end local first_sc = codes[1] if first_sc == "All" then return find_best_script_without_lang(text) end local codes_len = #codes if not (forceDetect or first_sc == "Hants" or codes_len > 1) then first_sc = get_script(first_sc) local charset = first_sc.characters return charset and umatch(text, "[" .. charset .. "]") and first_sc or get_script("None") end -- Remove all formatting characters. text = get_plaintext(text) -- Remove all spaces and any ASCII punctuation. Some non-ASCII punctuation is script-specific, so can't be removed. text = ugsub(text, "[%s!\"#%%&'()*,%-./:;?@[\\%]_{}]+", "") if #text == 0 then return get_script("None") end -- Try to match every script against the text, -- and return the one with the most matching characters. local bestcount, bestscript, length = 0 for i = 1, codes_len do local sc = codes[i] -- Special case for "Hants", which is a special code that represents whichever of "Hant" or "Hans" best matches, or "Hani" if they match equally. This avoids having to list all three. In addition, "Hants" will be treated as the best match if there is at least one matching character, under the assumption that a Han script is desirable in terms that contain a mix of Han and other scripts (not counting those which use Jpan or Kore). if sc == "Hants" then local Hani = get_script("Hani") if not Hant_chars then Hant_chars = load_data("Module:zh/data/ts") Hans_chars = load_data("Module:zh/data/st") end local t, s, found = 0, 0 -- This is faster than using mw.ustring.gmatch directly. for ch in gmatch((ugsub(text, "[" .. Hani.characters .. "]", "\255%0")), "\255(.[\128-\191]*)") do found = true if Hant_chars[ch] then t = t + 1 if Hans_chars[ch] then s = s + 1 end elseif Hans_chars[ch] then s = s + 1 else t, s = t + 1, s + 1 end end if found then if t == s then return Hani end return get_script(t > s and "Hant" or "Hans") end else sc = get_script(sc) if not length then length = ulen(text) end -- Count characters by removing everything in the script's charset and comparing to the original length. local charset = sc.characters local count = charset and length - ulen((ugsub(text, "[" .. charset .. "]+", ""))) or 0 if count >= length then return sc elseif count > bestcount then bestcount = count bestscript = sc end end end -- Return best matching script, or otherwise None. return bestscript or get_script("None") end --[==[Returns a <code>Family</code> object for the language family that the language belongs to. See [[Module:families]].]==] function Language:getFamily() local family = self._familyObject if family == nil then family = self:getFamilyCode() -- If the value is nil, it's cached as false. family = family and get_family(family) or false self._familyObject = family end return family or nil end --[==[Returns the family code in the language's data file.]==] function Language:getFamilyCode() local family = self._familyCode if family == nil then -- If the value is nil, it's cached as false. family = self._data[3] or false self._familyCode = family end return family or nil end function Language:getFamilyName() local family = self._familyName if family == nil then family = self:getFamily() -- If the value is nil, it's cached as false. family = family and family:getCanonicalName() or false self._familyName = family end return family or nil end do local function check_family(self, family) if type(family) == "table" then family = family:getCode() end if self:getFamilyCode() == family then return true end local self_family = self:getFamily() if self_family:inFamily(family) then return true -- If the family isn't a real family (e.g. creoles) check any ancestors. elseif self_family:inFamily("qfa-not") then local ancestors = self:getAncestors() for _, ancestor in ipairs(ancestors) do if ancestor:inFamily(family) then return true end end end end --[==[Check whether the language belongs to `family` (which can be a family code or object). A list of objects can be given in place of `family`; in that case, return true if the language belongs to any of the specified families. Note that some languages (in particular, certain creoles) can have multiple immediate ancestors potentially belonging to different families; in that case, return true if the language belongs to any of the specified families.]==] function Language:inFamily(...) if self:getFamilyCode() == nil then return false end return check_inputs(self, check_family, false, ...) end end function Language:getParent() local parent = self._parentObject if parent == nil then parent = self:getParentCode() -- If the value is nil, it's cached as false. parent = parent and get_by_code(parent, nil, true, true) or false self._parentObject = parent end return parent or nil end function Language:getParentCode() local parent = self._parentCode if parent == nil then -- If the value is nil, it's cached as false. parent = self._data.parent or false self._parentCode = parent end return parent or nil end function Language:getParentName() local parent = self._parentName if parent == nil then parent = self:getParent() -- If the value is nil, it's cached as false. parent = parent and parent:getCanonicalName() or false self._parentName = parent end return parent or nil end function Language:getParentChain() local chain = self._parentChain if chain == nil then chain = {} local parent, n = self:getParent(), 0 while parent do n = n + 1 chain[n] = parent parent = parent:getParent() end self._parentChain = chain end return chain end do local function check_lang(self, lang) for _, parent in ipairs(self:getParentChain()) do if (type(lang) == "string" and lang or lang:getCode()) == parent:getCode() then return true end end end function Language:hasParent(...) return check_inputs(self, check_lang, false, ...) end end --[==[ If the language is etymology-only, this iterates through parents until a full language or family is found, and the corresponding object is returned. If the language is a full language, then it simply returns itself. ]==] function Language:getFull() local full = self._fullObject if full == nil then full = self:getFullCode() full = full == self._code and self or get_by_code(full) self._fullObject = full end return full end --[==[ If the language is an etymology-only language, this iterates through parents until a full language or family is found, and the corresponding code is returned. If the language is a full language, then it simply returns the language code. ]==] function Language:getFullCode() return self._fullCode or self._code end --[==[ If the language is an etymology-only language, this iterates through parents until a full language or family is found, and the corresponding canonical name is returned. If the language is a full language, then it simply returns the canonical name of the language. ]==] function Language:getFullName() local full = self._fullName if full == nil then full = self:getFull():getCanonicalName() self._fullName = full end return full end --[==[Returns a table of <code class="nf">Language</code> objects for all languages that this language is directly descended from. Generally this is only a single language, but creoles, pidgins and mixed languages can have multiple ancestors.]==] function Language:getAncestors() local ancestors = self._ancestorObjects if ancestors == nil then ancestors = {} local ancestor_codes = self:getAncestorCodes() if #ancestor_codes > 0 then for _, ancestor in ipairs(ancestor_codes) do insert(ancestors, get_by_code(ancestor, nil, true)) end else local fam = self:getFamily() local protoLang = fam and fam:getProtoLanguage() or nil -- For the cases where the current language is the proto-language -- of its family, or an etymology-only language that is ancestral to that -- proto-language, we need to step up a level higher right from the -- start. if protoLang and ( protoLang:getCode() == self._code or (self:hasType("etymology-only") and protoLang:hasAncestor(self)) ) then fam = fam:getFamily() protoLang = fam and fam:getProtoLanguage() or nil end while not protoLang and not (not fam or fam:getCode() == "qfa-not") do fam = fam:getFamily() protoLang = fam and fam:getProtoLanguage() or nil end insert(ancestors, protoLang) end self._ancestorObjects = ancestors end return ancestors end do -- Avoid a language being its own ancestor via class inheritance. We only need to check for this if the language has inherited an ancestor table from its parent, because we never want to drop ancestors that have been explicitly set in the data. -- Recursively iterate over ancestors until we either find self or run out. If self is found, return true. local function check_ancestor(self, lang) local codes = lang:getAncestorCodes() if not codes then return nil end for i = 1, #codes do local code = codes[i] if code == self._code then return true end local anc = get_by_code(code, nil, true) if check_ancestor(self, anc) then return true end end end --[==[Returns a table of <code class="nf">Language</code> codes for all languages that this language is directly descended from. Generally this is only a single language, but creoles, pidgins and mixed languages can have multiple ancestors.]==] function Language:getAncestorCodes() if self._ancestorCodes then return self._ancestorCodes end local data = self._data local codes = data.ancestors if codes == nil then codes = {} self._ancestorCodes = codes return codes end codes = split(codes, ",", true, true) self._ancestorCodes = codes -- If there are no codes or the ancestors weren't inherited data, there's nothing left to check. if #codes == 0 or self:getData(false, "raw").ancestors ~= nil then return codes end local i, code = 1 while i <= #codes do code = codes[i] if check_ancestor(self, self) then remove(codes, i) else i = i + 1 end end return codes end end --[==[Given a list of language objects or codes, returns true if at least one of them is an ancestor. This includes any etymology-only children of that ancestor. If the language's ancestor(s) are etymology-only languages, it will also return true for those language parent(s) (e.g. if Vulgar Latin is the ancestor, it will also return true for its parent, Latin). However, a parent is excluded from this if the ancestor is also ancestral to that parent (e.g. if Classical Persian is the ancestor, Persian would return false, because Classical Persian is also ancestral to Persian).]==] function Language:hasAncestor(...) local function iterateOverAncestorTree(node, func, parent_check) local ancestors = node:getAncestors() local ancestorsParents = {} for _, ancestor in ipairs(ancestors) do -- When checking the parents of the other language, and the ancestor is also a parent, skip to the next ancestor, so that we exclude any etymology-only children of that parent that are not directly related (see below). local ret = (parent_check or not node:hasParent(ancestor)) and func(ancestor) or iterateOverAncestorTree(ancestor, func, parent_check) if ret then return ret end end -- Check the parents of any ancestors. We don't do this if checking the parents of the other language, so that we exclude any etymology-only children of those parents that are not directly related (e.g. if the ancestor is Vulgar Latin and we are checking New Latin, we want it to return false because they are on different ancestral branches. As such, if we're already checking the parent of New Latin (Latin) we don't want to compare it to the parent of the ancestor (Latin), as this would be a false positive; it should be one or the other). if not parent_check then return nil end for _, ancestor in ipairs(ancestors) do local ancestorParents = ancestor:getParentChain() for _, ancestorParent in ipairs(ancestorParents) do if ancestorParent:getCode() == self._code or ancestorParent:hasAncestor(ancestor) then break else insert(ancestorsParents, ancestorParent) end end end for _, ancestorParent in ipairs(ancestorsParents) do local ret = func(ancestorParent) if ret then return ret end end end local function do_iteration(otherlang, parent_check) -- otherlang can't be self if (type(otherlang) == "string" and otherlang or otherlang:getCode()) == self._code then return false end repeat if iterateOverAncestorTree( self, function(ancestor) return ancestor:getCode() == (type(otherlang) == "string" and otherlang or otherlang:getCode()) end, parent_check ) then return true elseif type(otherlang) == "string" then otherlang = get_by_code(otherlang, nil, true) end otherlang = otherlang:getParent() parent_check = false until not otherlang end local parent_check = true for _, otherlang in ipairs{...} do local ret = do_iteration(otherlang, parent_check) if ret then return true end end return false end do local function construct_node(lang, memo) local branch, ancestors = {lang = lang:getCode()} memo[lang:getCode()] = branch for _, ancestor in ipairs(lang:getAncestors()) do if ancestors == nil then ancestors = {} end insert(ancestors, memo[ancestor:getCode()] or construct_node(ancestor, memo)) end branch.ancestors = ancestors return branch end function Language:getAncestorChain() local chain = self._ancestorChain if chain == nil then chain = construct_node(self, {}) self._ancestorChain = chain end return chain end end function Language:getAncestorChainOld() local chain = self._ancestorChain if chain == nil then chain = {} local step = self while true do local ancestors = step:getAncestors() step = #ancestors == 1 and ancestors[1] or nil if not step then break end insert(chain, step) end self._ancestorChain = chain end return chain end local function fetch_descendants(self, fmt) local descendants, family = {}, self:getFamily() -- Iterate over all three datasets. for _, data in ipairs{ require("Module:languages/code to canonical name"), require("Module:etymology languages/code to canonical name"), require("Module:families/code to canonical name"), } do for code in pairs(data) do local lang = get_by_code(code, nil, true, true) -- Test for a descendant. Earlier tests weed out most candidates, while the more intensive tests are only used sparingly. if ( code ~= self._code and -- Not self. lang:inFamily(family) and -- In the same family. ( family:getProtoLanguageCode() == self._code or -- Self is the protolanguage. self:hasDescendant(lang) or -- Full hasDescendant check. (lang:getFullCode() == self._code and not self:hasAncestor(lang)) -- Etymology-only child which isn't an ancestor. ) ) then if fmt == "object" then insert(descendants, lang) elseif fmt == "code" then insert(descendants, code) elseif fmt == "name" then insert(descendants, lang:getCanonicalName()) end end end end return descendants end function Language:getDescendants() local descendants = self._descendantObjects if descendants == nil then descendants = fetch_descendants(self, "object") self._descendantObjects = descendants end return descendants end function Language:getDescendantCodes() local descendants = self._descendantCodes if descendants == nil then descendants = fetch_descendants(self, "code") self._descendantCodes = descendants end return descendants end function Language:getDescendantNames() local descendants = self._descendantNames if descendants == nil then descendants = fetch_descendants(self, "name") self._descendantNames = descendants end return descendants end do local function check_lang(self, lang) if type(lang) == "string" then lang = get_by_code(lang, nil, true) end if lang:hasAncestor(self) then return true end end function Language:hasDescendant(...) return check_inputs(self, check_lang, false, ...) end end local function fetch_children(self, fmt) local m_etym_data = require(etymology_languages_data_module) local self_code, children = self._code, {} for code, lang in pairs(m_etym_data) do local _lang = lang repeat local parent = _lang.parent if parent == self_code then if fmt == "object" then insert(children, get_by_code(code, nil, true)) elseif fmt == "code" then insert(children, code) elseif fmt == "name" then insert(children, lang[1]) end break end _lang = m_etym_data[parent] until not _lang end return children end function Language:getChildren() local children = self._childObjects if children == nil then children = fetch_children(self, "object") self._childObjects = children end return children end function Language:getChildrenCodes() local children = self._childCodes if children == nil then children = fetch_children(self, "code") self._childCodes = children end return children end function Language:getChildrenNames() local children = self._childNames if children == nil then children = fetch_children(self, "name") self._childNames = children end return children end function Language:hasChild(...) local lang = ... if not lang then return false elseif type(lang) == "string" then lang = get_by_code(lang, nil, true) end if lang:hasParent(self) then return true end return self:hasChild(select(2, ...)) end --[==[Returns the name of the main category of that language. Example: {{code|lua|"French language"}} for French, whose category is at [[:Category:French language]]. Unless optional argument <code>nocap</code> is given, the language name at the beginning of the returned value will be capitalized. This capitalization is correct for category names, but not if the language name is lowercase and the returned value of this function is used in the middle of a sentence.]==] function Language:getCategoryName(nocap) local name = self._categoryName if name == nil then name = self:getCanonicalNameLower() -- If a substrate, omit any leading article. if self:getFamilyCode() == "qfa-sub" then name = name:gsub("^the ", ""):gsub("^a ", "") end -- Only add " language" if a full language. if self:hasType("full") then -- Unless the canonical name already ends with "language", "lect" or their derivatives, add " language". if not (match(name, "[Ll]anguage$") or match(name, "[Ll]ect$")) then name = name .. " language" end end self._categoryName = name end if nocap then return name end return mw.getContentLanguage():ucfirst(name) end --[==[Creates a link to the category; the link text is the canonical name.]==] function Language:makeCategoryLink() return make_link(self, ":Category:" .. self:getCategoryName(), self:getDisplayForm()) end function Language:getStandardCharacters(sc) local standard_chars = self._data.standardChars if type(standard_chars) ~= "table" then return standard_chars elseif sc and type(sc) ~= "string" then check_object("script", nil, sc) sc = sc:getCode() end if (not sc) or sc == "None" then local scripts = {} for _, script in pairs(standard_chars) do insert(scripts, script) end return concat(scripts) end if standard_chars[sc] then return standard_chars[sc] .. (standard_chars[1] or "") end end --[==[ Strip diacritics from display text `text` (in a language-specific fashion), which is in the script `sc`. If `sc` is omitted or {nil}, the script is autodetected. This also strips certain punctuation characters from the end and (in the case of Spanish upside-down question mark and exclamation points) from the beginning; strips any whitespace at the end of the text or between the text and final stripped punctuation characters; and applies some language-specific Unicode normalizations to replace discouraged characters with their prescribed alternatives. Return the stripped text. ]==] function Language:stripDiacritics(text, sc) if (not text) or text == "" then return text end sc = checkScript(text, self, sc) text = normalize(text, sc) -- FIXME, rename makeEntryName to stripDiacritics and get rid of second and third return values -- everywhere text, _, _ = iterateSectionSubstitutions(self, text, sc, nil, nil, self._data.strip_diacritics or self._data.entry_name, "strip_diacritics", "stripDiacritics") text = umatch(text, "^[¿¡]?(.-[^%s%p].-)%s*[؟?!;՛՜ ՞ ՟?!︖︕।॥။၊་།]?$") or text return text end --[==[ Convert a ''logical'' pagename (the pagename as it appears to the user, after diacritics and punctuation have been stripped) to a ''physical'' pagename (the pagename as it appears in the MediaWiki database). Reasons for a difference between the two are (a) unsupported titles such as `[ ]` (with square brackets in them), `#` (pound/hash sign) and `¯\_(ツ)_/¯` (with underscores), as well as overly long titles of various sorts; (b) "mammoth" pages that are split into parts (e.g. `a`, which is split into physical pagenames `a/languages A to L` and `a/languages M to Z`). For almost all purposes, you should work with logical and not physical pagenames. But there are certain use cases that require physical pagenames, such as checking the existence of a page or retrieving a page's contents. `pagename` is the logical pagename to be converted. `is_reconstructed_or_appendix` indicates whether the page is in the `Reconstruction` or `Appendix` namespaces. If it is omitted or has the value {nil}, the pagename is checked for an initial asterisk, and if found, the page is assumed to be a `Reconstruction` page. Setting a value of `false` or `true` to `is_reconstructed_or_appendix` disables this check and allows for mainspace pagenames that begin with an asterisk. ]==] function Language:logicalToPhysical(pagename, is_reconstructed_or_appendix) -- FIXME: This probably shouldn't happen but it happens when makeEntryName() receives nil. if pagename == nil then track("nil-passed-to-logicalToPhysical") return nil end local initial_asterisk if is_reconstructed_or_appendix == nil then local pagename_minus_initial_asterisk initial_asterisk, pagename_minus_initial_asterisk = pagename:match("^(%*)(.*)$") if pagename_minus_initial_asterisk then is_reconstructed_or_appendix = true pagename = pagename_minus_initial_asterisk elseif self:hasType("appendix-constructed") then is_reconstructed_or_appendix = true end end if not is_reconstructed_or_appendix then -- Check if the pagename is a listed unsupported title. local unsupportedTitles = load_data(links_data_module).unsupported_titles if unsupportedTitles[pagename] then return "Unsupported titles/" .. unsupportedTitles[pagename] end end -- Set `unsupported` as true if certain conditions are met. local unsupported -- Check if there's an unsupported character. \239\191\189 is the replacement character U+FFFD, which can't be typed -- directly here due to an abuse filter. Unix-style dot-slash notation is also unsupported, as it is used for -- relative paths in links, as are 3 or more consecutive tildes. Note: match is faster with magic -- characters/charsets; find is faster with plaintext. if ( match(pagename, "[#<>%[%]_{|}]") or find(pagename, "\239\191\189") or match(pagename, "%f[^%z/]%.%.?%f[%z/]") or find(pagename, "~~~") ) then unsupported = true -- If it looks like an interwiki link. elseif find(pagename, ":") then local prefix = gsub(pagename, "^:*(.-):.*", ulower) if ( load_data("Module:data/namespaces")[prefix] or load_data("Module:data/interwikis")[prefix] ) then unsupported = true end end -- Escape unsupported characters so they can be used in titles. ` is used as a delimiter for this, so a raw use of -- it in an unsupported title is also escaped here to prevent interference; this is only done with unsupported -- titles, though, so inclusion won't in itself mean a title is treated as unsupported (which is why it's excluded -- from the earlier test). if unsupported then -- FIXME: This conversion needs to be different for reconstructed pages with unsupported characters. There -- aren't any currently, but if there ever are, we need to fix this e.g. to put them in something like -- Reconstruction:Proto-Indo-European/Unsupported titles/`lowbar``num`. local unsupported_characters = load_data(links_data_module).unsupported_characters pagename = pagename:gsub("[#<>%[%]_`{|}\239]\191?\189?", unsupported_characters) :gsub("%f[^%z/]%.%.?%f[%z/]", function(m) return (gsub(m, "%.", "`period`")) end) :gsub("~~~+", function(m) return (gsub(m, "~", "`tilde`")) end) pagename = "Unsupported titles/" .. pagename elseif not is_reconstructed_or_appendix then -- Check if this is a mammoth page. If so, which subpage should we link to? local m_links_data = load_data(links_data_module) local mammoth_page_type = m_links_data.mammoth_pages[pagename] if mammoth_page_type then local canonical_name = self:getFullName() if canonical_name ~= "Translingual" and canonical_name ~= "English" then local this_subpage local L2_sort_key = get_L2_sort_key(canonical_name) for _, subpage_spec in ipairs(m_links_data.mammoth_page_subpage_types[mammoth_page_type]) do -- unpack() fails utterly on data loaded using mw.loadData() even if offsets are given local subpage, pattern = subpage_spec[1], subpage_spec[2] if pattern == true or L2_sort_key:match(pattern) then this_subpage = subpage break end end if not this_subpage then error(("Internal error: Bad data in mammoth_page_subpage_pages in [[Module:links/data]] for mammoth page %s, type %s; last entry didn't have 'true' in it"):format( pagename, mammoth_page_type)) end pagename = pagename .. "/" .. this_subpage end end end return (initial_asterisk or "") .. pagename end --[==[ Strip the diacritics from a display pagename and convert the resulting logical pagename into a physical pagename. This allows you, for example, to retrieve the contents of the page or check its existence. WARNING: This is deprecated and will be going away. It is a simple composition of `self:stripDiacritics` and `self:logicalToPhysical`; most callers only want the former, and if you need both, call them both yourself. `text` and `sc` are as in `self:stripDiacritics`, and `is_reconstructed_or_appendix` is as in `self:logicalToPhysical`. ]==] function Language:makeEntryName(text, sc, is_reconstructed_or_appendix) return self:logicalToPhysical(self:stripDiacritics(text, sc), is_reconstructed_or_appendix) end --[==[Generates alternative forms using a specified method, and returns them as a table. If no method is specified, returns a table containing only the input term.]==] function Language:generateForms(text, sc) local generate_forms = self._data.generate_forms if generate_forms == nil then return {text} end sc = checkScript(text, self, sc) return require("Module:" .. self._data.generate_forms).generateForms(text, self, sc) end --[==[Creates a sort key for the given stripped text, following the rules appropriate for the language. This removes diacritical marks from the stripped text if they are not considered significant for sorting, and may perform some other changes. Any initial hyphen is also removed, and anything in parentheses is removed as well. The <code>sort_key</code> setting for each language in the data modules defines the replacements made by this function, or it gives the name of the module that takes the stripped text and returns a sortkey.]==] function Language:makeSortKey(text, sc) if (not text) or text == "" then return text end if match(text, "<[^<>]+>") then track("track HTML tag") end -- Remove directional characters, bold, italics, soft hyphens, strip markers and HTML tags. -- FIXME: Partly duplicated with remove_formatting() in [[Module:links]]. text = ugsub(text, "[\194\173\226\128\170-\226\128\174\226\129\166-\226\129\169]", "") text = text:gsub("('*)'''(.-'*)'''", "%1%2"):gsub("('*)''(.-'*)''", "%1%2") text = gsub(unstrip(text), "<[^<>]+>", "") text = decode_uri(text, "PATH") text = checkNoEntities(self, text) -- Remove initial hyphens and * unless the term only consists of spacing + punctuation characters. text = ugsub(text, "^([􀀀-􏿽]*)[-־ـ᠊*]+([􀀀-􏿽]*)(.*[^%s%p].*)", "%1%2%3") sc = checkScript(text, self, sc) text = normalize(text, sc) text = removeCarets(text, sc) -- For languages with dotted dotless i, ensure that "İ" is sorted as "i", and "I" is sorted as "ı". if self:hasDottedDotlessI() then text = gsub(text, "I\204\135", "i") -- decomposed "İ" :gsub("I", "ı") text = sc:toFixedNFD(text) end -- Convert to lowercase, make the sortkey, then convert to uppercase. Where the language has dotted dotless i, it is -- usually not necessary to convert "i" to "İ" and "ı" to "I" first, because "I" will always be interpreted as -- conventional "I" (not dotless "İ") by any sorting algorithms, which will have been taken into account by the -- sortkey substitutions themselves. However, if no sortkey substitutions have been specified, then conversion is -- necessary so as to prevent "i" and "ı" both being sorted as "I". -- -- An exception is made for scripts that (sometimes) sort by scraping page content, as that means they are sensitive -- to changes in capitalization (as it changes the target page). if not sc:sortByScraping() then text = ulower(text) end local actual_substitution_data -- Don't trim whitespace here because it's significant at the beginning of a sort key or sort base. text, _, actual_substitution_data = iterateSectionSubstitutions(self, text, sc, nil, nil, self._data.sort_key, "sort_key", "makeSortKey", "notrim") if not sc:sortByScraping() then if self:hasDottedDotlessI() and not actual_substitution_data then text = text:gsub("ı", "I"):gsub("i", "İ") text = sc:toFixedNFC(text) end text = uupper(text) end -- Remove parentheses, as long as they are either preceded or followed by something. text = gsub(text, "(.)[()]+", "%1"):gsub("[()]+(.)", "%1") text = escape_risky_characters(text) return text end --[==[Create the form used as as a basis for display text and transliteration. FIXME: Rename to correctInputText().]==] local function processDisplayText(text, self, sc, keepCarets, keepPrefixes) local subbedChars = {} text, subbedChars = doTempSubstitutions(text, subbedChars, keepCarets) text = decode_uri(text, "PATH") text = checkNoEntities(self, text) sc = checkScript(text, self, sc) text = normalize(text, sc) text, subbedChars = iterateSectionSubstitutions(self, text, sc, subbedChars, keepCarets, self._data.display_text, "display_text", "makeDisplayText") text = removeCarets(text, sc) -- Remove any interwiki link prefixes (unless they have been escaped or this has been disabled). if find(text, ":") and not keepPrefixes then local rep repeat text, rep = gsub(text, "\\\\(\\*:)", "\3%1") until rep == 0 text = gsub(text, "\\:", "\4") while true do local prefix = gsub(text, "^(.-):.+", function(m1) return (gsub(m1, "\244[\128-\191]*", "")) end) -- Check if the prefix is an interwiki, though ignore capitalised Wiktionary:, which is a namespace. if not prefix or prefix == text or prefix == "Wiktionary" or not (load_data("Module:data/interwikis")[ulower(prefix)] or prefix == "") then break end text = gsub(text, "^(.-):(.*)", function(m1, m2) local ret = {} for subbedChar in gmatch(m1, "\244[\128-\191]*") do insert(ret, subbedChar) end return concat(ret) .. m2 end) end text = gsub(text, "\3", "\\"):gsub("\4", ":") end return text, subbedChars end --[==[Make the display text (i.e. what is displayed on the page).]==] function Language:makeDisplayText(text, sc, keepPrefixes) if not text or text == "" then return text end local subbedChars text, subbedChars = processDisplayText(text, self, sc, nil, keepPrefixes) text = escape_risky_characters(text) return undoTempSubstitutions(text, subbedChars) end --[==[Transliterates the text from the given script into the Latin script (see [[Wiktionary:Transliteration and romanization]]). The language must have the <code>translit</code> property for this to work; if it is not present, {{code|lua|nil}} is returned. The <code>sc</code> parameter is handled by the transliteration module, and how it is handled is specific to that module. Some transliteration modules may tolerate {{code|lua|nil}} as the script, others require it to be one of the possible scripts that the module can transliterate, and will throw an error if it's not one of them. For this reason, the <code>sc</code> parameter should always be provided when writing non-language-specific code. The <code>module_override</code> parameter is used to override the default module that is used to provide the transliteration. This is useful in cases where you need to demonstrate a particular module in use, but there is no default module yet, or you want to demonstrate an alternative version of a transliteration module before making it official. It should not be used in real modules or templates, only for testing. All uses of this parameter are tracked by [[Wiktionary:Tracking/languages/module_override]]. '''Known bugs''': * This function assumes {tr(s1) .. tr(s2) == tr(s1 .. s2)}. When this assertion fails, wikitext markups like <nowiki>'''</nowiki> can cause wrong transliterations. * HTML entities like <code>&amp;apos;</code>, often used to escape wikitext markups, do not work. ]==] function Language:transliterate(text, sc, module_override) -- If there is no text, or the language doesn't have transliteration data and there's no override, return nil. if not text or text == "" or text == "-" then return text end -- If the script is not transliteratable (and no override is given), return nil. sc = checkScript(text, self, sc) if not (sc:isTransliterated() or module_override) then -- temporary tracking to see if/when this gets triggered track("non-transliterable") track("non-transliterable/" .. self._code) track("non-transliterable/" .. sc:getCode()) track("non-transliterable/" .. sc:getCode() .. "/" .. self._code) return nil end -- Remove any strip markers. text = unstrip(text) -- Do not process the formatting into PUA characters for certain languages. local processed = load_data(languages_data_module).substitution[self._code] ~= "none" -- Get the display text with the keepCarets flag set. local subbedChars if processed then text, subbedChars = processDisplayText(text, self, sc, true) end -- Transliterate (using the module override if applicable). text, subbedChars = iterateSectionSubstitutions(self, text, sc, subbedChars, true, module_override or self._data.translit, "translit", "tr") if not text then return nil end -- Incomplete transliterations return nil. local charset = sc.characters if charset and umatch(text, "[" .. charset .. "]") then -- Remove any characters in Latin, which includes Latin characters also included in other scripts (as these are -- false positives), as well as any PUA substitutions. Anything remaining should only be script code "None" -- (e.g. numerals). local check_text = ugsub(text, "[" .. get_script("Latn").characters .. "􀀀-􏿽]+", "") -- Set none_is_last_resort_only flag, so that any non-None chars will cause a script other than "None" to be -- returned. if find_best_script_without_lang(check_text, true):getCode() ~= "None" then return nil end end if processed then text = escape_risky_characters(text) text = undoTempSubstitutions(text, subbedChars) end -- If the script does not use capitalization, then capitalize any letters of the transliteration which are -- immediately preceded by a caret (and remove the caret). if text and not sc:hasCapitalization() and text:find("^", 1, true) then text = processCarets(text, "%^([\128-\191\244]*%*?)([^\128-\191\244][\128-\191]*)", function(m1, m2) return m1 .. uupper(m2) end) end -- Track module overrides. if module_override ~= nil then track("module_override") end return text end do local function handle_language_spec(self, spec, sc) local ret = self["_" .. spec] if ret == nil then ret = self._data[spec] if type(ret) == "string" then ret = list_to_set(split(ret, ",", true, true)) end self["_" .. spec] = ret end if type(ret) == "table" then ret = ret[sc:getCode()] end return not not ret end function Language:overrideManualTranslit(sc) return handle_language_spec(self, "override_translit", sc) end function Language:link_tr(sc) return handle_language_spec(self, "link_tr", sc) end end --[==[Returns {{code|lua|true}} if the language has a transliteration module, or {{code|lua|false}} if it doesn't.]==] function Language:hasTranslit() return not not self._data.translit end --[==[Returns {{code|lua|true}} if the language uses the letters I/ı and İ/i, or {{code|lua|false}} if it doesn't.]==] function Language:hasDottedDotlessI() return not not self._data.dotted_dotless_i end function Language:toJSON(opts) local strip_diacritics, strip_diacritics_patterns, strip_diacritics_remove_diacritics = self._data.strip_diacritics if strip_diacritics then if strip_diacritics.from then strip_diacritics_patterns = {} for i, from in ipairs(strip_diacritics.from) do insert(strip_diacritics_patterns, {from = from, to = strip_diacritics.to[i] or ""}) end end strip_diacritics_remove_diacritics = strip_diacritics.remove_diacritics end -- mainCode should only end up non-nil if dontCanonicalizeAliases is passed to make_object(). -- props should either contain zero-argument functions to compute the value, or the value itself. local props = { ancestors = function() return self:getAncestorCodes() end, canonicalName = function() return self:getCanonicalName() end, categoryName = function() return self:getCategoryName("nocap") end, code = self._code, mainCode = self._mainCode, parent = function() return self:getParentCode() end, full = function() return self:getFullCode() end, stripDiacriticsPatterns = strip_diacritics_patterns, stripDiacriticsRemoveDiacritics = strip_diacritics_remove_diacritics, family = function() return self:getFamilyCode() end, aliases = function() return self:getAliases() end, varieties = function() return self:getVarieties() end, otherNames = function() return self:getOtherNames() end, scripts = function() return self:getScriptCodes() end, type = function() return keys_to_list(self:getTypes()) end, wikimediaLanguages = function() return self:getWikimediaLanguageCodes() end, wikidataItem = function() return self:getWikidataItem() end, wikipediaArticle = function() return self:getWikipediaArticle(true) end, } local ret = {} for prop, val in pairs(props) do if not opts.skip_fields or not opts.skip_fields[prop] then if type(val) == "function" then ret[prop] = val() else ret[prop] = val end end end -- Use `deep_copy` when returning a table, so that there are no editing restrictions imposed by `mw.loadData`. return opts and opts.lua_table and deep_copy(ret) or to_json(ret, opts) end function export.getDataModuleName(code) local letter = match(code, "^(%l)%l%l?$") return "Module:" .. ( letter == nil and "languages/data/exceptional" or #code == 2 and "languages/data/2" or "languages/data/3/" .. letter ) end get_data_module_name = export.getDataModuleName function export.getExtraDataModuleName(code) return get_data_module_name(code) .. "/extra" end get_extra_data_module_name = export.getExtraDataModuleName do local function make_stack(data) local key_types = { [2] = "unique", aliases = "unique", otherNames = "unique", type = "append", varieties = "unique", wikipedia_article = "unique", wikimedia_codes = "unique" } local function __index(self, k) local stack, key_type = getmetatable(self), key_types[k] -- Data that isn't inherited from the parent. if key_type == "unique" then local v = stack[stack[make_stack]][k] if v == nil then local layer = stack[0] if layer then -- Could be false if there's no extra data. v = layer[k] end end return v -- Data that is appended by each generation. elseif key_type == "append" then local parts, offset, n = {}, 0, stack[make_stack] for i = 1, n do local part = stack[i][k] if part == nil then offset = offset + 1 else parts[i - offset] = part end end return offset ~= n and concat(parts, ",") or nil end local n = stack[make_stack] while true do local layer = stack[n] if not layer then -- Could be false if there's no extra data. return nil end local v = layer[k] if v ~= nil then return v end n = n - 1 end end local function __newindex() error("table is read-only") end local function __pairs(self) -- Iterate down the stack, caching keys to avoid duplicate returns. local stack, seen = getmetatable(self), {} local n = stack[make_stack] local iter, state, k, v = pairs(stack[n]) return function() repeat repeat k = iter(state, k) if k == nil then n = n - 1 local layer = stack[n] if not layer then -- Could be false if there's no extra data. return nil end iter, state, k = pairs(layer) end until not (k == nil or seen[k]) -- Get the value via a lookup, as the one returned by the -- iterator will be the raw value from the current layer, -- which may not be the one __index will return for that -- key. Also memoize the key in `seen` (even if the lookup -- returns nil) so that it doesn't get looked up again. -- TODO: store values in `self`, avoiding the need to create -- the `seen` table. The iterator will need to iterate over -- `self` with `next` first to find these on future loops. v, seen[k] = self[k], true until v ~= nil return k, v end end local __ipairs = require(table_module).indexIpairs function make_stack(data) local stack = { data, [make_stack] = 1, -- stores the length and acts as a sentinel to confirm a given metatable is a stack. __index = __index, __newindex = __newindex, __pairs = __pairs, __ipairs = __ipairs, } stack.__metatable = stack return setmetatable({}, stack), stack end return make_stack(data) end local function get_stack(data) local stack = getmetatable(data) return stack and type(stack) == "table" and stack[make_stack] and stack or nil end --[==[ <span style="color: var(--wikt-palette-red,#BA0000)">This function is not for use in entries or other content pages.</span> Returns a blob of data about the language. The format of this blob is undocumented, and perhaps unstable; it's intended for things like the module's own unit-tests, which are "close friends" with the module and will be kept up-to-date as the format changes. If `extra` is set, any extra data in the relevant `/extra` module will be included. (Note that it will be included anyway if it has already been loaded into the language object.) If `raw` is set, then the returned data will not contain any data inherited from parent objects. -- Do NOT use these methods! -- All uses should be pre-approved on the talk page! ]==] function Language:getData(extra, raw) if extra then self:loadInExtraData() end local data = self._data -- If raw is not set, just return the data. if not raw then return data end local stack = get_stack(data) -- If there isn't a stack or its length is 1, return the data. Extra data (if any) will be included, as it's stored at key 0 and doesn't affect the reported length. if stack == nil then return data end local n = stack[make_stack] if n == 1 then return data end local extra = stack[0] -- If there isn't any extra data, return the top layer of the stack. if extra == nil then return stack[n] end -- If there is, return a new stack which has the top layer at key 1 and the extra data at key 0. data, stack = make_stack(stack[n]) stack[0] = extra return data end function Language:loadInExtraData() -- Only full languages have extra data. if not self:hasType("language", "full") then return end local data = self._data -- If there's no stack, create one. local stack = get_stack(self._data) if stack == nil then data, stack = make_stack(data) -- If already loaded, return. elseif stack[0] ~= nil then return end self._data = data -- Load extra data from the relevant module and add it to the stack at key 0, so that the __index and __pairs metamethods will pick it up, since they iterate down the stack until they run out of layers. local code = self._code local modulename = get_extra_data_module_name(code) -- No data cached as false. stack[0] = modulename and load_data(modulename)[code] or false end --[==[Returns the name of the module containing the language's data. Currently, this is always [[Module:scripts/data]].]==] function Language:getDataModuleName() local name = self._dataModuleName if name == nil then name = self:hasType("etymology-only") and etymology_languages_data_module or get_data_module_name(self._mainCode or self._code) self._dataModuleName = name end return name end --[==[Returns the name of the module containing the language's data. Currently, this is always [[Module:scripts/data]].]==] function Language:getExtraDataModuleName() local name = self._extraDataModuleName if name == nil then name = not self:hasType("etymology-only") and get_extra_data_module_name(self._mainCode or self._code) or false self._extraDataModuleName = name end return name or nil end function export.makeObject(code, data, dontCanonicalizeAliases) local data_type = type(data) if data_type ~= "table" then error(("bad argument #2 to 'makeObject' (table expected, got %s)"):format(data_type)) end -- Convert any aliases. local input_code = code code = normalize_code(code) input_code = dontCanonicalizeAliases and input_code or code local parent if data.parent then parent = get_by_code(data.parent, nil, true, true) else parent = Language end parent.__index = parent local lang = {_code = input_code} -- This can only happen if dontCanonicalizeAliases is passed to make_object(). if code ~= input_code then lang._mainCode = code end local parent_data = parent._data if parent_data == nil then -- Full code is the same as the code. lang._fullCode = parent._code or code else -- Copy full code. lang._fullCode = parent._fullCode local stack = get_stack(parent_data) if stack == nil then parent_data, stack = make_stack(parent_data) end -- Insert the input data as the new top layer of the stack. local n = stack[make_stack] + 1 data, stack[n], stack[make_stack] = parent_data, data, n end lang._data = data return setmetatable(lang, parent) end make_object = export.makeObject end --[==[Finds the language whose code matches the one provided. If it exists, it returns a <code class="nf">Language</code> object representing the language. Otherwise, it returns {{code|lua|nil}}, unless <code class="n">paramForError</code> is given, in which case an error is generated. If <code class="n">paramForError</code> is {{code|lua|true}}, a generic error message mentioning the bad code is generated; otherwise <code class="n">paramForError</code> should be a string or number specifying the parameter that the code came from, and this parameter will be mentioned in the error message along with the bad code. If <code class="n">allowEtymLang</code> is specified, etymology-only language codes are allowed and looked up along with normal language codes. If <code class="n">allowFamily</code> is specified, language family codes are allowed and looked up along with normal language codes.]==] function export.getByCode(code, paramForError, allowEtymLang, allowFamily) -- Track uses of paramForError, ultimately so it can be removed, as error-handling should be done by [[Module:parameters]], not here. if paramForError ~= nil then track("paramForError") end if type(code) ~= "string" then local typ if not code then typ = "nil" elseif check_object("language", true, code) then typ = "a language object" elseif check_object("family", true, code) then typ = "a family object" else typ = "a " .. type(code) end error("The function getByCode expects a string as its first argument, but received " .. typ .. ".") end local m_data = load_data(languages_data_module) if m_data.aliases[code] or m_data.track[code] then track(code) end local norm_code = normalize_code(code) -- Get the data, checking for etymology-only languages if allowEtymLang is set. local data = load_data(get_data_module_name(norm_code))[norm_code] or allowEtymLang and load_data(etymology_languages_data_module)[norm_code] -- If no data was found and allowFamily is set, check the family data. If the main family data was found, make the object with [[Module:families]] instead, as family objects have different methods. However, if it's an etymology-only family, use make_object in this module (which handles object inheritance), and the family-specific methods will be inherited from the parent object. if data == nil and allowFamily then data = load_data("Module:families/data")[norm_code] if data ~= nil then if data.parent == nil then return make_family_object(norm_code, data) elseif not allowEtymLang then data = nil end end end local retval = code and data and make_object(code, data) if not retval and paramForError then require("Module:languages/errorGetBy").code(code, paramForError, allowEtymLang, allowFamily) end return retval end get_by_code = export.getByCode --[==[Finds the language whose canonical name (the name used to represent that language on Wiktionary) or other name matches the one provided. If it exists, it returns a <code class="nf">Language</code> object representing the language. Otherwise, it returns {{code|lua|nil}}, unless <code class="n">paramForError</code> is given, in which case an error is generated. If <code class="n">allowEtymLang</code> is specified, etymology-only language codes are allowed and looked up along with normal language codes. If <code class="n">allowFamily</code> is specified, language family codes are allowed and looked up along with normal language codes. The canonical name of languages should always be unique (it is an error for two languages on Wiktionary to share the same canonical name), so this is guaranteed to give at most one result. This function is powered by [[Module:languages/canonical names]], which contains a pre-generated mapping of full-language canonical names to codes. It is generated by going through the [[:Category:Language data modules]] for full languages. When <code class="n">allowEtymLang</code> is specified for the above function, [[Module:etymology languages/canonical names]] may also be used, and when <code class="n">allowFamily</code> is specified for the above function, [[Module:families/canonical names]] may also be used.]==] function export.getByCanonicalName(name, errorIfInvalid, allowEtymLang, allowFamily) local byName = load_data("Module:languages/canonical names") local code = byName and byName[name] if not code and allowEtymLang then byName = load_data("Module:etymology languages/canonical names") code = byName and byName[name] or byName[gsub(name, " [Ss]ubstrate$", "")] or byName[gsub(name, "^a ", "")] or byName[gsub(name, "^a ", ""):gsub(" [Ss]ubstrate$", "")] or -- For etymology families like "ira-pro". -- FIXME: This is not ideal, as it allows " languages" to be appended to any etymology-only language, too. byName[match(name, "^(.*) languages$")] end if not code and allowFamily then byName = load_data("Module:families/canonical names") code = byName[name] or byName[match(name, "^(.*) languages$")] end local retval = code and get_by_code(code, errorIfInvalid, allowEtymLang, allowFamily) if not retval and errorIfInvalid then require("Module:languages/errorGetBy").canonicalName(name, allowEtymLang, allowFamily) end return retval end --[==[Used by [[Module:languages/data/2]] (et al.) and [[Module:etymology languages/data]], [[Module:families/data]], [[Module:scripts/data]] and [[Module:writing systems/data]] to finalize the data into the format that is actually returned.]==] function export.finalizeData(data, main_type, variety) local fields = {"type"} if main_type == "language" then insert(fields, 4) -- script codes insert(fields, "ancestors") insert(fields, "link_tr") insert(fields, "override_translit") insert(fields, "wikimedia_codes") elseif main_type == "script" then insert(fields, 3) -- writing system codes end -- Families and writing systems have no extra fields to process. local fields_len = #fields for _, entity in next, data do if variety then -- Move parent from 3 to "parent" and family from "family" to 3. These are different for the sake of convenience, since very few varieties have the family specified, whereas all of them have a parent. entity.parent, entity[3], entity.family = entity[3], entity.family -- Give the type "regular" iff not a variety and no other types are assigned. elseif not (entity.type or entity.parent) then entity.type = "regular" end for i = 1, fields_len do local key = fields[i] local field = entity[key] if field and type(field) == "string" then entity[key] = gsub(field, "%s*,%s*", ",") end end end return data end --[==[For backwards compatibility only; modules should require the error themselves.]==] function export.err(lang_code, param, code_desc, template_tag, not_real_lang) return require("Module:languages/error")(lang_code, param, code_desc, template_tag, not_real_lang) end return export rw1pkh5vcotyasnogcby1mdt3aeln5x terngiang-ngiang 0 201723 1348984 1230833 2026-04-08T16:20:10Z Iripseudocorus 40083 Kutipan23 1348984 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{ulang ter-|kelas=v| ngiang}} #[[terngiang]] #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Ingin rasanya aku balik ke belakang, lelaki yang ada di hadapanku sekarang ini pernah menghinaku, kata-katanya masih '''terngiang-ngiang''' di telingaku. | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Ingin%20rasanya%20aku%20balik%20ke%20belakang%2C%20lelaki%20yang%20ada%20di%20hadapanku%20sekarang%20ini%20pernah%20menghinaku%2C%20kata%2Dkatanya%20masih%20terngiang%2Dngiang%20di%20telingaku. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} ng7cqm33324qn1inlcbuzzeoejl86f4 buah-buahan 0 202926 1349165 1344962 2026-04-09T08:15:47Z Swarabakti 18192 1349165 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{ulang -an|buah|kelas=n}} # [[tiruan]] [[buah]] # [[berbagai]] [[macam]] buah #*{{RQ:Mustikarasa |page=31 |text= Dari itu durian sering mentjapai harga pendjualan jang tertinggi diantara semua djenis '''buah²an'''. |norm= Dari itu durian sering mencapai harga penjualan yang tertinggi di antara semua jenis '''buah-buahan.''' |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/39#:~:text=Dari%20itu%20durian%20sering%20mentjapai%20harga%20pendjualan%20jang%20tertinggi%20diantara%20semua%20djenis%20buah%C2%B2an.}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} kdq0987agk4k66hirud4177rl6ploit benar-benar 0 203756 1348957 1145693 2026-04-08T13:57:34Z Losstreak 36825 1348957 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-a-|id}} ([[benar]] + [[benar]]) # bentuk jamak plural dari '''[[benar]]''' # [[sungguh-sungguh]]: <br />''nasihat gurunya benar-benar dipegangnya'' #* {{RQ:Perahu Tulis |page= 158 |text= Anduang memandangku dengan tatapan yang tidak kumengerti. Bukan, bukan tatapan marah. Tapi tatapan lega, bahagia, ah entahlah, sulit kujelaskan. Setelah diam cukup lama, akhirnya aku mengambil tangan anduang, menciumnya. Begitu saja, tanpa terucap maaf. Barangkali hatiku masih butuh sedikit waktu untuk '''benar-benar''' berbaikan dengan anduang. Mungkin besok kami akan bicara. |url= https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/170#:~:text=Anduang%20memandangku%20dengan,kami%20akan%20bicara. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} [[Kategori:Turunan kata benar]] [[Kategori:id:Kata ulang semu]] 72szuxyt04bxfbq00ru705c2m6xpg0m menerima 0 207626 1349178 1241910 2026-04-09T09:46:26Z Sofi Solihah 23681 1349178 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|terima}} # menyambut; mengambil (mendapat, menampung, dsb) sesuatu yg diberikan, dikirimkan, dsb:<br>'' ia senang sekali krn telah menerima kiriman uang dr ibunya;<br>'' menerima pesanan ; menerima surat; menerima tamu; #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Yang kalah terpaksa harus '''menerima''' kekalahannya dengan secara sportif serta harus mengakui keunggulan lawannya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Yang%20kalah%20terpaksa%20harus%20menerima%20kekalahannya%20dengan%20secara%20sportif%20serta%20harus%20mengakui%20keunggulan%20lawannya. }} # mengesahkan; membenarkan; menyetujui (usul, anjuran, dsb); meluluskan atau mengabulkan (permintaan dsb):<br>'' rapat pleno menerima baik laporan pengurus; # mendapat atau menderita sesuatu; # menganggap (sbg):<br>'' saya menerima teguran Paman sbg cambuk untuk bekerja lebih teliti lagi; # mengizinkan (masuk menjadi anggota, murid, pegawai, dsb):<br>'' aku menerima engkau sbg anggota baru; perguruan tinggi itu menerima nya hanya sbg pendengar; # mau menjabat (pangkat) dsb:<br>'' ia telah menerima jabatan baru yg lebih berat tanggung jawabnya; {{-turunan-|id}} {{-sinonim-}} {{t-atas}} * Inggris: to [[receive]], to [[welcome]] * Jepang: [[もらう]] {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} g9rsvacscdskzfcy6l7k7p9t7akgfna 1349179 1349178 2026-04-09T09:47:03Z Sofi Solihah 23681 1349179 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|terima}} # menyambut; mengambil (mendapat, menampung, dsb) sesuatu yg diberikan, dikirimkan, dsb:<br>'' ia senang sekali krn telah menerima kiriman uang dr ibunya;<br>'' menerima pesanan ; menerima surat; menerima tamu; #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Yang kalah terpaksa harus '''menerima''' kekalahannya dengan secara sportif serta harus mengakui keunggulan lawannya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Yang%20kalah%20terpaksa%20harus%20menerima%20kekalahannya%20dengan%20secara%20sportif%20serta%20harus%20mengakui%20keunggulan%20lawannya. }} # mengesahkan; membenarkan; menyetujui (usul, anjuran, dsb); meluluskan atau mengabulkan (permintaan dsb):<br>'' rapat pleno menerima baik laporan pengurus; # mendapat atau menderita sesuatu; # menganggap (sbg):<br>'' saya menerima teguran Paman sbg cambuk untuk bekerja lebih teliti lagi; # mengizinkan (masuk menjadi anggota, murid, pegawai, dsb):<br>'' aku menerima engkau sbg anggota baru; perguruan tinggi itu menerima nya hanya sbg pendengar; # mau menjabat (pangkat) dsb:<br>'' ia telah menerima jabatan baru yg lebih berat tanggung jawabnya; {{-turunan-|id}} {{-sinonim-}} {{t-atas}} * Inggris: to [[receive]], to [[welcome]] * Jepang: [[もらう]] {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} am7gkjul8qkls09t01h6cive0e8q8mn 1349182 1349179 2026-04-09T09:51:22Z Sofi Solihah 23681 1349182 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|terima}} # menyambut; mengambil (mendapat, menampung, dsb) sesuatu yg diberikan, dikirimkan, dsb:<br>'' ia senang sekali krn telah menerima kiriman uang dr ibunya;<br>'' menerima pesanan ; menerima surat; menerima tamu; # mengesahkan; membenarkan; menyetujui (usul, anjuran, dsb); meluluskan atau mengabulkan (permintaan dsb):<br>'' rapat pleno menerima baik laporan pengurus; # mendapat atau menderita sesuatu; # menganggap (sbg):<br>'' saya menerima teguran Paman sbg cambuk untuk bekerja lebih teliti lagi; # mengizinkan (masuk menjadi anggota, murid, pegawai, dsb):<br>'' aku menerima engkau sbg anggota baru; perguruan tinggi itu menerima nya hanya sbg pendengar; # mau menjabat (pangkat) dsb:<br>'' ia telah menerima jabatan baru yg lebih berat tanggung jawabnya; #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Yang kalah terpaksa harus '''menerima''' kekalahannya dengan secara sportif serta harus mengakui keunggulan lawannya. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Yang%20kalah%20terpaksa%20harus%20menerima%20kekalahannya%20dengan%20secara%20sportif%20serta%20harus%20mengakui%20keunggulan%20lawannya. }} {{-turunan-|id}} {{-sinonim-}} {{t-atas}} * Inggris: to [[receive]], to [[welcome]] * Jepang: [[もらう]] {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} die3cpatrcg7ro4dp7zch0aferj314y memulai 0 214043 1348987 1230381 2026-04-08T16:23:13Z Iripseudocorus 40083 Kutipan23 1348987 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-|mulai}} # Menyebabkan sesuatu mulai: #: ''Tepat pada pukul tujuh malam, [[sang]] [[wasit]] '''memulai''' [[pertandingan]] [[tersebut]].'' #* {{RQ:Perahu Tulis | page = 133 | author = Balai Bahasa Sumatera Barat | chapter = | text = Maafkan aku ya, kala itu aku baru belajar berdakwah jadi aku belum tahu harus '''memulai''' dengan apa, lagian waktu itu Kau main emosi saja | url =https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/145#:~:text=Maafkan%20aku%20ya%2C%20kala%20itu%20aku%20baru%20belajar%20berdakwah%2C%20jadi%20aku%20belum%20tahu%20harus%20memulai%20dengan%20apa%2C%20lagian%20waktu%20itu%20Kau%20main%20emosi%20saja }} # {{ragam dari|id|mulai}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} ebpql6bd60ffja5b5mdoko47we9nujg Templat:inh 10 214695 1349041 1107475 2026-04-08T17:18:41Z Swarabakti 18192 templat nama bahasa sudah usang, jika ada yang tertinggal nanti saya bantu bersihkan 1349041 wikitext text/x-wiki #ALIH [[Templat:warisan]] qrd29pv0h393509hlfdsd1rir0ragmm Modul:etymology/templates 828 214696 1348983 1107915 2026-04-08T16:18:36Z Swarabakti 18192 1348983 Scribunto text/plain local export = {} local require_when_needed = require("Module:require when needed") local concat = table.concat local format_categories = require_when_needed("Module:utilities", "format_categories") local insert = table.insert local process_params = require_when_needed("Module:parameters", "process") local trim = mw.text.trim local lower = mw.ustring.lower local dump = mw.dumpObject local etymology_module = "Module:etymology" local etymology_specialized_module = "Module:etymology/specialized" local parameter_utilities_module = "Module:parameter utilities" -- For testing local force_cat = false local allowed_conjs = {"and", "or", ",", "/", "~", ";"} local function parse_etym_args(parent_args, base_params, has_dest_lang) local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, } local sourcearg, termarg if has_dest_lang then sourcearg, termarg = 2, 3 else sourcearg, termarg = 1, 2 end local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params { params = base_params, param_mods = param_mods, raw_args = parent_args, termarg = termarg, track_module = "etymology", lang = function(args) return args[sourcearg][#args[sourcearg]] end, sc = "sc", -- Don't do this, doesn't seem to make sense. -- parse_lang_prefix = true, make_separate_g_into_list = true, splitchar = ",", subitem_param_handling = "last", } -- If term param 3= is empty, there will be no terms in terms.terms. To facilitate further code and for -- compatibility,, insert one. It will display as <small>[Term?]</small>. if not terms.terms[1] then terms.terms[1] = { lang = args[sourcearg][#args[sourcearg]], sc = args.sc, } end return terms.terms, args end function export.parse_2_lang_args(parent_args, has_text, no_family) local boolean = {type = "boolean"} local params = { [1] = { required = true, type = "language", default = "und" }, [2] = { required = true, sublist = true, type = "language", family = not no_family, default = "und" }, [3] = true, [4] = {alias_of = "alt"}, [5] = {alias_of = "t"}, ["senseid"] = true, ["nocat"] = boolean, ["sort"] = true, ["sourceconj"] = true, ["conj"] = {set = allowed_conjs, default = ","}, } if has_text then params["notext"] = boolean params["nocap"] = boolean end return parse_etym_args(parent_args, params, "has dest lang") end -- Implementation of deprecated {{etyl}}. Provided to make histories more legible. function export.etyl(frame) local params = { [1] = {required = true, type = "language", default = "und"}, [2] = {type = "language", default = "en"}, ["sort"] = {}, } -- Empty language means English, but "-" means no language. Yes, confusing... local args = frame:getParent().args if args[2] and trim(args[2]) == "-" then params[2] = nil args = process_params({ [1] = args[1], ["sort"] = args.sort }, params) else args = process_params(args, params) end return require(etymology_module).format_source { lang = args[2], source = args[1], sort_key = args.sort, force_cat = force_cat, } end -- Implementation of {{derived}}/{{der}}. function export.derived(frame) local parent_args = frame:getParent().args local terms, args = export.parse_2_lang_args(parent_args) return require(etymology_module).format_derived { lang = args[1], sources = args[2], terms = terms, sort_key = args.sort, nocat = args.nocat, sourceconj = args.sourceconj, conj = args.conj, template_name = "derived", force_cat = force_cat, } end -- Implementation of {{borrowed}}/{{bor}}. function export.borrowed(frame) local parent_args = frame:getParent().args local terms, args = export.parse_2_lang_args(parent_args) return require(etymology_module).format_borrowed { lang = args[1], sources = args[2], terms = terms, sort_key = args.sort, nocat = args.nocat, sourceconj = args.sourceconj, conj = args.conj, force_cat = force_cat, } end function export.inherited(frame) local parent_args = frame:getParent().args local terms, args = export.parse_2_lang_args(parent_args) local sources = args[2] if sources[2] then -- Because this doesn't really make sense. error("[[Template:inherited]] doesn't support multiple comma-separated sources") end return require(etymology_module).format_inherited { lang = args[1], terms = terms, sort_key = args.sort, nocat = args.nocat, conj = args.conj, force_cat = force_cat, } end function export.cognate(frame) local params = { [1] = { required = true, sublist = true, type = "language", family = true, default = "und" }, [2] = true, [3] = {alias_of = "alt"}, [4] = {alias_of = "t"}, sourceconj = true, ["conj"] = {set = allowed_conjs, default = ","}, sort = true, } local parent_args = frame:getParent().args local terms, args = parse_etym_args(parent_args, params, false) return require(etymology_module).format_cognate { sources = args[1], terms = terms, sort_key = args.sort, sourceconj = args.sourceconj, conj = args.conj, force_cat = force_cat, } end function export.noncognate(frame) return export.cognate(frame) end -- Supports various specialized types of borrowings, according to `frame.args.bortype`: -- "learned" = {{lbor}}/{{learned borrowing}} -- "semi-learned" = {{slbor}}/{{semi-learned borrowing}} -- "orthographic" = {{obor}}/{{orthographic borrowing}} -- "unadapted" = {{ubor}}/{{unadapted borrowing}} -- "calque" = {{cal}}/{{calque}} -- "partial-calque" = {{pcal}}/{{partial calque}} -- "semantic-loan" = {{sl}}/{{semantic loan}} -- "transliteration" = {{translit}}/{{transliteration}} -- "phono-semantic-matching" = {{psm}}/{{phono-semantic matching}} function export.specialized_borrowing(frame) local parent_args = frame:getParent().args local terms, args = export.parse_2_lang_args(parent_args, "has text") local m_etymology_specialized = require(etymology_specialized_module) return m_etymology_specialized.specialized_borrowing { bortype = frame.args.bortype, lang = args[1], sources = args[2], terms = terms, sort_key = args.sort, nocap = args.nocap, notext = args.notext, nocat = args.nocat, sourceconj = args.sourceconj, conj = args.conj, senseid = args.senseid, force_cat = force_cat, } end -- Implementation of miscellaneous templates such as {{abbrev}}, {{back-formation}}, {{clipping}}, {{ellipsis}}, -- {{rebracketing}} and {{reduplication}} that have a single associated term. function export.misc_variant(frame) local iparams = { ["ignore-params"] = true, text = {required = true}, oftext = true, cat = {list = true}, -- allow and compress holes conj = true, } local iargs = process_params(frame.args, iparams) local boolean = {type = "boolean"} local params = { [1] = {required = true, type = "language", default = "und"}, [2] = true, [3] = {alias_of = "alt"}, [4] = {alias_of = "t"}, nocap = boolean, -- should be processed in the template itself notext = boolean, nocat = boolean, conj = {set = allowed_conjs}, sort = true, } -- |ignore-params= parameter to module invocation specifies -- additional parameter names to allow in template invocation, separated by -- commas. They must consist of ASCII letters or numbers or hyphens. local ignore_params = iargs["ignore-params"] if ignore_params then ignore_params = trim(ignore_params) if not ignore_params:match("^[%w%-,]+$") then error("Invalid characters in |ignore-params=: " .. ignore_params:gsub("[%w%-,]+", "")) end for param in ignore_params:gmatch("[%w%-]+") do if params[param] then error("Duplicate param |" .. param .. " in |ignore-params=: already specified in params") end params[param] = true end end local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "q", "l", "ref"}}, } local parent_args = frame:getParent().args local terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 2, track_module = "etymology", -- Don't set lang here as we want to know whether there was a lang prefix or not. sc = "sc", parse_lang_prefix = true, allow_multiple_lang_prefixes = true, make_separate_g_into_list = true, splitchar = ",", subitem_param_handling = "last", } return require(etymology_module).format_misc_variant { lang = args[1], notext = args.notext, text = iargs.text, oftext = iargs.oftext, terms = terms.terms, sort_key = args.sort, conj = args.conj or iargs.conj or "and", nocat = args.nocat, cats = iargs.cat, force_cat = force_cat, } end -- Implementation of miscellaneous templates such as {{doublet}} that can take multiple terms. Doesn't handle {{blend}} -- or {{univerbation}}, which display + signs between elements and use compound_like in [[Module:affix/templates]]. function export.misc_variant_multiple_terms(frame) local iparams = { text = {required = true}, oftext = true, cat = {list = true}, -- allow and compress holes conj = true, } local iargs = process_params(frame.args, iparams) local boolean = {type = "boolean"} local params = { [1] = {required = true, type = "language", template_default = "und"}, [2] = {list = true, allow_holes = true}, nocap = boolean, -- should be processed in the template itself notext = boolean, nocat = boolean, conj = {set = allowed_conjs}, sort = true, } local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { -- We want to require an index for all params. {default = true, require_index = true}, {group = {"link", "q", "l", "ref"}}, } local parent_args = frame:getParent().args local terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 2, parse_lang_prefix = true, allow_multiple_lang_prefixes = true, track_module = "etymology-templates-doublet", disallow_custom_separators = true, -- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do -- {{suffix|lang||foo}} to generate "+ -foo". dont_skip_items = true, -- Don't set lang here as we want to know whether there was a lang prefix or not. sc = "sc.default", } return require(etymology_module).format_misc_variant { lang = args[1], notext = args.notext, text = iargs.text, oftext = iargs.oftext, terms = terms, sort_key = args.sort, conj = args.conj or iargs.conj or "and", nocat = args.nocat, cats = iargs.cat, force_cat = force_cat, } end -- Implementation of miscellaneous templates such as {{unknown}} that have no associated terms. do local function get_args(frame) local boolean = {type = "boolean"} local params = { [1] = {required = true, type = "language", default = "und"}, ["title"] = true, ["nocap"] = boolean, -- should be processed in the template itself ["notext"] = boolean, ["nocat"] = boolean, ["sort"] = true, } if frame.args.title2_alias then params[2] = {alias_of = "title"} end return process_params(frame:getParent().args, params) end function export.misc_variant_no_term(frame) local args = get_args(frame) return require(etymology_module).format_misc_variant_no_term { lang = args[1], notext = args.notext, title = args.title or frame.args.text, nocat = args.nocat, cat = frame.args.cat, sort_key = args.sort, force_cat = force_cat, } end -- This function works similarly to misc_variant_no_term(), but with some automatic linking to the glossary in -- `title`. function export.onomatopoeia(frame) local args = get_args(frame) local title = args.title if title and (lower(title) == "imitative" or lower(title) == "imitation") then title = "[[Lampiran:Glosarium#imitatif|" .. title .. "]]" end return require(etymology_module).format_misc_variant_no_term { lang = args[1], notext = args.notext, title = title or frame.args.text, nocat = args.nocat, cat = frame.args.cat, sort_key = args.sort, force_cat = force_cat, } end end return export clvgzmw9cigfnxxte41qr60nr2kcxo7 Modul:etymology 828 214697 1348967 1107943 2026-04-08T16:03:17Z Swarabakti 18192 1348967 Scribunto text/plain local export = {} -- For testing local force_cat = false local debug_track_module = "Modul:debug/track" local languages_module = "Modul:languages" local links_module = "Modul:links" local pron_qualifier_module = "Modul:pron qualifier" local table_module = "Modul:table" local utilities_module = "Modul:utilities" local concat = table.concat local insert = table.insert local new_title = mw.title.new local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function full_link(...) full_link = require(links_module).full_link return full_link(...) end local function get_language_data_module_name(...) get_language_data_module_name = require(languages_module).getDataModuleName return get_language_data_module_name(...) end local function get_link_page(...) get_link_page = require(links_module).get_link_page return get_link_page(...) end local function language_link(...) language_link = require(links_module).language_link return language_link(...) end local function serial_comma_join(...) serial_comma_join = require(table_module).serialCommaJoin return serial_comma_join(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function track(page, code) local tracking_page = "etymology/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function join_segs(segs, conj) if not segs[2] then return segs[1] elseif conj == "and" or conj == "or" then return serial_comma_join(segs, {conj = conj}) end local sep if conj == "," or conj == ";" then sep = conj .. " " elseif conj == "/" then sep = "/" elseif conj == "~" then sep = " ~ " elseif conj then error(("Internal error: Unrecognized conjunction \"%s\""):format(conj)) else error(("Internal error: No value supplied for conjunction"):format(conj)) end return concat(segs, sep) end -- Returns true if `lang` is the same as `source`, or a variety of it. local function lang_is_source(lang, source) return lang:getCode() == source:getCode() or lang:hasParent(source) end --[==[ Format one or more links as specified in `termobjs`, a list of term objects of the format accepted by `full_link()` in [[Module:links]], additionally with optional qualifiers, labels and references. `conj` is used to join multiple terms and must be specified if there is more than one term. `template_name` is the template name used in debug tracking and must be specified. Optional `sourcetext` is text to prepend to the concatenated terms, separated by a space if the concatenated terms are non-empty (which is always the case unless there is a single term with the value "-"). If `qualifiers_labels_on_outside` is given, any qualifiers, labels or references specified in the first term go on the outside of (i.e before) `sourcetext`; otherwise they will end up on the inside. ]==] function export.format_links(termobjs, conj, template_name, sourcetext, qualifiers_labels_on_outside) if not template_name then error("Internal error: Must specify `template_name` to format_links()") end for i, termobj in ipairs(termobjs) do if termobj.lang:hasType("family") or termobj.lang:getFamilyCode() == "qfa-sub" then if termobj.term and termobj.term ~= "-" then debug_track(template_name .. "/family-with-term") end termobj.term = "-" end if termobj.term == "-" then --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]] ]=] debug_track(template_name .. "/no-term") termobjs[i] = i == 1 and sourcetext or "" else if i == 1 and qualifiers_labels_on_outside and sourcetext then termobj.pretext = sourcetext .. " " sourcetext = nil end termobjs[i] = (i == 1 and sourcetext and sourcetext .. " " or "") .. full_link(termobj, "term", nil, "show qualifiers") end end return join_segs(termobjs, conj) end function export.get_display_and_cat_name(source, raw) local display, cat_name if source:getCode() == "und" then display = "undetermined" cat_name = "other languages" elseif source:getCode() == "mul" then display = raw and "translingual" or "[[w:Translingualism|translingual]]" cat_name = "Translingual" elseif source:getCode() == "mul-tax" then display = raw and "taxonomic name" or "[[w:Biological nomenclature|taxonomic name]]" cat_name = "taxonomic names" else display = raw and source:getCanonicalName() or source:makeWikipediaLink() cat_name = source:getDisplayForm() end return display, cat_name end function export.insert_source_cat_get_display(data) local categories, lang, source = data.categories, data.lang, data.source local display, cat_name = export.get_display_and_cat_name(source, data.raw) if lang and not data.nocat then -- Add the category, but only if there is a current language if not categories then categories = {} end local langcode = lang:getFullCode() -- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`. -- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a -- category 'Latin terms derived from Latin'. insert(categories, langcode .. ( lang_is_source(lang, source) and ":Istilah yang diserap kembali ke " .. cat_name or ":" .. (data.borrowing_type or "Istilah yang berasal") .. " dari " .. cat_name )) end return display, categories end function export.format_source(data) local lang, sort_key = data.lang, data.sort_key -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]] if sort_key then track("sortkey") end local display, categories = export.insert_source_cat_get_display(data) if lang and not data.nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat) else categories = "" end return "<span class=\"etyl\">" .. display .. categories .. "</span>" end --[==[ Format sources for etymology templates such as {{tl|bor}}, {{tl|der}}, {{tl|inh}} and {{tl|cog}}. There may potentially be more than one source language (except currently {{tl|inh}}, which doesn't support it because it doesn't really make sense). In that case, all but the last source language is linked to the first term, but only if there is such a term and this linking makes sense, i.e. either (1) the term page exists after stripping diacritics according to the source language in question, or (2) the result of stripping diacritics according to the source language in question results in a different page from the same process applied with the last source language. For example, {{m|ru|соля́нка}} will link to [[солянка]] but {{m|en|соля́нка}} will link to [[соля́нка]] with an accent, and since they are different pages, the use of English as a non-final source with term 'соля́нка' will link to [[соля́нка]] even though it doesn't exist, on the assumption that it is merely a redlink that might exist. If none of the above criteria apply, a non-final source language will be linked to the Wikipedia entry for the language, just as final source languages always are. `data` contains the following fields: * `lang`: The destination language object into which the terms were borrowed, inherited or otherwise derived. Used for categorization and can be nil, as with {{tl|cog}}. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see above. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_sources(data) local lang, sources, terms, borrowing_type, sort_key, categories, nocat = data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat local term1, sources_n, source_segs = terms[1], #sources, {} local final_link_page local term1_term, term1_sc = term1.term, term1.sc if sources_n > 1 and term1_term and term1_term ~= "-" then final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc) end for i, source in ipairs(sources) do local seg, display_term if i < sources_n and term1_term and term1_term ~= "-" then local link_page = get_link_page(term1_term, source, term1_sc) display_term = (link_page ~= final_link_page) or (link_page and not not new_title(link_page):getContent()) end -- TODO: if the display forms or transliterations are different, display the terms separately. if display_term then local display, this_cats = export.insert_source_cat_get_display{ lang = lang, source = source, borrowing_type = borrowing_type, raw = true, categories = categories, nocat = nocat, } seg = language_link { lang = source, term = term1_term, alt = display, tr = "-", } if lang and not nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat) else this_cats = "" end seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>" else seg = export.format_source{ lang = lang, source = source, borrowing_type = borrowing_type, sort_key = sort_key, categories = categories, nocat = nocat, } end insert(source_segs, seg) end return join_segs(source_segs, data.sourceconj or "and") end -- Internal implementation of {{cognate}}/{{cog}} template. function export.format_cognate(data) return export.format_derived { sources = data.sources, terms = data.terms, sort_key = data.sort_key, sourceconj = data.sourceconj, conj = data.conj, template_name = "cognate", force_cat = data.force_cat, } end --[==[ Internal implementation of {{derived}}/{{der}} template. This dispThis is called externally from [[Module:affix]], [[Module:affixusex]] and [[Module:see]] and needs to support qualifiers, labels and references on the outside of the sources for use by those modules. `data` contains the following fields: * `lang`: The destination language object into which the terms were derived. Used for categorization and can be nil, as with {{tl|cog}}; in this case, no categories are added. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see `format_sources()`. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `conj`: Conjunction used to separate multiple terms. '''Required'''. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are as for `conj` above. * `qualifiers_labels_on_outside`: If specified, any qualifiers, labels or references in the first term in `terms` will be displayed on the outside of (before) the source language(s) in `sources`. Normally this should be specified if there is only one term possible in `terms`. * `template_name`: Name of the template invoking this function. Must be specified. Only used for tracking pages. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_derived(data) local terms = data.terms local sourcetext = export.format_sources(data) return export.format_links(terms, data.conj, data.template_name, sourcetext, data.qualifiers_labels_on_outside) end function export.insert_borrowed_cat(categories, lang, source) if lang_is_source(lang, source) then return end -- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not -- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source(). -- The second parameter here doesn't matter as it only affects `display`, which we don't use. insert(categories, lang:getFullCode() .. "Istilah yang diserap dari " .. select(2, export.get_display_and_cat_name(source, "raw"))) end -- Internal implementation of {{borrowed}}/{{bor}} template. function export.format_borrowed(data) local categories = {} if not data.nocat then local lang = data.lang for _, source in ipairs(data.sources) do export.insert_borrowed_cat(categories, lang, source) end end data = shallow_copy(data) data.categories = categories return export.format_links(data.terms, data.conj, "borrowed", export.format_sources(data)) end do -- Generate the non-ancestor error message. local function show_language(lang) local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode()) if lang:hasType("etymology-only") then retval = retval .. (" (an etymology-only language whose regular parent is %s)"):format( show_language(lang:getParent())) end return retval end -- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if -- not. When `lang` is a family, verifies that `otherlang` is a language in that family. function export.check_ancestor(lang, otherlang) -- When `lang` is a family, verify `otherlang` is in that family or in its parent family. if lang.hasType and lang:hasType("family") then local family_code = lang:getCode() local function in_family_code(fcode, other) if not fcode or fcode == "" then return false end if other.inFamily and other:inFamily(fcode) then return true end if other.getFamilyCode and other:getFamilyCode() == fcode then return true end return false end local in_family = in_family_code(family_code, otherlang) if not in_family then local parent_code if lang.getParent then local parent_family = lang:getParent() if parent_family and parent_family.getCode then parent_code = parent_family:getCode() end end if not parent_code and family_code:find("-", 1, true) then parent_code = family_code:match("^(.+)-[^-]+$") end if parent_code then in_family = in_family_code(parent_code, otherlang) end end if not in_family then local other_display = (otherlang.getCanonicalName and otherlang:getCanonicalName()) or (otherlang.getCode and otherlang:getCode()) or tostring(otherlang) local fam_display = (lang.getCanonicalName and lang:getCanonicalName()) or family_code error(("%s is not in family %s; inherited ancestor under a family must be a language in that family or its parent family.") :format(other_display, fam_display)) end return end -- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up -- the module link code appropriately (June 2024) but the remaining logic is untouched. if lang:hasAncestor(otherlang) then -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/variety]] -- Track inheritance from varieties of Latin that shouldn't have any descendants (everything except Old Latin, Classical Latin and Vulgar Latin). if otherlang:getFullCode() == "la" then otherlang = otherlang:getCode() if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then track("bad ancestor", otherlang) end end return end local ancestors, postscript = lang:getAncestors() local etym_module_link = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or "" local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]" if not ancestors[1] then postscript = show_language(lang) .. " has no ancestors." else local ancestor_list = {} for _, ancestor in ipairs(ancestors) do insert(ancestor_list, show_language(ancestor)) end postscript = ("The ancestor%s of %s %s %s."):format( ancestors[2] and "s" or "", lang:getCanonicalName(), ancestors[2] and "are" or "is", concat(ancestor_list, " and ")) end error(("%s is not set as an ancestor of %s in %s%s. %s") :format(show_language(otherlang), show_language(lang), etym_module_link, module_link, postscript)) end end -- Internal implementation of {{inherited}}/{{inh}} template. function export.format_inherited(data) local lang, terms, nocat = data.lang, data.terms, data.nocat local source = terms[1].lang local categories = {} if not nocat then insert(categories, lang:getFullCode() .. ":Istilah yang diwariskan dari " .. source:getCanonicalName()) end export.check_ancestor(lang, source) data = shallow_copy(data) data.categories = categories data.source = source return export.format_links(terms, data.conj, "inherited", export.format_source(data)) end -- Internal implementation of "misc variant" templates such as {{abbrev}}, {{clipping}}, {{reduplication}} and the like. function export.format_misc_variant(data) local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {} if not notext then insert(parts, data.text) end if terms[1] then if not notext then -- FIXME: If term is given as '-', we should consider displaying just "Clipping" not "Clipping of". insert(parts, " " .. (data.oftext or "dari")) end local termparts = {} -- Make links out of all the parts. for _, termobj in ipairs(terms) do local result if termobj.lang then result = export.format_derived { lang = lang, terms = {termobj}, sources = termobj.termlangs or {termobj.lang}, template_name = "misc_variant", qualifiers_labels_on_outside = true, force_cat = data.force_cat, } else termobj.lang = lang result = export.format_links({termobj}, nil, "misc_variant") end table.insert(termparts, result) end local linktext = join_segs(termparts, data.conj) if not notext and linktext ~= "" then insert(parts, " ") end insert(parts, linktext) end local categories = {} if not data.nocat and cats then for _, cat in ipairs(cats) do insert(categories, lang:getFullCode() .. ":" .. cat) end end if categories[1] then insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end -- Implementation of miscellaneous templates such as {{unknown}} and {{onomatopoeia}} that have no associated terms. function export.format_misc_variant_no_term(data) local parts = {} if not data.notext then insert(parts, data.title) end if not data.nocat and data.cat then local lang, categories = data.lang, {} insert(categories, lang:getFullCode() .. ":" .. data.cat) insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end return export f9dxkfhwrf7v26zsymrbbss6pcfx3ol 1348980 1348967 2026-04-08T16:16:03Z Swarabakti 18192 sederhanakan 1348980 Scribunto text/plain local export = {} -- For testing local force_cat = false local debug_track_module = "Modul:debug/track" local languages_module = "Modul:languages" local links_module = "Modul:links" local pron_qualifier_module = "Modul:pron qualifier" local table_module = "Modul:table" local utilities_module = "Modul:utilities" local concat = table.concat local insert = table.insert local new_title = mw.title.new local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function full_link(...) full_link = require(links_module).full_link return full_link(...) end local function get_language_data_module_name(...) get_language_data_module_name = require(languages_module).getDataModuleName return get_language_data_module_name(...) end local function get_link_page(...) get_link_page = require(links_module).get_link_page return get_link_page(...) end local function language_link(...) language_link = require(links_module).language_link return language_link(...) end local function serial_comma_join(...) serial_comma_join = require(table_module).serialCommaJoin return serial_comma_join(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function track(page, code) local tracking_page = "etymology/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function join_segs(segs, conj) if not segs[2] then return segs[1] elseif conj == "and" or conj == "or" then return serial_comma_join(segs, {conj = conj}) end local sep if conj == "," or conj == ";" then sep = conj .. " " elseif conj == "/" then sep = "/" elseif conj == "~" then sep = " ~ " elseif conj then error(("Internal error: Unrecognized conjunction \"%s\""):format(conj)) else error(("Internal error: No value supplied for conjunction"):format(conj)) end return concat(segs, sep) end -- Returns true if `lang` is the same as `source`, or a variety of it. local function lang_is_source(lang, source) return lang:getCode() == source:getCode() or lang:hasParent(source) end --[==[ Format one or more links as specified in `termobjs`, a list of term objects of the format accepted by `full_link()` in [[Module:links]], additionally with optional qualifiers, labels and references. `conj` is used to join multiple terms and must be specified if there is more than one term. `template_name` is the template name used in debug tracking and must be specified. Optional `sourcetext` is text to prepend to the concatenated terms, separated by a space if the concatenated terms are non-empty (which is always the case unless there is a single term with the value "-"). If `qualifiers_labels_on_outside` is given, any qualifiers, labels or references specified in the first term go on the outside of (i.e before) `sourcetext`; otherwise they will end up on the inside. ]==] function export.format_links(termobjs, conj, template_name, sourcetext, qualifiers_labels_on_outside) if not template_name then error("Internal error: Must specify `template_name` to format_links()") end for i, termobj in ipairs(termobjs) do if termobj.lang:hasType("family") or termobj.lang:getFamilyCode() == "qfa-sub" then if termobj.term and termobj.term ~= "-" then debug_track(template_name .. "/family-with-term") end termobj.term = "-" end if termobj.term == "-" then --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]] ]=] debug_track(template_name .. "/no-term") termobjs[i] = i == 1 and sourcetext or "" else if i == 1 and qualifiers_labels_on_outside and sourcetext then termobj.pretext = sourcetext .. " " sourcetext = nil end termobjs[i] = (i == 1 and sourcetext and sourcetext .. " " or "") .. full_link(termobj, "term", nil, "show qualifiers") end end return join_segs(termobjs, conj) end function export.get_display_and_cat_name(source, raw) local display, cat_name if source:getCode() == "und" then display = "undetermined" cat_name = "other languages" elseif source:getCode() == "mul" then display = raw and "translingual" or "[[w:Translingualism|translingual]]" cat_name = "Translingual" elseif source:getCode() == "mul-tax" then display = raw and "taxonomic name" or "[[w:Biological nomenclature|taxonomic name]]" cat_name = "taxonomic names" else display = raw and source:getCanonicalName() or source:makeWikipediaLink() cat_name = source:getDisplayForm() end return display, cat_name end function export.insert_source_cat_get_display(data) local categories, lang, source = data.categories, data.lang, data.source local display, cat_name = export.get_display_and_cat_name(source, data.raw) if lang and not data.nocat then -- Add the category, but only if there is a current language if not categories then categories = {} end local langcode = lang:getFullCode() -- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`. -- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a -- category 'Latin terms derived from Latin'. insert(categories, langcode .. ( lang_is_source(lang, source) and ":Serapan balik ke " .. cat_name or ":" .. (data.borrowing_type or "Berasal") .. " dari " .. cat_name )) end return display, categories end function export.format_source(data) local lang, sort_key = data.lang, data.sort_key -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]] if sort_key then track("sortkey") end local display, categories = export.insert_source_cat_get_display(data) if lang and not data.nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat) else categories = "" end return "<span class=\"etyl\">" .. display .. categories .. "</span>" end --[==[ Format sources for etymology templates such as {{tl|bor}}, {{tl|der}}, {{tl|inh}} and {{tl|cog}}. There may potentially be more than one source language (except currently {{tl|inh}}, which doesn't support it because it doesn't really make sense). In that case, all but the last source language is linked to the first term, but only if there is such a term and this linking makes sense, i.e. either (1) the term page exists after stripping diacritics according to the source language in question, or (2) the result of stripping diacritics according to the source language in question results in a different page from the same process applied with the last source language. For example, {{m|ru|соля́нка}} will link to [[солянка]] but {{m|en|соля́нка}} will link to [[соля́нка]] with an accent, and since they are different pages, the use of English as a non-final source with term 'соля́нка' will link to [[соля́нка]] even though it doesn't exist, on the assumption that it is merely a redlink that might exist. If none of the above criteria apply, a non-final source language will be linked to the Wikipedia entry for the language, just as final source languages always are. `data` contains the following fields: * `lang`: The destination language object into which the terms were borrowed, inherited or otherwise derived. Used for categorization and can be nil, as with {{tl|cog}}. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see above. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_sources(data) local lang, sources, terms, borrowing_type, sort_key, categories, nocat = data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat local term1, sources_n, source_segs = terms[1], #sources, {} local final_link_page local term1_term, term1_sc = term1.term, term1.sc if sources_n > 1 and term1_term and term1_term ~= "-" then final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc) end for i, source in ipairs(sources) do local seg, display_term if i < sources_n and term1_term and term1_term ~= "-" then local link_page = get_link_page(term1_term, source, term1_sc) display_term = (link_page ~= final_link_page) or (link_page and not not new_title(link_page):getContent()) end -- TODO: if the display forms or transliterations are different, display the terms separately. if display_term then local display, this_cats = export.insert_source_cat_get_display{ lang = lang, source = source, borrowing_type = borrowing_type, raw = true, categories = categories, nocat = nocat, } seg = language_link { lang = source, term = term1_term, alt = display, tr = "-", } if lang and not nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat) else this_cats = "" end seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>" else seg = export.format_source{ lang = lang, source = source, borrowing_type = borrowing_type, sort_key = sort_key, categories = categories, nocat = nocat, } end insert(source_segs, seg) end return join_segs(source_segs, data.sourceconj or "and") end -- Internal implementation of {{cognate}}/{{cog}} template. function export.format_cognate(data) return export.format_derived { sources = data.sources, terms = data.terms, sort_key = data.sort_key, sourceconj = data.sourceconj, conj = data.conj, template_name = "cognate", force_cat = data.force_cat, } end --[==[ Internal implementation of {{derived}}/{{der}} template. This dispThis is called externally from [[Module:affix]], [[Module:affixusex]] and [[Module:see]] and needs to support qualifiers, labels and references on the outside of the sources for use by those modules. `data` contains the following fields: * `lang`: The destination language object into which the terms were derived. Used for categorization and can be nil, as with {{tl|cog}}; in this case, no categories are added. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see `format_sources()`. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `conj`: Conjunction used to separate multiple terms. '''Required'''. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are as for `conj` above. * `qualifiers_labels_on_outside`: If specified, any qualifiers, labels or references in the first term in `terms` will be displayed on the outside of (before) the source language(s) in `sources`. Normally this should be specified if there is only one term possible in `terms`. * `template_name`: Name of the template invoking this function. Must be specified. Only used for tracking pages. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_derived(data) local terms = data.terms local sourcetext = export.format_sources(data) return export.format_links(terms, data.conj, data.template_name, sourcetext, data.qualifiers_labels_on_outside) end function export.insert_borrowed_cat(categories, lang, source) if lang_is_source(lang, source) then return end -- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not -- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source(). -- The second parameter here doesn't matter as it only affects `display`, which we don't use. insert(categories, lang:getFullCode() .. ":Serapan dari " .. select(2, export.get_display_and_cat_name(source, "raw"))) end -- Internal implementation of {{borrowed}}/{{bor}} template. function export.format_borrowed(data) local categories = {} if not data.nocat then local lang = data.lang for _, source in ipairs(data.sources) do export.insert_borrowed_cat(categories, lang, source) end end data = shallow_copy(data) data.categories = categories return export.format_links(data.terms, data.conj, "borrowed", export.format_sources(data)) end do -- Generate the non-ancestor error message. local function show_language(lang) local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode()) if lang:hasType("etymology-only") then retval = retval .. (" (an etymology-only language whose regular parent is %s)"):format( show_language(lang:getParent())) end return retval end -- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if -- not. When `lang` is a family, verifies that `otherlang` is a language in that family. function export.check_ancestor(lang, otherlang) -- When `lang` is a family, verify `otherlang` is in that family or in its parent family. if lang.hasType and lang:hasType("family") then local family_code = lang:getCode() local function in_family_code(fcode, other) if not fcode or fcode == "" then return false end if other.inFamily and other:inFamily(fcode) then return true end if other.getFamilyCode and other:getFamilyCode() == fcode then return true end return false end local in_family = in_family_code(family_code, otherlang) if not in_family then local parent_code if lang.getParent then local parent_family = lang:getParent() if parent_family and parent_family.getCode then parent_code = parent_family:getCode() end end if not parent_code and family_code:find("-", 1, true) then parent_code = family_code:match("^(.+)-[^-]+$") end if parent_code then in_family = in_family_code(parent_code, otherlang) end end if not in_family then local other_display = (otherlang.getCanonicalName and otherlang:getCanonicalName()) or (otherlang.getCode and otherlang:getCode()) or tostring(otherlang) local fam_display = (lang.getCanonicalName and lang:getCanonicalName()) or family_code error(("%s is not in family %s; inherited ancestor under a family must be a language in that family or its parent family.") :format(other_display, fam_display)) end return end -- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up -- the module link code appropriately (June 2024) but the remaining logic is untouched. if lang:hasAncestor(otherlang) then -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/variety]] -- Track inheritance from varieties of Latin that shouldn't have any descendants (everything except Old Latin, Classical Latin and Vulgar Latin). if otherlang:getFullCode() == "la" then otherlang = otherlang:getCode() if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then track("bad ancestor", otherlang) end end return end local ancestors, postscript = lang:getAncestors() local etym_module_link = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or "" local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]" if not ancestors[1] then postscript = show_language(lang) .. " has no ancestors." else local ancestor_list = {} for _, ancestor in ipairs(ancestors) do insert(ancestor_list, show_language(ancestor)) end postscript = ("The ancestor%s of %s %s %s."):format( ancestors[2] and "s" or "", lang:getCanonicalName(), ancestors[2] and "are" or "is", concat(ancestor_list, " and ")) end error(("%s is not set as an ancestor of %s in %s%s. %s") :format(show_language(otherlang), show_language(lang), etym_module_link, module_link, postscript)) end end -- Internal implementation of {{inherited}}/{{inh}} template. function export.format_inherited(data) local lang, terms, nocat = data.lang, data.terms, data.nocat local source = terms[1].lang local categories = {} if not nocat then insert(categories, lang:getFullCode() .. ":Warisan dari " .. source:getCanonicalName()) end export.check_ancestor(lang, source) data = shallow_copy(data) data.categories = categories data.source = source return export.format_links(terms, data.conj, "inherited", export.format_source(data)) end -- Internal implementation of "misc variant" templates such as {{abbrev}}, {{clipping}}, {{reduplication}} and the like. function export.format_misc_variant(data) local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {} if not notext then insert(parts, data.text) end if terms[1] then if not notext then -- FIXME: If term is given as '-', we should consider displaying just "Clipping" not "Clipping of". insert(parts, " " .. (data.oftext or "dari")) end local termparts = {} -- Make links out of all the parts. for _, termobj in ipairs(terms) do local result if termobj.lang then result = export.format_derived { lang = lang, terms = {termobj}, sources = termobj.termlangs or {termobj.lang}, template_name = "misc_variant", qualifiers_labels_on_outside = true, force_cat = data.force_cat, } else termobj.lang = lang result = export.format_links({termobj}, nil, "misc_variant") end table.insert(termparts, result) end local linktext = join_segs(termparts, data.conj) if not notext and linktext ~= "" then insert(parts, " ") end insert(parts, linktext) end local categories = {} if not data.nocat and cats then for _, cat in ipairs(cats) do insert(categories, lang:getFullCode() .. ":" .. cat) end end if categories[1] then insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end -- Implementation of miscellaneous templates such as {{unknown}} and {{onomatopoeia}} that have no associated terms. function export.format_misc_variant_no_term(data) local parts = {} if not data.notext then insert(parts, data.title) end if not data.nocat and data.cat then local lang, categories = data.lang, {} insert(categories, lang:getFullCode() .. ":" .. data.cat) insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end return export mnj5lke7kgb5eqoa1q0zf5yyl8hmqi1 1348989 1348980 2026-04-08T16:26:20Z Swarabakti 18192 1348989 Scribunto text/plain local export = {} -- For testing local force_cat = false local debug_track_module = "Modul:debug/track" local languages_module = "Modul:languages" local links_module = "Modul:links" local pron_qualifier_module = "Modul:pron qualifier" local table_module = "Modul:table" local utilities_module = "Modul:utilities" local concat = table.concat local insert = table.insert local new_title = mw.title.new local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function format_categories(...) format_categories = require(utilities_module).format_categories return format_categories(...) end local function format_qualifiers(...) format_qualifiers = require(pron_qualifier_module).format_qualifiers return format_qualifiers(...) end local function full_link(...) full_link = require(links_module).full_link return full_link(...) end local function get_language_data_module_name(...) get_language_data_module_name = require(languages_module).getDataModuleName return get_language_data_module_name(...) end local function get_link_page(...) get_link_page = require(links_module).get_link_page return get_link_page(...) end local function language_link(...) language_link = require(links_module).language_link return language_link(...) end local function serial_comma_join(...) serial_comma_join = require(table_module).serialCommaJoin return serial_comma_join(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function track(page, code) local tracking_page = "etymology/" .. page debug_track(tracking_page) if code then debug_track(tracking_page .. "/" .. code) end end local function join_segs(segs, conj) if not segs[2] then return segs[1] elseif conj == "and" or conj == "or" then return serial_comma_join(segs, {conj = conj}) end local sep if conj == "," or conj == ";" then sep = conj .. " " elseif conj == "/" then sep = "/" elseif conj == "~" then sep = " ~ " elseif conj then error(("Internal error: Unrecognized conjunction \"%s\""):format(conj)) else error(("Internal error: No value supplied for conjunction"):format(conj)) end return concat(segs, sep) end -- Returns true if `lang` is the same as `source`, or a variety of it. local function lang_is_source(lang, source) return lang:getCode() == source:getCode() or lang:hasParent(source) end --[==[ Format one or more links as specified in `termobjs`, a list of term objects of the format accepted by `full_link()` in [[Module:links]], additionally with optional qualifiers, labels and references. `conj` is used to join multiple terms and must be specified if there is more than one term. `template_name` is the template name used in debug tracking and must be specified. Optional `sourcetext` is text to prepend to the concatenated terms, separated by a space if the concatenated terms are non-empty (which is always the case unless there is a single term with the value "-"). If `qualifiers_labels_on_outside` is given, any qualifiers, labels or references specified in the first term go on the outside of (i.e before) `sourcetext`; otherwise they will end up on the inside. ]==] function export.format_links(termobjs, conj, template_name, sourcetext, qualifiers_labels_on_outside) if not template_name then error("Internal error: Must specify `template_name` to format_links()") end for i, termobj in ipairs(termobjs) do if termobj.lang:hasType("family") or termobj.lang:getFamilyCode() == "qfa-sub" then if termobj.term and termobj.term ~= "-" then debug_track(template_name .. "/family-with-term") end termobj.term = "-" end if termobj.term == "-" then --[=[ [[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]] [[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]] ]=] debug_track(template_name .. "/no-term") termobjs[i] = i == 1 and sourcetext or "" else if i == 1 and qualifiers_labels_on_outside and sourcetext then termobj.pretext = sourcetext .. " " sourcetext = nil end termobjs[i] = (i == 1 and sourcetext and sourcetext .. " " or "") .. full_link(termobj, "term", nil, "show qualifiers") end end return join_segs(termobjs, conj) end function export.get_display_and_cat_name(source, raw) local display, cat_name if source:getCode() == "und" then display = "undetermined" cat_name = "other languages" elseif source:getCode() == "mul" then display = raw and "translingual" or "[[w:Translingualism|translingual]]" cat_name = "Translingual" elseif source:getCode() == "mul-tax" then display = raw and "taxonomic name" or "[[w:Biological nomenclature|taxonomic name]]" cat_name = "taxonomic names" else display = raw and source:getCanonicalNameLower() or source:makeWikipediaLink() cat_name = source:getDisplayForm() end return display, cat_name end function export.insert_source_cat_get_display(data) local categories, lang, source = data.categories, data.lang, data.source local display, cat_name = export.get_display_and_cat_name(source, data.raw) if lang and not data.nocat then -- Add the category, but only if there is a current language if not categories then categories = {} end local langcode = lang:getFullCode() -- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`. -- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a -- category 'Latin terms derived from Latin'. insert(categories, langcode .. ( lang_is_source(lang, source) and ":Serapan balik ke " .. cat_name or ":" .. (data.borrowing_type or "Berasal") .. " dari " .. cat_name )) end return display, categories end function export.format_source(data) local lang, sort_key = data.lang, data.sort_key -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]] if sort_key then track("sortkey") end local display, categories = export.insert_source_cat_get_display(data) if lang and not data.nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat) else categories = "" end return "<span class=\"etyl\">" .. display .. categories .. "</span>" end --[==[ Format sources for etymology templates such as {{tl|bor}}, {{tl|der}}, {{tl|inh}} and {{tl|cog}}. There may potentially be more than one source language (except currently {{tl|inh}}, which doesn't support it because it doesn't really make sense). In that case, all but the last source language is linked to the first term, but only if there is such a term and this linking makes sense, i.e. either (1) the term page exists after stripping diacritics according to the source language in question, or (2) the result of stripping diacritics according to the source language in question results in a different page from the same process applied with the last source language. For example, {{m|ru|соля́нка}} will link to [[солянка]] but {{m|en|соля́нка}} will link to [[соля́нка]] with an accent, and since they are different pages, the use of English as a non-final source with term 'соля́нка' will link to [[соля́нка]] even though it doesn't exist, on the assumption that it is merely a redlink that might exist. If none of the above criteria apply, a non-final source language will be linked to the Wikipedia entry for the language, just as final source languages always are. `data` contains the following fields: * `lang`: The destination language object into which the terms were borrowed, inherited or otherwise derived. Used for categorization and can be nil, as with {{tl|cog}}. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see above. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_sources(data) local lang, sources, terms, borrowing_type, sort_key, categories, nocat = data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat local term1, sources_n, source_segs = terms[1], #sources, {} local final_link_page local term1_term, term1_sc = term1.term, term1.sc if sources_n > 1 and term1_term and term1_term ~= "-" then final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc) end for i, source in ipairs(sources) do local seg, display_term if i < sources_n and term1_term and term1_term ~= "-" then local link_page = get_link_page(term1_term, source, term1_sc) display_term = (link_page ~= final_link_page) or (link_page and not not new_title(link_page):getContent()) end -- TODO: if the display forms or transliterations are different, display the terms separately. if display_term then local display, this_cats = export.insert_source_cat_get_display{ lang = lang, source = source, borrowing_type = borrowing_type, raw = true, categories = categories, nocat = nocat, } seg = language_link { lang = source, term = term1_term, alt = display, tr = "-", } if lang and not nocat then -- Format categories, but only if there is a current language; {{cog}} currently gets no categories this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat) else this_cats = "" end seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>" else seg = export.format_source{ lang = lang, source = source, borrowing_type = borrowing_type, sort_key = sort_key, categories = categories, nocat = nocat, } end insert(source_segs, seg) end return join_segs(source_segs, data.sourceconj or "and") end -- Internal implementation of {{cognate}}/{{cog}} template. function export.format_cognate(data) return export.format_derived { sources = data.sources, terms = data.terms, sort_key = data.sort_key, sourceconj = data.sourceconj, conj = data.conj, template_name = "cognate", force_cat = data.force_cat, } end --[==[ Internal implementation of {{derived}}/{{der}} template. This dispThis is called externally from [[Module:affix]], [[Module:affixusex]] and [[Module:see]] and needs to support qualifiers, labels and references on the outside of the sources for use by those modules. `data` contains the following fields: * `lang`: The destination language object into which the terms were derived. Used for categorization and can be nil, as with {{tl|cog}}; in this case, no categories are added. * `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are handled specially; see `format_sources()`. * `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as multiple term objects, the non-final source objects link to the first term object. * `conj`: Conjunction used to separate multiple terms. '''Required'''. Currently recognized values are `and`, `or`, `,`, `;`, `/` and `~`. * `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized values are as for `conj` above. * `qualifiers_labels_on_outside`: If specified, any qualifiers, labels or references in the first term in `terms` will be displayed on the outside of (before) the source language(s) in `sources`. Normally this should be specified if there is only one term possible in `terms`. * `template_name`: Name of the template invoking this function. Must be specified. Only used for tracking pages. * `sort_key`: Sort key for categories. Usually nil. * `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be added. * `nocat`: Don't add any categories to the page. * `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}. * `force_cat`: Force category generation on non-mainspace pages. ]==] function export.format_derived(data) local terms = data.terms local sourcetext = export.format_sources(data) return export.format_links(terms, data.conj, data.template_name, sourcetext, data.qualifiers_labels_on_outside) end function export.insert_borrowed_cat(categories, lang, source) if lang_is_source(lang, source) then return end -- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not -- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source(). -- The second parameter here doesn't matter as it only affects `display`, which we don't use. insert(categories, lang:getFullCode() .. ":Serapan dari " .. select(2, export.get_display_and_cat_name(source, "raw"))) end -- Internal implementation of {{borrowed}}/{{bor}} template. function export.format_borrowed(data) local categories = {} if not data.nocat then local lang = data.lang for _, source in ipairs(data.sources) do export.insert_borrowed_cat(categories, lang, source) end end data = shallow_copy(data) data.categories = categories return export.format_links(data.terms, data.conj, "borrowed", export.format_sources(data)) end do -- Generate the non-ancestor error message. local function show_language(lang) local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode()) if lang:hasType("etymology-only") then retval = retval .. (" (an etymology-only language whose regular parent is %s)"):format( show_language(lang:getParent())) end return retval end -- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if -- not. When `lang` is a family, verifies that `otherlang` is a language in that family. function export.check_ancestor(lang, otherlang) -- When `lang` is a family, verify `otherlang` is in that family or in its parent family. if lang.hasType and lang:hasType("family") then local family_code = lang:getCode() local function in_family_code(fcode, other) if not fcode or fcode == "" then return false end if other.inFamily and other:inFamily(fcode) then return true end if other.getFamilyCode and other:getFamilyCode() == fcode then return true end return false end local in_family = in_family_code(family_code, otherlang) if not in_family then local parent_code if lang.getParent then local parent_family = lang:getParent() if parent_family and parent_family.getCode then parent_code = parent_family:getCode() end end if not parent_code and family_code:find("-", 1, true) then parent_code = family_code:match("^(.+)-[^-]+$") end if parent_code then in_family = in_family_code(parent_code, otherlang) end end if not in_family then local other_display = (otherlang.getCanonicalNameLower and otherlang:getCanonicalNameLower()) or (otherlang.getCode and otherlang:getCode()) or tostring(otherlang) local fam_display = (lang.getCanonicalNameLower and lang:getCanonicalNameLower()) or family_code error(("%s is not in family %s; inherited ancestor under a family must be a language in that family or its parent family.") :format(other_display, fam_display)) end return end -- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up -- the module link code appropriately (June 2024) but the remaining logic is untouched. if lang:hasAncestor(otherlang) then -- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/variety]] -- Track inheritance from varieties of Latin that shouldn't have any descendants (everything except Old Latin, Classical Latin and Vulgar Latin). if otherlang:getFullCode() == "la" then otherlang = otherlang:getCode() if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then track("bad ancestor", otherlang) end end return end local ancestors, postscript = lang:getAncestors() local etym_module_link = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or "" local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]" if not ancestors[1] then postscript = show_language(lang) .. " has no ancestors." else local ancestor_list = {} for _, ancestor in ipairs(ancestors) do insert(ancestor_list, show_language(ancestor)) end postscript = ("The ancestor%s of %s %s %s."):format( ancestors[2] and "s" or "", lang:getCanonicalNameLower(), ancestors[2] and "are" or "is", concat(ancestor_list, " and ")) end error(("%s is not set as an ancestor of %s in %s%s. %s") :format(show_language(otherlang), show_language(lang), etym_module_link, module_link, postscript)) end end -- Internal implementation of {{inherited}}/{{inh}} template. function export.format_inherited(data) local lang, terms, nocat = data.lang, data.terms, data.nocat local source = terms[1].lang local categories = {} if not nocat then insert(categories, lang:getFullCode() .. ":Warisan dari " .. source:getCanonicalNameLower()) end export.check_ancestor(lang, source) data = shallow_copy(data) data.categories = categories data.source = source return export.format_links(terms, data.conj, "inherited", export.format_source(data)) end -- Internal implementation of "misc variant" templates such as {{abbrev}}, {{clipping}}, {{reduplication}} and the like. function export.format_misc_variant(data) local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {} if not notext then insert(parts, data.text) end if terms[1] then if not notext then -- FIXME: If term is given as '-', we should consider displaying just "Clipping" not "Clipping of". insert(parts, " " .. (data.oftext or "dari")) end local termparts = {} -- Make links out of all the parts. for _, termobj in ipairs(terms) do local result if termobj.lang then result = export.format_derived { lang = lang, terms = {termobj}, sources = termobj.termlangs or {termobj.lang}, template_name = "misc_variant", qualifiers_labels_on_outside = true, force_cat = data.force_cat, } else termobj.lang = lang result = export.format_links({termobj}, nil, "misc_variant") end table.insert(termparts, result) end local linktext = join_segs(termparts, data.conj) if not notext and linktext ~= "" then insert(parts, " ") end insert(parts, linktext) end local categories = {} if not data.nocat and cats then for _, cat in ipairs(cats) do insert(categories, lang:getFullCode() .. ":" .. cat) end end if categories[1] then insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end -- Implementation of miscellaneous templates such as {{unknown}} and {{onomatopoeia}} that have no associated terms. function export.format_misc_variant_no_term(data) local parts = {} if not data.notext then insert(parts, data.title) end if not data.nocat and data.cat then local lang, categories = data.lang, {} insert(categories, lang:getFullCode() .. ":" .. data.cat) insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat)) end return concat(parts) end return export 2u3jssmetx3l856z23gev3dyhoa5npc Templat:bor 10 216409 1349000 1083538 2026-04-08T16:49:02Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:pinjaman]] ke [[Templat:serapan]] 1349000 wikitext text/x-wiki #REDIRECT [[Template:serapan]] mii8qe173kc8s1iqpl2pvgx6intdf1v 1349001 1349000 2026-04-08T16:49:16Z Swarabakti 18192 1349001 wikitext text/x-wiki #ALIH [[Templat:serapan]] 9xb701nzk0pmb6ve10i4gwb12sepr38 Templat:cog 10 216446 1349026 1083631 2026-04-08T17:08:56Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:kognat]] ke [[Templat:seakar]] 1349026 wikitext text/x-wiki #ALIH [[Templat:seakar]] nrf594fl4jmi3vdayw6da06eojerk7f melemparkan 0 219496 1349191 1228134 2026-04-09T10:14:59Z Sofi Solihah 23681 1349191 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan me-kan|lempar}} # membuang jauh-jauh; [[melontarkan]]; [[melantingkan]]: <br>''ia melemparkan buah itu ke tengah kolam'' # [[melepaskan]] ([[tuduhan]], [[kritik]], dsb): <br>''ia pernah melemparkan kritik terhadap tindakan pengurus; ia selalu melemparkan tuduhan yang bukan-bukan'' #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 55 |text= Sedangkan bagi pemain yang kurang mahir dalam '''melemparkan''' akan banyak kehilangan karet gelang sebagai alat taruhan. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Badurit#:~:text=Sedangkan%20bagi%20pemain%20yang%20kurang%20mahir%20dalam%20melemparkan%20akan%20banyak%20kehilangan%20karet%20gelang%20sebagai%20alat%20taruhan. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 74kll2pxhq5x3sjb3sowi8xn3uqlh4l sugeng rawuh 0 221878 1349063 1294796 2026-04-08T18:00:39Z Swarabakti 18192 pindahkan penjelasan ke entri masing-masing 1349063 wikitext text/x-wiki =={{bahasa|jv}}== {{kepala|jv}} {{-etimologi-}} : Dari {{compound|jv|sugeng|rawuh}} <!-- *''sugeng'': **{{sebut|jv|su-}}: berasal dari {{Der|jv|sa|सु-}}. **''geng'': mungkin dari {{Der*|jv|mkh-pro|gluŋ|t=banyak}} atau {{Der*|jv|mkh-pro|ɟoŋ|t=panjang, tinggi}}. *''rawuh'': mungkin dari {{Der*|jv|mkh-pro|rəh}}, {{Der^|mkh-pro|ruəh}}, {{Der^|mkh-pro|ruuh|t=jatuh}} atau dari {{Der*|jv|PMP|ket=Barat|dabuq|t=jatuh}}.--> {{-interjeksi-|jv}} # [[selamat datang]] {{-n-|jv}} # [[selamat datang]] rsuxmt6s8dfmd1av7vbuoamhr8vycbt 1349064 1349063 2026-04-08T18:00:50Z Swarabakti 18192 1349064 wikitext text/x-wiki =={{bahasa|jv}}== {{kepala|jv}} {{-etimologi-}} : Dari {{compound|jv|sugeng|rawuh}}. <!-- *''sugeng'': **{{sebut|jv|su-}}: berasal dari {{Der|jv|sa|सु-}}. **''geng'': mungkin dari {{Der*|jv|mkh-pro|gluŋ|t=banyak}} atau {{Der*|jv|mkh-pro|ɟoŋ|t=panjang, tinggi}}. *''rawuh'': mungkin dari {{Der*|jv|mkh-pro|rəh}}, {{Der^|mkh-pro|ruəh}}, {{Der^|mkh-pro|ruuh|t=jatuh}} atau dari {{Der*|jv|PMP|ket=Barat|dabuq|t=jatuh}}.--> {{-interjeksi-|jv}} # [[selamat datang]] {{-n-|jv}} # [[selamat datang]] 8hsm1n7quvi5nqm5basbwwx1zcnl4p2 Templat:doublet 10 221990 1349120 983224 2026-04-08T19:09:40Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:kembaran]] ke [[Templat:bentuk kembar]] 1349120 wikitext text/x-wiki #ALIH[[Templat:bentuk kembar]] fp7mn588r5a5w58k9qju27h704gsem6 Templat:lbor 10 222128 1349106 958563 2026-04-08T18:43:45Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:learned borrowing]] ke [[Templat:serapan terencana]] 1349106 wikitext text/x-wiki #REDIRECT [[Template:serapan terencana]] 750i8vnqni3m0fjmi77dn2hud8ccfl9 Templat:serapan terencana 10 222129 1349067 1022370 2026-04-08T18:14:18Z Swarabakti 18192 1349067 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=sengaja}}</includeonly><noinclude>{{lbor|id|id|sengaja}}. {{documentation}}</noinclude> dgvtespvwsbe3q0ofyjhtewo8da8xbm 1349072 1349067 2026-04-08T18:21:52Z Swarabakti 18192 1349072 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=terencana}}</includeonly><noinclude>{{lbor|id|id|rencana}}. {{documentation}}</noinclude> f4v9y8a9q1osb03izikv7ms7nu78eq3 1349075 1349072 2026-04-08T18:23:32Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:learned borrowing]] ke [[Templat:serapan terencana]] 1349072 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=terencana}}</includeonly><noinclude>{{lbor|id|id|rencana}}. {{documentation}}</noinclude> f4v9y8a9q1osb03izikv7ms7nu78eq3 alamaik 0 222925 1348939 1137542 2026-04-08T13:17:53Z Bennylin 723 /* {{bahasa|min}} */ 1348939 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{suara|min|LL-Q13324 (min)-Ardzun-alamaik.wav}} {{-n-|min}} # [[alamat]] 9bs1iyglncz3oi3q2oly69318zqhkpk 1348941 1348939 2026-04-08T13:29:58Z Bennylin 723 1348941 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{suara|min|LL-Q13324 (min)-Ardzun-alamaik.wav}} {{-n-|min}} # [[alamat]] 2wt643rbib8n5k5aee2rf12vov4i2z5 1348942 1348941 2026-04-08T13:30:25Z Bennylin 723 /* {{bahasa|min}} */ 1348942 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{suara|min|LL-Q13324 (min)-Ardzun-alamaik.wav}} {{-n-|min}} # [[alamat]] lyjktphtpv1d7s9e71dlzm3xvz469pl mudiak 0 225682 1348936 1248492 2026-04-08T13:05:41Z Ardzun 8096 1348936 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-n-|min}} # [[hulu]] #:{{syn|min|ulu}} #:''bisuak den baru pai ka '''mudiak''''' #::besok aku akan pergi ke '''hulu''' {{-v-|min}} # [[mudik]] #:{{syn|min|baliak kampuang}} #:''dek ari ka Rayo, urang '''mudiak''' kini'' #::karena sebentar lagi Hari Raya, orang-orang '''mudik''' sekarang ih0l1yagvbcpkzqls3z697mpl6iowpn Modul:auto cat 828 227700 1348995 1119868 2026-04-08T16:43:31Z Swarabakti 18192 1348995 Scribunto text/plain -- Disesuaikan dari [[:bew:Modul:autocat]] 2025-12-27 local p = {} local U = require("Modul:utilitas") local Lang = require("Modul:bahasa") -- Pohon kategori local categoryTree = { -- Induk ["Simbol"] = { base = true, global = true }, ["Rima"] = { base = true, global = true }, ["Lema"] = { base = true, global = true }, ["Nonlema"] = { base = true, global = true }, ["Topik"] = { base = true, topical = true }, ["Istilah pilihan"] = { base = true, global = true }, ["Istilah menurut etimologi"] = { base = true, global = true }, ["Pemeliharaan halaman"] = { base = true, global = true }, ["Ragam bahasa"] = { base = true, global = true }, -- Kelas kata ["Nomina"] = { parents = { "Lema" }, global = true }, ["Nama diri"] = { parents = { "Nomina" }, global = true }, ["Verba"] = { parents = { "Lema" }, global = true }, ["Partisip"] = { parents = { "Verba" }, global = true }, ["Adjektiva"] = { parents = { "Lema" }, global = true }, ["Numeralia"] = { parents = { "Lema" }, global = true }, ["Adverbia"] = { parents = { "Lema" }, global = true }, ["Pronomina"] = { parents = { "Lema" }, global = true }, ["Konjungsi"] = { parents = { "Lema" }, global = true }, ["Interjeksi"] = { parents = { "Lema" }, global = true }, ["Partikula"] = { parents = { "Lema" }, global = true }, ["Penentu"] = { parents = { "Lema" }, global = true }, ["Artikula"] = { parents = { "Lema" }, global = true }, ["Penggolong"] = { parents = { "Lema" }, global = true }, ["Preposisi"] = { parents = { "Lema" }, global = true }, ["Postposisi"] = { parents = { "Lema" }, global = true }, ["Sirkumposisi"] = { parents = { "Lema" }, global = true }, ["Ambiposisi"] = { parents = { "Lema" }, global = true }, ["Morfem"] = { parents = { "Lema" }, global = true }, ["Istilah rangkaian kata"] = { parents = { "Lema" }, global = true }, -- Bentuk nonlema ["Bentuk nomina"] = { parents = { "Nonlema", "Nomina" }, global = true }, ["Bentuk verba"] = { parents = { "Nonlema", "Verba" }, global = true }, ["Bentuk adjektiva"] = { parents = { "Nonlema", "Adjektiva" }, global = true }, ["Bentuk numeralia"] = { parents = { "Nonlema", "Numeralia" }, global = true }, ["Bentuk adverbia"] = { parents = { "Nonlema", "Adverbia" }, global = true }, ["Bentuk pronomina"] = { parents = { "Nonlema", "Pronomina" }, global = true }, ["Bentuk konjungsi"] = { parents = { "Nonlema", "Konjungsi" }, global = true }, ["Bentuk interjeksi"] = { parents = { "Nonlema", "Interjeksi" }, global = true }, ["Bentuk partikula"] = { parents = { "Nonlema", "Partikula" }, global = true }, ["Bentuk penentu"] = { parents = { "Nonlema", "Penentu" }, global = true }, ["Bentuk artikula"] = { parents = { "Nonlema", "Artikula" }, global = true }, ["Bentuk penggolong"] = { parents = { "Nonlema", "Penggolong" }, global = true }, ["Bentuk preposisi"] = { parents = { "Nonlema", "Preposisi" }, global = true }, ["Bentuk postposisi"] = { parents = { "Nonlema", "Postposisi" }, global = true }, ["Bentuk sirkumposisi"] = { parents = { "Nonlema", "Sirkumposisi" }, global = true }, ["Bentuk ambiposisi"] = { parents = { "Nonlema", "Ambiposisi" }, global = true }, -- Morfem ["Awalan"] = { parents = { "Morfem" }, global = true }, ["Akhiran"] = { parents = { "Morfem" }, global = true }, ["Sisipan"] = { parents = { "Morfem" }, global = true }, ["Apitan"] = { parents = { "Morfem" }, global = true }, ["Sambungan"] = { parents = { "Morfem" }, global = true }, ["Akar"] = { parents = { "Morfem" }, global = true }, -- Istilah rangkaian kata ["Frasa"] = { parents = { "Istilah rangkaian kata" }, global = true }, ["Peribahasa"] = { parents = { "Istilah rangkaian kata" }, global = true }, -- Lain-lain ["Romanisasi"] = { parents = { "Nonlema" }, global = true }, ["Huruf"] = { parents = { "Simbol" }, global = true }, -- Permintaan ["Istilah dengan permintaan definisi"] = { parents = { "Istilah dengan permintaan" }, global = true }, ["Istilah dengan permintaan etimologi"] = { parents = { "Istilah dengan permintaan" }, global = true }, ["Istilah dengan permintaan pemastian"] = { parents = { "Istilah dengan permintaan" }, global = true }, -- Pemeliharaan halaman ["Istilah dengan permintaan"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan transkripsi AFI"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan tautan audio"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan kutipan"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan contoh kalimat"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan ragam bentuk aksara"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah dengan romanisasi"] = { parents = { "Pemeliharaan halaman" }, global = true }, ["Istilah homonim"] = { parents = { "Pemeliharaan halaman" }, global = true }, } -- Etymology category types -- If value = true → base type -- If value = "<parent>" → subtype, parent = that base type local etymTypes = { otherlang = { ["Serapan dari"] = true, ["Serapan palsu dari"] = "Serapan", --pseudo ["Serapan sengaja dari"] = "Serapan", --learned ["Serapan utuh dari"] = "Serapan", --unadapted ["Berasal dari"] = true, ["Warisan dari"] = true, }, samelang = { ["Gabungan kata"] = true, ["Paduan"] = true, }, } -- Unified global category insertion local globalCats = function(cat) return { U.cat(cat .. " menurut bahasa") } end -- Helper: lowercase first letter only local function lcFirst(str) if not str or str == "" then return str end return mw.ustring.lower(mw.ustring.sub(str, 1, 1)) .. mw.ustring.sub(str, 2) end -- Unified description generation local function makeDescription(usePart, langNameNocap, rhyme, syll, etyType, srcLangName, isSamelang) if etyType and srcLangName then return string.format("Halaman kategori ini memuat %s dari %s dalam %s.", lcFirst(etyType), srcLangName, langNameNocap) elseif isSamelang then return string.format("Halaman kategori ini memuat %s dalam %s.", lcFirst(usePart), langNameNocap) elseif usePart == "Rima" then return string.format("Halaman kategori ini memuat istilah menurut rima dalam %s.", langNameNocap) elseif rhyme and not syll then return string.format("Halaman kategori ini memuat istilah berima -%s dalam %s.", rhyme, langNameNocap) elseif rhyme and syll then return string.format("Halaman kategori ini memuat istilah berima -%s dengan %s suku kata dalam %s.", rhyme, syll, langNameNocap) else return string.format("Halaman kategori ini memuat %s %s.", lcFirst(usePart), langNameNocap) end end function p.main(frame) local title = mw.title.getCurrentTitle().text local langCode, usePart = title:match("^([^:]+):(.+)$") if not langCode or not usePart then return "" end local langName = Lang.getLangName{ args = { langCode } } local langNameNocap = lcFirst(langName) if not langName then return U.errorcat("basa") end local output, parents = {}, {} -- detect rhyme and syllable local rhyme, syll = usePart:match("^Rima/([^/]+)/(%d+) ucap$") if not rhyme then rhyme = usePart:match("^Rima/([^/]+)$") end -- detect cross-language local etyType, srcLangName = usePart:match("^(.+) dari (.+)$") if etyType and not etymTypes.otherlang[etyType] then etyType, srcLangName = nil, nil end -- etymology parents if etymTypes.otherlang[usePart] or etymTypes.samelang[usePart] then local etyParent = etymTypes.otherlang[usePart] or etymTypes.samelang[usePart] if etyParent == true then -- base type table.insert(parents, U.langcat(langCode, "Istilah menurut etimologi")) else -- subtype table.insert(parents, U.langcat(langCode, etyParent)) end for _, cat in ipairs(globalCats(usePart)) do table.insert(parents, cat) end end -- Rhymecats hierarchy if usePart == "Rima" then elseif rhyme and not syll then table.insert(parents, U.langcat(langCode, "Rima")) elseif rhyme and syll then table.insert(parents, U.langcat(langCode, "Rima/" .. rhyme)) end -- tree-defined parents local def = categoryTree[usePart] if def then if def.parents then for _, parent in ipairs(def.parents) do table.insert(parents, U.langcat(langCode, parent)) end end if def.topical then table.insert(parents, U.cat(usePart)) end if def.global then table.insert(parents, U.cat(usePart .. " menurut bahasa")) end end -- base language category if def and def.base then table.insert(parents, U.cat(langName)) end -- cross-language parents if etyType and srcLangName then table.insert(parents, U.langcat(langCode, etyType)) table.insert(parents, U.cat(etyType .. " dari " .. srcLangName .. " menurut bahasa")) end -- stack parents below description table.insert(output, makeDescription(usePart, langNameNocap, rhyme, syll, etyType, srcLangName, etymTypes.samelang[usePart])) if #parents > 0 then table.insert(output, table.concat(parents, "\n")) end return table.concat(output, "\n") end return p nmhdv2niqp61bckyd0uc7nofvt44p77 Templat:bentuk penggalan 10 227748 1349123 984001 2026-04-08T19:16:35Z Swarabakti 18192 1349123 wikitext text/x-wiki {{#invoke:etymology/templates|misc_variant|text={{#if:{{{nocap|}}}|b|B}}entuk penggalan|cat=Bentuk penggalan|conj=atau}}<noinclude>{{dokumentasi}}</noinclude> 8ub0kv69hh24msrpuce22o1ygd6bwv7 1349124 1349123 2026-04-08T19:17:35Z Swarabakti 18192 1349124 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant|text={{#if:{{{nocap|}}}|b|B}}entuk penggalan|cat=Bentuk penggalan|conj=atau}}<noinclude>. {{dokumentasi}}</noinclude> 8qwrmorvi9wlue6zhz57vkte31p2mvi 1349125 1349124 2026-04-08T19:17:45Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:clipping]] ke [[Templat:bentuk penggalan]] 1349124 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant|text={{#if:{{{nocap|}}}|b|B}}entuk penggalan|cat=Bentuk penggalan|conj=atau}}<noinclude>. {{dokumentasi}}</noinclude> 8qwrmorvi9wlue6zhz57vkte31p2mvi 1349134 1349125 2026-04-08T19:32:21Z Swarabakti 18192 1349134 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant|text={{#if:{{{nocap|}}}|b|B}}entuk [[penggalan]]|cat=Bentuk penggalan|conj=atau}}<noinclude>. {{dokumentasi}}</noinclude> afg35wduhcvljhahu2yollbjortrqin Templat:onomatopoeic 10 227775 1349109 984012 2026-04-08T18:56:48Z Swarabakti 18192 1349109 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|onomatopoeia|text=[[onomatope|{{#if:{{{nocap|}}}|o|O}}nomatope]]|cat=Onomatopoeia}}<noinclude>.{{dokumentasi}}</noinclude> c0k6ctgw8gzmplvwtda5utfbu8ur9a6 1349110 1349109 2026-04-08T18:57:18Z Swarabakti 18192 1349110 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|onomatopoeia|text=[[onomatope|{{#if:{{{nocap|}}}|o|O}}nomatope]]|cat=Onomatope}}<noinclude>.{{dokumentasi}}</noinclude> 5dmq5n6yjrst9hxwtwi43l7x0oovuxj 1349112 1349110 2026-04-08T19:00:06Z Swarabakti 18192 1349112 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant_no_term|text=[[onomatope|{{#if:{{{nocap|}}}|o|O}}nomatope]]|cat=Onomatope}}<noinclude>.{{dokumentasi}}</noinclude> ih8cqoqbr9z86gbz6vv3tn6ruxrzdru ajep 0 227776 1349111 1137084 2026-04-08T18:58:29Z Swarabakti 18192 /* {{bahasa|id}} */ 1349111 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-etimologi-}} : {{onom|id}}. {{-intj-|id}} # {{label|id|cakapan}} tiruan suara musik dalam [[klub malam]], [[diskotik]], dsb. #* '''2014''', Esto Triramdani Nurlustiawan, ''[https://www.google.co.id/books/edition/Putih_Biru/DGnuDwAAQBAJ?hl=en&gbpv=1&pg=PA49 Putih Biru: Coretan Kecil Pelajar Idiot]'', Rasibook, hlm. 49: #*: ''<nowiki>'</nowiki>Jep! '''Ajep'''! '''Ajep'''! '''Ajep'''! '''Ajep'''! Ampun DJ!' sambil geleng-geleng.'' {{-turunan-}} * [[ajep-ajep]] * [[jep]] gkaix6nznm6m6bnu3wzrxxcr3kxu3zo Templat:serapan utuh 10 232109 1349073 1022368 2026-04-08T18:22:19Z Swarabakti 18192 1349073 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=utuh}}</includeonly><noinclude>{{unadapted borrowing|mul|mul|term}}.{{documentation}}</noinclude> g7hnigd2z1atlh68o7mbyt5jqbplgd0 1349074 1349073 2026-04-08T18:22:39Z Swarabakti 18192 1349074 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=utuh}}</includeonly><noinclude>{{unadapted borrowing|id|id|utuh}}.{{documentation}}</noinclude> 62o8u6yfxllm9bnxgox8345um38inym 1349081 1349074 2026-04-08T18:25:25Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:unadapted borrowing]] ke [[Templat:serapan utuh]] 1349074 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=utuh}}</includeonly><noinclude>{{unadapted borrowing|id|id|utuh}}.{{documentation}}</noinclude> 62o8u6yfxllm9bnxgox8345um38inym Templat:bentuk kembar 10 232115 1349113 1103891 2026-04-08T19:05:13Z Swarabakti 18192 1349113 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant_multiple_terms|text={{glossary|bentuk kembar|{{#if:{{{nocap|}}}|b|B}}entuk kembar}}|cat=Bentuk kembar}}<noinclude>. {{dokumentasi}}</noinclude> 9xnfhvh01kgr632y4momd6rpubcuqak 1349116 1349113 2026-04-08T19:09:16Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kembaran]] ke [[Templat:bentuk kembar]] 1349113 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant_multiple_terms|text={{glossary|bentuk kembar|{{#if:{{{nocap|}}}|b|B}}entuk kembar}}|cat=Bentuk kembar}}<noinclude>. {{dokumentasi}}</noinclude> 9xnfhvh01kgr632y4momd6rpubcuqak Modul:etymology/templates/doc 828 232259 1349005 983570 2026-04-08T16:52:17Z Swarabakti 18192 Swarabakti memindahkan halaman [[Modul:etimologi/templat/doc]] ke [[Modul:etymology/templates/dokumentasi]] tanpa membuat pengalihan 983570 wikitext text/x-wiki Modul ini menghasilkan konten untuk beberapa [[:CAT:Foreign derivation templates|templat etimologi]]: * {{temp|etyl}} * {{temp|learned borrowing}} * {{temp|orthographic borrowing}} * {{temp|unadapted borrowing}} * {{temp|calque}} * {{temp|partial calque}} * {{temp|semantic loan}} * {{temp|phono-semantic matching}} Beberapa template yang dulu ada di sini kini telah dipindahkan ke submodul: * [[Module:etymology/templates/cognate]]: {{temp|cognate}}, {{temp|noncognate}} * [[Module:etymology/templates/derived]]: {{temp|derived}} * [[Modul:etimologi/templat/terwarisi]]: {{temp|terwarisi}} * [[Module:etymology/templates/borrowed]]: {{temp|borrowed}} * [[Module:etymology/templates/doublet]]: {{temp|doublet}} * [[Module:etymology/templates/descendant]]: {{temp|descendant}}, {{temp|descendants tree}} <includeonly> [[Category:Template interface modules]] </includeonly> pam9kad5lri62n25q08o2n2uzvmoagj 1349006 1349005 2026-04-08T16:52:34Z Swarabakti 18192 Swarabakti memindahkan halaman [[Modul:etymology/templates/dokumentasi]] ke [[Modul:etymology/templates/doc]] tanpa membuat pengalihan 983570 wikitext text/x-wiki Modul ini menghasilkan konten untuk beberapa [[:CAT:Foreign derivation templates|templat etimologi]]: * {{temp|etyl}} * {{temp|learned borrowing}} * {{temp|orthographic borrowing}} * {{temp|unadapted borrowing}} * {{temp|calque}} * {{temp|partial calque}} * {{temp|semantic loan}} * {{temp|phono-semantic matching}} Beberapa template yang dulu ada di sini kini telah dipindahkan ke submodul: * [[Module:etymology/templates/cognate]]: {{temp|cognate}}, {{temp|noncognate}} * [[Module:etymology/templates/derived]]: {{temp|derived}} * [[Modul:etimologi/templat/terwarisi]]: {{temp|terwarisi}} * [[Module:etymology/templates/borrowed]]: {{temp|borrowed}} * [[Module:etymology/templates/doublet]]: {{temp|doublet}} * [[Module:etymology/templates/descendant]]: {{temp|descendant}}, {{temp|descendants tree}} <includeonly> [[Category:Template interface modules]] </includeonly> pam9kad5lri62n25q08o2n2uzvmoagj 1349107 1349006 2026-04-08T18:49:53Z Swarabakti 18192 blm selesai 1349107 wikitext text/x-wiki Modul ini menghasilkan konten untuk [[:Kategori:Templat etimologi|templat etimologi]], yang melingkupi templat-templat berikut. Templat dasar untuk pewarisan, penyerapan, dan kekerabatan lain: * {{temp|seakar}}/{{temp|cog}} * {{temp|berasal}}/{{temp|der}} * {{temp|warisan}}/{{temp|inh}} * {{temp|serapan}}/{{temp|bor}} Templat-templat penyerapan khusus (tidak termasuk templat {{temp|bor}}/{{temp|serapan}} itu sendiri), yang mirip dengan {{temp|bor}} tetapi memunculkan teks jenis serapan sebelum bahasa sumber dan istilahnya: * {{temp|serapan terencana}}/{{temp|lbor}} (''learned borrowing'') * {{temp|serapan semi-terencana}}/{{temp|slbor}} (''semi-learned borrowing'') * {{temp|serapan ejaan}}/{{temp|obor}} (''orthographic borrowing'') * {{temp|serapan utuh}}/{{temp|ubor}} (''unadapted borrowing'') * {{temp|serapan lebur}}/{{temp|abor}} (''adapted borrowing'') * {{temp|serapan terjemahan}}/{{temp|cal}}/{{temp|clq}} (''calque'') * {{temp|serapan terjemahan sebagian}}/{{temp|pcal}}/{{temp|pclq}} (''partial calque'') * {{temp|serapan semantik}}/{{temp|sl}} (''semantic loan'') * {{temp|pemadanan fono-semantik}}/{{temp|psm}} (''phono-semantic matching'') * {{temp|alih aksara}}/{{temp|translit}} (''transliteration'') * {{temp|bor+}} Aneka templat etimologi dengan parameter istilah tunggal: * {{temp|abbrev}} * {{temp|acronym}} * {{temp|back-formation}} * {{temp|clipping}} * {{temp|ellipsis}} * {{temp|initialism}} * {{temp|rebracketing}} * {{temp|reduplication}} * {{temp|spoonerism}} * ... Aneka templat etimologi yang dengan parameter istilah majemuk: * {{temp|doublet}}/{{temp|dbt}} Aneka templat etimologi tanpa parameter istilah (hanya untuk kategorisasi): * {{temp|onomatopoeic}} * {{temp|uncertain}} * {{temp|unknown}} * ... <includeonly> [[Category:Template interface modules]][[Category:Etymology modules]] </includeonly> o7sjzf1kbrwelokdw7js479gde558we 1349108 1349107 2026-04-08T18:50:36Z Swarabakti 18192 1349108 wikitext text/x-wiki Modul ini menghasilkan konten untuk [[:Kategori:Templat etimologi|templat etimologi]], yang melingkupi templat-templat berikut. Templat dasar untuk pewarisan, penyerapan, dan kekerabatan lain: * {{temp|seakar}}/{{temp|cog}} (''cognate'') * {{temp|berasal}}/{{temp|der}} (''derived'') * {{temp|warisan}}/{{temp|inh}} (''inherited'') * {{temp|serapan}}/{{temp|bor}} (''borrowed'') Templat-templat penyerapan khusus (tidak termasuk templat {{temp|bor}}/{{temp|serapan}} itu sendiri), yang mirip dengan {{temp|bor}} tetapi memunculkan teks jenis serapan sebelum bahasa sumber dan istilahnya: * {{temp|serapan terencana}}/{{temp|lbor}} (''learned borrowing'') * {{temp|serapan semi-terencana}}/{{temp|slbor}} (''semi-learned borrowing'') * {{temp|serapan ejaan}}/{{temp|obor}} (''orthographic borrowing'') * {{temp|serapan utuh}}/{{temp|ubor}} (''unadapted borrowing'') * {{temp|serapan lebur}}/{{temp|abor}} (''adapted borrowing'') * {{temp|serapan terjemahan}}/{{temp|cal}}/{{temp|clq}} (''calque'') * {{temp|serapan terjemahan sebagian}}/{{temp|pcal}}/{{temp|pclq}} (''partial calque'') * {{temp|serapan semantik}}/{{temp|sl}} (''semantic loan'') * {{temp|pemadanan fono-semantik}}/{{temp|psm}} (''phono-semantic matching'') * {{temp|alih aksara}}/{{temp|translit}} (''transliteration'') * {{temp|bor+}} Aneka templat etimologi dengan parameter istilah tunggal: * {{temp|abbrev}} * {{temp|acronym}} * {{temp|back-formation}} * {{temp|clipping}} * {{temp|ellipsis}} * {{temp|initialism}} * {{temp|rebracketing}} * {{temp|reduplication}} * {{temp|spoonerism}} * ... Aneka templat etimologi yang dengan parameter istilah majemuk: * {{temp|doublet}}/{{temp|dbt}} Aneka templat etimologi tanpa parameter istilah (hanya untuk kategorisasi): * {{temp|onomatopoeic}} * {{temp|uncertain}} * {{temp|unknown}} * ... <includeonly> [[Category:Template interface modules]][[Category:Etymology modules]] </includeonly> c7xxs48vi29lqgrhtsmnes8peupbxlp berikutnya 0 233804 1349051 1305737 2026-04-08T17:32:00Z Sofi Solihah 23681 1349051 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{verba -nya|berikut}} # {{rfdef|id}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Tahap '''berikutnya''' adalah tahap ke dua. A yang menang pin - sut mendapatkan hak untuk membuka permainan yaitu mengambil 3 biji anak cit milik B ; misalnya biji yang diambil A adalah 6 B, 11 B dan 12 B. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Tahap%20berikutnya%20adalah%20tahap%20ke%20dua.%20A%20yang%20menang%20pin%20%2D%20sut%20mendapatkan%20hak%20untuk%20membuka%20permainan%20yaitu%20mengambil%203%20biji%20anak%20cit%20milik%20B%C2%A0%3B%20misalnya%20biji%20yang%20diambil%20A%20adalah%206%20B%2C%2011%20B%20dan%2012%20B. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} hslmcjhf2h7lt9thnfxze9lxqawh3sf Lampiran:Rekonstruksi bahasa Proto-Melayu-Polinesia/laŋuy 102 243919 1349130 1103899 2026-04-08T19:25:06Z Swarabakti 18192 /* {{bahasa|poz-pro}} */ 1349130 wikitext text/x-wiki {{rekonstruksi}} =={{bahasa|poz-pro}}== {{kepala|poz-pro}} : {{AFI|poz-pro|/laŋuj/}} {{-etimologi-}} : {{inh+|map-pro|*Naŋuy}}. {{doublet|poz-pro|*naŋuy}}. {{-verba-|poz-pro}} # {{label|poz-pro|intransitif}} {{l|id|renang}} {{-keturunan-}} * {{anak|kaw|laṅuy}} ** {{anak|jv|langi}} * {{anak|phi-pro|*laŋúy}} btqfsng9uso5ve3jnc1yvro35uup802 1349131 1349130 2026-04-08T19:25:21Z Swarabakti 18192 1349131 wikitext text/x-wiki {{rekonstruksi}} =={{bahasa|poz-pro}}== {{kepala|poz-pro}} : {{AFI|poz-pro|/laŋuj/}} {{-etimologi-}} : {{inh+|poz-pro|map-pro|*Naŋuy}}. {{doublet|poz-pro|*naŋuy}}. {{-verba-|poz-pro}} # {{label|poz-pro|intransitif}} {{l|id|renang}} {{-keturunan-}} * {{anak|kaw|laṅuy}} ** {{anak|jv|langi}} * {{anak|phi-pro|*laŋúy}} 7xtge0f43spteimd0ycgd2lr69ix46x Jawo 0 245287 1349062 1195754 2026-04-08T17:59:57Z Swarabakti 18192 1349062 wikitext text/x-wiki {{also|jawo}} == {{bahasa|jax}} == {{kepala|jax}} {{-n-|jax}} # {{label|jax|pulau}} [[Jawa]] # {{label|jax|sukubangsa}} [[Jawa]] # {{label|jax|bahasa}} [[Jawa]] =={{bahasa|min}}== {{kepala|min}} {{-ragam-}} * {{alter|min|Djawo}} {{q|ejaan Belanda}} {{-n-|min}} # {{label|min|pulau}} [[Jawa]] # {{label|min|sukubangsa}} [[Jawa]] # {{label|min|bahasa}} [[Jawa]] =={{bahasa|mui-plm}}== {{kepala|mui-plm}} : {{AFI|mui-plm|/ɟa.wɔ/}} {{suara|mui-plm|LL-Q12497929 (mis)-Swarabakti-Jawo.wav}} {{-etimologi-}} : {{bor+|mui-plm|jv|Jawa}}, dari {{der|mui-plm|kaw|Jawa}}. {{-n-|mui-plm}} # {{label|mui-plm|pulau}} [[Jawa]] # {{label|mui-plm|sukubangsa}} [[Jawa]] # {{label|mui-plm|bahasa}} [[Jawa]] [[Kategori:WikiTutur - Palembang]] [[Kategori:WikiTutur Palembang 18 Februari 2024]] =={{bahasa|rej}}== {{kepala|rej}} {{-n-|rej}} # {{label|rej|pulau}} [[Jawa]] # {{label|rej|sukubangsa}} [[Jawa]] # {{label|rej|bahasa}} [[Jawa]] 2fgg6ibo9vblxzfehtcv54ujk0axude sarinya 0 246429 1349139 1236680 2026-04-08T20:08:37Z Alfiyah Rizzy Afdiquni 40651 WikiRiksa 1349139 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan -nya|sari}} #* {{RQ:Mustikarasa |page=30 |text=Djeruk sitrun, rasanja asam, untuk diambil '''sarinja''' guna bumbu atau minuman |norm=Jeruk sitrun, rasanya asam, untuk diambil '''sarinya''' guna bumbu atau minuman |url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/38#:~:text=Djeruk%20sitrun%2C%20rasanja%20asam%2C%20untuk%20diambil%20sarinja%20guna%20bumbu%20atau%20minuman}} {{-turunan-|id}} {{-terjemahan-}} {{t-atas}} {{t-bawah}} jlfugamj1x8fcs09lzz3tj90zk97oai sebagainya 0 246519 1349040 1222358 2026-04-08T17:18:15Z Sofi Solihah 23681 1349040 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan se-|bagai|nya|kelas=p}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Aturan permainan disepakati lebih dahulu, misalnya pengambilan anak cit yang pertama kali maksimum 3 biji dan selanjutnya hanya sebiji dan '''sebagainya'''. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Aturan%20permainan%20disepakati%20lebih%20dahulu%2C%20misalnya%20pengambilan%20anak%20cit%20yang%20pertama%20kali%20maksimum%203%20biji%20dan%20selanjutnya%20hanya%20sebiji%20dan%20sebagainya. }} {{-terjemahan-}} {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 5vhoklf455fwci2bg8xuojk61l337rn diperlihatkan 0 247141 1349053 1320062 2026-04-08T17:33:02Z Sofi Solihah 23681 1349053 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{imbuhan diper-kan|lihat}} # {{rfdef|id}} #* {{RQ:Permainan Rakyat Daerah Kalimantan Selatan |page= 31 |text= Posisi anak cit menjadi seperti yang '''diperlihatkan''' dalam diagram V ini. |url= https://id.wikisource.org/wiki/Permainan_Rakyat_Daerah_Kalimantan_Selatan/Bacit#:~:text=Posisi%20anak%20cit%20menjadi%20seperti%20yang%20diperlihatkan%20dalam%20diagram%20V%20ini%C2%A0. }} {{-terjemahan-}} <!--Anda dapat menyalin templat {{t-atas}} -- {{t-bawah}} di bawah berulang kali untuk masing masing arti kata, masing-masing dibedakan melalui parameter pertamanya (misalkan {{t-atas|arti 1}} dan {{t-atas|arti 2}} dst). Lihat [[Wiktionary:Terjemahan]] untuk panduan membuat lebih dari satu kolom terjemahan--> {{t-atas}} {{t-bawah}} ht5ouujg82tgdw47rgkn1ew26e0ql3x Modul:affix/templates 828 247717 1349052 1061855 2026-04-08T17:32:46Z Swarabakti 18192 1349052 Scribunto text/plain local export = {} local m_affix = require("Module:affix") local m_utilities = require("Module:utilities") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local pseudo_loan_module = "Module:affix/pseudo-loan" local insert = table.insert local boolean_param = {type = "boolean"} local function is_property_key(k) return require(parameter_utilities_module).item_key_is_property(k) end local recognized_affix_types = { prefix = "prefix", pre = "prefix", suffix = "suffix", suf = "suffix", interfix = "interfix", inter = "interfix", infix = "infix", ["in"] = "infix", circumfix = "circumfix", circum = "circumfix", ["non-affix"] = "non-affix", naf = "non-affix", root = "non-affix", } local function pre_normalize_affix_type(data) local modtext = data.modtext modtext = modtext:match("^<(.*)>$") if not modtext then error(("Internal error: Passed-in modifier isn't surrounded by angle brackets: %s"):format(data.modtext)) end if recognized_affix_types[modtext] then modtext = "type:" .. modtext end return "<" .. modtext .. ">" end -- Parse raw arguments. A single parameter `data` is passed in, with the following fields: -- * `raw_args`: The raw arguments to parse, normally taken from `frame:getParent().args`. -- * `extra_params`: An optional function of one argument that is called on the `params` structure before parsing; its -- purpose is to specify additional allowed parameters or possibly disable parameters. -- * `has_source`: There is a source-language parameter following 1= (which becomes the "destination" language -- parameter) and preceding the terms. This is currently used for {{pseudo-loan}}. -- * `ilang`: If given, it is a language object that serves as the default for the language. If specified, there is no -- language code specified in 1=; instead the term parameters start directly at 1= (or at 2= if `has_source` is -- given). -- * `require_index_for_pos`: There is no separate |pos= parameter distinct from |pos1=, |pos2=, etc. Instead, -- specifying |pos= results in an error. -- * `dont_require_index`: Allow |foo= to be specified as a synonym for |foo1= (except for |lit=, which remains -- distinct). -- * `allow_type`: Allow |type1=, |type2=, etc. or inline <type:...> for the affix type, and allow a separate |type= -- parameter for the etymology type (FIXME: this may be confusing; consider changing the etymology type to |etype=). -- * `allow_semicolon_separator`: Allow semicolon as a separator, displaying as " or ". This requires changes in the -- display of the output, to not always put a + between the items. -- -- Note that all language parameters are allowed to be etymology-only languages. -- -- Return five values ARGS, ITEMS, LANG_OBJ, SCRIPT_OBJ, SOURCE_LANG_OBJ where ARGS is a table of the parsed arguments; -- ITEMS is the list of parsed items; LANG_OBJ is the language object corresponding to the language code specified in 1= -- (or taken from `ilang` if given); SCRIPT_OBJ is the script object corresponding to sc= (if given, otherwise nil); and -- SOURCE_LANG_OBJ is the language object corresponding to the source-language code specified in 2= (or 1= if `ilang` is -- given) if `has_source` is specified (otherwise nil). local function parse_args(data) local raw_args = data.raw_args local has_source = data.has_source local ilang = data.ilang if raw_args.lang then error("The |lang= parameter is not used by this template. Place the language code in parameter 1 instead.") end local term_index = (ilang and 1 or 2) + (has_source and 1 or 0) local params = { [term_index] = {list = true, allow_holes = true}, ["sort"] = {}, ["nocap"] = boolean_param, -- always allow this even if not used, for use with {{surf}}, which adds it } if not ilang then params[1] = {required = true, type = "language", default = "und"} end local source_index if has_source then source_index = term_index - 1 params[source_index] = {required = true, type = "language", default = "und"} end local m_param_utils = require(parameter_utilities_module) local param_mod_source = {} if not data.dont_require_index then insert(param_mod_source, -- We want to require an index for all params (or use separate_no_index, which also requires an index for the -- param corresponding to the first item). {default = true, require_index = true} ) end insert(param_mod_source, {group = {"link", "ref", "lang", "q", "l", "infl"}}) -- Override lit= to be separate from lit1=. insert(param_mod_source, {param = "lit", separate_no_index = true}) if not data.dont_require_index and not data.require_index_for_pos then -- Override pos= to be separate from pos1=. insert(param_mod_source, {param = "pos", separate_no_index = true}) end if data.allow_type then insert(param_mod_source, {param = "type", separate_no_index = true}) end local param_mods = m_param_utils.construct_param_mods(param_mod_source) if data.extra_params then data.extra_params(params) end local items, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = raw_args, termarg = term_index, parse_lang_prefix = true, track_module = "homophones", -- the inclusion of &lrm; is what [[Module:affix]] has always done default_separator = data.allow_semicolon_separator and " +&lrm; " or nil, special_separators = data.allow_semicolon_separator and {[";"] = " or "} or nil, disallow_custom_separators = not data.allow_semicolon_separator, -- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do -- {{suffix|lang||foo}} to generate "+ -foo". dont_skip_items = true, -- Allow e.g. <infix> to be specified in place of <type:infix>. pre_normalize_modifiers = pre_normalize_affix_type, -- Don't pass in `lang` or `sc`, as they will be used as defaults to initialize the items, which we don't want -- (particularly for `lang`), as the code in [[Module:affix]] uses the presence of `lang` as an indicator that -- a part-specific language was explicitly given. } local lang = ilang or args[1] local source if has_source then source = args[source_index] end -- For compatibility with the prior code, we need to convert items without term or properties to nil. for i = 1, #items do local item = items[i] local saw_item_property = item.term if not saw_item_property then for k, v in pairs(item) do if is_property_key(k) then saw_item_property = true break end end end if not saw_item_property then items[i] = nil elseif item.type then -- Validate and canonicalize affix types. if not recognized_affix_types[item.type] then local valid_types = {} for k in pairs(recognized_affix_types) do insert(valid_types, ("'%s'"):format(k)) end table.sort(recognized_affix_types) error(("Unrecognized affix type '%s' in item %s; valid values are %s"):format( item.type, item.itemno, table.concat(valid_types, ", "))) else item.type = recognized_affix_types[item.type] end end end if args.type and args.type.default and not m_affix.etymology_types[args.type.default] then error("Unrecognized etymology type: '" .. args.type.default .. "'") end return args, items, lang, args.sc.default, source end local function augment_affix_data(data, args, lang, sc) data.lang = lang data.sc = sc data.pos = args.pos and args.pos.default data.lit = args.lit and args.lit.default data.sort_key = args.sort data.type = args.type and args.type.default data.nocap = args.nocap data.notext = args.notext data.nocat = args.nocat data.force_cat = args.force_cat data.l = args.l.default data.ll = args.ll.default data.q = args.q.default data.qq = args.qq.default data.infl = args.infl.default return data end function export.affix(frame) local function extra_params(params) params.notext = boolean_param params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, allow_type = true, allow_semicolon_separator = true, } -- There must be at least one part to display. If there are gaps, a term -- request will be shown. if not next(parts) and not args.type.default then if mw.title.getCurrentTitle().nsText == "Template" then parts = { {term = "prefix-"}, {term = "base"}, {term = "-suffix"} } else error("You must provide at least one part.") end end return m_affix.show_affix(augment_affix_data({ parts = parts }, args, lang, sc)) end function export.compound(frame) local function extra_params(params) params.notext = boolean_param params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, allow_type = true, allow_semicolon_separator = true, } -- There must be at least one part to display. If there are gaps, a term -- request will be shown. if not next(parts) and not args.type.default then if mw.title.getCurrentTitle().nsText == "Template" then parts = { {term = "first"}, {separator = " +&lrm; ", term = "second"} } else error("You must provide at least one part of a compound.") end end return m_affix.show_compound(augment_affix_data({ parts = parts }, args, lang, sc)) end -- FIXME: Temporary for check in compound_like() below for old-style {{contraction}} parameters. Remove eventually. local function ine(arg) if arg == "" then return nil else return arg end end function export.compound_like(frame) local iparams = { ["lang"] = {type = "language"}, ["template"] = {}, ["text"] = {}, ["oftext"] = {}, ["cat"] = {}, ["noaffixcat"] = boolean_param, ["dont_require_index"] = boolean_param, } local iargs = require("Module:parameters").process(frame.args, iparams) local parent_args = frame:getParent().args -- Error to catch most uses of old-style parameters for {{contraction}}. (FIXME: Remove eventually.) local term_param = iargs.lang and 1 or 2 if ine(parent_args[term_param + 2]) and not ine(parent_args[term_param + 1]) and not ine(parent_args.tr2) and not ine(parent_args.ts2) and not ine(parent_args.t2) and not ine(parent_args.gloss2) and not ine(parent_args.g2) and not ine(parent_args.alt2) then error(("You specified a term in %s= and not one in %s=. You probably meant to use t= to specify a gloss instead. " .. "If you intended to specify two terms, put the second term in %s=."):format(term_param + 2, term_param + 1, term_param + 1)) end if not ine(parent_args[term_param + 1]) and not ine(parent_args.alt2) and not ine(parent_args.tr2) and not ine(parent_args.ts2) and ine(parent_args.g2) then error(("You specified a gender in g2= but no term in %s=. You were probably trying to specify two genders for " .. "a single term. To do that, put both genders in g=, comma-separated."):format(term_param + 1)) end local function extra_params(params) params.notext = boolean_param params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = parent_args, extra_params = extra_params, ilang = iargs.lang, dont_require_index = iargs.dont_require_index, -- FIXME, why are we doing this? Formerly we had 'params.pos = nil' whose intention was to disable the overall -- pos= while preserving posN=, which is equivalent to the following using the new syntax. But why is this -- necessary? require_index_for_pos = not iargs.dont_require_index, allow_semicolon_separator = true, } local template = iargs.template local nocat = args.nocat local notext = args.notext local text = not notext and iargs.text local oftext = not notext and (iargs.oftext or text and "of") local cat = not nocat and iargs.cat local noaffixcat = nocat or iargs.noaffixcat if not next(parts) then if mw.title.getCurrentTitle().nsText == "Template" then parts = { {term = "first"}, {separator = " +&lrm; ", term = "second"} } end end return m_affix.show_compound_like(augment_affix_data({ parts = parts, text = text, oftext = oftext, cat = cat, noaffixcat = noaffixcat }, args, lang, sc)) end function export.surface_analysis(frame) local function ine(arg) -- Since we're operating before calling [[Module:parameters]], we need to imitate how that module processes -- arguments, including trimming since numbered arguments don't have automatic whitespace trimming. if not arg then return arg end arg = mw.text.trim(arg) if arg == "" then arg = nil end return arg end local parent_args = frame:getParent().args local etymtext local arg1 = ine(parent_args[1]) if not arg1 then -- Allow omitted first argument to just display "By surface analysis". etymtext = "" elseif arg1:find("^%+") then -- If the first argument (normally a language code) is prefixed with a +, it's a template name. local template_name = arg1:sub(2) local new_args = {} for i, v in pairs(parent_args) do if type(i) == "number" then if i > 1 then new_args[i - 1] = v end else new_args[i] = v end end new_args.nocap = true etymtext = ", " .. frame:expandTemplate { title = template_name, args = new_args } end if etymtext then return (ine(parent_args.nocap) and "b" or "B") .. "y [[Appendix:Glossary#surface analysis|surface analysis]]" .. etymtext end local function extra_params(params) params.notext = boolean_param params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = parent_args, extra_params = extra_params, allow_type = true, allow_semicolon_separator = true, } -- There must be at least one part to display. If there are gaps, a term -- request will be shown. if not next(parts) then if mw.title.getCurrentTitle().nsText == "Template" then parts = { {term = "first"}, {separator = " +&lrm; ", term = "second"} } else error("You must provide at least one part.") end end return m_affix.show_surface_analysis(augment_affix_data({ parts = parts }, args, lang, sc)) end local function check_max_items(items, max_allowed) if #items > max_allowed then local bad_item = items[max_allowed + 1] if bad_item.term then error(("At most %s terms can be specified but saw a term specified for term #%s") :format(max_allowed, max_allowed + 1)) else for k, v in pairs(bad_item) do if is_property_key(k) then error(("At most %s terms can be specified but saw a value for property '%s' of term #%s") :format(max_allowed, k, max_allowed + 1)) end end end error(("Internal error: Something wrong, %s items generated when there should be at most %s, but item #%s doesn't have a term or any properties") :format(#items, max_allowed, max_allowed + 1)) end end function export.circumfix(frame) local function extra_params(params) params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, } check_max_items(parts, 3) local prefix = parts[1] local base = parts[2] local suffix = parts[3] -- Just to make sure someone didn't use the template in a silly way if not (prefix and base and suffix) then if mw.title.getCurrentTitle().nsText == "Templat" then prefix = {term = "circumfix", alt = "prefix"} base = {term = "base"} suffix = {term = "circumfix", alt = "suffix"} else error("You must specify a prefix part, a base term and a suffix part.") end end return m_affix.show_circumfix(augment_affix_data({ prefix = prefix, base = base, suffix = suffix }, args, lang, sc)) end function export.confix(frame) local function extra_params(params) params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, } check_max_items(parts, 3) local prefix = parts[1] local base = parts[3] and parts[2] or nil local suffix = parts[3] or parts[2] -- Just to make sure someone didn't use the template in a silly way if not (prefix and suffix) then if mw.title.getCurrentTitle().nsText == "Template" then prefix = {term = "prefix"} suffix = {term = "suffix"} else error("You must specify a prefix part, an optional base term and a suffix part.") end end return m_affix.show_confix(augment_affix_data({ prefix = prefix, base = base, suffix = suffix }, args, lang, sc)) end function export.pseudo_loan(frame) local function extra_params(params) params.notext = boolean_param params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc, source = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, has_source = true, -- FIXME, why are we doing this? Formerly we had 'params.pos = nil' whose intention was to disable the overall -- pos= while preserving posN=, which is equivalent to the following using the new syntax. But why is this -- necessary? require_index_for_pos = true, allow_semicolon_separator = true, } return require(pseudo_loan_module).show_pseudo_loan( augment_affix_data({ source = source, parts = parts }, args, lang, sc)) end function export.infix(frame) local function extra_params(params) params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, } check_max_items(parts, 3) local base = parts[1] local infix = parts[2] -- Just to make sure someone didn't use the template in a silly way if not (base and infix) then if mw.title.getCurrentTitle().nsText == "Template" then base = {term = "base"} infix = {term = "infix"} else error("You must provide a base term and an infix.") end end return m_affix.show_infix(augment_affix_data({ base = base, infix = infix }, args, lang, sc)) end function export.prefix(frame) local function extra_params(params) params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, } local prefixes = parts local base = nil local max_prefix = 0 for k, v in pairs(prefixes) do max_prefix = math.max(k, max_prefix) end if max_prefix >= 2 then base = prefixes[max_prefix] prefixes[max_prefix] = nil end -- Just to make sure someone didn't use the template in a silly way if not next(prefixes) then if mw.title.getCurrentTitle().nsText == "Template" then base = {term = "base"} prefixes = { {term = "prefix"} } else error("You must provide at least one prefix.") end end return m_affix.show_prefix(augment_affix_data({ prefixes = prefixes, base = base }, args, lang, sc)) end function export.suffix(frame) local function extra_params(params) params.nocat = boolean_param params.force_cat = boolean_param end local args, parts, lang, sc = parse_args { raw_args = frame:getParent().args, extra_params = extra_params, } local base = parts[1] local suffixes = {} for k, v in pairs(parts) do suffixes[k - 1] = v end -- Just to make sure someone didn't use the template in a silly way if not next(suffixes) then if mw.title.getCurrentTitle().nsText == "Template" then base = {term = "base"} suffixes = { {term = "suffix"} } else error("You must provide at least one suffix.") end end return m_affix.show_suffix(augment_affix_data({ base = base, suffixes = suffixes }, args, lang, sc)) end function export.derivsee(frame) local iargs = frame.args local iparams = { ["derivtype"] = {}, } local iargs = require("Module:parameters").process(frame.args, iparams) local params = { ["head"] = {}, ["id"] = {}, ["sc"] = {type = "script"}, ["pos"] = {}, } local derivtype = iargs.derivtype params[1] = {required = "true", type = "language", default = "und"} params[2] = {} local args = require("Module:parameters").process(frame:getParent().args, params) local lang = args[1] local term = args[2] or args.head local id = args.id local sc = args.sc local pos = require(en_utilities_module).pluralize(args.pos or "term") if not term then local SUBPAGE = mw.loadData("Module:headword/data").pagename if lang:hasType("reconstructed") or mw.title.getCurrentTitle().nsText == "Reconstruction" then term = "*" .. SUBPAGE elseif lang:hasType("appendix-constructed") then term = SUBPAGE else term = SUBPAGE end end local category = nil local langcode = lang:getFullCode() if (derivtype == "compound" and pos == nil) then category = langcode .. ":Gabungan kata dengan " .. term elseif derivtype == "compound" and pos == "verbs" then category = langcode .. ":Gabungan kata " .. pos .. " yang dibentuk dengan " .. term elseif derivtype == "compound" then category = langcode .. ":Gabungan kata " .. pos .. " dengan " .. term else category = langcode .. ":Gabungan kata " .. derivtype .. " " .. pos .. " dengan " .. term .. (id and " (" .. id .. ")" or "") end return require('Module:collapsible category tree').make{ lang = lang, sc = sc, category = category, } end return export isv7pfrvzs0yhbggk4lxahe4n7cl4nx Modul:affix 828 247718 1349056 1109014 2026-04-08T17:41:24Z Swarabakti 18192 1349056 Scribunto text/plain local export = {} local debug_force_cat = false -- if set to true, always display categories even on userspace pages local m_links = require("Module:links") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local utilities_module = "Module:utilities" -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.affix_lang_data_module_prefix = "Module:affix/lang-data/" local rsub = m_str_utils.gsub local usub = m_str_utils.sub local ulen = m_str_utils.len local rfind = m_str_utils.find local rmatch = m_str_utils.match local pluralize = require(en_utilities_module).pluralize local u = m_str_utils.char local ucfirst = m_str_utils.ucfirst local unpack = unpack or table.unpack -- Lua 5.2 compatibility function export.affix_variants(canonical, variants) local mappings = {} for _, variant in ipairs(variants) do mappings[variant] = canonical end return mappings end function export.id_mapping(default, ids) local mapping = { default = default } if ids then for id, target in pairs(ids) do mapping[id] = target end end return mapping end function export.id_mapping_with_affix_variants(base, id_variants) local mappings = {} for id, variants in pairs(id_variants) do for _, variant in ipairs(variants) do mappings[variant] = export.id_mapping(base, {[id] = base}) end end return mappings end function export.merge_tables(...) local result = {} for i = 1, select('#', ...) do local t = select(i, ...) if t then for k, v in pairs(t) do result[k] = v end end end return result end -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.langs_with_lang_specific_data = { ["az"] = true, ["fi"] = true, ["fr"] = true, ["izh"] = true, ["la"] = true, ["sah"] = true, ["tr"] = true, } local default_pos = "term" --[==[ intro: ===About different types of hyphens ("template", "display" and "lookup"):=== * The "template hyphen" is the per-script hyphen character that is used in template calls to indicate that a term is an affix. This is always a single Unicode char, but there may be multiple possible hyphens for a given script. Normally this is just the regular hyphen character "-", but for some non-Latin-script languages (currently only right-to-left languages), it is different. * The "display hyphen" is the string (which might be an empty string) that is added onto a term as displayed and linked, to indicate that a term is an affix. Currently this is always either the same as the template hyphen or an empty string, but the code below is written generally enough to handle arbitrary display hyphens. Specifically: *# For East Asian languages, the display hyphen is always blank. *# For Arabic-script languages, either tatweel (ـ) or ZWNJ (zero-width non-joiner) are allowed as template hyphens, where ZWNJ is supported primarily for Farsi, because some suffixes have non-joining behavior. The display hyphen corresponding to tatweel is also tatweel, but the display hyphen corresponding to ZWNJ is blank (tatweel is also the default display hyphen, for calls to {{tl|prefix}}/{{tl|suffix}}/etc. that don't include an explicit hyphen). * The "lookup hyphen" is the hyphen that is used when looking up language-specific affix mappings. (These mappings are discussed in more detail below when discussing link affixes.) It depends only on the script of the affix in question. Most scripts (including East Asian scripts) use a regular hyphen "-" as the lookup hyphen, but Hebrew and Arabic have their own lookup hyphens (respectively maqqef and tatweel). Note that for Arabic in particular, there are three possible template hyphens that are recognized (tatweel, ZWNJ and regular hyphen), but mappings must use tatweel. ===About different types of affixes ("template", "display", "link", "lookup" and "category"):=== * A "template affix" is an affix in its source form as it appears in a template call. Generally, a template affix has an attached template hyphen (see above) to indicate that it is an affix and indicate what type of affix it is (prefix, suffix, interfix or circumfix), but some of the older-style templates such as {{tl|suffix}}, {{tl|prefix}}, {{tl|confix}}, etc. have "positional" affixes where the presence of the affix in a certain position (e.g. the second or third parameter) indicates that it is a certain type of affix, whether or not it has an attached template hyphen. * A "display affix" is the corresponding affix as it is actually displayed to the user. The display affix may differ from the template affix for various reasons: *# The display affix may be specified explicitly using the {{para|alt<var>N</var>}} parameter, the `<alt:...>` inline modifier or a piped link of the form e.g. `<nowiki>[[-kas|-käs]]</nowiki>` (here indicating that the affix should display as `-käs` but be linked as `-kas`). Here, the template affix is arguably the entire piped link, while the display affix is `-käs`. *# Even in the absence of {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers and piped links, certain languages have differences between the "template hyphen" specified in the template (which always needs to be specified somehow or other in templates like {{tl|affix}}, to indicate that the term is an affix and what type of affix it is) and the display hyphen (see above), with corresponding differences between template and display affixes. * A (regular) "link affix" is the affix that is linked to when the affix is shown to the user. The link affix is usually the same as the display affix, but will differ in one of three circumstances: *# The display and link affixes are explicitly made different using {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers or piped links, as described above under "display affix". *# For certain languages, certain affixes are mapped to canonical form using language-specific mappings. For example, in Finnish, the adjective-forming suffix {{m|fi|-kas}} appears as {{m|fi|-käs}} after front vowels, but logically both forms are the same suffix and should be linked and categorized the same. Similarly, in Latin, the negative and intensive prefixes spelled {{m|la|in-}} (etymologically two distinct prefixes) appear variously as {{m|la|il-}}, {{m|la|im-}} or {{m|la|ir-}} before certain consonants. Mappings are supplied in [[Module:affix/lang-data/LANGCODE]] to convert Finnish {{m|fi|-käs}} to {{m|fi|-kas}} for linking and categorization purposes. Note that the affixes in the mappings use "lookup hyphens" to indicate the different types of affixes, which is usually the same as the template hyphen but differs for Arabic scripts, because there are multiple possible template hyphens recognized but only one lookup hyphen (tatweel). The form of the affix as used to look up in the mapping tables is called the "lookup affix"; see below. * A "stripped link affix" is a link affix that has been passed through the language's `stripDiacritics()` function, which may strip certain diacritics: e.g. macrons in Latin and Old English (indicating length); acute and grave accents in Russian and various other Slavic languages (indicating stress); vowel diacritics in most Arabic-script languages; and also tatweel in some Arabic-script languages (currently, for example, Persian, Arabic and Urdu strip tatweel, but Ottoman Turkish does not). Stripped link affixes are currently what are used in category names. * A "lookup affix" is the form of the affix as it is looked up in the language-specific lookup mappings described above under link affixes. There are actually two lookup stages: *# First, the affix is looked up in a modified display form (specifically, the same as the display affix but using lookup hyphens). Note that this lookup does not occur if an explicit display form is given using {{para|alt<var>N</var>}} or an `<alt:...>` inline modifier, or if the template affix contains a piped or embedded link. *# If no entry is found, the affix is then looked up in a modified link form (specifically, the modified display form passed through the language's `stripDiacritics()` function, which strips out certain diacritics, but with the lookup hyphen re-added if it was stripped out, as in the case of tatweel in many Arabic-script languages). The reason for this double lookup procedure is to allow for mappings that are sensitive to the extra diacritics, but also allow for mappings that are not sensitive in this fashion (e.g. Russian {{m|ru|-ливый}} occurs both stressed and unstressed, but is the same prefix either way). * A "category affix" is the affix as it appears in categories such as [[:Category:Finnish terms suffixed with -kas| Category:Finnish terms suffixed with ''-kas'']]. The category affix is currently always the same as the stripped link affix. This means that for Arabic-script languages, it may or may not have a tatweel, even if the correponding display affix and regular link affix have a tatweel. As mentioned above, stripDiacritics() strips tatweel for Arabic, Persian and Urdu, but not for Ottoman Turkish. Hence affix categories for Arabic, Persian and Urdu will be missing the tatweel, but affix categories for Ottoman Turkish will have it. An additional complication is that if the template affix contains a ZWNJ, the display (and hence the link and category affixes) will have no hyphen attached in any case. ]==] ----------------------------------------------------------------------------------------- -- Template and display hyphens -- ----------------------------------------------------------------------------------------- --[=[ Per-script template hyphens. The template hyphen is what appears in the {{affix}}/{{prefix}}/{{suffix}}/etc. template (in the wikicode). See above. They key below is a script code, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' will match 'Arab'. The value below is a string consisting of one or more hyphen characters. If there is more than one character, the default hyphen must come last and a non-default function must be specified for the script in display_hyphens[] so the correct display hyphen will be specified when no template hyphen is given (in {{suffix}}/{{prefix}}/etc.). Script detection is normally done when linking, but we need to do it earlier. However, under most circumstances we don't need to do script detection. Specifically, we only need to do script detection for a given language if (a) the language has multiple scripts; and (b) at least one of those scripts is listed below or in display_hyphens. ]=] local ZWNJ = u(0x200C) -- zero-width non-joiner local template_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = "ـ" .. ZWNJ .. "-", -- tatweel + zero-width non-joiner + regular hyphen ["Hebr"] = "־", -- Hebrew-specific hyphen termed "maqqef" ["Mong"] = "᠊", -- FIXME! What about the following right-to-left scripts? -- Adlm (Adlam) -- Armi (Imperial Aramaic) -- Avst (Avestan) -- Cprt (Cypriot) -- Khar (Kharoshthi) -- Mand (Mandaic/Mandaean) -- Mani (Manichaean) -- Mend (Mende/Mende Kikakui) -- Narb (Old North Arabian) -- Nbat (Nabataean/Nabatean) -- Nkoo (N'Ko) -- Orkh (Orkhon runes) -- Phli (Inscriptional Pahlavi) -- Phlp (Psalter Pahlavi) -- Phlv (Book Pahlavi) -- Phnx (Phoenician) -- Prti (Inscriptional Parthian) -- Rohg (Hanifi Rohingya) -- Samr (Samaritan) -- Sarb (Old South Arabian) -- Sogd (Sogdian) -- Sogo (Old Sogdian) -- Syrc (Syriac) -- Thaa (Thaana) } -- Hyphens used when looking up an affix in a lang-specific affix mapping. Defaults to regular hyphen (-). The keys -- are script codes, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' -- will match 'Arab'. The value should be a single character. local lookup_hyphens = { ["Hebr"] = "־", -- This covers all Arabic scripts. See above. ["Arab"] = "ـ", } -- Default display-hyphen function. local function default_display_hyphen(script, hyph) if not hyph then return template_hyphens[script] or "-" end return hyph end local function arab_get_display_hyphen(script, hyph) if not hyph then return "ـ" -- tatweel elseif hyph == ZWNJ then return "" else return hyph end end local function no_display_hyphen(script, hyph) return "" end -- Per-script function to return the correct display hyphen given the script and template hyphen. The function should -- also handle the case where the passed-in template hyphen is nil, corresponding to the situation in -- {{prefix}}/{{suffix}}/etc. where no template hyphen is specified. The key is the script code after removing a hyphen -- and anything preceding, so 'fa-Arab', 'ur-Arab' etc. will match 'Arab'. local display_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = arab_get_display_hyphen, ["Bopo"] = no_display_hyphen, ["Hani"] = no_display_hyphen, ["Hans"] = no_display_hyphen, ["Hant"] = no_display_hyphen, -- The following is a mixture of several scripts. Hopefully the specs here are correct! ["Jpan"] = no_display_hyphen, ["Jurc"] = no_display_hyphen, ["Kitl"] = no_display_hyphen, ["Kits"] = no_display_hyphen, ["Laoo"] = no_display_hyphen, ["Nshu"] = no_display_hyphen, ["Shui"] = no_display_hyphen, ["Tang"] = no_display_hyphen, ["Thaa"] = no_display_hyphen, ["Thai"] = no_display_hyphen, } ----------------------------------------------------------------------------------------- -- Basic Utility functions -- ----------------------------------------------------------------------------------------- local function glossary_link(entry, text) text = text or entry return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]" end local function track(page) if type(page) == "table" then for i, pg in ipairs(page) do page[i] = "affix/" .. pg end else page = "affix/" .. page end require("Module:debug/track")(page) end local function ine(val) return val ~= "" and val or nil end ----------------------------------------------------------------------------------------- -- Compound types -- ----------------------------------------------------------------------------------------- local function make_compound_type(typ, alttext) return { text = glossary_link(typ, alttext) .. " compound", cat = typ .. " compounds", } end -- Make a compound type entry with a simple rather than glossary link. -- These should be replaced with a glossary link when the entry in the glossary -- is created. local function make_non_glossary_compound_type(typ, alttext) local link = alttext and "[[" .. typ .. "|" .. alttext .. "]]" or "[[" .. typ .. "]]" return { text = link .. " compound", cat = typ .. " compounds", } end local function make_raw_compound_type(typ, alttext) return { text = glossary_link(typ, alttext), cat = pluralize(typ), } end local function make_borrowing_type(typ, alttext) return { text = glossary_link(typ, alttext), borrowing_type = pluralize(typ), } end export.etymology_types = { ["adapted borrowing"] = make_borrowing_type("adapted borrowing"), ["adap"] = "adapted borrowing", ["abor"] = "adapted borrowing", ["alliterative"] = make_non_glossary_compound_type("alliterative"), ["allit"] = "alliterative", ["antonymous"] = make_non_glossary_compound_type("antonymous"), ["ant"] = "antonymous", ["bahuvrihi"] = make_compound_type("bahuvrihi", "bahuvrīhi"), ["bahu"] = "bahuvrihi", ["bv"] = "bahuvrihi", ["coordinative"] = make_compound_type("coordinative"), ["coord"] = "coordinative", ["descriptive"] = make_compound_type("descriptive"), ["desc"] = "descriptive", ["determinative"] = make_compound_type("determinative"), ["det"] = "determinative", ["dvandva"] = make_compound_type("dvandva"), ["dva"] = "dvandva", ["dvigu"] = make_compound_type("dvigu"), ["dvi"] = "dvigu", ["endocentric"] = make_compound_type("endocentric"), ["endo"] = "endocentric", ["exocentric"] = make_compound_type("exocentric"), ["exo"] = "exocentric", ["izafet I"] = make_compound_type("izafet I"), ["iz1"] = "izafet I", ["izafet II"] = make_compound_type("izafet II"), ["iz2"] = "izafet II", ["izafet III"] = make_compound_type("izafet III"), ["iz3"] = "izafet III", ["karmadharaya"] = make_compound_type("karmadharaya", "karmadhāraya"), ["karma"] = "karmadharaya", ["kd"] = "karmadharaya", ["kenning"] = make_raw_compound_type("kenning"), ["ken"] = "kenning", ["rhyming"] = make_non_glossary_compound_type("rhyming"), ["rhy"] = "rhyming", ["synonymous"] = make_non_glossary_compound_type("synonymous"), ["syn"] = "synonymous", ["tatpurusa"] = make_compound_type("tatpurusa", "tatpuruṣa"), ["tat"] = "tatpurusa", ["tp"] = "tatpurusa", } local function process_etymology_type(typ, nocap, notext, has_parts) local text_sections = {} local categories = {} local borrowing_type if typ then local typdata = export.etymology_types[typ] if type(typdata) == "string" then typdata = export.etymology_types[typdata] end if not typdata then error("Internal error: Unrecognized type '" .. typ .. "'") end local text = typdata.text if not nocap then text = ucfirst(text) end local cat = typdata.cat borrowing_type = typdata.borrowing_type local oftext = typdata.oftext or " of" if not notext then table.insert(text_sections, text) if has_parts then table.insert(text_sections, oftext) table.insert(text_sections, " ") end end if cat then table.insert(categories, cat) end end return text_sections, categories, borrowing_type end ----------------------------------------------------------------------------------------- -- Utility functions -- ----------------------------------------------------------------------------------------- -- Iterate an array up to the greatest integer index found. local function ipairs_with_gaps(t) local indices = m_table.numKeys(t) local max_index = #indices > 0 and math.max(unpack(indices)) or 0 local i = 0 return function() while i < max_index do i = i + 1 return i, t[i] end end end export.ipairs_with_gaps = ipairs_with_gaps --[==[ Join formatted parts (in `parts_formatted`) together with any overall {{para|lit}} spec (in `lit`) plus categories, which are formatted by prepending the language name as found in `lang`. The value of an entry in `categories` can be either a string (which is formatted using `sort_key`) or a table of the form `{ {cat=<var>category</var>, sort_key=<var>sort_key</var>, sort_base=<var>sort_base</var>}`, specifying the sort key and sort base to use when formatting the category. If `nocat` is given, no categories are added; otherwise, `force_cat` causes categories to be added even on userspace pages. ]==] function export.join_formatted_parts(data) local cattext local lang = data.data.lang local force_cat = data.data.force_cat or debug_force_cat if data.data.nocat then cattext = "" else for i, cat in ipairs(data.categories) do if type(cat) == "table" then data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat.cat, lang, cat.sort_key, cat.sort_base, force_cat) else data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat, lang, data.data.sort_key, nil, force_cat) end end cattext = table.concat(data.categories) end local result = table.concat(data.parts_formatted, not data.separator_already_added and " +&lrm; " or nil) .. (data.data.lit and ", literally " .. m_links.mark(data.data.lit, "gloss") or "") local q = data.data.q local qq = data.data.qq local l = data.data.l local ll = data.data.ll if q and q[1] or qq and qq[1] or l and l[1] or ll and ll[1] then result = require(pron_qualifier_module).format_qualifiers { lang = lang, text = result, q = q, qq = qq, l = l, ll = ll, } end return result .. cattext end local function pluralize(pos) if pos ~= "nouns" and usub(pos, -5) ~= "verbs" and usub(pos, -4) ~= "ives" then if pos:find("[sx]$") then pos = pos .. "es" else pos = pos .. "s" end end return pos end -- Remove links and call lang:stripDiacritics(term). local function strip_diacritics_no_links(lang, term) return lang:stripDiacritics(m_links.remove_links(term)) end --[=[ Convert a raw part as passed into an entry point into a part ready for linking. `lang` and `sc` are the overall language and script objects. This uses the overall language and script objects as defaults for the part and parses off any fragment from the term. We need to do the latter so that fragments don't end up in categories and so that we correctly do affix mapping even in the presence of fragments. ]=] local function canonicalize_part(part, lang, sc) if not part then return end -- Save the original (user-specified, part-specific) value of `lang`. If such a value is specified, we don't insert -- a '*fixed with' category, and we format the part using format_derived() in [[Module:etymology]] rather than -- full_link() in [[Module:links]]. part.part_lang = part.lang part.lang = part.lang or lang part.sc = part.sc or sc local term = part.term if not term then return elseif not part.fragment then part.term, part.fragment = m_links.get_fragment(term) else part.term = m_links.get_fragment(term) end end --[==[ Construct a single linked part based on the information in `part`, for use by `show_affix()` and other entry points. This should be called after `canonicalize_part()` is called on the part. This is a thin wrapper around `full_link()` in [[Module:links]] unless `part.part_lang` is specified (indicating that a part-specific language was given), in which case `format_derived()` in [[Module:etymology]] is called to display a term in a language other than the language of the overall term (specified in `data.lang`). `data` contains the entire object passed into the entry point and is used to access information for constructing the categories added by `format_derived()`. ]==] function export.link_term(part, data, include_separator) local result if part.part_lang then result = require(etymology_module).format_derived { lang = data.lang, terms = {part}, sources = {part.lang}, sort_key = data.sort_key, nocat = data.nocat, template_name = "affix", qualifiers_labels_on_outside = true, borrowing_type = data.borrowing_type, force_cat = data.force_cat or debug_force_cat, } else result = m_links.full_link(part, "term", nil, "show qualifiers") end if include_separator and part.separator then return part.separator .. result else return result end end local function canonicalize_script_code(scode) -- Convert fa-Arab, ur-Arab etc. to Arab. return (scode:gsub("^.*%-", "")) end ----------------------------------------------------------------------------------------- -- Affix-handling functions -- ----------------------------------------------------------------------------------------- -- Figure out the appropriate script for the given affix and language (unless the script is explicitly passed in), and -- return the values of template_hyphens[], display_hyphens[] and lookup_hyphens[] for that script, substituting -- default values as appropriate. Four values are returned: -- DETECTED_SCRIPT, TEMPLATE_HYPHEN, DISPLAY_HYPHEN, LOOKUP_HYPHEN local function detect_script_and_hyphens(text, lang, sc) local scode -- 1. If the script is explicitly passed in, use it. if sc then scode = sc:getCode() else local possible_script_codes = lang:getScriptCodes() -- YUCK! `possible_script_codes` comes from loadData() so #possible_scripts doesn't work (always returns 0). local num_possible_script_codes = m_table.length(possible_script_codes) if num_possible_script_codes == 0 then -- This shouldn't happen; if the language has no script codes, -- the list {"None"} should be returned. error("Something is majorly wrong! Language " .. lang:getCanonicalName() .. " has no script codes.") end if num_possible_script_codes == 1 then -- 2. If the language has only one possible script, use it. scode = possible_script_codes[1] else -- 3. Check if any of the possible scripts for the language have non-default values for template_hyphens[] -- or display_hyphens[]. If so, we need to do script detection on the text. If not, just use "Latn", -- which may not be technically correct but produces the right results because Latn has all default -- values for template_hyphens[] and display_hyphens[]. local may_have_nondefault_hyphen = false for _, script_code in ipairs(possible_script_codes) do script_code = canonicalize_script_code(script_code) if template_hyphens[script_code] or display_hyphens[script_code] then may_have_nondefault_hyphen = true break end end if not may_have_nondefault_hyphen then scode = "Latn" else scode = lang:findBestScript(text):getCode() end end end scode = canonicalize_script_code(scode) local template_hyphen = template_hyphens[scode] or "-" local lookup_hyphen = lookup_hyphens[scode] or "-" local display_hyphen = display_hyphens[scode] or default_display_hyphen return scode, template_hyphen, display_hyphen, lookup_hyphen end --[=[ Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function reconstruct_term_per_hyphens(term, affix_type, scode, thyph_re, new_hyphen) local function get_hyphen(hyph) if type(new_hyphen) == "string" then return new_hyphen end return new_hyphen(scode, hyph) end if affix_type == "non-affix" then return term elseif affix_type == "circumfix" then local before, before_hyphen, after_hyphen, after = rmatch(term, "^(.*)" .. thyph_re .. " " .. thyph_re .. "(.*)$") if not before or ulen(term) <= 3 then -- Unlike with other types of affixes, don't try to add hyphens in the middle of the term to convert it to -- a circumfix. Also, if the term is just hyphen + space + hyphen, return it. return term end return before .. get_hyphen(before_hyphen) .. " " .. get_hyphen(after_hyphen) .. after elseif affix_type == "infix" or affix_type == "interfix" then local before_hyphen, middle, after_hyphen = rmatch(term, "^" .. thyph_re .. "(.*)" .. thyph_re .. "$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "prefix" then local middle, after_hyphen = rmatch(term, "^(.*)" .. thyph_re .. "$") if middle and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "suffix" then local before_hyphen, middle = rmatch(term, "^" .. thyph_re .. "(.*)$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) else error(("Internal error: Unrecognized affix type '%s'"):format(affix_type)) end end --[=[ Look up a mapping from a given affix variant to the canonical form used in categories and links. The lookup tables are language-specific according to `lang`, and may be ID-specific according to `affix_id`. The affixes as they appear in the lookup tables (both the variant and the canonical form) are in "lookup affix" format (approximately speaking, they use a regular hyphen for most scripts, but a tatweel for Arabic-script entries and a maqqef for Hebrew-script entries), but the passed-in `affix` param is in "template affix" format (which differs from the lookup affix for Arabic-script entries, because more types of hyphens are allowed in template affixes; see the comments at the top of the file). The remaining parameters to this function are used to convert from template affixes to lookup affixes; see the reconstruct_term_per_hyphens() function above. If the affix contains brackets, no lookup is done. Otherwise, a two-stage process is used, first looking up the affix directly and then stripping diacritics and looking it up again. The reason for this is documented above in the comments at the top of the file (specifically, the comments describing lookup affixes). The value of a mapping can either be a string (do the mapping regardless of affix ID) or a table indexed by affix ID (where the special value `false` indicates no affix ID). The values of entries in this table can also be strings, or tables with keys `affix` and `id` (again, use `false` to indicate no ID). This allows an affix mapping to map from one ID to another (for example, this is used in English to map the [[an-]] prefix with no ID to the [[a-]] prefix with the ID 'not'). The Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function lookup_affix_mapping(affix, affix_type, lang, scode, thyph_re, lookup_hyph, affix_id) local function do_lookup(affix) -- Ensure that the affix uses lookup hyphens regardless of whether it used a different type of hyphens before -- or no hyphens. local lookup_affix = reconstruct_term_per_hyphens(affix, affix_type, scode, thyph_re, lookup_hyph) local function do_lookup_for_langcode(langcode) if export.langs_with_lang_specific_data[langcode] then local langdata = mw.loadData(export.affix_lang_data_module_prefix .. langcode) if langdata.affix_mappings then local mapping = langdata.affix_mappings[lookup_affix] if mapping then if type(mapping) == "table" then mapping = mapping[affix_id] or mapping.default or mapping[affix_id or false] if mapping then return mapping end else return mapping end end end end end -- If `lang` is an etymology-only language, look for a mapping both for it and its full parent. local langcode = lang:getCode() local mapping = do_lookup_for_langcode(langcode) if mapping then return mapping end local full_langcode = lang:getFullCode() if full_langcode ~= langcode then mapping = do_lookup_for_langcode(full_langcode) if mapping then return mapping end end return nil end if affix:find("%[%[") then return nil end return do_lookup(affix) or do_lookup(lang:stripDiacritics(affix)) or nil end --[==[ For a given template term in a given language (see the definition of "template affix" near the top of the file), possibly in an explicitly specified script `sc` (but usually nil), return the term's affix type ({"prefix"}, {"interfix"}, {"suffix"}, {"circumfix"} or {"non-affix"}) along with the corresponding link and display affixes (see definitions near the top of the file); also the corresponding lookup affix (if `return_lookup_affix` is specified). The term passed in should already have any fragment (after the # sign) parsed off of it. Four values are returned: `affix_type`, `link_term`, `display_term` and `lookup_term`. The affix type can be passed in instead of autodetected; in this case, the template term need not have any attached hyphens, and the appropriate hyphens will be added in the appropriate places. If `do_affix_mapping` is specified, look up the affix in the lang-specific affix mappings, as described in the comment at the top of the file; otherwise, the link and display terms will always be the same. (They will be the same in any case if the template term has a bracketed link in it or is not an affix.) If `return_lookup_affix` is given, the fourth return value contains the term with appropriate lookup hyphens in the appropriate places; otherwise, it is the same as the display term. (This functionality is used in [[Module:category tree/affixes and compounds]] to convert link affixes into lookup affixes so that they can be looked up in the affix mapping tables.) ]==] local function parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not term then return "non-affix", nil, nil, nil end if term == "^" then -- Indicates a null term to emulate the behavior of {{suffix|foo||bar}}. term = "" return "non-affix", term, term, term end if term:find("^%^") then -- HACK! ^ at the beginning of Korean languages has a special meaning, triggering capitalization of the -- transliteration. Don't interpret it as "force non-affix" for those languages. local langcode = lang:getCode() if langcode ~= "ko" and langcode ~= "okm" and langcode ~= "jje" then -- Formerly we allowed ^ to force non-affix type; this is now handled using an inline modifier -- <naf>, <root>, etc. Throw an error for the moment when the old way is encountered. error("Use of ^ to force non-affix status is no longer supported; use an inline modifier <naf> or <root> " .. "after the component") end end -- Remove an asterisk if the morpheme is reconstructed and add it back at the end. local reconstructed = "" if term:find("^%*") then reconstructed = "*" term = term:gsub("^%*", "") end local scode, thyph, dhyph, lhyph = detect_script_and_hyphens(term, lang, sc) thyph = "([" .. thyph .. "])" if not affix_type then if rfind(term, thyph .. " " .. thyph) then affix_type = "circumfix" else local has_beginning_hyphen = rfind(term, "^" .. thyph) local has_ending_hyphen = rfind(term, thyph .. "$") if has_beginning_hyphen and has_ending_hyphen then affix_type = "interfix" elseif has_ending_hyphen then affix_type = "prefix" elseif has_beginning_hyphen then affix_type = "suffix" else affix_type = "non-affix" end end end local link_term, display_term, lookup_term if affix_type == "non-affix" then link_term = term display_term = term lookup_term = term else display_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, dhyph) if do_affix_mapping then link_term = lookup_affix_mapping(term, affix_type, lang, scode, thyph, lhyph, affix_id) -- The return value of lookup_affix_mapping() may be an affix mapping with lookup hyphens if a mapping -- was found, otherwise nil if a mapping was not found. We need to convert to display hyphens in -- either case, but in the latter case we can reuse the display term, which has already been converted. if link_term then link_term = reconstruct_term_per_hyphens(link_term, affix_type, scode, thyph, dhyph) else link_term = display_term end else link_term = display_term end if return_lookup_affix then lookup_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, lhyph) else lookup_term = display_term end end link_term = reconstructed .. link_term display_term = reconstructed .. display_term lookup_term = reconstructed .. lookup_term return affix_type, link_term, display_term, lookup_term end --[==[ Add a hyphen to a term in the appropriate place, based on the specified affix type, stripping off any existing hyphens in that place. For example, if `affix_type` == {"prefix"}, we'll add a hyphen onto the end if it's not already there (or is of the wrong type). Three values are returned: the link term, display term and lookup term. This function is a thin wrapper around `parse_term_for_affixes`; see the comments above that function for more information. Note that this function is exposed externally because it is called by [[Module:category tree/affixes and compounds]]; see the comment in `parse_term_for_affixes` for more information. ]==] function export.make_affix(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not (affix_type == "prefix" or affix_type == "suffix" or affix_type == "circumfix" or affix_type == "infix" or affix_type == "interfix" or affix_type == "non-affix") then error("Internal error: Invalid affix type " .. (affix_type or "(nil)")) end local _, link_term, display_term, lookup_term = parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) return link_term, display_term, lookup_term end ----------------------------------------------------------------------------------------- -- Main entry points -- ----------------------------------------------------------------------------------------- --[==[ Core categorization logic for affixes. This is shared between show_affix(), show_compound_like() and get_affix_categories_only(). Returns the categories array and other metadata needed for formatting. ]==] local function generate_affix_categories(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.surface_analysis or data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type -- Process each part local whole_words = 0 local is_affix_or_compound = false -- Canonicalize and generate links for all the parts first; then do categorization in a separate step, because when -- processing the first part for categorization, we may access the second part and need it already canonicalized. for i, part in ipairs_with_gaps(data.parts) do part = part or {} data.parts[i] = part canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). Store them in the part -- (in fields that won't clash with fields used by full_link() in [[Module:links]] or link_term()), so they -- can be used in the loop below when categorizing. part.affix_type, part.affix_link_term, part.affix_display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with inline -- modifiers. The intention in either case is not to link the term. part.term = ine(part.affix_link_term) -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt or (part.affix_display_term ~= part.affix_link_term and part.affix_display_term) or nil end -- Now do categorization. for i, part in ipairs_with_gaps(data.parts) do local affix_type = part.affix_type if affix_type ~= "non-affix" then is_affix_or_compound = true -- Make a sort key. For the first part, use the second part as the sort key; the intention is that if the -- term has a prefix, sorting by the prefix won't be very useful so we sort by what follows, which is -- presumably the root. local part_sort_base = nil local part_sort = part.sort or data.sort_key if i == 1 and data.parts[2] and data.parts[2].term then local part2 = data.parts[2] -- If the second-part link term is empty, the user requested an unlinked term; avoid a wikitext error -- by using the alt value if available. part_sort_base = ine(part2.affix_link_term) or ine(part2.alt) if part_sort_base then part_sort_base = strip_diacritics_no_links(part2.lang, part_sort_base) end end if part.pos and rfind(part.pos, "patronym") then table.insert(categories, {cat = "patronymics", sort_key = part_sort, sort_base = part_sort_base}) end if data.pos ~= "terms" and part.pos and rfind(part.pos, "diminutive") then table.insert(categories, {cat = "diminutive " .. data.pos, sort_key = part_sort, sort_base = part_sort_base}) end -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if ine(part.affix_link_term) and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.affix_link_term) .. (part.id and " (" .. part.id .. ")" or ""), sort_key = part_sort, sort_base = part_sort_base}) end else whole_words = whole_words + 1 if whole_words == 2 then is_affix_or_compound = true table.insert(categories, "Gabungan kata " .. data.pos) end end end -- Make sure there was either an affix or a compound (two or more non-affix terms). if not is_affix_or_compound and not data.allow_no_affixes_or_compounds then error("The parameters did not include any affixes, and the term is not a compound. Please provide at least one affix.") end return text_sections, categories, borrowing_type end --[==[ Implementation of {{tl|affix}} and {{tl|surface analysis}}. `data` contains all the information describing the affixes to be displayed, and contains the following: * `.lang` ('''required'''): Overall language object. Different from term-specific language objects (see `.parts` below). * `.sc`: Overall script object (usually omitted). Different from term-specific script objects. * `.parts` ('''required'''): List of objects describing the affixes to show. The general format of each object is as would be passed to `full_link()`, except that the `.lang` field should be missing unless the term is of a language different from the overall `.lang` value (in such a case, the language name is shown along with the term and an additional "derived from" category is added). '''WARNING''': The data in `.parts` will be destructively modified. * `.pos`: Overall part of speech (used in categories, defaults to {"terms"}). Different from term-specific part of speech. * `.sort_key`: Overall sort key. Normally omitted except e.g. in Japanese. * `.type`: Type of compound, if the parts in `.parts` describe a compound. Strictly optional, and if supplied, the compound type is displayed before the parts (normally capitalized, unless `.nocap` is given). * `.nocap`: Don't capitalize the first letter of text displayed before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.notext`: Don't display any text before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.nocat`: Disable all categorization. * `.lit`: Overall literal definition. Different from term-specific literal definitions. * `.force_cat`: Always display categories, even on userspace pages. * `.surface_analysis`: Implement {{surface analysis}}; adds `By surface analysis, ` before the parts. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_affix(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if data.surface_analysis then local text = "by " .. glossary_link("surface analysis") .. ", " if not data.nocap then text = ucfirst(text) end table.insert(text_sections, 1, text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Get only the categories that would be generated by show_affix(), without any text output or formatting. This is used by Module:etymon to get affix categorization. Returns an array of category objects, where each entry is either a string (simple category name) or a table with keys `cat`, `sort_key`, and `sort_base` for more complex categorization. `data` should have the same structure as passed to show_affix(): * `.lang` (required): Overall language object * `.parts` (required): Array of affix part objects with `.term`, `.lang`, `.id`, etc. * `.pos`: Part of speech (defaults to "terms") * `.sort_key`: Overall sort key for categories '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.get_affix_categories_only(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) return categories end function export.show_surface_analysis(data) data.surface_analysis = true return export.show_affix(data) end --[==[ Implementation of {{tl|compound}}. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type local parts_formatted = {} table.insert(categories, data.pos .. "gabungan kata") -- Make links out of all the parts local whole_words = 0 for i, part in ipairs(data.parts) do canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). local affix_type, link_term, display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If the term is an interfix or the type was explicitly given, recognize it as such (which means e.g. that we -- will display the term without hyphens for East Asian languages). Otherwise, ignore the fact that it looks -- like an affix and display as specified in the template (but pay attention to the detected affix type for -- certain tracking purposes). if affix_type == "interfix" or (part.type and part.type ~= "non-affix") then -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with -- inline modifiers. The intention in either case is not to link the term. Don't add a '*fixed with' -- category in this case, or if the term is in a different language. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. if link_term and link_term ~= "" and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, link_term), sort_key = part.sort or data.sort_key}) end part.term = link_term ~= "" and link_term or nil part.alt = part.alt or (display_term ~= link_term and display_term) or nil else if affix_type ~= "non-affix" then local langcode = data.lang:getCode() -- If `data.lang` is an etymology-only language, track both using its code and its full parent's code. track { affix_type, affix_type .. "/lang/" .. langcode } local full_langcode = data.lang:getFullCode() if langcode ~= full_langcode then track(affix_type .. "/lang/" .. full_langcode) end else whole_words = whole_words + 1 end end table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if whole_words == 1 then track("one whole word") elseif whole_words == 0 then track("looks like confix") end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Implementation of {{tl|blend}}, {{tl|univerbation}} and similar "compound-like" templates. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound_like(data) data.allow_no_affixes_or_compounds = true local text_sections, categories, borrowing_type = generate_affix_categories(data) if data.cat then table.insert(categories, data.cat) end -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if #data.parts > 0 and data.oftext then table.insert(text_sections, 1, " " .. data.oftext .. " ") end if data.text then table.insert(text_sections, 1, data.text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Make `part` (a structure holding information on an affix part) into an affix of type `affix_type`, and apply any relevant affix mappings. For example, if the desired affix type is "suffix", this will (in general) add a hyphen onto the beginning of the term, alt, tr and ts components of the part if not already present. The hyphen that's added is the "display hyphen" (see above) and may be script-specific. (In the case of East Asian scripts, the display hyphen is an empty string whereas the template hyphen is the regular hyphen, meaning that any regular hyphen at the beginning of the part will be effectively removed.) `lang` and `sc` hold overall language and script objects. Note that this also applies any language-specific affix mappings, so that e.g. if the language is Finnish and the user specified [[-käs]] in the affix and didn't specify an `.alt` value, `part.term` will contain [[-kas]] and `part.alt` will contain [[-käs]]. This function is used by the "legacy" templates ({{tl|prefix}}, {{tl|suffix}}, {{tl|confix}}, etc.) where the nature of the affix is specified by the template itself rather than auto-determined from the affix, as is the case with {{tl|affix}}. '''WARNING''': This destructively modifies `part`. ]==] local function make_part_into_affix(part, lang, sc, affix_type) canonicalize_part(part, lang, sc) local link_term, display_term = export.make_affix(part.term, part.lang, part.sc, affix_type, not part.alt, nil, part.id) part.term = link_term -- When we don't specify `do_affix_mapping` to make_affix(), link and display terms (first and second retvals of -- make_affix()) are the same. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt and export.make_affix(part.alt, part.lang, part.sc, affix_type) or (display_term ~= link_term and display_term) or nil local Latn = require(scripts_module).getByCode("Latn") part.tr = export.make_affix(part.tr, part.lang, Latn, affix_type) part.ts = export.make_affix(part.ts, part.lang, Latn, affix_type) end local function track_wrong_affix_type(template, part, expected_affix_type) if part and not part.type then local affix_type = parse_term_for_affixes(part.term, part.lang, part.sc) if affix_type ~= expected_affix_type then local part_name = expected_affix_type or "base" local langcode = part.lang:getCode() local full_langcode = part.lang:getFullCode() require("Module:debug/track") { template, template .. "/" .. part_name, template .. "/" .. part_name .. "/" .. (affix_type or "none"), template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. langcode } -- If `part.lang` is an etymology-only language, track both using its code and its full parent's code. if full_langcode ~= langcode then require("Module:debug/track")( template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. full_langcode ) end end end end local function insert_affix_category(categories, pos, affix_type, part, sort_key, sort_base) -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if part.term and not part.part_lang then local cat = pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.term) .. (part.id and " (" .. part.id .. ")" or "") if sort_key or sort_base then table.insert(categories, {cat = cat, sort_key = sort_key, sort_base = sort_base}) else table.insert(categories, cat) end end end --[==[ Implementation of {{tl|circumfix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_circumfix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("circumfix", data.prefix, "prefix") track_wrong_affix_type("circumfix", data.base, nil) track_wrong_affix_type("circumfix", data.suffix, "suffix") -- Create circumfix term. local circumfix = nil if data.prefix.term and data.suffix.term then circumfix = data.prefix.term .. " " .. data.suffix.term data.prefix.alt = data.prefix.alt or data.prefix.term data.suffix.alt = data.suffix.alt or data.suffix.term data.prefix.term = circumfix data.suffix.term = circumfix end -- Make links out of all the parts. local parts_formatted = {} local categories = {} local sort_base if data.base.term then sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) end table.insert(parts_formatted, export.link_term(data.prefix, data)) table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.suffix, data)) -- Insert the categories, but don't add a '*fixed with' category if the link term is in a different language. if not data.prefix.part_lang then table.insert(categories, {cat=data.pos .. " dengan apitan " .. strip_diacritics_no_links(data.prefix.lang, circumfix), sort_key=data.sort_key, sort_base=sort_base}) end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|confix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_confix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("confix", data.prefix, "prefix") track_wrong_affix_type("confix", data.base, nil) track_wrong_affix_type("confix", data.suffix, "suffix") -- Make links out of all the parts. local parts_formatted = {} local prefix_sort_base if data.base and data.base.term then prefix_sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) elseif data.suffix.term then prefix_sort_base = strip_diacritics_no_links(data.suffix.lang, data.suffix.term) end -- Insert the categories and parts. local categories = {} table.insert(parts_formatted, export.link_term(data.prefix, data)) insert_affix_category(categories, data.pos, "prefix", data.prefix, data.sort_key, prefix_sort_base) if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) end table.insert(parts_formatted, export.link_term(data.suffix, data)) -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", data.suffix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|infix}}. '''WARNING''': This destructively modifies both `data` and `.base` and `.infix`. ]==] function export.show_infix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.infix, data.lang, data.sc, "infix") track_wrong_affix_type("infix", data.base, nil) track_wrong_affix_type("infix", data.infix, "infix") -- Make links out of all the parts. local parts_formatted = {} local categories = {} table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.infix, data)) -- Insert the categories. -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "infix", data.infix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|prefix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.prefixes`, as well as `.base`. ]==] function export.show_prefix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, prefix in ipairs(data.prefixes) do make_part_into_affix(prefix, data.lang, data.sc, "prefix") end for i, prefix in ipairs(data.prefixes) do track_wrong_affix_type("prefix", prefix, "prefix") end track_wrong_affix_type("prefix", data.base, nil) -- Make links out of all the parts. local parts_formatted = {} local first_sort_base = nil local categories = {} if data.prefixes[2] then first_sort_base = ine(data.prefixes[2].term) or ine(data.prefixes[2].alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.prefixes[2].lang, first_sort_base) end elseif data.base then first_sort_base = ine(data.base.term) or ine(data.base.alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.base.lang, first_sort_base) end end for i, prefix in ipairs(data.prefixes) do table.insert(parts_formatted, export.link_term(prefix, data)) insert_affix_category(categories, data.pos, "prefix", prefix, data.sort_key, i == 1 and first_sort_base or nil) end if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|suffix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.suffixes`, as well as `.base`. ]==] function export.show_suffix(data) local categories = {} data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, suffix in ipairs(data.suffixes) do make_part_into_affix(suffix, data.lang, data.sc, "suffix") end track_wrong_affix_type("suffix", data.base, nil) for i, suffix in ipairs(data.suffixes) do track_wrong_affix_type("suffix", suffix, "suffix") end -- Make links out of all the parts. local parts_formatted = {} if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end for i, suffix in ipairs(data.suffixes) do table.insert(parts_formatted, export.link_term(suffix, data)) end -- Insert the categories. for i, suffix in ipairs(data.suffixes) do -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", suffix) if suffix.pos and rfind(suffix.pos, "patronym") then table.insert(categories, "patronymics") end end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end return export odjmvre3oivg69s6kcm1zzrntdpxuig 1349058 1349056 2026-04-08T17:51:14Z Swarabakti 18192 1349058 Scribunto text/plain local export = {} local debug_force_cat = false -- if set to true, always display categories even on userspace pages local m_links = require("Module:links") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local utilities_module = "Module:utilities" -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.affix_lang_data_module_prefix = "Module:affix/lang-data/" local rsub = m_str_utils.gsub local usub = m_str_utils.sub local ulen = m_str_utils.len local rfind = m_str_utils.find local rmatch = m_str_utils.match local pluralize = require(en_utilities_module).pluralize local u = m_str_utils.char local ucfirst = m_str_utils.ucfirst local unpack = unpack or table.unpack -- Lua 5.2 compatibility function export.affix_variants(canonical, variants) local mappings = {} for _, variant in ipairs(variants) do mappings[variant] = canonical end return mappings end function export.id_mapping(default, ids) local mapping = { default = default } if ids then for id, target in pairs(ids) do mapping[id] = target end end return mapping end function export.id_mapping_with_affix_variants(base, id_variants) local mappings = {} for id, variants in pairs(id_variants) do for _, variant in ipairs(variants) do mappings[variant] = export.id_mapping(base, {[id] = base}) end end return mappings end function export.merge_tables(...) local result = {} for i = 1, select('#', ...) do local t = select(i, ...) if t then for k, v in pairs(t) do result[k] = v end end end return result end -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.langs_with_lang_specific_data = { ["az"] = true, ["fi"] = true, ["fr"] = true, ["izh"] = true, ["la"] = true, ["sah"] = true, ["tr"] = true, } local default_pos = "Istilah" --[==[ intro: ===About different types of hyphens ("template", "display" and "lookup"):=== * The "template hyphen" is the per-script hyphen character that is used in template calls to indicate that a term is an affix. This is always a single Unicode char, but there may be multiple possible hyphens for a given script. Normally this is just the regular hyphen character "-", but for some non-Latin-script languages (currently only right-to-left languages), it is different. * The "display hyphen" is the string (which might be an empty string) that is added onto a term as displayed and linked, to indicate that a term is an affix. Currently this is always either the same as the template hyphen or an empty string, but the code below is written generally enough to handle arbitrary display hyphens. Specifically: *# For East Asian languages, the display hyphen is always blank. *# For Arabic-script languages, either tatweel (ـ) or ZWNJ (zero-width non-joiner) are allowed as template hyphens, where ZWNJ is supported primarily for Farsi, because some suffixes have non-joining behavior. The display hyphen corresponding to tatweel is also tatweel, but the display hyphen corresponding to ZWNJ is blank (tatweel is also the default display hyphen, for calls to {{tl|prefix}}/{{tl|suffix}}/etc. that don't include an explicit hyphen). * The "lookup hyphen" is the hyphen that is used when looking up language-specific affix mappings. (These mappings are discussed in more detail below when discussing link affixes.) It depends only on the script of the affix in question. Most scripts (including East Asian scripts) use a regular hyphen "-" as the lookup hyphen, but Hebrew and Arabic have their own lookup hyphens (respectively maqqef and tatweel). Note that for Arabic in particular, there are three possible template hyphens that are recognized (tatweel, ZWNJ and regular hyphen), but mappings must use tatweel. ===About different types of affixes ("template", "display", "link", "lookup" and "category"):=== * A "template affix" is an affix in its source form as it appears in a template call. Generally, a template affix has an attached template hyphen (see above) to indicate that it is an affix and indicate what type of affix it is (prefix, suffix, interfix or circumfix), but some of the older-style templates such as {{tl|suffix}}, {{tl|prefix}}, {{tl|confix}}, etc. have "positional" affixes where the presence of the affix in a certain position (e.g. the second or third parameter) indicates that it is a certain type of affix, whether or not it has an attached template hyphen. * A "display affix" is the corresponding affix as it is actually displayed to the user. The display affix may differ from the template affix for various reasons: *# The display affix may be specified explicitly using the {{para|alt<var>N</var>}} parameter, the `<alt:...>` inline modifier or a piped link of the form e.g. `<nowiki>[[-kas|-käs]]</nowiki>` (here indicating that the affix should display as `-käs` but be linked as `-kas`). Here, the template affix is arguably the entire piped link, while the display affix is `-käs`. *# Even in the absence of {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers and piped links, certain languages have differences between the "template hyphen" specified in the template (which always needs to be specified somehow or other in templates like {{tl|affix}}, to indicate that the term is an affix and what type of affix it is) and the display hyphen (see above), with corresponding differences between template and display affixes. * A (regular) "link affix" is the affix that is linked to when the affix is shown to the user. The link affix is usually the same as the display affix, but will differ in one of three circumstances: *# The display and link affixes are explicitly made different using {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers or piped links, as described above under "display affix". *# For certain languages, certain affixes are mapped to canonical form using language-specific mappings. For example, in Finnish, the adjective-forming suffix {{m|fi|-kas}} appears as {{m|fi|-käs}} after front vowels, but logically both forms are the same suffix and should be linked and categorized the same. Similarly, in Latin, the negative and intensive prefixes spelled {{m|la|in-}} (etymologically two distinct prefixes) appear variously as {{m|la|il-}}, {{m|la|im-}} or {{m|la|ir-}} before certain consonants. Mappings are supplied in [[Module:affix/lang-data/LANGCODE]] to convert Finnish {{m|fi|-käs}} to {{m|fi|-kas}} for linking and categorization purposes. Note that the affixes in the mappings use "lookup hyphens" to indicate the different types of affixes, which is usually the same as the template hyphen but differs for Arabic scripts, because there are multiple possible template hyphens recognized but only one lookup hyphen (tatweel). The form of the affix as used to look up in the mapping tables is called the "lookup affix"; see below. * A "stripped link affix" is a link affix that has been passed through the language's `stripDiacritics()` function, which may strip certain diacritics: e.g. macrons in Latin and Old English (indicating length); acute and grave accents in Russian and various other Slavic languages (indicating stress); vowel diacritics in most Arabic-script languages; and also tatweel in some Arabic-script languages (currently, for example, Persian, Arabic and Urdu strip tatweel, but Ottoman Turkish does not). Stripped link affixes are currently what are used in category names. * A "lookup affix" is the form of the affix as it is looked up in the language-specific lookup mappings described above under link affixes. There are actually two lookup stages: *# First, the affix is looked up in a modified display form (specifically, the same as the display affix but using lookup hyphens). Note that this lookup does not occur if an explicit display form is given using {{para|alt<var>N</var>}} or an `<alt:...>` inline modifier, or if the template affix contains a piped or embedded link. *# If no entry is found, the affix is then looked up in a modified link form (specifically, the modified display form passed through the language's `stripDiacritics()` function, which strips out certain diacritics, but with the lookup hyphen re-added if it was stripped out, as in the case of tatweel in many Arabic-script languages). The reason for this double lookup procedure is to allow for mappings that are sensitive to the extra diacritics, but also allow for mappings that are not sensitive in this fashion (e.g. Russian {{m|ru|-ливый}} occurs both stressed and unstressed, but is the same prefix either way). * A "category affix" is the affix as it appears in categories such as [[:Category:Finnish terms suffixed with -kas| Category:Finnish terms suffixed with ''-kas'']]. The category affix is currently always the same as the stripped link affix. This means that for Arabic-script languages, it may or may not have a tatweel, even if the correponding display affix and regular link affix have a tatweel. As mentioned above, stripDiacritics() strips tatweel for Arabic, Persian and Urdu, but not for Ottoman Turkish. Hence affix categories for Arabic, Persian and Urdu will be missing the tatweel, but affix categories for Ottoman Turkish will have it. An additional complication is that if the template affix contains a ZWNJ, the display (and hence the link and category affixes) will have no hyphen attached in any case. ]==] ----------------------------------------------------------------------------------------- -- Template and display hyphens -- ----------------------------------------------------------------------------------------- --[=[ Per-script template hyphens. The template hyphen is what appears in the {{affix}}/{{prefix}}/{{suffix}}/etc. template (in the wikicode). See above. They key below is a script code, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' will match 'Arab'. The value below is a string consisting of one or more hyphen characters. If there is more than one character, the default hyphen must come last and a non-default function must be specified for the script in display_hyphens[] so the correct display hyphen will be specified when no template hyphen is given (in {{suffix}}/{{prefix}}/etc.). Script detection is normally done when linking, but we need to do it earlier. However, under most circumstances we don't need to do script detection. Specifically, we only need to do script detection for a given language if (a) the language has multiple scripts; and (b) at least one of those scripts is listed below or in display_hyphens. ]=] local ZWNJ = u(0x200C) -- zero-width non-joiner local template_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = "ـ" .. ZWNJ .. "-", -- tatweel + zero-width non-joiner + regular hyphen ["Hebr"] = "־", -- Hebrew-specific hyphen termed "maqqef" ["Mong"] = "᠊", -- FIXME! What about the following right-to-left scripts? -- Adlm (Adlam) -- Armi (Imperial Aramaic) -- Avst (Avestan) -- Cprt (Cypriot) -- Khar (Kharoshthi) -- Mand (Mandaic/Mandaean) -- Mani (Manichaean) -- Mend (Mende/Mende Kikakui) -- Narb (Old North Arabian) -- Nbat (Nabataean/Nabatean) -- Nkoo (N'Ko) -- Orkh (Orkhon runes) -- Phli (Inscriptional Pahlavi) -- Phlp (Psalter Pahlavi) -- Phlv (Book Pahlavi) -- Phnx (Phoenician) -- Prti (Inscriptional Parthian) -- Rohg (Hanifi Rohingya) -- Samr (Samaritan) -- Sarb (Old South Arabian) -- Sogd (Sogdian) -- Sogo (Old Sogdian) -- Syrc (Syriac) -- Thaa (Thaana) } -- Hyphens used when looking up an affix in a lang-specific affix mapping. Defaults to regular hyphen (-). The keys -- are script codes, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' -- will match 'Arab'. The value should be a single character. local lookup_hyphens = { ["Hebr"] = "־", -- This covers all Arabic scripts. See above. ["Arab"] = "ـ", } -- Default display-hyphen function. local function default_display_hyphen(script, hyph) if not hyph then return template_hyphens[script] or "-" end return hyph end local function arab_get_display_hyphen(script, hyph) if not hyph then return "ـ" -- tatweel elseif hyph == ZWNJ then return "" else return hyph end end local function no_display_hyphen(script, hyph) return "" end -- Per-script function to return the correct display hyphen given the script and template hyphen. The function should -- also handle the case where the passed-in template hyphen is nil, corresponding to the situation in -- {{prefix}}/{{suffix}}/etc. where no template hyphen is specified. The key is the script code after removing a hyphen -- and anything preceding, so 'fa-Arab', 'ur-Arab' etc. will match 'Arab'. local display_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = arab_get_display_hyphen, ["Bopo"] = no_display_hyphen, ["Hani"] = no_display_hyphen, ["Hans"] = no_display_hyphen, ["Hant"] = no_display_hyphen, -- The following is a mixture of several scripts. Hopefully the specs here are correct! ["Jpan"] = no_display_hyphen, ["Jurc"] = no_display_hyphen, ["Kitl"] = no_display_hyphen, ["Kits"] = no_display_hyphen, ["Laoo"] = no_display_hyphen, ["Nshu"] = no_display_hyphen, ["Shui"] = no_display_hyphen, ["Tang"] = no_display_hyphen, ["Thaa"] = no_display_hyphen, ["Thai"] = no_display_hyphen, } ----------------------------------------------------------------------------------------- -- Basic Utility functions -- ----------------------------------------------------------------------------------------- local function glossary_link(entry, text) text = text or entry return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]" end local function track(page) if type(page) == "table" then for i, pg in ipairs(page) do page[i] = "affix/" .. pg end else page = "affix/" .. page end require("Module:debug/track")(page) end local function ine(val) return val ~= "" and val or nil end ----------------------------------------------------------------------------------------- -- Compound types -- ----------------------------------------------------------------------------------------- local function make_compound_type(typ, alttext) return { text = glossary_link(typ, alttext) .. " compound", cat = typ .. " compounds", } end -- Make a compound type entry with a simple rather than glossary link. -- These should be replaced with a glossary link when the entry in the glossary -- is created. local function make_non_glossary_compound_type(typ, alttext) local link = alttext and "[[" .. typ .. "|" .. alttext .. "]]" or "[[" .. typ .. "]]" return { text = link .. " compound", cat = typ .. " compounds", } end local function make_raw_compound_type(typ, alttext) return { text = glossary_link(typ, alttext), cat = pluralize(typ), } end local function make_borrowing_type(typ, alttext) return { text = glossary_link(typ, alttext), borrowing_type = pluralize(typ), } end export.etymology_types = { ["adapted borrowing"] = make_borrowing_type("adapted borrowing"), ["adap"] = "adapted borrowing", ["abor"] = "adapted borrowing", ["alliterative"] = make_non_glossary_compound_type("alliterative"), ["allit"] = "alliterative", ["antonymous"] = make_non_glossary_compound_type("antonymous"), ["ant"] = "antonymous", ["bahuvrihi"] = make_compound_type("bahuvrihi", "bahuvrīhi"), ["bahu"] = "bahuvrihi", ["bv"] = "bahuvrihi", ["coordinative"] = make_compound_type("coordinative"), ["coord"] = "coordinative", ["descriptive"] = make_compound_type("descriptive"), ["desc"] = "descriptive", ["determinative"] = make_compound_type("determinative"), ["det"] = "determinative", ["dvandva"] = make_compound_type("dvandva"), ["dva"] = "dvandva", ["dvigu"] = make_compound_type("dvigu"), ["dvi"] = "dvigu", ["endocentric"] = make_compound_type("endocentric"), ["endo"] = "endocentric", ["exocentric"] = make_compound_type("exocentric"), ["exo"] = "exocentric", ["izafet I"] = make_compound_type("izafet I"), ["iz1"] = "izafet I", ["izafet II"] = make_compound_type("izafet II"), ["iz2"] = "izafet II", ["izafet III"] = make_compound_type("izafet III"), ["iz3"] = "izafet III", ["karmadharaya"] = make_compound_type("karmadharaya", "karmadhāraya"), ["karma"] = "karmadharaya", ["kd"] = "karmadharaya", ["kenning"] = make_raw_compound_type("kenning"), ["ken"] = "kenning", ["rhyming"] = make_non_glossary_compound_type("rhyming"), ["rhy"] = "rhyming", ["synonymous"] = make_non_glossary_compound_type("synonymous"), ["syn"] = "synonymous", ["tatpurusa"] = make_compound_type("tatpurusa", "tatpuruṣa"), ["tat"] = "tatpurusa", ["tp"] = "tatpurusa", } local function process_etymology_type(typ, nocap, notext, has_parts) local text_sections = {} local categories = {} local borrowing_type if typ then local typdata = export.etymology_types[typ] if type(typdata) == "string" then typdata = export.etymology_types[typdata] end if not typdata then error("Internal error: Unrecognized type '" .. typ .. "'") end local text = typdata.text if not nocap then text = ucfirst(text) end local cat = typdata.cat borrowing_type = typdata.borrowing_type local oftext = typdata.oftext or " of" if not notext then table.insert(text_sections, text) if has_parts then table.insert(text_sections, oftext) table.insert(text_sections, " ") end end if cat then table.insert(categories, cat) end end return text_sections, categories, borrowing_type end ----------------------------------------------------------------------------------------- -- Utility functions -- ----------------------------------------------------------------------------------------- -- Iterate an array up to the greatest integer index found. local function ipairs_with_gaps(t) local indices = m_table.numKeys(t) local max_index = #indices > 0 and math.max(unpack(indices)) or 0 local i = 0 return function() while i < max_index do i = i + 1 return i, t[i] end end end export.ipairs_with_gaps = ipairs_with_gaps --[==[ Join formatted parts (in `parts_formatted`) together with any overall {{para|lit}} spec (in `lit`) plus categories, which are formatted by prepending the language name as found in `lang`. The value of an entry in `categories` can be either a string (which is formatted using `sort_key`) or a table of the form `{ {cat=<var>category</var>, sort_key=<var>sort_key</var>, sort_base=<var>sort_base</var>}`, specifying the sort key and sort base to use when formatting the category. If `nocat` is given, no categories are added; otherwise, `force_cat` causes categories to be added even on userspace pages. ]==] function export.join_formatted_parts(data) local cattext local lang = data.data.lang local force_cat = data.data.force_cat or debug_force_cat if data.data.nocat then cattext = "" else for i, cat in ipairs(data.categories) do if type(cat) == "table" then data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat.cat, lang, cat.sort_key, cat.sort_base, force_cat) else data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat, lang, data.data.sort_key, nil, force_cat) end end cattext = table.concat(data.categories) end local result = table.concat(data.parts_formatted, not data.separator_already_added and " +&lrm; " or nil) .. (data.data.lit and ", literally " .. m_links.mark(data.data.lit, "gloss") or "") local q = data.data.q local qq = data.data.qq local l = data.data.l local ll = data.data.ll if q and q[1] or qq and qq[1] or l and l[1] or ll and ll[1] then result = require(pron_qualifier_module).format_qualifiers { lang = lang, text = result, q = q, qq = qq, l = l, ll = ll, } end return result .. cattext end local function pluralize(pos) if pos ~= "nouns" and usub(pos, -5) ~= "verbs" and usub(pos, -4) ~= "ives" then if pos:find("[sx]$") then pos = pos .. "es" else pos = pos .. "s" end end return pos end -- Remove links and call lang:stripDiacritics(term). local function strip_diacritics_no_links(lang, term) return lang:stripDiacritics(m_links.remove_links(term)) end --[=[ Convert a raw part as passed into an entry point into a part ready for linking. `lang` and `sc` are the overall language and script objects. This uses the overall language and script objects as defaults for the part and parses off any fragment from the term. We need to do the latter so that fragments don't end up in categories and so that we correctly do affix mapping even in the presence of fragments. ]=] local function canonicalize_part(part, lang, sc) if not part then return end -- Save the original (user-specified, part-specific) value of `lang`. If such a value is specified, we don't insert -- a '*fixed with' category, and we format the part using format_derived() in [[Module:etymology]] rather than -- full_link() in [[Module:links]]. part.part_lang = part.lang part.lang = part.lang or lang part.sc = part.sc or sc local term = part.term if not term then return elseif not part.fragment then part.term, part.fragment = m_links.get_fragment(term) else part.term = m_links.get_fragment(term) end end --[==[ Construct a single linked part based on the information in `part`, for use by `show_affix()` and other entry points. This should be called after `canonicalize_part()` is called on the part. This is a thin wrapper around `full_link()` in [[Module:links]] unless `part.part_lang` is specified (indicating that a part-specific language was given), in which case `format_derived()` in [[Module:etymology]] is called to display a term in a language other than the language of the overall term (specified in `data.lang`). `data` contains the entire object passed into the entry point and is used to access information for constructing the categories added by `format_derived()`. ]==] function export.link_term(part, data, include_separator) local result if part.part_lang then result = require(etymology_module).format_derived { lang = data.lang, terms = {part}, sources = {part.lang}, sort_key = data.sort_key, nocat = data.nocat, template_name = "affix", qualifiers_labels_on_outside = true, borrowing_type = data.borrowing_type, force_cat = data.force_cat or debug_force_cat, } else result = m_links.full_link(part, "term", nil, "show qualifiers") end if include_separator and part.separator then return part.separator .. result else return result end end local function canonicalize_script_code(scode) -- Convert fa-Arab, ur-Arab etc. to Arab. return (scode:gsub("^.*%-", "")) end ----------------------------------------------------------------------------------------- -- Affix-handling functions -- ----------------------------------------------------------------------------------------- -- Figure out the appropriate script for the given affix and language (unless the script is explicitly passed in), and -- return the values of template_hyphens[], display_hyphens[] and lookup_hyphens[] for that script, substituting -- default values as appropriate. Four values are returned: -- DETECTED_SCRIPT, TEMPLATE_HYPHEN, DISPLAY_HYPHEN, LOOKUP_HYPHEN local function detect_script_and_hyphens(text, lang, sc) local scode -- 1. If the script is explicitly passed in, use it. if sc then scode = sc:getCode() else local possible_script_codes = lang:getScriptCodes() -- YUCK! `possible_script_codes` comes from loadData() so #possible_scripts doesn't work (always returns 0). local num_possible_script_codes = m_table.length(possible_script_codes) if num_possible_script_codes == 0 then -- This shouldn't happen; if the language has no script codes, -- the list {"None"} should be returned. error("Something is majorly wrong! Language " .. lang:getCanonicalName() .. " has no script codes.") end if num_possible_script_codes == 1 then -- 2. If the language has only one possible script, use it. scode = possible_script_codes[1] else -- 3. Check if any of the possible scripts for the language have non-default values for template_hyphens[] -- or display_hyphens[]. If so, we need to do script detection on the text. If not, just use "Latn", -- which may not be technically correct but produces the right results because Latn has all default -- values for template_hyphens[] and display_hyphens[]. local may_have_nondefault_hyphen = false for _, script_code in ipairs(possible_script_codes) do script_code = canonicalize_script_code(script_code) if template_hyphens[script_code] or display_hyphens[script_code] then may_have_nondefault_hyphen = true break end end if not may_have_nondefault_hyphen then scode = "Latn" else scode = lang:findBestScript(text):getCode() end end end scode = canonicalize_script_code(scode) local template_hyphen = template_hyphens[scode] or "-" local lookup_hyphen = lookup_hyphens[scode] or "-" local display_hyphen = display_hyphens[scode] or default_display_hyphen return scode, template_hyphen, display_hyphen, lookup_hyphen end --[=[ Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function reconstruct_term_per_hyphens(term, affix_type, scode, thyph_re, new_hyphen) local function get_hyphen(hyph) if type(new_hyphen) == "string" then return new_hyphen end return new_hyphen(scode, hyph) end if affix_type == "non-affix" then return term elseif affix_type == "circumfix" then local before, before_hyphen, after_hyphen, after = rmatch(term, "^(.*)" .. thyph_re .. " " .. thyph_re .. "(.*)$") if not before or ulen(term) <= 3 then -- Unlike with other types of affixes, don't try to add hyphens in the middle of the term to convert it to -- a circumfix. Also, if the term is just hyphen + space + hyphen, return it. return term end return before .. get_hyphen(before_hyphen) .. " " .. get_hyphen(after_hyphen) .. after elseif affix_type == "infix" or affix_type == "interfix" then local before_hyphen, middle, after_hyphen = rmatch(term, "^" .. thyph_re .. "(.*)" .. thyph_re .. "$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "prefix" then local middle, after_hyphen = rmatch(term, "^(.*)" .. thyph_re .. "$") if middle and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "suffix" then local before_hyphen, middle = rmatch(term, "^" .. thyph_re .. "(.*)$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) else error(("Internal error: Unrecognized affix type '%s'"):format(affix_type)) end end --[=[ Look up a mapping from a given affix variant to the canonical form used in categories and links. The lookup tables are language-specific according to `lang`, and may be ID-specific according to `affix_id`. The affixes as they appear in the lookup tables (both the variant and the canonical form) are in "lookup affix" format (approximately speaking, they use a regular hyphen for most scripts, but a tatweel for Arabic-script entries and a maqqef for Hebrew-script entries), but the passed-in `affix` param is in "template affix" format (which differs from the lookup affix for Arabic-script entries, because more types of hyphens are allowed in template affixes; see the comments at the top of the file). The remaining parameters to this function are used to convert from template affixes to lookup affixes; see the reconstruct_term_per_hyphens() function above. If the affix contains brackets, no lookup is done. Otherwise, a two-stage process is used, first looking up the affix directly and then stripping diacritics and looking it up again. The reason for this is documented above in the comments at the top of the file (specifically, the comments describing lookup affixes). The value of a mapping can either be a string (do the mapping regardless of affix ID) or a table indexed by affix ID (where the special value `false` indicates no affix ID). The values of entries in this table can also be strings, or tables with keys `affix` and `id` (again, use `false` to indicate no ID). This allows an affix mapping to map from one ID to another (for example, this is used in English to map the [[an-]] prefix with no ID to the [[a-]] prefix with the ID 'not'). The Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function lookup_affix_mapping(affix, affix_type, lang, scode, thyph_re, lookup_hyph, affix_id) local function do_lookup(affix) -- Ensure that the affix uses lookup hyphens regardless of whether it used a different type of hyphens before -- or no hyphens. local lookup_affix = reconstruct_term_per_hyphens(affix, affix_type, scode, thyph_re, lookup_hyph) local function do_lookup_for_langcode(langcode) if export.langs_with_lang_specific_data[langcode] then local langdata = mw.loadData(export.affix_lang_data_module_prefix .. langcode) if langdata.affix_mappings then local mapping = langdata.affix_mappings[lookup_affix] if mapping then if type(mapping) == "table" then mapping = mapping[affix_id] or mapping.default or mapping[affix_id or false] if mapping then return mapping end else return mapping end end end end end -- If `lang` is an etymology-only language, look for a mapping both for it and its full parent. local langcode = lang:getCode() local mapping = do_lookup_for_langcode(langcode) if mapping then return mapping end local full_langcode = lang:getFullCode() if full_langcode ~= langcode then mapping = do_lookup_for_langcode(full_langcode) if mapping then return mapping end end return nil end if affix:find("%[%[") then return nil end return do_lookup(affix) or do_lookup(lang:stripDiacritics(affix)) or nil end --[==[ For a given template term in a given language (see the definition of "template affix" near the top of the file), possibly in an explicitly specified script `sc` (but usually nil), return the term's affix type ({"prefix"}, {"interfix"}, {"suffix"}, {"circumfix"} or {"non-affix"}) along with the corresponding link and display affixes (see definitions near the top of the file); also the corresponding lookup affix (if `return_lookup_affix` is specified). The term passed in should already have any fragment (after the # sign) parsed off of it. Four values are returned: `affix_type`, `link_term`, `display_term` and `lookup_term`. The affix type can be passed in instead of autodetected; in this case, the template term need not have any attached hyphens, and the appropriate hyphens will be added in the appropriate places. If `do_affix_mapping` is specified, look up the affix in the lang-specific affix mappings, as described in the comment at the top of the file; otherwise, the link and display terms will always be the same. (They will be the same in any case if the template term has a bracketed link in it or is not an affix.) If `return_lookup_affix` is given, the fourth return value contains the term with appropriate lookup hyphens in the appropriate places; otherwise, it is the same as the display term. (This functionality is used in [[Module:category tree/affixes and compounds]] to convert link affixes into lookup affixes so that they can be looked up in the affix mapping tables.) ]==] local function parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not term then return "non-affix", nil, nil, nil end if term == "^" then -- Indicates a null term to emulate the behavior of {{suffix|foo||bar}}. term = "" return "non-affix", term, term, term end if term:find("^%^") then -- HACK! ^ at the beginning of Korean languages has a special meaning, triggering capitalization of the -- transliteration. Don't interpret it as "force non-affix" for those languages. local langcode = lang:getCode() if langcode ~= "ko" and langcode ~= "okm" and langcode ~= "jje" then -- Formerly we allowed ^ to force non-affix type; this is now handled using an inline modifier -- <naf>, <root>, etc. Throw an error for the moment when the old way is encountered. error("Use of ^ to force non-affix status is no longer supported; use an inline modifier <naf> or <root> " .. "after the component") end end -- Remove an asterisk if the morpheme is reconstructed and add it back at the end. local reconstructed = "" if term:find("^%*") then reconstructed = "*" term = term:gsub("^%*", "") end local scode, thyph, dhyph, lhyph = detect_script_and_hyphens(term, lang, sc) thyph = "([" .. thyph .. "])" if not affix_type then if rfind(term, thyph .. " " .. thyph) then affix_type = "circumfix" else local has_beginning_hyphen = rfind(term, "^" .. thyph) local has_ending_hyphen = rfind(term, thyph .. "$") if has_beginning_hyphen and has_ending_hyphen then affix_type = "interfix" elseif has_ending_hyphen then affix_type = "prefix" elseif has_beginning_hyphen then affix_type = "suffix" else affix_type = "non-affix" end end end local link_term, display_term, lookup_term if affix_type == "non-affix" then link_term = term display_term = term lookup_term = term else display_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, dhyph) if do_affix_mapping then link_term = lookup_affix_mapping(term, affix_type, lang, scode, thyph, lhyph, affix_id) -- The return value of lookup_affix_mapping() may be an affix mapping with lookup hyphens if a mapping -- was found, otherwise nil if a mapping was not found. We need to convert to display hyphens in -- either case, but in the latter case we can reuse the display term, which has already been converted. if link_term then link_term = reconstruct_term_per_hyphens(link_term, affix_type, scode, thyph, dhyph) else link_term = display_term end else link_term = display_term end if return_lookup_affix then lookup_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, lhyph) else lookup_term = display_term end end link_term = reconstructed .. link_term display_term = reconstructed .. display_term lookup_term = reconstructed .. lookup_term return affix_type, link_term, display_term, lookup_term end --[==[ Add a hyphen to a term in the appropriate place, based on the specified affix type, stripping off any existing hyphens in that place. For example, if `affix_type` == {"prefix"}, we'll add a hyphen onto the end if it's not already there (or is of the wrong type). Three values are returned: the link term, display term and lookup term. This function is a thin wrapper around `parse_term_for_affixes`; see the comments above that function for more information. Note that this function is exposed externally because it is called by [[Module:category tree/affixes and compounds]]; see the comment in `parse_term_for_affixes` for more information. ]==] function export.make_affix(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not (affix_type == "prefix" or affix_type == "suffix" or affix_type == "circumfix" or affix_type == "infix" or affix_type == "interfix" or affix_type == "non-affix") then error("Internal error: Invalid affix type " .. (affix_type or "(nil)")) end local _, link_term, display_term, lookup_term = parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) return link_term, display_term, lookup_term end ----------------------------------------------------------------------------------------- -- Main entry points -- ----------------------------------------------------------------------------------------- --[==[ Core categorization logic for affixes. This is shared between show_affix(), show_compound_like() and get_affix_categories_only(). Returns the categories array and other metadata needed for formatting. ]==] local function generate_affix_categories(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.surface_analysis or data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type -- Process each part local whole_words = 0 local is_affix_or_compound = false -- Canonicalize and generate links for all the parts first; then do categorization in a separate step, because when -- processing the first part for categorization, we may access the second part and need it already canonicalized. for i, part in ipairs_with_gaps(data.parts) do part = part or {} data.parts[i] = part canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). Store them in the part -- (in fields that won't clash with fields used by full_link() in [[Module:links]] or link_term()), so they -- can be used in the loop below when categorizing. part.affix_type, part.affix_link_term, part.affix_display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with inline -- modifiers. The intention in either case is not to link the term. part.term = ine(part.affix_link_term) -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt or (part.affix_display_term ~= part.affix_link_term and part.affix_display_term) or nil end -- Now do categorization. for i, part in ipairs_with_gaps(data.parts) do local affix_type = part.affix_type if affix_type ~= "non-affix" then is_affix_or_compound = true -- Make a sort key. For the first part, use the second part as the sort key; the intention is that if the -- term has a prefix, sorting by the prefix won't be very useful so we sort by what follows, which is -- presumably the root. local part_sort_base = nil local part_sort = part.sort or data.sort_key if i == 1 and data.parts[2] and data.parts[2].term then local part2 = data.parts[2] -- If the second-part link term is empty, the user requested an unlinked term; avoid a wikitext error -- by using the alt value if available. part_sort_base = ine(part2.affix_link_term) or ine(part2.alt) if part_sort_base then part_sort_base = strip_diacritics_no_links(part2.lang, part_sort_base) end end if part.pos and rfind(part.pos, "patronym") then table.insert(categories, {cat = "patronymics", sort_key = part_sort, sort_base = part_sort_base}) end if data.pos ~= "Istilah" and part.pos and rfind(part.pos, "diminutif") then table.insert(categories, {cat = "Bentuk diminutif" .. data.pos, sort_key = part_sort, sort_base = part_sort_base}) end -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if ine(part.affix_link_term) and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.affix_link_term) .. (part.id and " (" .. part.id .. ")" or ""), sort_key = part_sort, sort_base = part_sort_base}) end else whole_words = whole_words + 1 if whole_words == 2 then is_affix_or_compound = true table.insert(categories, data.pos .. " gabungan kata") end end end -- Make sure there was either an affix or a compound (two or more non-affix terms). if not is_affix_or_compound and not data.allow_no_affixes_or_compounds then error("The parameters did not include any affixes, and the term is not a compound. Please provide at least one affix.") end return text_sections, categories, borrowing_type end --[==[ Implementation of {{tl|affix}} and {{tl|surface analysis}}. `data` contains all the information describing the affixes to be displayed, and contains the following: * `.lang` ('''required'''): Overall language object. Different from term-specific language objects (see `.parts` below). * `.sc`: Overall script object (usually omitted). Different from term-specific script objects. * `.parts` ('''required'''): List of objects describing the affixes to show. The general format of each object is as would be passed to `full_link()`, except that the `.lang` field should be missing unless the term is of a language different from the overall `.lang` value (in such a case, the language name is shown along with the term and an additional "derived from" category is added). '''WARNING''': The data in `.parts` will be destructively modified. * `.pos`: Overall part of speech (used in categories, defaults to {"terms"}). Different from term-specific part of speech. * `.sort_key`: Overall sort key. Normally omitted except e.g. in Japanese. * `.type`: Type of compound, if the parts in `.parts` describe a compound. Strictly optional, and if supplied, the compound type is displayed before the parts (normally capitalized, unless `.nocap` is given). * `.nocap`: Don't capitalize the first letter of text displayed before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.notext`: Don't display any text before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.nocat`: Disable all categorization. * `.lit`: Overall literal definition. Different from term-specific literal definitions. * `.force_cat`: Always display categories, even on userspace pages. * `.surface_analysis`: Implement {{surface analysis}}; adds `By surface analysis, ` before the parts. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_affix(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if data.surface_analysis then local text = "by " .. glossary_link("surface analysis") .. ", " if not data.nocap then text = ucfirst(text) end table.insert(text_sections, 1, text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Get only the categories that would be generated by show_affix(), without any text output or formatting. This is used by Module:etymon to get affix categorization. Returns an array of category objects, where each entry is either a string (simple category name) or a table with keys `cat`, `sort_key`, and `sort_base` for more complex categorization. `data` should have the same structure as passed to show_affix(): * `.lang` (required): Overall language object * `.parts` (required): Array of affix part objects with `.term`, `.lang`, `.id`, etc. * `.pos`: Part of speech (defaults to "terms") * `.sort_key`: Overall sort key for categories '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.get_affix_categories_only(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) return categories end function export.show_surface_analysis(data) data.surface_analysis = true return export.show_affix(data) end --[==[ Implementation of {{tl|compound}}. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type local parts_formatted = {} table.insert(categories, data.pos .. " gabungan kata") -- Make links out of all the parts local whole_words = 0 for i, part in ipairs(data.parts) do canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). local affix_type, link_term, display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If the term is an interfix or the type was explicitly given, recognize it as such (which means e.g. that we -- will display the term without hyphens for East Asian languages). Otherwise, ignore the fact that it looks -- like an affix and display as specified in the template (but pay attention to the detected affix type for -- certain tracking purposes). if affix_type == "interfix" or (part.type and part.type ~= "non-affix") then -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with -- inline modifiers. The intention in either case is not to link the term. Don't add a '*fixed with' -- category in this case, or if the term is in a different language. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. if link_term and link_term ~= "" and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, link_term), sort_key = part.sort or data.sort_key}) end part.term = link_term ~= "" and link_term or nil part.alt = part.alt or (display_term ~= link_term and display_term) or nil else if affix_type ~= "non-affix" then local langcode = data.lang:getCode() -- If `data.lang` is an etymology-only language, track both using its code and its full parent's code. track { affix_type, affix_type .. "/lang/" .. langcode } local full_langcode = data.lang:getFullCode() if langcode ~= full_langcode then track(affix_type .. "/lang/" .. full_langcode) end else whole_words = whole_words + 1 end end table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if whole_words == 1 then track("one whole word") elseif whole_words == 0 then track("looks like confix") end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Implementation of {{tl|blend}}, {{tl|univerbation}} and similar "compound-like" templates. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound_like(data) data.allow_no_affixes_or_compounds = true local text_sections, categories, borrowing_type = generate_affix_categories(data) if data.cat then table.insert(categories, data.cat) end -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if #data.parts > 0 and data.oftext then table.insert(text_sections, 1, " " .. data.oftext .. " ") end if data.text then table.insert(text_sections, 1, data.text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Make `part` (a structure holding information on an affix part) into an affix of type `affix_type`, and apply any relevant affix mappings. For example, if the desired affix type is "suffix", this will (in general) add a hyphen onto the beginning of the term, alt, tr and ts components of the part if not already present. The hyphen that's added is the "display hyphen" (see above) and may be script-specific. (In the case of East Asian scripts, the display hyphen is an empty string whereas the template hyphen is the regular hyphen, meaning that any regular hyphen at the beginning of the part will be effectively removed.) `lang` and `sc` hold overall language and script objects. Note that this also applies any language-specific affix mappings, so that e.g. if the language is Finnish and the user specified [[-käs]] in the affix and didn't specify an `.alt` value, `part.term` will contain [[-kas]] and `part.alt` will contain [[-käs]]. This function is used by the "legacy" templates ({{tl|prefix}}, {{tl|suffix}}, {{tl|confix}}, etc.) where the nature of the affix is specified by the template itself rather than auto-determined from the affix, as is the case with {{tl|affix}}. '''WARNING''': This destructively modifies `part`. ]==] local function make_part_into_affix(part, lang, sc, affix_type) canonicalize_part(part, lang, sc) local link_term, display_term = export.make_affix(part.term, part.lang, part.sc, affix_type, not part.alt, nil, part.id) part.term = link_term -- When we don't specify `do_affix_mapping` to make_affix(), link and display terms (first and second retvals of -- make_affix()) are the same. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt and export.make_affix(part.alt, part.lang, part.sc, affix_type) or (display_term ~= link_term and display_term) or nil local Latn = require(scripts_module).getByCode("Latn") part.tr = export.make_affix(part.tr, part.lang, Latn, affix_type) part.ts = export.make_affix(part.ts, part.lang, Latn, affix_type) end local function track_wrong_affix_type(template, part, expected_affix_type) if part and not part.type then local affix_type = parse_term_for_affixes(part.term, part.lang, part.sc) if affix_type ~= expected_affix_type then local part_name = expected_affix_type or "base" local langcode = part.lang:getCode() local full_langcode = part.lang:getFullCode() require("Module:debug/track") { template, template .. "/" .. part_name, template .. "/" .. part_name .. "/" .. (affix_type or "none"), template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. langcode } -- If `part.lang` is an etymology-only language, track both using its code and its full parent's code. if full_langcode ~= langcode then require("Module:debug/track")( template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. full_langcode ) end end end end local function insert_affix_category(categories, pos, affix_type, part, sort_key, sort_base) -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if part.term and not part.part_lang then local cat = pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.term) .. (part.id and " (" .. part.id .. ")" or "") if sort_key or sort_base then table.insert(categories, {cat = cat, sort_key = sort_key, sort_base = sort_base}) else table.insert(categories, cat) end end end --[==[ Implementation of {{tl|circumfix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_circumfix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("circumfix", data.prefix, "prefix") track_wrong_affix_type("circumfix", data.base, nil) track_wrong_affix_type("circumfix", data.suffix, "suffix") -- Create circumfix term. local circumfix = nil if data.prefix.term and data.suffix.term then circumfix = data.prefix.term .. " " .. data.suffix.term data.prefix.alt = data.prefix.alt or data.prefix.term data.suffix.alt = data.suffix.alt or data.suffix.term data.prefix.term = circumfix data.suffix.term = circumfix end -- Make links out of all the parts. local parts_formatted = {} local categories = {} local sort_base if data.base.term then sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) end table.insert(parts_formatted, export.link_term(data.prefix, data)) table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.suffix, data)) -- Insert the categories, but don't add a '*fixed with' category if the link term is in a different language. if not data.prefix.part_lang then table.insert(categories, {cat=data.pos .. " dengan apitan " .. strip_diacritics_no_links(data.prefix.lang, circumfix), sort_key=data.sort_key, sort_base=sort_base}) end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|confix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_confix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("confix", data.prefix, "prefix") track_wrong_affix_type("confix", data.base, nil) track_wrong_affix_type("confix", data.suffix, "suffix") -- Make links out of all the parts. local parts_formatted = {} local prefix_sort_base if data.base and data.base.term then prefix_sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) elseif data.suffix.term then prefix_sort_base = strip_diacritics_no_links(data.suffix.lang, data.suffix.term) end -- Insert the categories and parts. local categories = {} table.insert(parts_formatted, export.link_term(data.prefix, data)) insert_affix_category(categories, data.pos, "prefix", data.prefix, data.sort_key, prefix_sort_base) if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) end table.insert(parts_formatted, export.link_term(data.suffix, data)) -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", data.suffix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|infix}}. '''WARNING''': This destructively modifies both `data` and `.base` and `.infix`. ]==] function export.show_infix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.infix, data.lang, data.sc, "infix") track_wrong_affix_type("infix", data.base, nil) track_wrong_affix_type("infix", data.infix, "infix") -- Make links out of all the parts. local parts_formatted = {} local categories = {} table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.infix, data)) -- Insert the categories. -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "infix", data.infix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|prefix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.prefixes`, as well as `.base`. ]==] function export.show_prefix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, prefix in ipairs(data.prefixes) do make_part_into_affix(prefix, data.lang, data.sc, "prefix") end for i, prefix in ipairs(data.prefixes) do track_wrong_affix_type("prefix", prefix, "prefix") end track_wrong_affix_type("prefix", data.base, nil) -- Make links out of all the parts. local parts_formatted = {} local first_sort_base = nil local categories = {} if data.prefixes[2] then first_sort_base = ine(data.prefixes[2].term) or ine(data.prefixes[2].alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.prefixes[2].lang, first_sort_base) end elseif data.base then first_sort_base = ine(data.base.term) or ine(data.base.alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.base.lang, first_sort_base) end end for i, prefix in ipairs(data.prefixes) do table.insert(parts_formatted, export.link_term(prefix, data)) insert_affix_category(categories, data.pos, "prefix", prefix, data.sort_key, i == 1 and first_sort_base or nil) end if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|suffix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.suffixes`, as well as `.base`. ]==] function export.show_suffix(data) local categories = {} data.pos = data.pos or default_pos data.pos = pluralize(data.pos) canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, suffix in ipairs(data.suffixes) do make_part_into_affix(suffix, data.lang, data.sc, "suffix") end track_wrong_affix_type("suffix", data.base, nil) for i, suffix in ipairs(data.suffixes) do track_wrong_affix_type("suffix", suffix, "suffix") end -- Make links out of all the parts. local parts_formatted = {} if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end for i, suffix in ipairs(data.suffixes) do table.insert(parts_formatted, export.link_term(suffix, data)) end -- Insert the categories. for i, suffix in ipairs(data.suffixes) do -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", suffix) if suffix.pos and rfind(suffix.pos, "patronym") then table.insert(categories, "patronymics") end end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end return export nscaxh7immk8ixjsp8a7ejqv50o86ed 1349059 1349058 2026-04-08T17:56:42Z Swarabakti 18192 1349059 Scribunto text/plain local export = {} local debug_force_cat = false -- if set to true, always display categories even on userspace pages local m_links = require("Module:links") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local utilities_module = "Module:utilities" -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.affix_lang_data_module_prefix = "Module:affix/lang-data/" local rsub = m_str_utils.gsub local usub = m_str_utils.sub local ulen = m_str_utils.len local rfind = m_str_utils.find local rmatch = m_str_utils.match local u = m_str_utils.char local ucfirst = m_str_utils.ucfirst local unpack = unpack or table.unpack -- Lua 5.2 compatibility function export.affix_variants(canonical, variants) local mappings = {} for _, variant in ipairs(variants) do mappings[variant] = canonical end return mappings end function export.id_mapping(default, ids) local mapping = { default = default } if ids then for id, target in pairs(ids) do mapping[id] = target end end return mapping end function export.id_mapping_with_affix_variants(base, id_variants) local mappings = {} for id, variants in pairs(id_variants) do for _, variant in ipairs(variants) do mappings[variant] = export.id_mapping(base, {[id] = base}) end end return mappings end function export.merge_tables(...) local result = {} for i = 1, select('#', ...) do local t = select(i, ...) if t then for k, v in pairs(t) do result[k] = v end end end return result end -- Export this so the category code in [[Module:category tree/etymology]] can access it. export.langs_with_lang_specific_data = { ["az"] = true, ["fi"] = true, ["fr"] = true, ["izh"] = true, ["la"] = true, ["sah"] = true, ["tr"] = true, } local default_pos = "kata" --[==[ intro: ===About different types of hyphens ("template", "display" and "lookup"):=== * The "template hyphen" is the per-script hyphen character that is used in template calls to indicate that a term is an affix. This is always a single Unicode char, but there may be multiple possible hyphens for a given script. Normally this is just the regular hyphen character "-", but for some non-Latin-script languages (currently only right-to-left languages), it is different. * The "display hyphen" is the string (which might be an empty string) that is added onto a term as displayed and linked, to indicate that a term is an affix. Currently this is always either the same as the template hyphen or an empty string, but the code below is written generally enough to handle arbitrary display hyphens. Specifically: *# For East Asian languages, the display hyphen is always blank. *# For Arabic-script languages, either tatweel (ـ) or ZWNJ (zero-width non-joiner) are allowed as template hyphens, where ZWNJ is supported primarily for Farsi, because some suffixes have non-joining behavior. The display hyphen corresponding to tatweel is also tatweel, but the display hyphen corresponding to ZWNJ is blank (tatweel is also the default display hyphen, for calls to {{tl|prefix}}/{{tl|suffix}}/etc. that don't include an explicit hyphen). * The "lookup hyphen" is the hyphen that is used when looking up language-specific affix mappings. (These mappings are discussed in more detail below when discussing link affixes.) It depends only on the script of the affix in question. Most scripts (including East Asian scripts) use a regular hyphen "-" as the lookup hyphen, but Hebrew and Arabic have their own lookup hyphens (respectively maqqef and tatweel). Note that for Arabic in particular, there are three possible template hyphens that are recognized (tatweel, ZWNJ and regular hyphen), but mappings must use tatweel. ===About different types of affixes ("template", "display", "link", "lookup" and "category"):=== * A "template affix" is an affix in its source form as it appears in a template call. Generally, a template affix has an attached template hyphen (see above) to indicate that it is an affix and indicate what type of affix it is (prefix, suffix, interfix or circumfix), but some of the older-style templates such as {{tl|suffix}}, {{tl|prefix}}, {{tl|confix}}, etc. have "positional" affixes where the presence of the affix in a certain position (e.g. the second or third parameter) indicates that it is a certain type of affix, whether or not it has an attached template hyphen. * A "display affix" is the corresponding affix as it is actually displayed to the user. The display affix may differ from the template affix for various reasons: *# The display affix may be specified explicitly using the {{para|alt<var>N</var>}} parameter, the `<alt:...>` inline modifier or a piped link of the form e.g. `<nowiki>[[-kas|-käs]]</nowiki>` (here indicating that the affix should display as `-käs` but be linked as `-kas`). Here, the template affix is arguably the entire piped link, while the display affix is `-käs`. *# Even in the absence of {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers and piped links, certain languages have differences between the "template hyphen" specified in the template (which always needs to be specified somehow or other in templates like {{tl|affix}}, to indicate that the term is an affix and what type of affix it is) and the display hyphen (see above), with corresponding differences between template and display affixes. * A (regular) "link affix" is the affix that is linked to when the affix is shown to the user. The link affix is usually the same as the display affix, but will differ in one of three circumstances: *# The display and link affixes are explicitly made different using {{para|alt<var>N</var>}} parameters, `<alt:...>` inline modifiers or piped links, as described above under "display affix". *# For certain languages, certain affixes are mapped to canonical form using language-specific mappings. For example, in Finnish, the adjective-forming suffix {{m|fi|-kas}} appears as {{m|fi|-käs}} after front vowels, but logically both forms are the same suffix and should be linked and categorized the same. Similarly, in Latin, the negative and intensive prefixes spelled {{m|la|in-}} (etymologically two distinct prefixes) appear variously as {{m|la|il-}}, {{m|la|im-}} or {{m|la|ir-}} before certain consonants. Mappings are supplied in [[Module:affix/lang-data/LANGCODE]] to convert Finnish {{m|fi|-käs}} to {{m|fi|-kas}} for linking and categorization purposes. Note that the affixes in the mappings use "lookup hyphens" to indicate the different types of affixes, which is usually the same as the template hyphen but differs for Arabic scripts, because there are multiple possible template hyphens recognized but only one lookup hyphen (tatweel). The form of the affix as used to look up in the mapping tables is called the "lookup affix"; see below. * A "stripped link affix" is a link affix that has been passed through the language's `stripDiacritics()` function, which may strip certain diacritics: e.g. macrons in Latin and Old English (indicating length); acute and grave accents in Russian and various other Slavic languages (indicating stress); vowel diacritics in most Arabic-script languages; and also tatweel in some Arabic-script languages (currently, for example, Persian, Arabic and Urdu strip tatweel, but Ottoman Turkish does not). Stripped link affixes are currently what are used in category names. * A "lookup affix" is the form of the affix as it is looked up in the language-specific lookup mappings described above under link affixes. There are actually two lookup stages: *# First, the affix is looked up in a modified display form (specifically, the same as the display affix but using lookup hyphens). Note that this lookup does not occur if an explicit display form is given using {{para|alt<var>N</var>}} or an `<alt:...>` inline modifier, or if the template affix contains a piped or embedded link. *# If no entry is found, the affix is then looked up in a modified link form (specifically, the modified display form passed through the language's `stripDiacritics()` function, which strips out certain diacritics, but with the lookup hyphen re-added if it was stripped out, as in the case of tatweel in many Arabic-script languages). The reason for this double lookup procedure is to allow for mappings that are sensitive to the extra diacritics, but also allow for mappings that are not sensitive in this fashion (e.g. Russian {{m|ru|-ливый}} occurs both stressed and unstressed, but is the same prefix either way). * A "category affix" is the affix as it appears in categories such as [[:Category:Finnish terms suffixed with -kas| Category:Finnish terms suffixed with ''-kas'']]. The category affix is currently always the same as the stripped link affix. This means that for Arabic-script languages, it may or may not have a tatweel, even if the correponding display affix and regular link affix have a tatweel. As mentioned above, stripDiacritics() strips tatweel for Arabic, Persian and Urdu, but not for Ottoman Turkish. Hence affix categories for Arabic, Persian and Urdu will be missing the tatweel, but affix categories for Ottoman Turkish will have it. An additional complication is that if the template affix contains a ZWNJ, the display (and hence the link and category affixes) will have no hyphen attached in any case. ]==] ----------------------------------------------------------------------------------------- -- Template and display hyphens -- ----------------------------------------------------------------------------------------- --[=[ Per-script template hyphens. The template hyphen is what appears in the {{affix}}/{{prefix}}/{{suffix}}/etc. template (in the wikicode). See above. They key below is a script code, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' will match 'Arab'. The value below is a string consisting of one or more hyphen characters. If there is more than one character, the default hyphen must come last and a non-default function must be specified for the script in display_hyphens[] so the correct display hyphen will be specified when no template hyphen is given (in {{suffix}}/{{prefix}}/etc.). Script detection is normally done when linking, but we need to do it earlier. However, under most circumstances we don't need to do script detection. Specifically, we only need to do script detection for a given language if (a) the language has multiple scripts; and (b) at least one of those scripts is listed below or in display_hyphens. ]=] local ZWNJ = u(0x200C) -- zero-width non-joiner local template_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = "ـ" .. ZWNJ .. "-", -- tatweel + zero-width non-joiner + regular hyphen ["Hebr"] = "־", -- Hebrew-specific hyphen termed "maqqef" ["Mong"] = "᠊", -- FIXME! What about the following right-to-left scripts? -- Adlm (Adlam) -- Armi (Imperial Aramaic) -- Avst (Avestan) -- Cprt (Cypriot) -- Khar (Kharoshthi) -- Mand (Mandaic/Mandaean) -- Mani (Manichaean) -- Mend (Mende/Mende Kikakui) -- Narb (Old North Arabian) -- Nbat (Nabataean/Nabatean) -- Nkoo (N'Ko) -- Orkh (Orkhon runes) -- Phli (Inscriptional Pahlavi) -- Phlp (Psalter Pahlavi) -- Phlv (Book Pahlavi) -- Phnx (Phoenician) -- Prti (Inscriptional Parthian) -- Rohg (Hanifi Rohingya) -- Samr (Samaritan) -- Sarb (Old South Arabian) -- Sogd (Sogdian) -- Sogo (Old Sogdian) -- Syrc (Syriac) -- Thaa (Thaana) } -- Hyphens used when looking up an affix in a lang-specific affix mapping. Defaults to regular hyphen (-). The keys -- are script codes, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' -- will match 'Arab'. The value should be a single character. local lookup_hyphens = { ["Hebr"] = "־", -- This covers all Arabic scripts. See above. ["Arab"] = "ـ", } -- Default display-hyphen function. local function default_display_hyphen(script, hyph) if not hyph then return template_hyphens[script] or "-" end return hyph end local function arab_get_display_hyphen(script, hyph) if not hyph then return "ـ" -- tatweel elseif hyph == ZWNJ then return "" else return hyph end end local function no_display_hyphen(script, hyph) return "" end -- Per-script function to return the correct display hyphen given the script and template hyphen. The function should -- also handle the case where the passed-in template hyphen is nil, corresponding to the situation in -- {{prefix}}/{{suffix}}/etc. where no template hyphen is specified. The key is the script code after removing a hyphen -- and anything preceding, so 'fa-Arab', 'ur-Arab' etc. will match 'Arab'. local display_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = arab_get_display_hyphen, ["Bopo"] = no_display_hyphen, ["Hani"] = no_display_hyphen, ["Hans"] = no_display_hyphen, ["Hant"] = no_display_hyphen, -- The following is a mixture of several scripts. Hopefully the specs here are correct! ["Jpan"] = no_display_hyphen, ["Jurc"] = no_display_hyphen, ["Kitl"] = no_display_hyphen, ["Kits"] = no_display_hyphen, ["Laoo"] = no_display_hyphen, ["Nshu"] = no_display_hyphen, ["Shui"] = no_display_hyphen, ["Tang"] = no_display_hyphen, ["Thaa"] = no_display_hyphen, ["Thai"] = no_display_hyphen, } ----------------------------------------------------------------------------------------- -- Basic Utility functions -- ----------------------------------------------------------------------------------------- local function glossary_link(entry, text) text = text or entry return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]" end local function track(page) if type(page) == "table" then for i, pg in ipairs(page) do page[i] = "affix/" .. pg end else page = "affix/" .. page end require("Module:debug/track")(page) end local function ine(val) return val ~= "" and val or nil end ----------------------------------------------------------------------------------------- -- Compound types -- ----------------------------------------------------------------------------------------- local function make_compound_type(typ, alttext) return { text = glossary_link(typ, alttext) .. " compound", cat = typ .. " compounds", } end -- Make a compound type entry with a simple rather than glossary link. -- These should be replaced with a glossary link when the entry in the glossary -- is created. local function make_non_glossary_compound_type(typ, alttext) local link = alttext and "[[" .. typ .. "|" .. alttext .. "]]" or "[[" .. typ .. "]]" return { text = link .. " compound", cat = typ .. " compounds", } end local function make_raw_compound_type(typ, alttext) return { text = glossary_link(typ, alttext), cat = typ, } end local function make_borrowing_type(typ, alttext) return { text = glossary_link(typ, alttext), borrowing_type = typ, } end export.etymology_types = { ["adapted borrowing"] = make_borrowing_type("adapted borrowing"), ["adap"] = "adapted borrowing", ["abor"] = "adapted borrowing", ["alliterative"] = make_non_glossary_compound_type("alliterative"), ["allit"] = "alliterative", ["antonymous"] = make_non_glossary_compound_type("antonymous"), ["ant"] = "antonymous", ["bahuvrihi"] = make_compound_type("bahuvrihi", "bahuvrīhi"), ["bahu"] = "bahuvrihi", ["bv"] = "bahuvrihi", ["coordinative"] = make_compound_type("coordinative"), ["coord"] = "coordinative", ["descriptive"] = make_compound_type("descriptive"), ["desc"] = "descriptive", ["determinative"] = make_compound_type("determinative"), ["det"] = "determinative", ["dvandva"] = make_compound_type("dvandva"), ["dva"] = "dvandva", ["dvigu"] = make_compound_type("dvigu"), ["dvi"] = "dvigu", ["endocentric"] = make_compound_type("endocentric"), ["endo"] = "endocentric", ["exocentric"] = make_compound_type("exocentric"), ["exo"] = "exocentric", ["izafet I"] = make_compound_type("izafet I"), ["iz1"] = "izafet I", ["izafet II"] = make_compound_type("izafet II"), ["iz2"] = "izafet II", ["izafet III"] = make_compound_type("izafet III"), ["iz3"] = "izafet III", ["karmadharaya"] = make_compound_type("karmadharaya", "karmadhāraya"), ["karma"] = "karmadharaya", ["kd"] = "karmadharaya", ["kenning"] = make_raw_compound_type("kenning"), ["ken"] = "kenning", ["rhyming"] = make_non_glossary_compound_type("rhyming"), ["rhy"] = "rhyming", ["synonymous"] = make_non_glossary_compound_type("synonymous"), ["syn"] = "synonymous", ["tatpurusa"] = make_compound_type("tatpurusa", "tatpuruṣa"), ["tat"] = "tatpurusa", ["tp"] = "tatpurusa", } local function process_etymology_type(typ, nocap, notext, has_parts) local text_sections = {} local categories = {} local borrowing_type if typ then local typdata = export.etymology_types[typ] if type(typdata) == "string" then typdata = export.etymology_types[typdata] end if not typdata then error("Internal error: Unrecognized type '" .. typ .. "'") end local text = typdata.text if not nocap then text = ucfirst(text) end local cat = typdata.cat borrowing_type = typdata.borrowing_type local oftext = typdata.oftext or " of" if not notext then table.insert(text_sections, text) if has_parts then table.insert(text_sections, oftext) table.insert(text_sections, " ") end end if cat then table.insert(categories, cat) end end return text_sections, categories, borrowing_type end ----------------------------------------------------------------------------------------- -- Utility functions -- ----------------------------------------------------------------------------------------- -- Iterate an array up to the greatest integer index found. local function ipairs_with_gaps(t) local indices = m_table.numKeys(t) local max_index = #indices > 0 and math.max(unpack(indices)) or 0 local i = 0 return function() while i < max_index do i = i + 1 return i, t[i] end end end export.ipairs_with_gaps = ipairs_with_gaps --[==[ Join formatted parts (in `parts_formatted`) together with any overall {{para|lit}} spec (in `lit`) plus categories, which are formatted by prepending the language name as found in `lang`. The value of an entry in `categories` can be either a string (which is formatted using `sort_key`) or a table of the form `{ {cat=<var>category</var>, sort_key=<var>sort_key</var>, sort_base=<var>sort_base</var>}`, specifying the sort key and sort base to use when formatting the category. If `nocat` is given, no categories are added; otherwise, `force_cat` causes categories to be added even on userspace pages. ]==] function export.join_formatted_parts(data) local cattext local lang = data.data.lang local force_cat = data.data.force_cat or debug_force_cat if data.data.nocat then cattext = "" else for i, cat in ipairs(data.categories) do if type(cat) == "table" then data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat.cat, lang, cat.sort_key, cat.sort_base, force_cat) else data.categories[i] = require(utilities_module).format_categories(lang:getFullCode() .. ":" .. cat, lang, data.data.sort_key, nil, force_cat) end end cattext = table.concat(data.categories) end local result = table.concat(data.parts_formatted, not data.separator_already_added and " +&lrm; " or nil) .. (data.data.lit and ", literally " .. m_links.mark(data.data.lit, "gloss") or "") local q = data.data.q local qq = data.data.qq local l = data.data.l local ll = data.data.ll if q and q[1] or qq and qq[1] or l and l[1] or ll and ll[1] then result = require(pron_qualifier_module).format_qualifiers { lang = lang, text = result, q = q, qq = qq, l = l, ll = ll, } end return result .. cattext end -- Remove links and call lang:stripDiacritics(term). local function strip_diacritics_no_links(lang, term) return lang:stripDiacritics(m_links.remove_links(term)) end --[=[ Convert a raw part as passed into an entry point into a part ready for linking. `lang` and `sc` are the overall language and script objects. This uses the overall language and script objects as defaults for the part and parses off any fragment from the term. We need to do the latter so that fragments don't end up in categories and so that we correctly do affix mapping even in the presence of fragments. ]=] local function canonicalize_part(part, lang, sc) if not part then return end -- Save the original (user-specified, part-specific) value of `lang`. If such a value is specified, we don't insert -- a '*fixed with' category, and we format the part using format_derived() in [[Module:etymology]] rather than -- full_link() in [[Module:links]]. part.part_lang = part.lang part.lang = part.lang or lang part.sc = part.sc or sc local term = part.term if not term then return elseif not part.fragment then part.term, part.fragment = m_links.get_fragment(term) else part.term = m_links.get_fragment(term) end end --[==[ Construct a single linked part based on the information in `part`, for use by `show_affix()` and other entry points. This should be called after `canonicalize_part()` is called on the part. This is a thin wrapper around `full_link()` in [[Module:links]] unless `part.part_lang` is specified (indicating that a part-specific language was given), in which case `format_derived()` in [[Module:etymology]] is called to display a term in a language other than the language of the overall term (specified in `data.lang`). `data` contains the entire object passed into the entry point and is used to access information for constructing the categories added by `format_derived()`. ]==] function export.link_term(part, data, include_separator) local result if part.part_lang then result = require(etymology_module).format_derived { lang = data.lang, terms = {part}, sources = {part.lang}, sort_key = data.sort_key, nocat = data.nocat, template_name = "affix", qualifiers_labels_on_outside = true, borrowing_type = data.borrowing_type, force_cat = data.force_cat or debug_force_cat, } else result = m_links.full_link(part, "term", nil, "show qualifiers") end if include_separator and part.separator then return part.separator .. result else return result end end local function canonicalize_script_code(scode) -- Convert fa-Arab, ur-Arab etc. to Arab. return (scode:gsub("^.*%-", "")) end ----------------------------------------------------------------------------------------- -- Affix-handling functions -- ----------------------------------------------------------------------------------------- -- Figure out the appropriate script for the given affix and language (unless the script is explicitly passed in), and -- return the values of template_hyphens[], display_hyphens[] and lookup_hyphens[] for that script, substituting -- default values as appropriate. Four values are returned: -- DETECTED_SCRIPT, TEMPLATE_HYPHEN, DISPLAY_HYPHEN, LOOKUP_HYPHEN local function detect_script_and_hyphens(text, lang, sc) local scode -- 1. If the script is explicitly passed in, use it. if sc then scode = sc:getCode() else local possible_script_codes = lang:getScriptCodes() -- YUCK! `possible_script_codes` comes from loadData() so #possible_scripts doesn't work (always returns 0). local num_possible_script_codes = m_table.length(possible_script_codes) if num_possible_script_codes == 0 then -- This shouldn't happen; if the language has no script codes, -- the list {"None"} should be returned. error("Something is majorly wrong! Language " .. lang:getCanonicalName() .. " has no script codes.") end if num_possible_script_codes == 1 then -- 2. If the language has only one possible script, use it. scode = possible_script_codes[1] else -- 3. Check if any of the possible scripts for the language have non-default values for template_hyphens[] -- or display_hyphens[]. If so, we need to do script detection on the text. If not, just use "Latn", -- which may not be technically correct but produces the right results because Latn has all default -- values for template_hyphens[] and display_hyphens[]. local may_have_nondefault_hyphen = false for _, script_code in ipairs(possible_script_codes) do script_code = canonicalize_script_code(script_code) if template_hyphens[script_code] or display_hyphens[script_code] then may_have_nondefault_hyphen = true break end end if not may_have_nondefault_hyphen then scode = "Latn" else scode = lang:findBestScript(text):getCode() end end end scode = canonicalize_script_code(scode) local template_hyphen = template_hyphens[scode] or "-" local lookup_hyphen = lookup_hyphens[scode] or "-" local display_hyphen = display_hyphens[scode] or default_display_hyphen return scode, template_hyphen, display_hyphen, lookup_hyphen end --[=[ Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function reconstruct_term_per_hyphens(term, affix_type, scode, thyph_re, new_hyphen) local function get_hyphen(hyph) if type(new_hyphen) == "string" then return new_hyphen end return new_hyphen(scode, hyph) end if affix_type == "non-affix" then return term elseif affix_type == "circumfix" then local before, before_hyphen, after_hyphen, after = rmatch(term, "^(.*)" .. thyph_re .. " " .. thyph_re .. "(.*)$") if not before or ulen(term) <= 3 then -- Unlike with other types of affixes, don't try to add hyphens in the middle of the term to convert it to -- a circumfix. Also, if the term is just hyphen + space + hyphen, return it. return term end return before .. get_hyphen(before_hyphen) .. " " .. get_hyphen(after_hyphen) .. after elseif affix_type == "infix" or affix_type == "interfix" then local before_hyphen, middle, after_hyphen = rmatch(term, "^" .. thyph_re .. "(.*)" .. thyph_re .. "$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "prefix" then local middle, after_hyphen = rmatch(term, "^(.*)" .. thyph_re .. "$") if middle and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "suffix" then local before_hyphen, middle = rmatch(term, "^" .. thyph_re .. "(.*)$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) else error(("Internal error: Unrecognized affix type '%s'"):format(affix_type)) end end --[=[ Look up a mapping from a given affix variant to the canonical form used in categories and links. The lookup tables are language-specific according to `lang`, and may be ID-specific according to `affix_id`. The affixes as they appear in the lookup tables (both the variant and the canonical form) are in "lookup affix" format (approximately speaking, they use a regular hyphen for most scripts, but a tatweel for Arabic-script entries and a maqqef for Hebrew-script entries), but the passed-in `affix` param is in "template affix" format (which differs from the lookup affix for Arabic-script entries, because more types of hyphens are allowed in template affixes; see the comments at the top of the file). The remaining parameters to this function are used to convert from template affixes to lookup affixes; see the reconstruct_term_per_hyphens() function above. If the affix contains brackets, no lookup is done. Otherwise, a two-stage process is used, first looking up the affix directly and then stripping diacritics and looking it up again. The reason for this is documented above in the comments at the top of the file (specifically, the comments describing lookup affixes). The value of a mapping can either be a string (do the mapping regardless of affix ID) or a table indexed by affix ID (where the special value `false` indicates no affix ID). The values of entries in this table can also be strings, or tables with keys `affix` and `id` (again, use `false` to indicate no ID). This allows an affix mapping to map from one ID to another (for example, this is used in English to map the [[an-]] prefix with no ID to the [[a-]] prefix with the ID 'not'). The Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function lookup_affix_mapping(affix, affix_type, lang, scode, thyph_re, lookup_hyph, affix_id) local function do_lookup(affix) -- Ensure that the affix uses lookup hyphens regardless of whether it used a different type of hyphens before -- or no hyphens. local lookup_affix = reconstruct_term_per_hyphens(affix, affix_type, scode, thyph_re, lookup_hyph) local function do_lookup_for_langcode(langcode) if export.langs_with_lang_specific_data[langcode] then local langdata = mw.loadData(export.affix_lang_data_module_prefix .. langcode) if langdata.affix_mappings then local mapping = langdata.affix_mappings[lookup_affix] if mapping then if type(mapping) == "table" then mapping = mapping[affix_id] or mapping.default or mapping[affix_id or false] if mapping then return mapping end else return mapping end end end end end -- If `lang` is an etymology-only language, look for a mapping both for it and its full parent. local langcode = lang:getCode() local mapping = do_lookup_for_langcode(langcode) if mapping then return mapping end local full_langcode = lang:getFullCode() if full_langcode ~= langcode then mapping = do_lookup_for_langcode(full_langcode) if mapping then return mapping end end return nil end if affix:find("%[%[") then return nil end return do_lookup(affix) or do_lookup(lang:stripDiacritics(affix)) or nil end --[==[ For a given template term in a given language (see the definition of "template affix" near the top of the file), possibly in an explicitly specified script `sc` (but usually nil), return the term's affix type ({"prefix"}, {"interfix"}, {"suffix"}, {"circumfix"} or {"non-affix"}) along with the corresponding link and display affixes (see definitions near the top of the file); also the corresponding lookup affix (if `return_lookup_affix` is specified). The term passed in should already have any fragment (after the # sign) parsed off of it. Four values are returned: `affix_type`, `link_term`, `display_term` and `lookup_term`. The affix type can be passed in instead of autodetected; in this case, the template term need not have any attached hyphens, and the appropriate hyphens will be added in the appropriate places. If `do_affix_mapping` is specified, look up the affix in the lang-specific affix mappings, as described in the comment at the top of the file; otherwise, the link and display terms will always be the same. (They will be the same in any case if the template term has a bracketed link in it or is not an affix.) If `return_lookup_affix` is given, the fourth return value contains the term with appropriate lookup hyphens in the appropriate places; otherwise, it is the same as the display term. (This functionality is used in [[Module:category tree/affixes and compounds]] to convert link affixes into lookup affixes so that they can be looked up in the affix mapping tables.) ]==] local function parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not term then return "non-affix", nil, nil, nil end if term == "^" then -- Indicates a null term to emulate the behavior of {{suffix|foo||bar}}. term = "" return "non-affix", term, term, term end if term:find("^%^") then -- HACK! ^ at the beginning of Korean languages has a special meaning, triggering capitalization of the -- transliteration. Don't interpret it as "force non-affix" for those languages. local langcode = lang:getCode() if langcode ~= "ko" and langcode ~= "okm" and langcode ~= "jje" then -- Formerly we allowed ^ to force non-affix type; this is now handled using an inline modifier -- <naf>, <root>, etc. Throw an error for the moment when the old way is encountered. error("Use of ^ to force non-affix status is no longer supported; use an inline modifier <naf> or <root> " .. "after the component") end end -- Remove an asterisk if the morpheme is reconstructed and add it back at the end. local reconstructed = "" if term:find("^%*") then reconstructed = "*" term = term:gsub("^%*", "") end local scode, thyph, dhyph, lhyph = detect_script_and_hyphens(term, lang, sc) thyph = "([" .. thyph .. "])" if not affix_type then if rfind(term, thyph .. " " .. thyph) then affix_type = "circumfix" else local has_beginning_hyphen = rfind(term, "^" .. thyph) local has_ending_hyphen = rfind(term, thyph .. "$") if has_beginning_hyphen and has_ending_hyphen then affix_type = "interfix" elseif has_ending_hyphen then affix_type = "prefix" elseif has_beginning_hyphen then affix_type = "suffix" else affix_type = "non-affix" end end end local link_term, display_term, lookup_term if affix_type == "non-affix" then link_term = term display_term = term lookup_term = term else display_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, dhyph) if do_affix_mapping then link_term = lookup_affix_mapping(term, affix_type, lang, scode, thyph, lhyph, affix_id) -- The return value of lookup_affix_mapping() may be an affix mapping with lookup hyphens if a mapping -- was found, otherwise nil if a mapping was not found. We need to convert to display hyphens in -- either case, but in the latter case we can reuse the display term, which has already been converted. if link_term then link_term = reconstruct_term_per_hyphens(link_term, affix_type, scode, thyph, dhyph) else link_term = display_term end else link_term = display_term end if return_lookup_affix then lookup_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, lhyph) else lookup_term = display_term end end link_term = reconstructed .. link_term display_term = reconstructed .. display_term lookup_term = reconstructed .. lookup_term return affix_type, link_term, display_term, lookup_term end --[==[ Add a hyphen to a term in the appropriate place, based on the specified affix type, stripping off any existing hyphens in that place. For example, if `affix_type` == {"prefix"}, we'll add a hyphen onto the end if it's not already there (or is of the wrong type). Three values are returned: the link term, display term and lookup term. This function is a thin wrapper around `parse_term_for_affixes`; see the comments above that function for more information. Note that this function is exposed externally because it is called by [[Module:category tree/affixes and compounds]]; see the comment in `parse_term_for_affixes` for more information. ]==] function export.make_affix(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not (affix_type == "prefix" or affix_type == "suffix" or affix_type == "circumfix" or affix_type == "infix" or affix_type == "interfix" or affix_type == "non-affix") then error("Internal error: Invalid affix type " .. (affix_type or "(nil)")) end local _, link_term, display_term, lookup_term = parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) return link_term, display_term, lookup_term end ----------------------------------------------------------------------------------------- -- Main entry points -- ----------------------------------------------------------------------------------------- --[==[ Core categorization logic for affixes. This is shared between show_affix(), show_compound_like() and get_affix_categories_only(). Returns the categories array and other metadata needed for formatting. ]==] local function generate_affix_categories(data) data.pos = data.pos or default_pos local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.surface_analysis or data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type -- Process each part local whole_words = 0 local is_affix_or_compound = false -- Canonicalize and generate links for all the parts first; then do categorization in a separate step, because when -- processing the first part for categorization, we may access the second part and need it already canonicalized. for i, part in ipairs_with_gaps(data.parts) do part = part or {} data.parts[i] = part canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). Store them in the part -- (in fields that won't clash with fields used by full_link() in [[Module:links]] or link_term()), so they -- can be used in the loop below when categorizing. part.affix_type, part.affix_link_term, part.affix_display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with inline -- modifiers. The intention in either case is not to link the term. part.term = ine(part.affix_link_term) -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt or (part.affix_display_term ~= part.affix_link_term and part.affix_display_term) or nil end -- Now do categorization. for i, part in ipairs_with_gaps(data.parts) do local affix_type = part.affix_type if affix_type ~= "non-affix" then is_affix_or_compound = true -- Make a sort key. For the first part, use the second part as the sort key; the intention is that if the -- term has a prefix, sorting by the prefix won't be very useful so we sort by what follows, which is -- presumably the root. local part_sort_base = nil local part_sort = part.sort or data.sort_key if i == 1 and data.parts[2] and data.parts[2].term then local part2 = data.parts[2] -- If the second-part link term is empty, the user requested an unlinked term; avoid a wikitext error -- by using the alt value if available. part_sort_base = ine(part2.affix_link_term) or ine(part2.alt) if part_sort_base then part_sort_base = strip_diacritics_no_links(part2.lang, part_sort_base) end end if part.pos and rfind(part.pos, "patronym") then table.insert(categories, {cat = "patronymics", sort_key = part_sort, sort_base = part_sort_base}) end if data.pos ~= "kata" and part.pos and rfind(part.pos, "diminutif") then table.insert(categories, {cat = "Bentuk diminutif" .. data.pos, sort_key = part_sort, sort_base = part_sort_base}) end -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if ine(part.affix_link_term) and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.affix_link_term) .. (part.id and " (" .. part.id .. ")" or ""), sort_key = part_sort, sort_base = part_sort_base}) end else whole_words = whole_words + 1 if whole_words == 2 then is_affix_or_compound = true table.insert(categories, "Gabungan " .. data.pos) end end end -- Make sure there was either an affix or a compound (two or more non-affix terms). if not is_affix_or_compound and not data.allow_no_affixes_or_compounds then error("The parameters did not include any affixes, and the term is not a compound. Please provide at least one affix.") end return text_sections, categories, borrowing_type end --[==[ Implementation of {{tl|affix}} and {{tl|surface analysis}}. `data` contains all the information describing the affixes to be displayed, and contains the following: * `.lang` ('''required'''): Overall language object. Different from term-specific language objects (see `.parts` below). * `.sc`: Overall script object (usually omitted). Different from term-specific script objects. * `.parts` ('''required'''): List of objects describing the affixes to show. The general format of each object is as would be passed to `full_link()`, except that the `.lang` field should be missing unless the term is of a language different from the overall `.lang` value (in such a case, the language name is shown along with the term and an additional "derived from" category is added). '''WARNING''': The data in `.parts` will be destructively modified. * `.pos`: Overall part of speech (used in categories, defaults to {"terms"}). Different from term-specific part of speech. * `.sort_key`: Overall sort key. Normally omitted except e.g. in Japanese. * `.type`: Type of compound, if the parts in `.parts` describe a compound. Strictly optional, and if supplied, the compound type is displayed before the parts (normally capitalized, unless `.nocap` is given). * `.nocap`: Don't capitalize the first letter of text displayed before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.notext`: Don't display any text before the parts (relevant only if `.type` or `.surface_analysis` is given). * `.nocat`: Disable all categorization. * `.lit`: Overall literal definition. Different from term-specific literal definitions. * `.force_cat`: Always display categories, even on userspace pages. * `.surface_analysis`: Implement {{surface analysis}}; adds `By surface analysis, ` before the parts. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_affix(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if data.surface_analysis then local text = "by " .. glossary_link("surface analysis") .. ", " if not data.nocap then text = ucfirst(text) end table.insert(text_sections, 1, text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Get only the categories that would be generated by show_affix(), without any text output or formatting. This is used by Module:etymon to get affix categorization. Returns an array of category objects, where each entry is either a string (simple category name) or a table with keys `cat`, `sort_key`, and `sort_base` for more complex categorization. `data` should have the same structure as passed to show_affix(): * `.lang` (required): Overall language object * `.parts` (required): Array of affix part objects with `.term`, `.lang`, `.id`, etc. * `.pos`: Part of speech (defaults to "terms") * `.sort_key`: Overall sort key for categories '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.get_affix_categories_only(data) local text_sections, categories, borrowing_type = generate_affix_categories(data) return categories end function export.show_surface_analysis(data) data.surface_analysis = true return export.show_affix(data) end --[==[ Implementation of {{tl|compound}}. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound(data) data.pos = data.pos or default_pos local text_sections, categories, borrowing_type = process_etymology_type(data.type, data.nocap, data.notext, #data.parts > 0) data.borrowing_type = borrowing_type local parts_formatted = {} table.insert(categories, "Gabungan " .. data.pos) -- Make links out of all the parts local whole_words = 0 for i, part in ipairs(data.parts) do canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). local affix_type, link_term, display_term = parse_term_for_affixes(part.term, part.lang, part.sc, part.type, not part.alt, nil, part.id) -- If the term is an interfix or the type was explicitly given, recognize it as such (which means e.g. that we -- will display the term without hyphens for East Asian languages). Otherwise, ignore the fact that it looks -- like an affix and display as specified in the template (but pay attention to the detected affix type for -- certain tracking purposes). if affix_type == "interfix" or (part.type and part.type ~= "non-affix") then -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with -- inline modifiers. The intention in either case is not to link the term. Don't add a '*fixed with' -- category in this case, or if the term is in a different language. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. if link_term and link_term ~= "" and not part.part_lang then table.insert(categories, {cat = data.pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, link_term), sort_key = part.sort or data.sort_key}) end part.term = link_term ~= "" and link_term or nil part.alt = part.alt or (display_term ~= link_term and display_term) or nil else if affix_type ~= "non-affix" then local langcode = data.lang:getCode() -- If `data.lang` is an etymology-only language, track both using its code and its full parent's code. track { affix_type, affix_type .. "/lang/" .. langcode } local full_langcode = data.lang:getFullCode() if langcode ~= full_langcode then track(affix_type .. "/lang/" .. full_langcode) end else whole_words = whole_words + 1 end end table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if whole_words == 1 then track("one whole word") elseif whole_words == 0 then track("looks like confix") end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Implementation of {{tl|blend}}, {{tl|univerbation}} and similar "compound-like" templates. '''WARNING''': This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound_like(data) data.allow_no_affixes_or_compounds = true local text_sections, categories, borrowing_type = generate_affix_categories(data) if data.cat then table.insert(categories, data.cat) end -- Process each part for display local parts_formatted = {} for i, part in ipairs_with_gaps(data.parts) do -- Make a link for the part table.insert(parts_formatted, export.link_term(part, data, "include_separator")) end if #data.parts > 0 and data.oftext then table.insert(text_sections, 1, " " .. data.oftext .. " ") end if data.text then table.insert(text_sections, 1, data.text) end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories, separator_already_added = true }) return table.concat(text_sections) end --[==[ Make `part` (a structure holding information on an affix part) into an affix of type `affix_type`, and apply any relevant affix mappings. For example, if the desired affix type is "suffix", this will (in general) add a hyphen onto the beginning of the term, alt, tr and ts components of the part if not already present. The hyphen that's added is the "display hyphen" (see above) and may be script-specific. (In the case of East Asian scripts, the display hyphen is an empty string whereas the template hyphen is the regular hyphen, meaning that any regular hyphen at the beginning of the part will be effectively removed.) `lang` and `sc` hold overall language and script objects. Note that this also applies any language-specific affix mappings, so that e.g. if the language is Finnish and the user specified [[-käs]] in the affix and didn't specify an `.alt` value, `part.term` will contain [[-kas]] and `part.alt` will contain [[-käs]]. This function is used by the "legacy" templates ({{tl|prefix}}, {{tl|suffix}}, {{tl|confix}}, etc.) where the nature of the affix is specified by the template itself rather than auto-determined from the affix, as is the case with {{tl|affix}}. '''WARNING''': This destructively modifies `part`. ]==] local function make_part_into_affix(part, lang, sc, affix_type) canonicalize_part(part, lang, sc) local link_term, display_term = export.make_affix(part.term, part.lang, part.sc, affix_type, not part.alt, nil, part.id) part.term = link_term -- When we don't specify `do_affix_mapping` to make_affix(), link and display terms (first and second retvals of -- make_affix()) are the same. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt and export.make_affix(part.alt, part.lang, part.sc, affix_type) or (display_term ~= link_term and display_term) or nil local Latn = require(scripts_module).getByCode("Latn") part.tr = export.make_affix(part.tr, part.lang, Latn, affix_type) part.ts = export.make_affix(part.ts, part.lang, Latn, affix_type) end local function track_wrong_affix_type(template, part, expected_affix_type) if part and not part.type then local affix_type = parse_term_for_affixes(part.term, part.lang, part.sc) if affix_type ~= expected_affix_type then local part_name = expected_affix_type or "base" local langcode = part.lang:getCode() local full_langcode = part.lang:getFullCode() require("Module:debug/track") { template, template .. "/" .. part_name, template .. "/" .. part_name .. "/" .. (affix_type or "none"), template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. langcode } -- If `part.lang` is an etymology-only language, track both using its code and its full parent's code. if full_langcode ~= langcode then require("Module:debug/track")( template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. full_langcode ) end end end end local function insert_affix_category(categories, pos, affix_type, part, sort_key, sort_base) -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if part.term and not part.part_lang then local cat = pos .. " dengan " .. affix_type .. strip_diacritics_no_links(part.lang, part.term) .. (part.id and " (" .. part.id .. ")" or "") if sort_key or sort_base then table.insert(categories, {cat = cat, sort_key = sort_key, sort_base = sort_base}) else table.insert(categories, cat) end end end --[==[ Implementation of {{tl|circumfix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_circumfix(data) data.pos = data.pos or default_pos canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("circumfix", data.prefix, "prefix") track_wrong_affix_type("circumfix", data.base, nil) track_wrong_affix_type("circumfix", data.suffix, "suffix") -- Create circumfix term. local circumfix = nil if data.prefix.term and data.suffix.term then circumfix = data.prefix.term .. " " .. data.suffix.term data.prefix.alt = data.prefix.alt or data.prefix.term data.suffix.alt = data.suffix.alt or data.suffix.term data.prefix.term = circumfix data.suffix.term = circumfix end -- Make links out of all the parts. local parts_formatted = {} local categories = {} local sort_base if data.base.term then sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) end table.insert(parts_formatted, export.link_term(data.prefix, data)) table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.suffix, data)) -- Insert the categories, but don't add a '*fixed with' category if the link term is in a different language. if not data.prefix.part_lang then table.insert(categories, {cat=data.pos .. " dengan apitan " .. strip_diacritics_no_links(data.prefix.lang, circumfix), sort_key=data.sort_key, sort_base=sort_base}) end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|confix}}. '''WARNING''': This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_confix(data) data.pos = data.pos or default_pos canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix") track_wrong_affix_type("confix", data.prefix, "prefix") track_wrong_affix_type("confix", data.base, nil) track_wrong_affix_type("confix", data.suffix, "suffix") -- Make links out of all the parts. local parts_formatted = {} local prefix_sort_base if data.base and data.base.term then prefix_sort_base = strip_diacritics_no_links(data.base.lang, data.base.term) elseif data.suffix.term then prefix_sort_base = strip_diacritics_no_links(data.suffix.lang, data.suffix.term) end -- Insert the categories and parts. local categories = {} table.insert(parts_formatted, export.link_term(data.prefix, data)) insert_affix_category(categories, data.pos, "prefix", data.prefix, data.sort_key, prefix_sort_base) if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) end table.insert(parts_formatted, export.link_term(data.suffix, data)) -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", data.suffix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|infix}}. '''WARNING''': This destructively modifies both `data` and `.base` and `.infix`. ]==] function export.show_infix(data) data.pos = data.pos or default_pos canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.infix, data.lang, data.sc, "infix") track_wrong_affix_type("infix", data.base, nil) track_wrong_affix_type("infix", data.infix, "infix") -- Make links out of all the parts. local parts_formatted = {} local categories = {} table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.infix, data)) -- Insert the categories. -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "infix", data.infix) return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|prefix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.prefixes`, as well as `.base`. ]==] function export.show_prefix(data) data.pos = data.pos or default_pos canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, prefix in ipairs(data.prefixes) do make_part_into_affix(prefix, data.lang, data.sc, "prefix") end for i, prefix in ipairs(data.prefixes) do track_wrong_affix_type("prefix", prefix, "prefix") end track_wrong_affix_type("prefix", data.base, nil) -- Make links out of all the parts. local parts_formatted = {} local first_sort_base = nil local categories = {} if data.prefixes[2] then first_sort_base = ine(data.prefixes[2].term) or ine(data.prefixes[2].alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.prefixes[2].lang, first_sort_base) end elseif data.base then first_sort_base = ine(data.base.term) or ine(data.base.alt) if first_sort_base then first_sort_base = strip_diacritics_no_links(data.base.lang, first_sort_base) end end for i, prefix in ipairs(data.prefixes) do table.insert(parts_formatted, export.link_term(prefix, data)) insert_affix_category(categories, data.pos, "prefix", prefix, data.sort_key, i == 1 and first_sort_base or nil) end if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end --[==[ Implementation of {{tl|suffix}}. '''WARNING''': This destructively modifies both `data` and the structures within `.suffixes`, as well as `.base`. ]==] function export.show_suffix(data) local categories = {} data.pos = data.pos or default_pos canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, suffix in ipairs(data.suffixes) do make_part_into_affix(suffix, data.lang, data.sc, "suffix") end track_wrong_affix_type("suffix", data.base, nil) for i, suffix in ipairs(data.suffixes) do track_wrong_affix_type("suffix", suffix, "suffix") end -- Make links out of all the parts. local parts_formatted = {} if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end for i, suffix in ipairs(data.suffixes) do table.insert(parts_formatted, export.link_term(suffix, data)) end -- Insert the categories. for i, suffix in ipairs(data.suffixes) do -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", suffix) if suffix.pos and rfind(suffix.pos, "patronym") then table.insert(categories, "patronymics") end end return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end return export kfpiz4nb6cjiwy4p3i127ljeqm3f09d Templat:ubor 10 247732 1349103 1022367 2026-04-08T18:42:53Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:unadapted borrowing]] ke [[Templat:serapan utuh]] 1349103 wikitext text/x-wiki #ALIH [[Templat:serapan utuh]] 9hgp2vwliz440laz20ym3h0yragyd3k Modul:etymology/specialized 828 247733 1348965 1107946 2026-04-08T15:51:23Z Swarabakti 18192 1348965 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getCanonicalName() .. " " .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serap terjemah", "dari" inscat("terms calqued from") elseif bortype == "partial-calque" then text, prep = "serap terjemah sebagian", "dari" inscat("terms partially calqued from") elseif bortype == "semantic-loan" then text, prep = "serap makna", "dari" inscat("semantic loans from") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("terms borrowed from") inscat("transliterations of DISPLAY terms") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("phono-semantic matchings from") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("terms borrowed back into") else inscat("terms borrowed from") if bortype ~= "borrowing" then inscat( "serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "dipinjam", "loanword", "dari", "adjective" elseif ( bortype == "sengaja" or bortype == "semi-sengaja" or bortype == "ejaan" or bortype == "utuh" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "lebur" then text, prep = "serapan " .. bortype, "dari" else error("Internal error: Unrecognized bortype: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "from" end appendix = "Appendix:Glossary#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export 6na189jgpdyqedx802ejp3sgv4mip3a 1348978 1348965 2026-04-08T16:14:39Z Swarabakti 18192 1348978 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getFullCode() .. ":" .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serapan terjemah", "dari" inscat("Serapan terjemah dari") elseif bortype == "partial-calque" then text, prep = "serapan terjemah sebagian", "dari" inscat("Serapan terjemah sebagian dari") elseif bortype == "semantic-loan" then text, prep = "serapan semantik", "dari" inscat("Serapan semantik dari") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("Serapan dari") inscat("Alih aksara dari istilah DISPLAY") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("Pemadanan fono-semantik dari") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("Serapan balik ke") else inscat("Serapan dari") if bortype ~= "borrowing" then inscat( "Serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "diserap", "loanword", "dari", "adjective" elseif ( bortype == "sengaja" or bortype == "semi-sengaja" or bortype == "ejaan" or bortype == "utuh" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "lebur" then text, prep = "serapan " .. bortype, "dari" else error("Galat internal: Jenis serapan tidak diketahui: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "dari" end appendix = "Appendix:Glossary#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export tdevnvawea6v1xzziqvirou88z632rh 1348996 1348978 2026-04-08T16:44:40Z Swarabakti 18192 1348996 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getFullCode() .. ":" .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serapan terjemah", "dari" inscat("Serapan terjemah dari") elseif bortype == "partial-calque" then text, prep = "serapan terjemah sebagian", "dari" inscat("Serapan terjemah sebagian dari") elseif bortype == "semantic-loan" then text, prep = "serapan semantik", "dari" inscat("Serapan semantik dari") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("Serapan dari") inscat("Alih aksara dari istilah DISPLAY") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("Pemadanan fono-semantik dari") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("Serapan balik ke") else inscat("Serapan dari") if bortype ~= "borrowing" then inscat( "Serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "diserap", "serapan", "dari", "adjektiva" elseif ( bortype == "sengaja" or bortype == "semi-sengaja" or bortype == "ejaan" or bortype == "utuh" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "lebur" then text, prep = "serapan " .. bortype, "dari" else error("Galat internal: Jenis serapan tidak diketahui: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "dari" end appendix = "Lampiran:Glosarium#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export 18s2rjjrb8cw0ieqran4hxds6qgy85c 1349065 1348996 2026-04-08T18:09:09Z Swarabakti 18192 1349065 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getFullCode() .. ":" .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serapan terjemah", "dari" inscat("Serapan terjemah dari") elseif bortype == "partial-calque" then text, prep = "serapan terjemah sebagian", "dari" inscat("Serapan terjemah sebagian dari") elseif bortype == "semantic-loan" then text, prep = "serapan semantik", "dari" inscat("Serapan semantik dari") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("Serapan dari") inscat("Alih aksara dari istilah DISPLAY") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("Pemadanan fono-semantik dari") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("Serapan balik ke") else inscat("Serapan dari") if bortype ~= "borrowing" then inscat( "Serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "diserap", "serapan", "dari", "adjektiva" elseif ( bortype == "sengaja" or bortype == "semi-sengaja" or bortype == "ejaan" or bortype == "langsung" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "adaptasi" then text, prep = "serapan " .. bortype, "dari" else error("Galat internal: Jenis serapan tidak diketahui: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "dari" end appendix = "Lampiran:Glosarium#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export qwe0gcn6wyf7hsc1uib5rtz1soyoqtk 1349066 1349065 2026-04-08T18:10:23Z Swarabakti 18192 1349066 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getFullCode() .. ":" .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serapan terjemahan", "dari" inscat("Serapan terjemahan dari") elseif bortype == "partial-calque" then text, prep = "serapan terjemahan sebagian", "dari" inscat("Serapan terjemahan sebagian dari") elseif bortype == "semantic-loan" then text, prep = "serapan semantik", "dari" inscat("Serapan semantik dari") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("Serapan dari") inscat("Alih aksara dari istilah DISPLAY") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("Pemadanan fono-semantik dari") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("Serapan balik ke") else inscat("Serapan dari") if bortype ~= "borrowing" then inscat( "Serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "diserap", "serapan", "dari", "adjektiva" elseif ( bortype == "sengaja" or bortype == "semi-sengaja" or bortype == "ejaan" or bortype == "langsung" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "adaptasi" then text, prep = "serapan " .. bortype, "dari" else error("Galat internal: Jenis serapan tidak diketahui: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "dari" end appendix = "Lampiran:Glosarium#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export 1pibbwqkwge6p0jn6we5yswnr9g65ws 1349068 1349066 2026-04-08T18:19:59Z Swarabakti 18192 1349068 Scribunto text/plain local export = {} local m_str_utils = require("Module:string utilities") local en_utilities_module = "Module:en-utilities" local etymology_module = "Module:etymology" local gsub = m_str_utils.gsub local insert = table.insert local pluralize = require(en_utilities_module).pluralize local upper = m_str_utils.upper -- This function handles all the messiness of different types of specialized borrowings. It should insert any -- borrowing-type-specific categories into `categories` unless `nocat` is given, and return the text to display -- before the source + term (or "" for no text). local function get_specialized_borrowing_text_insert_cats(data) local bortype, categories, lang, terms, source, nocap, nocat, senseid = data.bortype, data.categories, data.lang, data.terms, data.source, data.nocap, data.nocat, data.senseid local function inscat(cat) if not nocat then local display, sourcedisp = require(etymology_module).get_display_and_cat_name(source, "raw") if cat:find("DISPLAY") then cat = cat:gsub("DISPLAY", display) elseif cat:find("SOURCE") then cat = cat:gsub("SOURCE", sourcedisp) else cat = cat .. " " .. sourcedisp end insert(categories, lang:getFullCode() .. ":" .. cat) end end -- `text` is the display text for the borrowing type, which gets converted -- into a link. -- `appendix` is a the glossary anchor, which defaults to `text` -- `prep` is the preposition between the borrowing type and the language -- name (e.g. "of", "from") -- `pos` is the part of speech for the borrowing type ("noun" or -- "adjective"; defaults to "noun") -- `plural` is the plural form of the borrowing type; if not specified, -- the pluralize function is used local text, appendix, prep, pos, plural if bortype == "calque" then text, prep = "serapan terjemahan", "dari" inscat("Serapan terjemahan dari") elseif bortype == "partial-calque" then text, prep = "serapan terjemahan sebagian", "dari" inscat("Serapan terjemahan sebagian dari") elseif bortype == "semantic-loan" then text, prep = "serapan semantik", "dari" inscat("Serapan semantik dari") elseif bortype == "transliteration" then text, prep = "alih aksara", "dari" inscat("Serapan dari") inscat("Alih aksara dari istilah DISPLAY") elseif bortype == "phono-semantic-matching" then text, prep = "pemadanan fono-semantik", "dari" inscat("Pemadanan fono-semantik dari") else local langcode = lang:getCode() local lang_is_source = langcode == source:getCode() if lang_is_source then -- Track, because this shouldn't be happening. A language can only have itself as a source further up the chain after a borrowing, which is always "derived". require("Module:debug/track"){ "etymology/specialized/self-as-source", "etymology/specialized/self-as-source/" .. langcode } inscat("Serapan balik ke") else inscat("Serapan dari") if bortype ~= "borrowing" then inscat( "Serapan " .. bortype .. " dari") end end if bortype == "borrowing" then text, appendix, prep, pos = "diserap", "serapan", "dari", "adjektiva" elseif ( bortype == "terencana" or bortype == "semi-terencana" or bortype == "ejaan" or bortype == "utuh" ) then text, prep = "serapan " .. bortype, "dari" elseif bortype == "lebur" then text, prep = "serapan " .. bortype, "dari" else error("Galat internal: Jenis serapan tidak diketahui: " .. bortype) end end -- If the term is suppressed, the preposition should always be "from": -- "Calque of Chinese 中國". -- "Calque from Chinese" (not "Calque of Chinese"). if terms[1].term == "-" then prep = "dari" end appendix = "Lampiran:Glosarium#" .. (appendix or text) if senseid then local senseids, output = mw.text.split(senseid, '!!'), {} for i, id in ipairs(senseids) do -- FIXME: This should be done via a function. insert(output, mw.getCurrentFrame():preprocess('{{senseno|' .. lang:getCode() .. '|' .. id .. (i == 1 and not nocap and "|uc=1" or "") .. '}}')) end local link if senseid:find('!!') then link, text = "are", pos == "adjective" and text or plural or pluralize(text) else link = pos == "adjective" and "is" or "is a" end text = mw.text.listToText(output) .. " " .. link .. " " .. '[[' .. appendix .. '|' .. text .. ']]' else text = "[[" .. appendix .. "|" .. (nocap and text or gsub(text, "^.", upper)) .. "]]" end return text .. " " .. prep .. " " end function export.specialized_borrowing(data) local lang, sources, terms = data.lang, data.sources, data.terms local categories = {} local text for _, source in ipairs(sources) do text = get_specialized_borrowing_text_insert_cats { bortype = data.bortype, categories = categories, lang = lang, terms = terms, source = source, nocap = data.nocap, nocat = data.nocat, senseid = data.senseid, } end text = data.notext and "" or text local sourcetext = require(etymology_module).format_sources { lang = lang, sources = sources, terms = terms, sort_key = data.sort_key, categories = categories, nocat = data.nocat, sourceconj = data.sourceconj, } return text .. require(etymology_module).format_links(terms, data.conj, "etymology/specialized", sourcetext) end return export 6y76zildwlv8o71l56tgz6jjjay7unh Templat:serapan semi-terencana 10 247734 1349069 1022372 2026-04-08T18:20:56Z Swarabakti 18192 1349069 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=semi-terencana}}</includeonly><noinclude>{{semi-learned borrowing|id|id|rencana}}. {{documentation}}</noinclude> qwm0m97ix6b9py70qhgive8rzvzif1u 1349077 1349069 2026-04-08T18:23:39Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:semi-learned borrowing]] ke [[Templat:serapan semi-terencana]] 1349069 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=semi-terencana}}</includeonly><noinclude>{{semi-learned borrowing|id|id|rencana}}. {{documentation}}</noinclude> qwm0m97ix6b9py70qhgive8rzvzif1u Templat:slbor 10 247735 1349105 1022373 2026-04-08T18:43:27Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:semi-learned borrowing]] ke [[Templat:serapan semi-terencana]] 1349105 wikitext text/x-wiki #ALIH [[Templat:serapan semi-terencana]] rparyvy73im6gnzub1qml22klvl9l20 Templat:serapan ejaan 10 247736 1349070 1022375 2026-04-08T18:21:23Z Swarabakti 18192 1349070 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=ejaan}}</includeonly><noinclude>{{orthographic borrowing|mul|mul|term}}. {{documentation}}</noinclude> d9zkftb4wjvycr4q69garuwo4dwsmux 1349071 1349070 2026-04-08T18:21:35Z Swarabakti 18192 1349071 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=ejaan}}</includeonly><noinclude>{{orthographic borrowing|id|id|eja}}. {{documentation}}</noinclude> ig3xvtxv78ped076nhnvgu2l96m1nsa 1349079 1349071 2026-04-08T18:25:01Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:orthographic borrowing]] ke [[Templat:serapan ejaan]] 1349071 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=ejaan}}</includeonly><noinclude>{{orthographic borrowing|id|id|eja}}. {{documentation}}</noinclude> ig3xvtxv78ped076nhnvgu2l96m1nsa Templat:obor 10 247737 1349104 1022376 2026-04-08T18:43:06Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:orthographic borrowing]] ke [[Templat:serapan ejaan]] 1349104 wikitext text/x-wiki #ALIH [[Templat:serapan ejaan]] kk6z8ualogs9ml7rs5yl8yhjvgc6lu9 Templat:serapan terjemahan 10 247738 1349083 1022378 2026-04-08T18:30:06Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:calque]] ke [[Templat:serapan terjemahan]] 1022377 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=calque}}</includeonly><noinclude>{{calque|mul|mul|term}}{{documentation}}</noinclude> kznslps4iqgblj8juwdwhjgon8xma1j 1349089 1349083 2026-04-08T18:34:07Z Swarabakti 18192 1349089 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=calque}}</includeonly><noinclude>{{serapan terjemahan|id|id|serap}}.{{documentation}}</noinclude> r6hnbo68eclnh9zg7sf85j5alyav2na Templat:cal 10 247739 1349085 1022379 2026-04-08T18:30:32Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:calque]] ke [[Templat:serapan terjemahan]] 1349085 wikitext text/x-wiki #ALIH [[Templat:serapan terjemahan]] tavmub705ntquh2fwtbxattuguv6bvj Templat:serapan terjemahan sebagian 10 247740 1349086 1022381 2026-04-08T18:31:01Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:partial calque]] ke [[Templat:serapan terjemahan sebagian]] 1022380 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=partial-calque}}</includeonly><noinclude>{{partial calque|mul|mul|term}}{{documentation}}</noinclude> jcxnmd7x7ce7bg2907yols8io1dhyv7 1349090 1349086 2026-04-08T18:34:21Z Swarabakti 18192 1349090 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=partial calque}}</includeonly><noinclude>{{serapan terjemahan sebagian|id|id|serap}}.{{documentation}}</noinclude> 46j3svhj4u71buzfrux6u02be2qopii 1349091 1349090 2026-04-08T18:34:30Z Swarabakti 18192 1349091 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=partial-calque}}</includeonly><noinclude>{{serapan terjemahan sebagian|id|id|serap}}.{{documentation}}</noinclude> 2qpz98awvd2ulyjzxbtozsrpnabpdht Templat:pcal 10 247741 1349088 1022382 2026-04-08T18:31:19Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:partial calque]] ke [[Templat:serapan terjemahan sebagian]] 1349088 wikitext text/x-wiki #ALIH [[Templat:serapan terjemahan sebagian]] 3gvefjeu6hc9ukx9eqb3jjrrcu579gi Templat:serapan semantik 10 247742 1349092 1022383 2026-04-08T18:35:52Z Swarabakti 18192 1349092 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=semantic-loan}}</includeonly><noinclude>{{serapan semantik|id|id|serap}}.{{documentation}}</noinclude> e7d4iu85lig21vsemeja1dd6x59pzg1 1349093 1349092 2026-04-08T18:36:03Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:semantic loan]] ke [[Templat:serapan semantik]] 1349092 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=semantic-loan}}</includeonly><noinclude>{{serapan semantik|id|id|serap}}.{{documentation}}</noinclude> e7d4iu85lig21vsemeja1dd6x59pzg1 Templat:alih aksara 10 247743 1349099 1022385 2026-04-08T18:41:30Z Swarabakti 18192 1349099 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=transliteration}}</includeonly><noinclude>{{alih aksara|id|id|serap}}.{{documentation}}</noinclude> rohgcozatehw4ujr2dsnajq2dijvjnh 1349100 1349099 2026-04-08T18:41:38Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:transliteration]] ke [[Templat:alih aksara]] 1349099 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=transliteration}}</includeonly><noinclude>{{alih aksara|id|id|serap}}.{{documentation}}</noinclude> rohgcozatehw4ujr2dsnajq2dijvjnh Templat:translit 10 247744 1349102 1022386 2026-04-08T18:42:04Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:transliteration]] ke [[Templat:alih aksara]] 1349102 wikitext text/x-wiki #ALIH [[Templat:alih aksara]] ce59my92wgw550drmc1oz9xd440vow0 Templat:pemadanan fono-semantik 10 247745 1349095 1022388 2026-04-08T18:37:45Z Swarabakti 18192 1349095 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=phono-semantic-matching}}</includeonly><noinclude>{{pemadanan fono-semantik|id|id|serap}}.{{documentation}}</noinclude> 5ctb7tr89uxn2iozpg7afwo3j3yz2vd 1349096 1349095 2026-04-08T18:37:55Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:phono-semantic matching]] ke [[Templat:pemadanan fono-semantik]] 1349095 wikitext text/x-wiki <noinclude>: </noinclude><includeonly>{{#invoke:etymology/templates|specialized_borrowing|bortype=phono-semantic-matching}}</includeonly><noinclude>{{pemadanan fono-semantik|id|id|serap}}.{{documentation}}</noinclude> 5ctb7tr89uxn2iozpg7afwo3j3yz2vd Templat:psm 10 247746 1349098 1022389 2026-04-08T18:40:54Z Swarabakti 18192 Ubah target pengalihan dari [[Templat:phono-semantic matching]] ke [[Templat:pemadanan fono-semantik]] 1349098 wikitext text/x-wiki #ALIH [[Templat:pemadanan fono-semantik]] muohw41fqp9satnhwjw6t1k6vtytmhm Modul:etymology/templates/descendant 828 247748 1348986 1022393 2026-04-08T16:22:20Z Swarabakti 18192 1348986 Scribunto text/plain local export = {} local debug_track_module = "Module:debug/track" local descendants_tree_module = "Module:descendants tree" local etymology_style_css = "Module:etymology/style.css" local labels_module = "Module:labels" local languages_module = "Module:languages" local links_module = "Module:links" local parameter_utilities_module = "Module:parameter utilities" local pron_qualifier_module = "Module:pron qualifier" local qualifier_module = "Module:qualifier" local scripts_module = "Module:scripts" local table_module = "Module:table" local table_module_list_to_set = "Module:table/listToSet" local template_styles_module = "Module:TemplateStyles" local concat = table.concat local insert = table.insert local rsplit = mw.text.split local list_to_set = require(table_module_list_to_set) local error_on_no_descendants = false local function track(page) return require(debug_track_module)("descendant/" .. page) end local function ine(arg) if arg == "" then return nil else return arg end end local function add_tooltip(text, tooltip) return '<span class="desc-arr" title="' .. tooltip .. '">' .. text .. '</span>' end -- Boolean params indicating whether a descendant term (or all terms) are particular sorts of borrowings. local bortypes = {"inh", "bor", "lbor", "slb", "obor", "translit", "der", "clq", "pclq", "sml", "unc"} local bortype_set = list_to_set(bortypes) -- Aliases of clq=. local calque_aliases = {"cal", "calq", "calque"} local calque_alias_set = list_to_set(calque_aliases) -- Aliases of pclq=. local partial_calque_aliases = {"pcal", "pcalq", "pcalque"} local partial_calque_alias_set = list_to_set(partial_calque_aliases) --- Return a function of one argument `field` (a param name), which fetches `args`[`field`].default if index == 0, else --- `container`[`field`]. local function get_val(container, args, index) return function(field) if index == 0 then return args[field].default else return container[field] end end end local function get_arrow(container, args, index) local val = get_val(container, args, index) local arrow if val("bor") then arrow = add_tooltip("→", "serapan") elseif val("lbor") then arrow = add_tooltip("→", "serapan sengaja") elseif val("slb") then arrow = add_tooltip("→", "serapan semi-sengaja") elseif val("obor") then arrow = add_tooltip("→", "serapan ejaan") elseif val("translit") then arrow = add_tooltip("→", "alih aksara") elseif val("clq") then arrow = add_tooltip("→", "serapan terjemah") elseif val("pclq") then arrow = add_tooltip("→", "serapan terjemah sebagian") elseif val("sml") then arrow = add_tooltip("→", "serapan semantik") elseif val("inh") or (val("unc") and not val("der")) then arrow = add_tooltip(">", "warisan") else arrow = "" end -- allow der=1 in conjunction with bor=1 to indicate e.g. English "pars recta" -- derived and borrowed from Latin "pars". if val("der") then arrow = arrow .. add_tooltip("⇒", "pembentukan ulang melalui analogi atau penambahan morfem") end if val("unc") then arrow = arrow .. add_tooltip("?", "tidak pasti") end if arrow ~= "" then arrow = arrow .. " " end return arrow end -- Return the pre-qualifier text for the `index`th term, or the overall pre-qualifier text if index == 0. local function get_pre_qualifiers_labels(container, args, index) if index > 0 then -- per term labels and qualifiers are handled at the subitem level, by full_link(). return nil, nil end local val = get_val(container, args, index) return val("l"), val("q") end -- Return the post-qualifier text for the `index`th term, or the overall post-qualifier text if index == 0. local function get_post_qualifiers_labels(container, args, index, lang) local val = get_val(container, args, index) local boolean_labels = {} if val("inh") then insert(boolean_labels, "inherited") end if val("lbor") then insert(boolean_labels, "learned") end if val("slb") then insert(boolean_labels, "semi-learned") end if val("translit") then insert(boolean_labels, "transliteration") end if val("clq") then insert(boolean_labels, "calque") end if val("pclq") then insert(boolean_labels, "partial calque") end if val("sml") then insert(boolean_labels, "semantic loan") end if index > 0 then -- per term labels, qualifiers and references are handled at the subitem level, by full_link(). return boolean_labels else local quals, refs, dash_labels quals = val("qq") if val("ll") then local labels = require(labels_module).show_labels { lang = lang, labels = val("ll"), nocat = true, open = false, close = false, no_track_already_seen = true, ok_to_destructively_modify = true, -- doesn't apply to `labels` } if labels ~= "" then dash_labels = " &mdash; " .. labels end end return boolean_labels, quals, dash_labels end end local function desc_or_desc_tree(frame, desc_tree) local params local boolean = {type = "boolean"} if desc_tree then params = { [1] = {required = true, type = "language", family = true, default = "gem-pro"}, [2] = {required = true, list = true, allow_holes = true, default = "*fuhsaz"}, notext = boolean, noalts = boolean, noparent = boolean, } else params = { [1] = {required = true, type = "language", family = true, default = "en"}, [2] = {list = true, allow_holes = true, template_default = "word"}, alts = boolean, } end -- Add other single params. params.sclang = boolean params.sclb = {replaced_by = "sclang", reason = "to avoid confusion with 'labels' as in [[Template:lb]]"} params.nolang = boolean params.nolb = {replaced_by = "nolang", reason = "to avoid confusion with 'labels' as in [[Template:lb]]"} local parent_args if frame.args[1] then parent_args = frame.args else parent_args = frame:getParent().args end -- Error to catch most uses of old-style parameters. if ine(parent_args[4]) and not ine(parent_args[3]) and not ine(parent_args.tr2) and not ine(parent_args.ts2) and not ine(parent_args.t2) and not ine(parent_args.gloss2) and not ine(parent_args.g2) and not ine(parent_args.alt2) then error("You specified a term in 4= and not one in 3=. You probably meant to use t= to specify a gloss instead. " .. "If you intended to specify two terms, put the second term in 3=.") end if not ine(parent_args[3]) and not ine(parent_args.alt2) and not ine(parent_args.tr2) and not ine(parent_args.ts2) and ine(parent_args.g2) then error("You specified a gender in g2= but no term in 3=. You were probably trying to specify two genders for " .. "a single term. To do that, put both genders in g=, comma-separated.") end local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { {group = {"link", "ref", "l", "q"}}, {param = "lb", replaced_by = false, instead = "use 'l' for left labels or 'll' for right labels"}, {param = bortypes, type = "boolean", overall = true, separate_no_index = true}, {param = calque_aliases, alias_of = "clq"}, {param = partial_calque_aliases, alias_of = "pclq"}, } local groups, args, globalprops = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 2, -- Need some work to support this. -- parse_lang_prefix = true, track_module = "descendant", -- Due to allowing families as langs and substituting 'und', it's easier to do this later. -- lang = function() ... end sc = "sc.default", splitchar = "[,~]", subitem_separator_map = {[","] = "/", ["~"] = " ~ "}, pre_normalize_modifiers = function(data) local modtext = data.modtext modtext = modtext:match("^<(.*)>$") if not modtext then error(("Internal error: Passed-in modifier isn't surrounded by angle brackets: %s"):format( data.modtext)) end if bortype_set[modtext] or calque_alias_set[modtext] or partial_calque_alias_set[modtext] then modtext = modtext .. ":1" end return "<" .. modtext .. ">" end, } local lang = args[1] local namespace = mw.title.getCurrentTitle().nsText if (namespace == "" or namespace == "Reconstruction") and ( lang:hasType("appendix-constructed") and not lang:hasType("regular")) then error("Terms in appendix-only constructed languages may not be given as descendants.") end local fetch_alt_forms = desc_tree and not args.noalts or not desc_tree and args.alts local m_desctree if desc_tree or fetch_alt_forms then m_desctree = require(descendants_tree_module) end if lang:getCode() ~= lang:getFullCode() then -- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/etymological]] track("etymological") track("etymological/" .. lang:getCode()) end local is_family = lang:hasType("family") local proxy_lang if is_family then -- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/family]] track("family") track("family/" .. lang:getCode()) proxy_lang = require(languages_module).getByCode("und") else proxy_lang = lang end local langname if is_family then -- The display form for families includes the word "languages", which we probably don't want to -- display. langname = lang:getCanonicalName() else langname = lang:getDisplayForm() end local langtag if args.sclang then local sc_to_use = args.sc.default if not sc_to_use then local first_termobj = groups[1] and groups[1].terms[1] if not first_termobj then error("sclang= given but no term exists to display the script name of") end sc_to_use = first_termobj.sc if not sc_to_use then local first_term = first_termobj.term or first_termobj.alt if not first_term then error("sclang= given but first specified item no term or display form to display the script name of") end if first_termobj.lang then sc_to_use = first_termobj.lang:findBestScript(first_term) elseif is_family then sc_to_use = require(scripts_module).findBestScriptWithoutLang(first_term, "none is last resort") else sc_to_use = lang:findBestScript(first_term) end end end langtag = sc_to_use:getDisplayForm() else langtag = langname end local terms_for_descendant_trees = {} -- Keep track of descendants whose descendant tree we fetch. Don't fetch the same descendant tree twice (which -- can happen especially with Arabic-script terms with the same unvocalized spelling but differing vocalization). -- This happens e.g. with Ottoman Turkish [[پورتقال]], which has {{desctree|fa-cls|پُرْتُقَال|پُرْتِقَال|bor=1}}, with -- two terms that have the same unvocalized spelling. local terms_and_ids_fetched = {} local descendant_terms_seen = {} local parts = {} for i, group in ipairs(groups) do local group_parts = {} local terms_for_alt_forms = {} for _, item in ipairs(group.terms) do local link = "" item.lang = item.lang or proxy_lang item.track_sc = true -- Construct a link out of `item`. Also add the term to the list of descendant trees and/or alternative -- forms to fetch, if the page+ID combination hasn't already been seen. if item.term ~= "-" then -- including term == nil item.show_qualifiers = true link = require(links_module).full_link(item, nil, true) if item.term and (desc_tree or fetch_alt_forms) then local m_links = require(links_module) -- Fetches information under entry. If term is of type A//B, it checks A. local entry_name = m_links.get_link_page(m_links.remove_links(mw.ustring.gsub(item.term, "//.+$", "")), lang, sc) -- NOTE: We use the term and ID as the key, but not the language. This is OK currently because -- all terms have the same language; but if we ever add support for a term-specific language, -- we need to fix this. local term_and_id = item.id and entry_name .. "!!!" .. item.id or entry_name if not terms_and_ids_fetched[term_and_id] then terms_and_ids_fetched[term_and_id] = true local term_for_fetching = { lang = lang, entry_name = entry_name, id = item.id } if desc_tree then if is_family then error("No support currently (and probably ever) for fetching a descendant tree when a family code instead of language code is given") end if error_on_no_descendants then require(table_module).insertIfNot(descendant_terms_seen, { term = item.term, id = item.id }) end table.insert(terms_for_descendant_trees, term_for_fetching) end if fetch_alt_forms then if is_family then error("No support currently (and probably ever) for fetching alternative forms when a family code instead of language code is given") end -- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/alts]] track("alts") table.insert(terms_for_alt_forms, term_for_fetching) end end end elseif item.tr or item.ts or item.gloss or item.genders then -- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/no term]] track("no term") item.term = nil item.show_qualifiers = true link = require(links_module).full_link(item, nil, true) link = link :gsub("<small>%[Term%?%]</small> ", "") :gsub("<small>%[Term%?%]</small>&nbsp;", "") :gsub("%[%[Category:[^%[%]]+ term requests%]%]", "") else -- display no link at all -- [[Special:WhatLinksHere/Wiktionary:Tracking/descendant/no term or annotations]] track("no term or annotations") end if link ~= "" then insert(group_parts, item.separator) insert(group_parts, link) end end if group_parts[1] then for _, altterm in ipairs(terms_for_alt_forms) do local altform = m_desctree.get_alternative_forms(altterm.lang, altterm.entry_name, altterm.id, globalprops.use_semicolon and "; " or ", ") if altform ~= "" then insert(group_parts, globalprops.use_semicolon and "; " or ", ") insert(group_parts, altform) end end local group_link = concat(group_parts) insert(parts, group.separator) if not args.notext then insert(parts, get_arrow(group, args, i)) end -- no pre-qualifiers/labels and no post-qualifiers/dash-labels local post_boolean_labels = get_post_qualifiers_labels(group, args, i, proxy_lang) if post_boolean_labels and post_boolean_labels[1] then group_link = require(pron_qualifier_module).format_qualifiers { lang = proxy_lang, text = group_link, ll = post_boolean_labels, } end insert(parts, group_link) end end local descendant_trees = {} for _, descterm in ipairs(terms_for_descendant_trees) do -- When I ([[User:Benwing2]]) first implemented this in Nov 2020, I had `maxmaxindex > 1` as the last argument. -- Since then, [[User:Fytcha]] changed the last param to `true`. local descendant_tree = m_desctree.get_descendants(descterm.lang, descterm.entry_name, descterm.id, true) if descendant_tree and descendant_tree ~= "" then insert(descendant_trees, descendant_tree) end end if error_on_no_descendants and desc_tree and not descendant_trees[1] then local function format_term_seen(term_seen) if term_seen.id then return ("[[%s]] with ID '%s'"):format(term_seen.term, term_seen.id) else return ("[[%s]]"):format(term_seen.term) end end if #descendant_terms_seen == 0 then error("[[Template:desctree]] invoked but no terms to retrieve descendants from") elseif #descendant_terms_seen == 1 then error(("No Descendants section was found in the entry %s under the header for %s"):format( format_term_seen(descendant_terms_seen[1]), lang:getFullName())) else for i, term_seen in ipairs(descendant_terms_seen) do descendant_terms_seen[i] = format_term_seen(term_seen) end error(("No Descendants section was found in any of the entries %s under the header for %s"):format( concat(descendant_terms_seen, ", "), lang:getFullName())) end end local descendants = concat(descendant_trees) if args.noparent then return descendants end local initial_labels, initial_quals = get_pre_qualifiers_labels(nil, args, 0) local final_boolean_labels, final_quals, final_dash_labels = get_post_qualifiers_labels(nil, args, 0, proxy_lang) local all_linktext = concat(parts) if initial_labels and initial_labels[1] or initial_quals and initial_quals[1] or final_boolean_labels and final_boolean_labels[1] or final_quals and final_quals[1] or final_refs and final_refs[1] then all_linktext = require(pron_qualifier_module).format_qualifiers { lang = proxy_lang, text = all_linktext, l = initial_labels, q = initial_quals, ll = final_boolean_labels, qq = final_quals, } end if final_dash_labels then all_linktext = all_linktext .. final_dash_labels end all_linktext = all_linktext .. descendants if args.notext then return all_linktext end local initial_arrow = get_arrow(nil, args, 0) if args.nolang then return initial_arrow .. all_linktext else return concat { initial_arrow, langtag, ":", all_linktext ~= "" and " " or "", all_linktext } end end function export.descendant(frame) return desc_or_desc_tree(frame, false) .. require(template_styles_module)(etymology_style_css) end function export.descendants_tree(frame) return desc_or_desc_tree(frame, true) end return export nbkbfe3sag05acrcb9733qr2q37rdc9 Templat:unknown 10 247872 1349057 1081227 2026-04-08T17:43:33Z Swarabakti 18192 1349057 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant_no_term|text={{#if:{{{nocap|}}}|t|T}}idak diketahui|cat=Istilah dengan etimologi yang tidak diketahui|title2_alias=1}}<noinclude>. {{documentation}}</noinclude> avcek5rpdvyxb8gtzwl1veckxk8cj5x 1349114 1349057 2026-04-08T19:06:45Z Swarabakti 18192 1349114 wikitext text/x-wiki <noinclude>: </noinclude>{{#invoke:etymology/templates|misc_variant_no_term|text={{#if:{{{nocap|}}}|t|T}}idak diketahui|cat=Istilah dengan etimologi yang tidak diketahui|title2_alias=1}}<noinclude>. {{dokumentasi}}</noinclude> horaqtzsdbg7rhl0b646xt463umqat4 Templat:bentuk kembar/dokumentasi 10 250021 1349115 1030522 2026-04-08T19:07:58Z Swarabakti 18192 1349115 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:dbt}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang diserap dari bahasa lain. ===Parameter=== ; <code>1=</code> : The language code (see [[Wiktionary:Languages]]) of the language this term appears in. All Wiktionary language codes are supported, including those for constructed and reconstructed languages. ; <code>2=</code>, <code>3=</code>, <code>4=</code>, <code>5=</code> : The term(s) that this term is a doublet of. The template will automatically remove diacritics and punctuation from the page title, according to the <code>entry_name</code> setting in [[Module:languages]], but will keep them in the displayed text. To link to a reconstructed term, such as Proto-Germanic {{m|gem-pro|*dagaz}}, add * in front of this parameter. ; <code>nocap=1</code> : Show the initial text with a lowercase initial letter. ; <code>notext=1</code> : Omit the initial text altogether. The first thing displayed will be the first term listed (i.e. the contents of {{para|2}}). ; <code>nocat=1</code> : Do not categorize the entry. This should be used when mentioning blends in languages other than the current language. The following parameters are available for each matching term in the numbered/positional parameters. The <code>''N''</code> must be replaced by the corresponding term index. For example, for the second part (positional parameter 3), use 2 for <code>''N''</code>. Most of these parameters correspond directly to the equivalent parameters in the standard {{temp|l}} (and {{temp|m}}) template. ; <code>alt''N''=</code> : The alternative display form. Equivalent to the second parameter of {{temp|l}}. ; <code>t''N''=</code> : A gloss/translation to show after the term. Equivalent to the third parameter of {{temp|l}}. <small>The parameter <code>gloss''N''=</code> is deprecated for this purpose.</small> ; <code>tr''N''=</code> : The transliteration, as in {{temp|l}}. ; <code>pos''N''=</code> : The part of speech label to show after the term, as in {{temp|l}}. ; <code>sc''N''=</code> : The script code (see [[Wiktionary:Scripts]]) for the script that the term is written in. When no code is given, the template will try to detect the script based on the characters in the term and the scripts in the language's data table (see {{section link|Module:scripts#findBestScript}}). In most cases, it will succeed. If it fails, the code <code>None</code> will be used. ; <code>g''N''=</code> : Zero or more gender/number codes for the term, comma-separated; see [[Module:gender and number]] for details. ; <code>lit''N''=</code> : A literal translation for the term. ; <code>id''N''=</code> : A sense id for the term, which links to anchors on the page set by the {{temp|senseid}} template. ===Examples=== <code><nowiki>{{doublet|en|fire}}</nowiki></code> produces :{{doublet|en|fire}} <code><nowiki>{{doublet|es|directo|notext=1}}</nowiki></code> produces :{{doublet|es|directo|notext=1}} <code><nowiki>{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}}</nowiki></code> produces :{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}} <code><nowiki>{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}}</nowiki></code> produces :{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}} <code><nowiki>{{doublet|en|advoke|avouch|avow}}</nowiki></code> produces :{{doublet|en|advoke|avouch|avow}} ===Examples=== <code><nowiki>{{doublet|en|fire}}</nowiki></code> produces :{{doublet|en|fire}} <code><nowiki>{{doublet|es|directo|notext=1}}</nowiki></code> produces :{{doublet|es|directo|notext=1}} <code><nowiki>{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}}</nowiki></code> produces :{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}} <code><nowiki>{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}}</nowiki></code> produces :{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}} <code><nowiki>{{doublet|en|advoke|avouch|avow}}</nowiki></code> produces :{{doublet|en|advoke|avouch|avow}} <includeonly>[[Kategori:Templat etimologi]]</includeonly> dc199fc6qpw5kwlcugcr57o04o8lzjj 1349118 1349115 2026-04-08T19:09:17Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kembaran/dokumentasi]] ke [[Templat:bentuk kembar/dokumentasi]] 1349115 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:dbt}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang diserap dari bahasa lain. ===Parameter=== ; <code>1=</code> : The language code (see [[Wiktionary:Languages]]) of the language this term appears in. All Wiktionary language codes are supported, including those for constructed and reconstructed languages. ; <code>2=</code>, <code>3=</code>, <code>4=</code>, <code>5=</code> : The term(s) that this term is a doublet of. The template will automatically remove diacritics and punctuation from the page title, according to the <code>entry_name</code> setting in [[Module:languages]], but will keep them in the displayed text. To link to a reconstructed term, such as Proto-Germanic {{m|gem-pro|*dagaz}}, add * in front of this parameter. ; <code>nocap=1</code> : Show the initial text with a lowercase initial letter. ; <code>notext=1</code> : Omit the initial text altogether. The first thing displayed will be the first term listed (i.e. the contents of {{para|2}}). ; <code>nocat=1</code> : Do not categorize the entry. This should be used when mentioning blends in languages other than the current language. The following parameters are available for each matching term in the numbered/positional parameters. The <code>''N''</code> must be replaced by the corresponding term index. For example, for the second part (positional parameter 3), use 2 for <code>''N''</code>. Most of these parameters correspond directly to the equivalent parameters in the standard {{temp|l}} (and {{temp|m}}) template. ; <code>alt''N''=</code> : The alternative display form. Equivalent to the second parameter of {{temp|l}}. ; <code>t''N''=</code> : A gloss/translation to show after the term. Equivalent to the third parameter of {{temp|l}}. <small>The parameter <code>gloss''N''=</code> is deprecated for this purpose.</small> ; <code>tr''N''=</code> : The transliteration, as in {{temp|l}}. ; <code>pos''N''=</code> : The part of speech label to show after the term, as in {{temp|l}}. ; <code>sc''N''=</code> : The script code (see [[Wiktionary:Scripts]]) for the script that the term is written in. When no code is given, the template will try to detect the script based on the characters in the term and the scripts in the language's data table (see {{section link|Module:scripts#findBestScript}}). In most cases, it will succeed. If it fails, the code <code>None</code> will be used. ; <code>g''N''=</code> : Zero or more gender/number codes for the term, comma-separated; see [[Module:gender and number]] for details. ; <code>lit''N''=</code> : A literal translation for the term. ; <code>id''N''=</code> : A sense id for the term, which links to anchors on the page set by the {{temp|senseid}} template. ===Examples=== <code><nowiki>{{doublet|en|fire}}</nowiki></code> produces :{{doublet|en|fire}} <code><nowiki>{{doublet|es|directo|notext=1}}</nowiki></code> produces :{{doublet|es|directo|notext=1}} <code><nowiki>{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}}</nowiki></code> produces :{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}} <code><nowiki>{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}}</nowiki></code> produces :{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}} <code><nowiki>{{doublet|en|advoke|avouch|avow}}</nowiki></code> produces :{{doublet|en|advoke|avouch|avow}} ===Examples=== <code><nowiki>{{doublet|en|fire}}</nowiki></code> produces :{{doublet|en|fire}} <code><nowiki>{{doublet|es|directo|notext=1}}</nowiki></code> produces :{{doublet|es|directo|notext=1}} <code><nowiki>{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}}</nowiki></code> produces :{{doublet|ja|tr1=Mosukō|モスコー|nocap=1}} <code><nowiki>{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}}</nowiki></code> produces :{{doublet|ja|ヴィエンヌ|tr1=Viennu|t1=[[Vienne]]|ウィーン|tr2=Wīn}} <code><nowiki>{{doublet|en|advoke|avouch|avow}}</nowiki></code> produces :{{doublet|en|advoke|avouch|avow}} <includeonly>[[Kategori:Templat etimologi]]</includeonly> dc199fc6qpw5kwlcugcr57o04o8lzjj Pengguna:Swarabakti 2 250466 1349153 1261710 2026-04-09T04:03:34Z Swarabakti 18192 tes 1349153 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id|entry=gula}} {{-n-|id}} # bahan [[pemanis]] dalam bentuk [[padatan]] atau [[butiran]] yang dibuat dari air [[tebu]], [[aren]], atau [[kelapa]] ==Halo!== Tolong ingatkan saya setiap kali melakukan kesalahan. Terima kasih! — [[Pembicaraan pengguna:Swarabakti|<span title="ngobrol">'''<span style="color:#008080">swarabakti<sup>💬</sup></span>'''</span>]] 23 Januari 2026 10.31 (UTC) {| style="float:right" |{{#babel:id|mui|en-3|bew-2}} |- |{{Pengguna pengurus}} |- |{{Peserta WikiTutur}} |} ==Proyek== * [[:Kategori:id:Lema]] * [[:Kategori:bew:Lema]] * [[:Kategori:mui-plm:Lema]] * [[:Wikikamus:ProyekWiki Verifikasi Kosakata]] ltnsdknk3h2unoya1divnwysca1p9o8 lambuik 0 250761 1348928 1211388 2026-04-08T12:54:06Z Ardzun 8096 1348928 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min|num=1}} : {{suara|min|LL-Q13324_(min)-Dhynyhafuza-lambuik.wav}} {{-var-}} *{{l|min|lombuik}} (dialek) {{-adj-|min}} # [[lembut]] #:{{syn|min|lunak|aluih}} #:'''''lambuik''' bana kue tu mah'' #: '''lembut''' sekali kue itu {{kepala|min|num=2}} {{-v-|min}} # [[lecut]] #:{{syn|min|ampeh|bae|lacuik}} #:'''''lambuik''' se lah inyo lai'' #:: '''lecut''' saja dia lagi [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] e3l6c768z0c7nz5xj4ud56gqpz8rrd5 1348930 1348928 2026-04-08T12:54:55Z Ardzun 8096 /* {{bahasa|min}} */ 1348930 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min|num=1}} : {{suara|min|LL-Q13324_(min)-Dhynyhafuza-lambuik.wav}} {{-var-}} *{{l|min|lombuik}} (dialek) {{-adj-|min}} # [[lembut]] #:{{syn|min|lunak|aluih}} #:'''''lambuik''' bana kue tu mah'' #: '''lembut''' sekali kue itu {{-turunan-}} {{kotak|min|title=Gabungan kata |lamah lambuik }} {{kotak|min|title=Peribahasa |lambuik gigi pado lidah}} {{kepala|min|num=2}} {{-v-|min}} # [[lecut]] #:{{syn|min|ampeh|bae|lacuik}} #:'''''lambuik''' se lah inyo lai'' #:: '''lecut''' saja dia lagi [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] gy7x2y8azjyhizuuxg3zdgx8uhd57ae 1348931 1348930 2026-04-08T12:56:03Z Ardzun 8096 /* {{bahasa|min}} */ 1348931 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min|num=1}} : {{suara|min|LL-Q13324_(min)-Dhynyhafuza-lambuik.wav}} {{-var-}} *{{l|min|lombuik}} (dialek) {{-adj-|min}} # [[lembut]] #:{{syn|min|lunak|aluih}} #:'''''lambuik''' bana kue tu mah'' #: '''lembut''' sekali kue itu {{-turunan-}} {{kotak|min|title=Gabungan kata |lamah lambuik }} {{kotak|min|title=Peribahasa |lambuik gigi pado lidah}} {{kepala|min|num=2}} {{-v-|min}} # [[lecut]] #:{{syn|min|ampeh|bae|lacuik}} #:'''''lambuik''' se lah inyo lai'' #:: '''lecut''' saja dia lagi {{-turunan-}} {{kotak|min|title=Kata turunan |dilambuiknyo |malambuik |palambuik }} {{kotak|min|title=Gabungan kata |tong palambuik |buayo malambuik lapiak }} [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] 9qq48uc045qtj0hu2zppxfy9xggqdu4 1348932 1348931 2026-04-08T12:56:14Z Ardzun 8096 /* {{bahasa|min}} */ 1348932 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min|num=1}} : {{suara|min|LL-Q13324_(min)-Dhynyhafuza-lambuik.wav}} {{-var-}} *{{l|min|lombuik}} (dialek) {{-adj-|min}} # [[lembut]] #:{{syn|min|lunak|aluih}} #:'''''lambuik''' bana kue tu mah'' #:: '''lembut''' sekali kue itu {{-turunan-}} {{kotak|min|title=Gabungan kata |lamah lambuik }} {{kotak|min|title=Peribahasa |lambuik gigi pado lidah}} {{kepala|min|num=2}} {{-v-|min}} # [[lecut]] #:{{syn|min|ampeh|bae|lacuik}} #:'''''lambuik''' se lah inyo lai'' #:: '''lecut''' saja dia lagi {{-turunan-}} {{kotak|min|title=Kata turunan |dilambuiknyo |malambuik |palambuik }} {{kotak|min|title=Gabungan kata |tong palambuik |buayo malambuik lapiak }} [[Kategori:WikiTutur Padang 11 Februari 2024]] [[Kategori:WikiTutur - Minangkabau]] gwaq44of29d6s8f2qrujosn2087brmz nongkrong 0 253508 1348970 1127498 2026-04-08T16:06:45Z Iripseudocorus 40083 Kutipan23 1348970 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-v-|id}} # {{nonformal}} [[istilah yang digunakan untuk berkumpul bersama teman-teman di suatu tempat]] #* {{RQ:Perahu Tulis | page = 132 | author = Balai Bahasa Sumatera Barat | chapter = | text = Pak Bidin suka '''nongkrong''' di lepau, tapi pengetahuannya sangat banyak, terutama dalam masalah agama. | url = https://id.wikisource.org/wiki/Halaman:Antologi_Cerpen_Remaja_Sumatera_Barat_Perahu_Tulis.pdf/144#:~:text=Pak%20Bidin%20suka%20nongkrong%20di%20lepau%2C%20tapi%20pengetahuannya%20sangat%20banyak%2C%20terutama%20dalam%20masalah%20agama. }} {{-turunan-|id}} {{-terjemahan-}} <!--Anda dapat menyalin templat {{t-atas}} -- {{t-bawah}} di bawah berulang kali untuk masing masing arti kata, masing-masing dibedakan melalui parameter pertamanya (misalkan {{kotak awal|arti 1}} dan {{kotak awal|arti 2}} dst). Lihat [[Wiktionary:Terjemahan]] untuk panduan membuat lebih dari satu kolom terjemahan--> {{t-atas}} {{t-bawah}} {{-bacaan-}} * {{R:KBBI Daring}} {{rfv|id|impor dari KBBI}} 48fj9ct6mfg4u7oeunzruieh149ua35 Modul:parameter utilities 828 257095 1349054 1099986 2026-04-08T17:33:52Z Swarabakti 18192 mutakhirkan 1349054 Scribunto text/plain local export = {} local debug_track_module = "Module:debug/track" local functions_module = "Module:fun" local parameters_module = "Module:parameters" local parse_interface_module = "Module:parse interface" local parse_utilities_module = "Module:parse utilities" local table_module = "Module:table" local dump = mw.dumpObject local error = error local insert = table.insert local ipairs = ipairs local next = next local pairs = pairs local require = require local tonumber = tonumber local type = type --[==[ Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls. ]==] local function debug_track(...) debug_track = require(debug_track_module) return debug_track(...) end local function is_callable(...) is_callable = require(functions_module).is_callable return is_callable(...) end local function list_to_set(...) list_to_set = require(table_module).listToSet return list_to_set(...) end local function parse_term_with_lang(...) parse_term_with_lang = require(parse_utilities_module).parse_term_with_lang return parse_term_with_lang(...) end local function parse_inline_modifiers(...) parse_inline_modifiers = require(parse_interface_module).parse_inline_modifiers return parse_inline_modifiers(...) end local function process_params(...) process_params = require(parameters_module).process return process_params(...) end local function shallow_copy(...) shallow_copy = require(table_module).shallowCopy return shallow_copy(...) end local function table_len(...) table_len = require(table_module).length return table_len(...) end ----------------- end loaders ---------------- local function track(page, track_module) return debug_track((track_module or "parameter utilities") .. "/" .. page) end -- Throw an error prefixed with the words "Internal error" (and suffixed with a dumped version of `spec`, if provided). -- This is for logic errors in the code itself rather than template user errors. local function internal_error(msg, spec) if spec then msg = ("%s: %s"):format(msg, dump(spec)) end error(("Internal error: %s"):format(msg)) end -- Table listing the default recognized special separator arguments and how they display. export.default_special_separators = { [";"] = "; ", ["_"] = " ", ["~"] = " ~ ", ["→"] = " → ", } -- Table listing how subitem delimiters display. Unlike for `default_special_separators`, the presence of an item in -- this table does not mean that the delimiter is recognized; only those specified by `data.splitchar` are recognized. export.default_subitem_separator_map = { [";"] = "; ", [","] = ", ", ["/"] = "/", ["_"] = " ", ["~"] = " ~ ", ["→"] = " → ", } --[==[ intro: The purpose of this module is to facilitate implementation of templates that can have arguments specified either through inline modifiers or separate parameters. There are two types of templates supported: those that take a list of items with associated properties, which can be specified either through indexed separate parameters (e.g. {{para|t2}}, {{para|pos3}}) or inline modifiers (`<t:...>`, `<pos:...>`, etc.); and those that take a single term, whose properties can be specified through non-indexed separate parameters (e.g. {{para|t}} or {{para|pos}}) or inline modifiers. Both types of templates can optionally have subitems in the term parameter(s), where the subitems are typically (but not necessarily) separated with commas and each subitem can have its own inline modifiers. Some examples of templates that take a list of items are {{tl|alter}}/{{tl|alt}}; {{tl|synonyms}}/{{tl|syn}}, {{tl|antonyms}}/{{tl|ant}}, and other "nyms" templates; {{tl|col}}, {{tl|col2}}, {{tl|col3}}, {{tl|col4}} and other column templates; {{tl|descendant}}/{{tl|desc}}; {{tl|affix}}/{{tl|af}}, {{tl|prefix}}/{{tl|pre}} and related *fix templates; {{tl|affixusex}}/{{tl|afex}} and related templates; {{tl|IPA}}; {{tl|homophones}}; {{tl|rhymes}}; and several others. Examples of templates that take a single item are form-of templates ({{tl|inflection of}}/{{tl|infl of}}, {{tl|form of}}, and specific templates such as {{tl|alt form}}/{{tl|alternative form of}}, {{tl|abbr of}}/{{tl|abbreviation of}}, {{tl|clipping of}}, and many others); for etymology templates ({{tl|bor}}/{{tl|borrowed}}, {{tl|der}}/{{tl|derived}}, etc. as well as `misc_variant` templates like {{tl|ellipsis}}, {{tl|abbrev}}, {{tl|clipping}}, {{tl|reduplication}} and the like); and other templates that take an argument structure similar to {{tl|l}} or {{tl|m}}. This module can be thought of as a combination of [[Module:parameters]] (which parses template parameters, and in particular handles the separate parameter versions of the properties) and `parse_inline_modifiers()` in [[Module:parse utilities]] (which parses inline modifiers). The two main entry points are `parse_list_with_inline_modifiers_and_separate_params()` (for templates that take a list of items) and `parse_term_with_inline_modifiers_and_separate_params()` (for templates that take a single item). However, there are other functions provided, e.g. to initialize the `param_mods` structure that is passed to the two entry points. The typical workflow for using `parse_list_with_inline_modifiers_and_separate_params()` looks as follows (a slightly simplified version of the code in [[Module:nyms]]): { local export = {} local parameter_utilities_module = "Module:parameter utilities" ... -- Entry point to be invoked from a template. function export.show(frame) local parent_args = frame:getParent().args -- Parameters that don't have corresponding inline modifiers. Note in particular that the parameter corresponding to -- the items themselves must be specified this way, and must specify either `allow_holes = true` (if the user can -- omit terms, typically by specifying the term using |altN= or <alt:...> so that they remain unlinked) or -- `disallow_holes = true` (if omitting terms is not allowed). (If neither `allow_holes` nor `disallow_holes` is -- specified, an error is thrown in parse_list_with_inline_modifiers_and_separate_params().) local params = { [1] = {required = true, type = "language", default = "und"}, [2] = {list = true, allow_holes = true, required = true, default = "term"}, } local m_param_utils = require(parameter_utilities_module) -- This constructs the `param_mods` structure by adding well-known groups of parameters (such as all the parameters -- associated with based on full_link() in [[Module:links]], with default properties that can be overridden. This is -- easier and less error-prone than manually specifying the `param_mods` structure (see below for how this would -- look). Here, we specify the group "link" (consisting of all the link parameters for use with full_link()), group -- "ref" (which adds the "ref" parameter for specifying references), group "l" (which adds the "l" and "ll" -- parameters for specifying labels) and group "q" (which adds the "q" and "qq" parameters for specifying regular -- qualifiers). By default, labels and qualifiers have `separate_no_index` set so that e.g. |q1= is distinct from -- |q=, the former specifying the left qualifier for the first item and the latter specifying the overall left -- qualifier. For compatibility, we override the `separate_no_index` setting for the group "q", which causes |q= and -- |q1= to be the same, and likewise for |qq= and |qq1=. Finally, also for compatibility, we add an "lb" parameter -- that is an alias of "ll" (in all respects; |lb= is the same as |ll=, |lb1= is the same as |ll1=, <lb:...> is the -- same as <ll:...>, etc.). local param_mods = m_param_utils.construct_param_mods { {group = {"link", "ref", "l"}}, {group = "q", separate_no_index = false}, {param = "lb", alias_of = "ll"}, } -- This processes the raw arguments in `parent_args`, parses inline modifiers and creates corresponding objects -- containing the property values specified either through inline modifiers or separate parameters. local items, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { params = params, param_mods = param_mods, raw_args = parent_args, termarg = 2, parse_lang_prefix = true, track_module = "nyms", lang = 1, sc = "sc.default", } local lang = args[1] -- Now do the actual implementation of the template. Generally this should be split into a separate function, often -- in a separate module (if the implementation goes in [[Module:foo]], the template interface code goes in -- [[Module:foo/templates]]). ... } The `param_mods` structure controls the properties that can be specified by the user for a given item, and is conceptually very similar to the `param_mods` structure used by `parse_inline_modifiers()`. The key is the name of the parameter (e.g. {"t"}, {"pos"}) and the value is a table with optional elements as follows: * `item_dest`, `store`: Same as the corresponding fields in the `param_mods` structure passed to `parse_inline_modifiers()`. * `type`, `set`, `sublist`, `convert` and associated fields such as `family` and `method`: These control parsing and conversion of the raw values specified by the user and have the same meaning as in [[Module:parameters]] and also in `parse_inline_modifiers()` (which delegates the actual conversion to [[Module:parameters]]). These fields — and for that matter, all fields other than `item_dest`, `store` and `overall` — are forwarded to the `process()` function in [[Module:parameters]]. * `alias_of`: This parameter is an alias of some other parameter. This spec is recognized only by `process()` in [[Module:parameters]], and not by `parse_inline_modifiers()`; to set up an alias in `parse_inline_modifiers()`, you need to make sure (using `item_dest`) that both the alias and aliasee modifiers store their values in the same location, and you need to copy the remaining properties from the aliasee's spec to the aliasing modifier's spec. All of this happens automatically if you generate the `param_mods` structure using `construct_param_mods()`. * `require_index`: This means that the non-indexed parameter version of the property is not recognized. E.g. in the case of the {"sc"} property, use of the {{para|sc}} parameter would result in an error, while {{para|sc1}} is recognized and specifies the {"sc"} property for the first item. The default, if neither `require_index` nor `separate_no_index` is given, is for {{para|sc}} and {{para|sc1}} to mean the same thing (both would specify the {"sc"} property of the first item). Note that `require_index` and `separate_no_index` are mutually exclusive, and if either one is specified during processing by `construct_param_mods()`, the other one is automaticallly turned off. * `separate_no_index`: This means that e.g. the {{para|sc}} parameter is distinct from the {{para|sc1}} parameter (and thus from the `<sc:...>` inline modifier on the first item). This is typically used to distinguish an overall version of a property from the corresponding item-specific property on the first item. (In this case, for example, {{para|sc}} overrides the script code for all items, while {{para|sc1}} overrides the script code only for the first item.) If not given, and if `require_index` is not given, {{para|sc}} and {{para|sc1}} would have the same meaning and refer to the item-specific property on the first item. When this is given, the overall value can be accessed using the `.default` field of the property value in `args`, e.g. in this case `args.sc.default`. Note that (as mentioned above) `require_index` and `separate_no_index` are mutually exclusive, and if either one is specified during processing by `construct_param_mods()`, the other one is automaticallly turned off. * `list`, `allow_holes`, `disallow_holes`: These should '''not''' be given. `list` and `allow_holes` are automatically set for all parameter specs added to the `params` structure used by `process()` in [[Module:parameters]], and `disallow_holes` clashes with `allow_holes`. For the above workflow example, the call to `construct_param_mods()` generates the following `param_mods` structure: { local param_mods = { -- the parameters generated by group "link" alt = {}, t = { -- [[Module:links]] expects the gloss in "gloss". item_dest = "gloss", }, gloss = { alias_of = "t", }, tr = {}, ts = {}, g = { -- [[Module:links]] expects the genders in "genders". item_dest = "genders", type = "genders", }, pos = {}, ng = {}, lit = {}, id = {}, sc = { separate_no_index = true, type = "script", }, -- the parameters generated by group "ref" ref = { item_dest = "refs", type = "references", }, -- the parameters generated by group "l" l = { type = "labels", separate_no_index = true, }, ll = { type = "labels", separate_no_index = true, }, -- the parameters generated by group "q"; note that `separate_no_index = true` would be set, but is overridden -- (specifying `separate_no_index = false` in the `param_mods` structure is equivalent to not specifying it at all) q = { type = "qualifier", separate_no_index = false, }, qq = { type = "qualifier", separate_no_index = false, }, infl = { type = "form of tags", separate_no_index = true, }, -- the parameter generated by the individual "lb" parameter spec; note that only `alias_of` was explicitly given, -- while `item_dest` is automatically set so that inline modifier <lb:...> stores into the same place as <ll:...>, -- and the other specs are copied from the `ll` spec so `lb` works like `ll` in all regards lb = { alias_of = "ll", item_dest = "ll", type = "labels", separate_no_index = true, }, } } ]==] local qualifier_spec = { type = "qualifier", separate_no_index = true, } local label_spec = { type = "labels", separate_no_index = true, } local form_of_spec = { type = "form of tags", separate_no_index = true, } local recognized_param_mod_groups = { link = { alt = {}, t = { -- [[Module:links]] expects the gloss in "gloss". item_dest = "gloss", }, gloss = { alias_of = "t", }, tr = {}, ts = {}, g = { -- [[Module:links]] expects the genders in "genders". item_dest = "genders", type = "genders", }, pos = {}, ng = {}, lit = {}, id = {}, sc = { separate_no_index = true, type = "script", }, }, lang = { lang = { require_index = true, type = "language", }, }, q = { q = qualifier_spec, qq = qualifier_spec, }, a = { a = label_spec, aa = label_spec, }, l = { l = label_spec, ll = label_spec, }, infl = { infl = form_of_spec, }, ref = { ref = { item_dest = "refs", type = "references", }, }, } local function merge_param_mod_settings(orig, additions) local merged = shallow_copy(orig) for k, v in pairs(additions) do merged[k] = v if k == "require_index" then merged.separate_no_index = nil elseif k == "separate_no_index" then merged.require_index = nil end end merged.default = nil merged.group = nil merged.param = nil merged.exclude = nil merged.include = nil return merged end local function verify_type(spec, param, typ1, typ2) if not spec[param] then return end local val = spec[param] if type(val) ~= typ1 and (not typ2 or type(val) ~= typ2) then internal_error(("Parameter `%s` must be a %s%s but saw a %s"):format(param, typ1, typ2 and " or " .. typ2 or "", type(val)), spec) end end local function verify_well_constructed_spec(spec) local num_control = (spec.default and 1 or 0) + (spec.group and 1 or 0) + (spec.param and 1 or 0) if num_control == 0 then internal_error( "Spec passed to construct_param_mods() must have either the `default`, `group` or `param` keys set", spec) end if num_control > 1 then internal_error( "Exactly one of `default`, `group` or `param` must be set in construct_param_mods() spec", spec) end if spec.list or spec.allow_holes then -- FIXME: We need to support list = "foo" for list parameters that are stored in e.g. 2=, foo2=, foo3=, etc. internal_error("`list` and `allow_holes` may not be set; they are automatically set when constructing the " .. "corresponding spec in the `params` object passed to [[Module:parameters]]", spec) end if spec.disallow_holes then internal_error("`disallow_holes` may not be set; it conflicts with `allow_holes`, which is automatically " .. "set when constructing the corresponding spec in the `params` object passed to [[Module:parameters]]", spec) end if spec.include and spec.exclude then internal_error("Saw both `include` and `exclude` in the same spec", spec) end if (spec.include or spec.exclude) and not spec.group then internal_error( "`include` and `exclude` can only be specified along with `group`, not with `default` or `param`", spec) end verify_type(spec, "group", "string", "table") verify_type(spec, "param", "string", "table") verify_type(spec, "include", "table") verify_type(spec, "exclude", "table") end --[==[ Construct the `param_mods` structure used in parsing arguments and inline modifiers from a list of specifications. A sample invocation (a slightly simplified version of the actual invocation associated with {{tl|affix}} and related templates) looks like this: { local param_mods = require("Module:parameter utilities").construct_param_mods { -- We want to require an index for all params (or use separate_no_index, which also requires an index for the -- param corresponding to the first item). {default = true, require_index = true}, {group = {"link", "ref", "lang", "q", "l"}}, -- Override these two to have separate_no_index. {param = {"lit", "pos"}, separate_no_index = true}, } } Each specification either sets the default value for further parameter specs or adds one or more parameters. Parameters can be added directly using `param`, or groups of predefined parameters can be added using `group`. Specifications are one of three types: # Those that set the default properties for future-added parameters. These contain {default = true} as one of the properties of the spec. Specs are processed in order and you can change the defaults mid-way through. # Those that add the parameters associated with one or more pre-defined groups. These contain {group = "group"} or {group = {"group1", "group2", ...}}. The pre-defined parameter groups and their associated properties are listed below. The pre-defined properties of parameters in a group override properties associated with a {default = true} spec, and are in turn overridden by any properties given directly in the spec itself. Note as well that setting the `separate_no_index` property will automatically cause the `require_index` property to be unset and vice-versa, as the two are mutually exclusive. (This happens in the example above, where the {separate_no_index = true} setting associated with the params {"lit"} and {"pos"} cancels out the {require_index = true} default setting, as well as less obviously with the pre-defined {"sc"} property of the {"link"} group, the {"q"} and {"qq"} properties of the {"q"} group, and the {"l"} and {"ll"} properties of the {"l"} group, all of which have an associated pre-defined property {separate_no_index = true}, which overrides and cancels out the {require_index = true} default setting. Finally, when adding the parameters of a group, you can request the only a subset of the parameters be added using either the `include` or `exclude` properties, each of whose values is a list of parameters that specify (respectively) the parameters to include (all other parameters of the group are excluded) or to exclude (all other parameters of the group are included). This is used, for example, in [[Module:romance etymology]] and [[Module:it-etymology]], which specify {group = "link", exclude = {"tr", "ts", "sc"}} to exclude link parameters that aren't relevant to Latin-script languages such as the Romance languages, and conversely in [[Module:IPA/templates]], which specifies {group = "link", include = {"t", "gloss", "pos"}} to include only the specified parameters for use with {{tl|IPA}}. # Those that add individual parameters. These contain {param = "param"} or {param = {"param1", "param2", ...}}, the latter syntax used to control a set of parameters together. The resulting spec is formed by initializing the parameter's settings with any previously-specified default properties (using a spec containing {default = true}) if the parameter hasn't already been initialized, and then overriding the resulting settings with any settings given directly in the specification. In the above example, the {"lit"} and {"pos"} parameters were previously initialized through the {"link"} group (specified in the second of the three specifications) but ended up with {require_index = true} due to the {default = true} spec (the first of the three specifications). We override these two parameters to have {separate_no_index = true} (which, as mentioned above, cancels out {require_index = true}). This is done so that {{tl|affix}} and related templates have {{para|pos}} and {{para|lit}} parameters distinct from {{para|pos1}} and {{para|lit1}}, which are used to specify an overall part of speech (which applies to all parts of the affix, as opposed to applying to just one element of the expression) or a literal definition for the entire expression (instead of just for one element of the expression). The built-in parameter groups are as follows: {|class="wikitable" ! Group !! Group meaning !! Parameter !! Parameter meaning !! Default properties |- | rowspan=11| `link` | rowspan=11| link parameters; same as those available on {{tl|l}}, {{tl|m}} and other linking templates | `alt` || display text, overriding the term's display form || — |- | `t` || gloss (translation) of a non-English term || {item_dest = "gloss"} |- | `gloss` || gloss (translation); same as `t` || {alias_of = "t"} |- | `tr` || transliteration of a non-Latin-script term; only needed if the automatic transliteration is incorrect or unavailable (e.g. in Hebrew, which doesn't have automatic transliteration) || — |- | `ts` || transcription of a non-Latin-script term, if the transliteration is markedly different from the actual pronunciation; should not be used for IPA pronunciations || — |- | `g` || comma-separated list of genders; whitespace may surround the comma and will be ignored || {item_dest = "genders", type = "genders"} |- | `pos` || part of speech for the term || — |- | `ng` || arbitrary non-gloss descriptive text for the term || — |- | `lit` || literal meaning (translation) of the term || — |- | `id` || a sense ID for the term, which links to anchors on the page set by the {{tl|senseid}} template || — |- | `sc` || the script code (see [[Wiktionary:Scripts]]) for the script that the term is written in; rarely necessary, as the script is autodetected (in most cases, correctly) || {separate_no_index = true, type = "script"} |- | rowspan=2| `q` | rowspan=2| left and right normal qualifiers (as displayed using {{tl|q}}) | `q` || left normal qualifier || {separate_no_index = true, type = "qualifier"} |- | `qq` || right normal qualifier || {separate_no_index = true, type = "qualifier"} |- | rowspan=2| `a` | rowspan=2| left and right accent qualifiers (as displayed using {{tl|a}}) | `a` || comma-separated list of left accent qualifiers; whitespace must not surround the comma || {separate_no_index = true, type = "labels"} |- | `aa` || comma-separated list of right accent qualifiers; whitespace must not surround the comma || {separate_no_index = true, type = "labels"} |- | rowspan=2| `l` | rowspan=2| left and right labels (as displayed using {{tl|lb}}, but without categorizing) | `l` || comma-separated list of left labels; whitespace must not surround the comma || {separate_no_index = true, type = "labels"} |- | `ll` || comma-separated list of right labels; whitespace must not surround the comma || {separate_no_index = true, type = "labels"} |- | `ref` | reference(s) (in the format accepted by [[Module:references]]; see also the documentation for the {{para|ref}} parameter to {{tl|IPA}}) | `ref` || one or more references, in the format accepted by [[Module:references]] || {item_dest = "refs", type = "references"} |- | `lang` | language for an individual term (provided for compatibility; it is preferred to specify languages for individual terms using language prefixes instead) | `lang` || language code (see [[Wiktionary:Languages]]) for the term || {require_index = true, type = "language"} |} ]==] function export.construct_param_mods(specs) local param_mods = {} local default_specs = {} for _, spec in ipairs(specs) do verify_well_constructed_spec(spec) if spec.default then -- This will have an extra `default` field in it, but it will be erased by merge_param_mod_settings() default_specs = spec else if spec.group then local groups = spec.group if type(groups) ~= "table" then groups = {groups} end local include_set if spec.include then include_set = list_to_set(spec.include) end local exclude_set if spec.exclude then exclude_set = list_to_set(spec.exclude) end for _, group in ipairs(groups) do local group_specs = recognized_param_mod_groups[group] if not group_specs then internal_error(("Unrecognized built-in param mod group '%s'"):format(group), spec) end for group_param, group_param_settings in pairs(group_specs) do local include_param if include_set then include_param = include_set[group_param] elseif exclude_set then include_param = not exclude_set[group_param] else include_param = true end if include_param then local merged_settings = merge_param_mod_settings(merge_param_mod_settings( param_mods[group_param] or default_specs, group_param_settings), spec) param_mods[group_param] = merged_settings end end end end if spec.param then local params = spec.param if type(params) ~= "table" then params = {params} end for _, param in ipairs(params) do local settings = merge_param_mod_settings(param_mods[param] or default_specs, spec) -- If this parameter is an alias of another parameter, we need to copy the specs from the other -- parameter, since parse_inline_modifiers() doesn't know about `alias_of` and having the specs -- duplicated won't cause problems for [[Module:parameters]]. We also need to set `item_dest` to -- point to the `item_dest` of the aliasee (defaulting to the aliasee's value itself), so that -- both modifiers write to the same location. Note that this works correctly in the common case of -- <t:...> with `item_dest = "gloss"` and <gloss:...> with `alias_of = "t"`, because both will end -- up with `item_dest = "gloss"`. local aliasee = settings.alias_of if aliasee then local aliasee_settings = param_mods[aliasee] if not aliasee_settings then internal_error(("Undefined aliasee '%s'"):format(aliasee), spec) end for k, v in pairs(aliasee_settings) do if settings[k] == nil then settings[k] = v end end if settings.item_dest == nil then settings.item_dest = aliasee end end param_mods[param] = settings end end end end return param_mods end -- Return true if `k` is a "built-in" (specially recognized) key in a `param_mod` specification. All other keys -- are forwarded to the structure passed to [[Module:parameters]]. local function param_mod_spec_key_is_builtin(k) return k == "item_dest" or k == "overall" or k == "store" end --[==[ Convert the properties in `param_mods` into the appropriate structures for use by `process()` in [[Module:parameters]] and store them in `params`. If `overall_only` is given, only store the properties in `param_mods` that correspond to overall (non-item-specific) parameters. Currently this only happens when `separate_no_index` is specified. ]==] function export.augment_params_with_modifiers(params, param_mods, overall_only) if overall_only then for param_mod, param_mod_spec in pairs(param_mods) do if overall_only == "always" or param_mod_spec.separate_no_index then local param_spec = {} for k, v in pairs(param_mod_spec) do if k ~= "separate_no_index" and k ~= "require_index" and not param_mod_spec_key_is_builtin(k) then param_spec[k] = v end end params[param_mod] = param_spec end end else local list_with_holes -- Add parameters for each term modifier. for param_mod, param_mod_spec in pairs(param_mods) do local param_spec for k, v in pairs(param_mod_spec) do if not param_mod_spec_key_is_builtin(k) then if param_spec == nil then param_spec = {list = true} end param_spec[k] = v end end if param_spec == nil then if list_with_holes == nil then list_with_holes = {list = true, allow_holes = true} end param_spec = list_with_holes elseif param_spec.alias_of == nil then param_spec.allow_holes = true end params[param_mod] = param_spec end end end --[==[ Return true if `k`, a key in an item, refers to a property of the item (is not one of the specially stored values). Note that `lang` and `sc` are considered properties of the item, although `lang` is set when there's a language prefix and both `lang` and `sc` may be set from default values specified in the `data` structure passed into `parse_list_with_inline_modifiers_and_separate_params()` and `parse_term_with_inline_modifiers_and_separate_params()`. If you don't want these treated as property keys, you need to check for them yourself. ]==] function export.item_key_is_property(k) return k ~= "term" and k ~= "termlang" and k ~= "termlangs" and k ~= "itemno" and k ~= "orig_index" and k ~= "separator" end -- Fetch the argument in `args` corresponding to `index_or_value`, which may be a string of the form "foo.default" -- (requesting the value of `args["foo"].default`); a string or number (requesting the value at that key); a function of -- one argument (`args`), which returns the argument value; or the value itself. Return the resulting value and the -- parameter in `args` that the value came from, or nil if unknown (i.e. a function or direct value was specified). local function fetch_argument(args, index_or_value) if not index_or_value then return index_or_value, nil end local index_or_value_type = type(index_or_value) if index_or_value_type == "string" then if index_or_value:sub(-8) == ".default" then local index_without_default = index_or_value:sub(1, -9) local arg_obj = fetch_argument(args, index_without_default) if type(arg_obj) ~= "table" then internal_error(("Requested that the '.default' key of argument `%s` be fetched, but argument value is undefined or not a table"): format(index_without_default), arg_obj) end return arg_obj.default, index_without_default end if index_or_value:match("^%d+$") then index_or_value = tonumber(index_or_value) end return args[index_or_value], index_or_value elseif index_or_value_type == "number" then return args[index_or_value], index_or_value elseif is_callable(index_or_value) then return index_or_value(args), nil end return index_or_value, nil end function export.generate_obj_maybe_parsing_lang_prefix(data) local term = data.term local term_dest = data.term_dest or "term" local termobj = data.termobj or {} if data.parse_lang_prefix and term:find(":", nil, true) then local actual_term, termlangs = parse_term_with_lang { term = term, parse_err = data.parse_err, paramname = data.paramname, allow_bad = data.allow_bad_lang_prefix, allow_multiple = data.allow_multiple_lang_prefixes, lang_cache = data.lang_cache, } termobj[term_dest] = actual_term ~= "" and actual_term or nil if termlangs then -- If we couldn't parse a language code, don't overwrite an existing setting in `lang` -- that may have originated from a separate |langN= param. if data.allow_multiple_lang_prefixes then termobj.termlangs = termlangs termobj.lang = termlangs and termlangs[1] or nil else termobj.termlang = termlangs termobj.lang = termlangs end end else termobj[term_dest] = term ~= "" and term or nil end return termobj end -- Subfunction of parse_list_with_inline_modifiers_and_separate_params() and -- parse_term_with_inline_modifiers_and_separate_params(), validating certain argument-related fields that are shared -- among the two functions. local function validate_argument_related_fields(data) if not data.termarg then internal_error("`data.termarg` must be given, indicating which argument contains the terms to be parsed", data) end if not data.param_mods then internal_error("`data.param_mods` must be given, indicating the allowed inline modifiers and separate " .. "parameters to copy", data) end local subitem_param_handling = data.subitem_param_handling or "only" if subitem_param_handling ~= "only" and subitem_param_handling ~= "first" and subitem_param_handling ~= "last" then internal_error("Unrecognized value for `data.subitem_param_handling`, should be 'first', 'last' or 'only'", subitem_param_handling) end if data.raw_args then if data.processed_args then internal_error("Only one of `data.raw_args` and `data.processed_args` can be specified", data) end if not data.params then internal_error("When `data.raw_args` is specified, so must `data.params`, so that the raw arguments " .. "can be parsed", data) end if data.params[data.termarg] == nil then internal_error("There must be a spec in `data.params` corresponding to `data.termarg`", data) end else if not data.processed_args then internal_error("Either `data.raw_args` or `data.processed_args` must be specified", data) end if data.params then internal_error("When `data.processed_args` is specified, `data.params` should not be specified", data) end end end local function argval_missing(val) return val == nil or type(val) == "table" and next(val) == nil end -- Subfunction of parse_list_with_inline_modifiers_and_separate_params() and -- parse_term_with_inline_modifiers_and_separate_params(). After parsing inline modifiers, copy the separate parameters -- to the generated object (or to the appropriate subobject if there are multiple). `data` contains the following -- fields: -- -- `args`: The separate-parameter argument structure. -- `param_mods`: The structure describing the inline modifiers. -- `itemno`: The logical item number of the term being processed, or nil if there's only a single term. -- `termobj`: The object to store the inline modifiers into. If there are subitems, they are in the `terms` field; -- otherwise the properties are stored directly into `termobj`. -- `has_subitems`: True if there are subitems. -- `subitem_separator_map`: If `has_subitems` and this is specified, controls the assignment of the `separator` field -- in subitems. If not specified or a delimiter is not in the map, it is copied unchanged. -- `lang`: Language object to store into all items. -- `sc`: Script object to store into all items, or nil. -- `subitem_param_handling`: "only", "first" or "last", indicating what to do if there are multiple subitems. -- `allow_conflicting_inline_mods_and_separate_params`: If true, specifying a value for both an inline modifier and -- corresponding separate parameter is allowed, and the inline modifier takes precedence. Otherwise, an error -- occurs. -- `postprocess_termobj`: Optional function called on all items at the end, to do any postprocessing. Called with one -- argument, the object to postprocess. local function copy_separate_params_to_termobj_and_postprocess(data) local args, param_mods, itemno, termobj = data.args, data.param_mods, data.itemno, data.termobj local function set_lang_and_sc(termobj) -- Set these after parsing inline modifiers, not in generate_obj(), otherwise we'll get an error in -- parse_inline_modifiers() if we try to use <lang:...> or <sc:...> as inline modifiers. termobj.lang = termobj.lang or data.lang termobj.sc = termobj.sc or data.sc end local function fetch_separate_param(args, paramkey, itemno) local argval = args[paramkey] -- Careful with argument values that may be `false`. if argval and itemno then argval = argval[itemno] end return argval end -- Copy separate parameters to a given object. local function copy_separate_params_to_termobj(fetch_destobj) for param_mod, param_mod_spec in pairs(param_mods) do local dest = param_mod_spec.item_dest or param_mod -- Don't do anything with the `sc` param, which will get overwritten below; we don't -- want it to cause an error if there are multiple subitems. if dest ~= "sc" then local argval = fetch_separate_param(args, param_mod, itemno) if not argval_missing(argval) then local destobj = fetch_destobj(param_mod, param_mod_spec, dest) -- Don't overwrite a value already set by an inline modifier. if argval_missing(destobj[dest]) then destobj[dest] = argval elseif not data.allow_conflicting_inline_mods_and_separate_params then error(("Can't specify a value for separate parameter %s%s= because there is " .. "already an inline modifier <%s:...> specifying a value for the term"):format( param_mod, itemno or "", param_mod)) end end end end end if data.has_subitems then -- If there are any separate indexed parameters, we need to copy them to the first, last or only -- subitem, depending on the value of `data.subitem_param_handling` (which defaults to 'only', -- meaning it's an error if there are multiple subitems). Do this before calling -- postprocess_termobj() because the latter sets .lang and .sc and we want the user to be able to -- set separate langN= and scN= parameters. -- If there was no term, `termobj.terms` will not exist; make it exist to make the callers' lives easier. if not termobj.terms then termobj.terms = {} end -- Compute whether any of the separate indexed params exist for this index. local any_param_at_index for param_mod in pairs(param_mods) do local argval = fetch_separate_param(args, param_mod, itemno) if not argval_missing(argval) then any_param_at_index = true break end end -- If there was no term, but there's a separate parameter, we need to create an empty subitem. if any_param_at_index and not termobj.terms[1] then termobj.terms[1] = {} end local function fetch_destobj(param_mod, param_mod_spec, dest) if param_mod_spec.overall then return termobj end if data.subitem_param_handling == "only" and termobj.terms[2] then error(("Can't specify a value for separate parameter %s%s= because there are " .. "multiple subitems (%s) in the term; use an inline modifier"):format( param_mod, itemno or "", #termobj.terms)) end local termind -- q/a/l need to go at the beginning and qq/aa/ll/refs at the end, regardless; otherwise, respect -- `data.subitem_param_handling`. if dest == "q" or dest == "a" or dest == "l" then termind = 1 elseif dest == "qq" or dest == "aa" or dest == "ll" or dest == "refs" then termind = #termobj.terms elseif data.subitem_param_handling == "only" or data.subitem_param_handling == "first" then termind = 1 else termind = #termobj.terms end return termobj.terms[termind] end copy_separate_params_to_termobj(fetch_destobj) for i, subitem in ipairs(termobj.terms) do set_lang_and_sc(subitem) if subitem.delimiter then subitem.separator = i == 1 and "" or data.subitem_separator_map and data.subitem_separator_map[subitem.delimiter] or subitem.delimiter end if data.postprocess_termobj then data.postprocess_termobj(subitem, data) end end else -- Copy all the parsed term-specific parameters into `termobj`. copy_separate_params_to_termobj(function(param_mod, dest) return termobj end) set_lang_and_sc(termobj) if data.postprocess_termobj then data.postprocess_termobj(termobj, data) end end end local function postprocess_termobj(item, data) if not (data.disallow_custom_separators or data.use_semicolon) then if data.has_subitems and item.separator and item.separator:find(",", nil, true) then data.use_semicolon = true else -- If the displayed term (from .term/etc. or .alt) has an embedded comma, use a semicolon to -- join the terms. local term_text = item[data.term_dest] or item.alt if term_text and term_text:find(",", nil, true) then data.use_semicolon = true end end end end --[==[ Parse a list of terms, each of which may have properties specified using inline modifiers or separate parameters. This function is intended for parsing the arguments of templates like {{tl|syn}}, {{tl|ant}} and related ''*nym'' templates; alternative-form templates {{tl|alt}}/{{tl|alter}}; affix templates like {{tl|af}}/{{tl|affix}}, {{tl|com}}/{{tl|compound}}, etc.; affix usex templates like {{tl|afex}}/{{tl|affixusex}}; name templates like {{tl|name translit}}; column templates like {{tl|col}}; pronunciation templates like {{tl|rhyme}}/{{tl|rhymes}} and {{tl|hmp}}/{{tl|homophones}}; etc. In these templates there are one or more terms specified using numeric parameters, and associated separate parameters specifying per-term properties such as {{para|t1}}, {{para|t2}}, {{para|t3}}, ... for the gloss of the first, second, third, ... term respectively. All such properties can also be specified through inline modifiers attached directly to each term (`<t:...>`, `<pos:...>`, etc.). Normally it is an error if both an inline modifier and separate parameter for the same value are given, but this can be overridden (in which case inline modifiers take precedence over separate parameters when both occur). For an example of a typical workflow involving this function, see the comment at the top of this file. Some notable properties of this function: # Processing of the raw frame parent args using `process()` in [[Module:parameters]] can occur either inside of this function (the usual workflow) or outside of this function (for more complex cases). In the former case the raw parent args are passed in along with a partially built `params` structure of the sort required by [[Module:parameters]], containing only the term list itself along with any other parameters that are '''not''' term properties (such as a language code in {{para|1}} and boolean flags like {{para|nocat}}, {{para|nocap}}, etc.). This structure is ''augmented'' with list parameters, one for each per-term property, and [[Module:parameters]] is invoked. In the latter case where raw argument processing is done by the caller, they must build the partial `params` structure; augment it themselves using `augment_params_with_modifiers()`; call [[Module:parameters]] themselves; and pass in the processed arguments. In both cases, the return value of this function contains three values: a list of objects, one per term, specifying the term and all properties; the processed arguments structure, so that the non-term-property arguments can be processed as appropriate; and an object containing miscellaneous global computed properties (currently only `use_semicolon`; see below). # Optionally, each term can consist of a number of ''subitems'' separated by delimiters (usually a comma, but the possible delimiter or delimiters are controllable). Each subitem can have its own inline modifiers. This functionality is used, for example, by {{tl|col}} and variants, which allow each row to have comma-separated or tilde-separated subitems. When this feature is invoked, the format of the per-term object changes; instead of directly being an object describing the term and its properties, it is an object with a `terms` field containing a list of per-subitem objects along with other top-level fields describing per-term properties. By default, if there are separate parameters specified along with multiple subitems, an error occurs, but this is controllable; currently, you can request that the parameters be assigned to the first or last subitem. # By default, special ''separator'' arguments may be present, mixed in among regular term arguments. Examples of such separator arguments are (by default; this can be overridden) a bare semicolon, specifying that the terms on either side should be separated by a semicolon instead of a comma (indicating a higher-level grouping); a bare tilde, replacing the comma separator with a tilde (indicating that the terms on either side are alternants); and a bare underscore, replacing the comma separator with a space. Separator arguments are ignored when numbering the separate parameters. You disable the separator argument handling entirely if it doesn't make sense to have this (e.g. in {{tl|af}}/{{tl|affix}}, where the separator is always a {{cd|+}} sign). `data` is an object containing several possible fields. 1. Fields that are required or recommended (usually related to argument processing): * `raw_args` ('''required''' unless `processed_args` is specified): The raw arguments, normally fetched from {frame:getParent().args}. They are parsed using `process()` in [[Module:parameters]]. Most callers pass in raw arguments. * `processed_args`: The object of parsed arguments returned by `process()` in [[Module:parameters]]. One (but not both) of `raw_args` and `processed_args` must be set. * `param_mods` ('''required'''): A structure describing the possible inline modifiers and their properties. See the introductory comment above. Most often, this is generated using `construct_param_mods()` rather than specified manually. * `params` ('''required''' unless `processed_args` is specified): A structure describing the possible parameters, '''other than''' the ones that are separate-parameter equivalents of inline modifiers. This is automatically "augmented" with the separate-parameter equivalents of the inline modifiers described in `param_mods` prior to parsing the raw arguments with [[Module:parameters]]. '''WARNING:''' This structure is destructively modified, both by the "augmentation" process of adding separate-parameter equivalents of inline modifiers, and by the processing done by [[Module:parameters]] itself. (Nonetheless, substructures can safely be shared in this structure, and will be correctly handled.) * `termarg` ('''required'''): The argument containing the first item with attached inline modifiers to be parsed. Usually a numeric value such as {1} or {2}. * `track_module` ('''recommended'''): The name of the calling module, for use in adding tracking pages that are used internally to track pages containing template invocations with certain properties. Example properties tracked are missing items with corresponding properties as well as missing items without corresponding properties (which are skipped entirely). To find out the exact properties tracked and the name of the tracking pages, read the code. * `lang` ('''recommended'''): The language object for the language of the items, or the name of the argument to fetch the object from. It is not strictly necessary to specify this, as this function only initializes items based on inline modifiers and separate arguments and doesn't actually format the resulting items. However, if specified, it is used for certain purposes: *# It specifies the default for the `lang` property of returned objects if not otherwise set (e.g. by a language prefix). *# It is used to initialize an internal cache for speeding up language-code parsing (primarily useful if the same language code may appear in several items, such as with {{tl|col}} and related templates). The value of `lang` can be any of the following: * If a string of the form "foo.default", it is assumed to be requesting the value of `args["foo"].default`. * Otherwise, if a string or number, it is assumed to be requesting the value of `args` at that key. Note that if the string is in the form of a number (e.g. "3"), it is normalized to a number prior to fetching (this also happens with a spec like "2.default"). * Otherwise, if a function, it is assumed to be a function to return the argument value given `args`, which is passed to the function as its only argument. * Otherwise, it is used directly. * `sc` ('''recommended'''): The script object for the items, or the name of the argument to fetch the object from. The possible values and their handling are the same as with `lang`. In general, as with `lang`, it is not strictly necessary to specify this. However, if specified, it is used to supply the default for the `sc` property of returned items if not otherwise set (e.g. by the {{para|sc<var>N</var>}} parameter or `<sc:...>` inline modifier). The most common value is {"sc.default"}. 2. Other argument-related fields: * `process_args_before_parsing`: An optional function to apply further processing to the processed `args` structure returned by [[Module:parameters]], before parsing inline modifiers. This is passed one argument, the processed arguments. It should make modifications in-place. * `term_dest`: The field to store the value of the item itself into, after inline modifiers and (if allowed) language prefixes are stripped off. Defaults to {"term"}. * `pre_normalize_modifiers`: As in `parse_inline_modifiers()`. * `allow_conflicting_inline_mods_and_separate_params`: If specified, don't throw an error if a value is specified for a given property using both an inline modifier and separate param; in this case, the inline modifier takes precedence. 3. Fields related to language prefixes: * `parse_lang_prefix`: If true, allow and parse off a language code prefix attached to items followed by a colon, such as {la:minūtia} or {grc:[[σκῶρ|σκατός]]}. Etymology-only languages are allowed. Inline modifiers can be attached to such items. The exact syntax allowed is as specified in the `parse_term_with_lang()` function in [[Module:parse utilities]]. If `allow_multiple_lang_prefixes` is given, a {{cd|+}}-sign-separated list of language prefixes can be attached to an item. The resulting language object is stored into the `termlang` field, and also into the `lang` field (or in the case of `allow_multiple_lang_prefixes`, the list of language objects is stored into the `termlangs` field, and the first specified object is stored in the `lang` field). * `allow_multiple_lang_prefixes`: If given in conjunction with `parse_lang_prefix`, multiple language code prefixes can be given, separated by a {{cd|+}} sign. See `parse_lang_prefix` above. * `allow_bad_lang_prefix`: If given in conjunction with `parse_lang_prefix`, unrecognized language prefixes do not trigger an error, but are simply ignored (and not stripped off the item). Note that, regardless of whether this is given, prefixes before a colon do not trigger an error if they do not have the form of a language prefix or if a space follows the colon. It is not recommended that this be given because typos in language prefixes will not trigger an error and will tend to remain unfixed. 4. Fields related to custom/special separators: * `disallow_custom_separators`: If specified, disallow specifying custom separators (semicolon, underscore, tilde; see the internal `default_special_separators` table, or the `special_separators` field) as an item value to override the default separator. By default, the previous separator of each item is considered to be an empty string (for the first item) and otherwise the value of the field `default_separator` (normally a comma + space), unless either the preceding item is one of the values listed in `special_separators`, such as a bare semicolon (which causes the following item's previous separator to be a semicolon + space) or an item has an embedded comma in it (which causes ''all'' items other than the first to have their previous separator be a semicolon + space). The previous separator of each item is set on the item's `separator` property. Bare semicolons and other separator arguments do not count when indexing items using separate parameters. For example, the following is correct: ** {{tl|template|lang|item 1|q1=qualifier 1|;|item 2|q2=qualifier 2}} If `disallow_custom_separators` is specified, however, the `separator` property is not set and separator arguments are not recognized. * `default_separator`: Override the default separator (normally {", "}). * `special_separators`: Table giving the special/custom separators that can be given, and how they should display. If not specified, the default in `default_special_separators` is used. This is a table mapping separator values (such as {"~"}) to the corresponding display string (such as {" ~ "}). 5. Fields related to multiple subitems in a given term: * `splitchar`: A Lua pattern. If specified, each user-specified argument can consist of multiple delimiter-separated subitems, each of which may be followed by inline modifiers. In this case, each element in the returned list of items is no longer an object describing an item, but instead an object with a `terms` field, whose value is a list describing the subitems (whose format is the same as the normal format of an item in the top-level list when `splitchar` is not specified). Each subitem object will have a `delimiter` field holding the actual delimiter occurring before the subitem, which is useful in the case where `splitchar` matches multiple possible characters. In this case, it is possible to specify that a given modifier can only occur after the last subitem and effectively modifies the whole collection of subitems by setting `overall = true` on the modifier. In this case, the modifier's value will be stored in the top-level object (the object with the `terms` field specifying the subitems). Note that splitting on delimiters will not happen in certain protected sequences (by default comma+whitespace; see below). In addition, the algorithm to split on delimiters is sensitive to inline modifier syntax and will not be confused by delimiters inside of inline modifiers or inside of square brackets, which do not trigger splitting (whether or not contained within protected sequences). * `escape_fun` and `unescape_fun`: As in `split_escaping()` and `split_alternating_runs_escaping()` in [[Module:parse utilities]]. They control the protected sequences that won't be split when `splitchar` is specified (see previous item). By default, `escape_comma_whitespace` and `unescape_comma_whitespace` are used, so that comma+whitespace sequences won't be split. * `subitem_param_handling`: How to handle separate parameters that are specified in the presence of multiple subitems. The possible values are {"only"} (only allow separate parameters if there aren't any subitems, otherwise throw an error), {"first"} (store the separate parameters in the first subitem) and {"last"} (store the separate parameters in the last subitem). The default is {"only"}. As a special case, an {{para|scN}} separate parameter will be stored into all subitems. * `subitem_separator_map`: Table mapping user-specified delimiters to displayed separators, stored in the `separator` field of the subitem. If not specified, it defaults to `default_subitem_separator_map`. Note that the presence of an item in this table does not mean that it can be used as a delimiter; only the delimiters specified using `splitchar` are recognized. Delimiters not in this map display as-is. 6. Other fields: * `dont_skip_items`: Normally, items that are completely unspecified (have no term and no properties) are skipped and not inserted into the returned list of items. (Such items cannot occur if `disallow_holes = true` is set on the term specification in the `params` structure passed to `process()` in [[Module:parameters]]. It is generally recommended to do so unless a specific meaning is associated the term value being missing.) If `dont_skip_items` is set, however, items are never skipped, and completely unspecified items will be returned along with others. (They will not have the term or any properties set, but will have the normal non-property fields set; see below.) * `stop_when`: If specified, a function to determine when to prematurely stop processing items. It is passed a single argument, an object containing the following fields: ** `term`: The raw term, prior to parsing off language prefixes and inline modifiers (since the processing of `stop_when` happens before parsing the term). ** `any_param_at_index`: True if any separate property parameters exist for this item. ** `orig_index`: Same as `orig_index` below. ** `itemno`: Same as `itemno` below. ** `stored_itemno`: The index where this item will be stored into the returned items table. This may differ from `itemno` due to skipped items (it will never be different if `dont_skip_items` is set). The function should return true to stop processing items and return the ones processed so far (not including the item currently being processed). This is used, for example, in [[Module:alternative forms]], where an unspecified item signal the end of items and the start of labels. Three values are returned: the list of items; the processed `args` structure; and an object of miscellaneous computed global values (currently only `use_semicolon`, indicating that commas were found in individual arguments and so the default separator should be a semicolon). In each returned item, there will be one field set for each specified property (either through inline modifiers or separate parameters). If subitems are not allowed, each item directly has fields set on it for the specified properties. If subitems ''are'' allowed, each item contains a `terms` field, which is a list of subitem objects, each of which has fields set on it for the specified properties of that subitem. In addition, the following fields may be set on each item or subitem: * `term`: The term portion of the item (minus inline modifiers and language prefixes). {nil} if no term was given. * `orig_index`: The original index into the item in the items table returned by `process()` in [[Module:parameters]]. This may differ from `itemno` if there are raw semiclons and `disallow_custom_separators` is not given. * `itemno`: The logical index of the item. The index of separate parameters corresponds to this index. This may be different from `orig_index` in the presence of raw semicolons; see above. * `termlang`: If there is a language prefix, the corresponding language object is stored here (only if `parse_lang_prefix` is set and `allow_multiple_lang_prefixes` is not set). * `termlangs`: If there is are language prefixes and both `parse_lang_prefix` and `allow_multiple_lang_prefixes` are set, the list of corresponding language objects is stored here. * `lang`: The language object of the item. This is set when either (a) there is a language prefix parsed off (if multiple prefixes are allowed, this corresponds to the first one); (b) the `lang` property is allowed and specified; (c) neither (a) nor (b) apply and the `lang` field of the overall `data` object is set, providing a default value. * `sc`: The script object of the item. This is set when either (a) the `sc` property is allowed and specified; (b) `sc` isn't otherwise set and the `sc` field of the overall `data` object is set, providing a default value. * `delimiter`: If subitems are allowed, this is set on subitems and specifies the delimiter used prior to the given subitem (e.g. {","}). * `separator`: The separator to display before the item. Always set on subitems, and set on top-level items if `disallow_custom_separators` is not given. Controlled by `special_separators` (for top-level items) and `subitem_separator_map` (for subitems). ]==] function export.parse_list_with_inline_modifiers_and_separate_params(data) validate_argument_related_fields(data) local raw_args, termarg, param_mods, args = data.raw_args, data.termarg, data.param_mods if raw_args then local params = data.params local termarg_spec = params[termarg] if termarg_spec == true or not termarg_spec.list then internal_error("Term spec in `data.params` must have `list` set", termarg_spec) end if termarg_spec == true or not (termarg_spec.allow_holes or termarg_spec.disallow_holes) then internal_error("Term spec in `data.params` must have either `allow_holes` or `disallow_holes` set", termarg_spec) end export.augment_params_with_modifiers(params, param_mods) args = process_params(raw_args, params) else args = data.processed_args end local process_args_before_parsing = data.process_args_before_parsing if process_args_before_parsing then process_args_before_parsing(args) end -- Find the maximum index among any of the list parameters. local term_args = args[termarg] -- As a special case, the term args might not have a `maxindex` field because they might have -- been declared with `disallow_holes = true`, so fall back to the actual length of the list -- using the table_len function, since # can be unpredictable with arbitrary tables. local maxmaxindex = term_args.maxindex or table_len(term_args) for _, v in pairs(args) do if type(v) == "table" and v.maxindex and v.maxindex > maxmaxindex then maxmaxindex = v.maxindex end end local special_separators = data.special_separators or export.default_special_separators local items, lang_cache, use_semicolon = {}, data.lang_cache or {} local lang = fetch_argument(args, data.lang) if lang then lang_cache[lang:getCode()] = lang end local sc = fetch_argument(args, data.sc) local term_dest = data.term_dest or "term" -- FIXME: this is vulnerable to abusive inputs like 1000000=. local itemno = 0 for i = 1, maxmaxindex do local term = term_args[i] if data.disallow_custom_separators or not special_separators[term] then itemno = itemno + 1 -- Compute whether any of the separate indexed params exist for this index. local any_param_at_index for param_mod in pairs(param_mods) do local argval = args[param_mod] -- Careful with argument values that may be `false`. if argval then argval = argval[itemno] end if not argval_missing(argval) then any_param_at_index = true break end end if data.stop_when and data.stop_when{ term = term, -- FIXME, we should just pass in `any_param_at_index` directly. any_param_at_index = term ~= nil or any_param_at_index, orig_index = i, itemno = itemno, stored_itemno = #items + 1, } then break end -- If any of the params used for formatting this term is present, create a term and add it to the list. if not data.dont_skip_items and term == nil and not any_param_at_index then track("skipped-term", data.track_module) else if not term then track("missing-term", data.track_module) end local termobj = { itemno = itemno, orig_index = i, } if not data.disallow_custom_separators then termobj.separator = i == 1 and "" or special_separators[term_args[i - 1]] end -- Add 1 because first term index starts at 2. local paramname = termarg + i - 1 if term then local function generate_obj(term, parse_err) return export.generate_obj_maybe_parsing_lang_prefix { term = term, termobj = data.splitchar and {} or termobj, term_dest = term_dest, paramname = paramname, parse_lang_prefix = data.parse_lang_prefix, parse_err = parse_err, allow_bad_lang_prefix = data.allow_bad_lang_prefix, allow_multiple_lang_prefixes = data.allow_multiple_lang_prefixes, lang_cache = lang_cache, } end parse_inline_modifiers(term, { paramname = paramname, param_mods = param_mods, generate_obj = generate_obj, splitchar = data.splitchar, preserve_splitchar = true, escape_fun = data.escape_fun, unescape_fun = data.unescape_fun, outer_container = data.splitchar and termobj or nil, pre_normalize_modifiers = data.pre_normalize_modifiers, }) end local term_data = { args = args, param_mods = param_mods, itemno = itemno, termobj = termobj, term_dest = term_dest, has_subitems = not not data.splitchar, lang = lang, -- As a special case, if the caller defined a scN= separate param, set it on all subitems if there -- are multiple, falling back to the overall sc= param. sc = args.sc and args.sc[itemno] or sc, subitem_param_handling = data.subitem_param_handling, subitem_separator_map = data.subitem_separator_map or export.default_subitem_separator_map, allow_conflicting_inline_mods_and_separate_params = data.allow_conflicting_inline_mods_and_separate_params, postprocess_termobj = postprocess_termobj, disallow_custom_separators = data.disallow_custom_separators, use_semicolon = use_semicolon, } copy_separate_params_to_termobj_and_postprocess(term_data) use_semicolon = term_data.use_semicolon insert(items, termobj) end end end if not data.disallow_custom_separators then -- Set the default separator of all those items for which a separator wasn't explicitly given to the default -- separator, defaulting to comma + space; but if any items have embedded commas, set the separator to -- semicolon + space. for _, item in ipairs(items) do if not item.separator then item.separator = use_semicolon and "; " or data.default_separator or ", " end end end return items, args, {use_semicolon = use_semicolon} end --[==[ Parse a single term that may have properties specified through inline modifiers or separate parameters. This differs from `parse_list_with_inline_modifiers_and_separate_params()` in that the latter is for parsing a list of terms, each of which may have properties specified through inline modifiers or separate parameters. Both functions optionally support having multiple subitems in a single term. This function is used e.g. for form-of templates ({{tl|inflection of}}/{{tl|infl of}}, {{tl|form of}}, and specific templates such as {{tl|alt form}}/{{tl|alternative form of}}, {{tl|abbr of}}/{{tl|abbreviation of}}, {{tl|clipping of}}, and many others); for etymology templates ({{tl|bor}}/{{tl|borrowed}}, {{tl|der}}/{{tl|derived}}, etc. as well as `misc_variant` templates like {{tl|ellipsis}}, {{tl|abbrev}}, {{tl|clipping}}, {{tl|reduplication}} and the like); and for other templates with an argument structure similar to {{tl|l}} or {{tl|m}}. In these templates there is a term specified using a numeric parameter and associated separate parameters specifying term properties such as {{para|t}} for the gloss or {{para|tr}} for manual transliteration. All such properties can also be specified through inline modifiers attached directly to each term (`<t:...>`, `<tr:...>`, etc.). Normally it is an error if both an inline modifier and separate parameter for the same value are given, but this can be overridden (in which case inline modifiers take precedence over separate parameters when both occur). Some notable properties of this function: # Processing of the raw frame parent args using `process()` in [[Module:parameters]] can occur either inside of this function (the usual workflow) or outside of this function (for more complex cases). In the former case the raw parent args are passed in along with a partially built `params` structure of the sort required by [[Module:parameters]], containing only the term list itself along with any other parameters that are '''not''' term properties (such as a language code in {{para|1}} and boolean flags like {{para|nocat}}, {{para|nocap}}, etc.). This structure is ''augmented'' with parameters, one for each per-term property, and [[Module:parameters]] is invoked. In the latter case where raw argument processing is done by the caller, they must build the partial `params` structure; augment it themselves using `augment_params_with_modifiers()`; call [[Module:parameters]] themselves; and pass in the processed arguments. In both cases, the return value of this function contains two values, an object specifying the term and all properties; and the processed arguments structure, so that the non-term-property arguments can be processed as appropriate. # Optionally, the term can consist of a number of ''subitems'' separated by delimiters (usually a comma, but the possible delimiter or delimiters are controllable). Each subitem can have its own inline modifiers. This functionality is used, for example, by form-of templates. When this feature is invoked, the format of the term object changes; instead of directly being an object describing the term and its properties, it is an object with a `terms` field containing a list of per-subitem objects along with other top-level fields describing per-term properties. By default, if there are separate parameters specified along with multiple subitems, an error occurs, but this is controllable; currently, you can request that the parameters be assigned to the first or last subitem. `data` is an object containing several possible fields. 1. Fields that are required or recommended (usually related to argument processing): * `raw_args` ('''required''' unless `processed_args` is specified): The raw arguments, normally fetched from {frame:getParent().args}. They are parsed using `process()` in [[Module:parameters]]. Most callers pass in raw arguments. * `processed_args`: The object of parsed arguments returned by `process()` in [[Module:parameters]]. One (but not both) of `raw_args` and `processed_args` must be set. * `param_mods` ('''required'''): A structure describing the possible inline modifiers and their properties. See the introductory comment above. Most often, this is generated using `construct_param_mods()` rather than specified manually. * `params` ('''required''' unless `processed_args` is specified): A structure describing the possible parameters, '''other than''' the ones that are separate-parameter equivalents of inline modifiers. This is automatically "augmented" with the separate-parameter equivalents of the inline modifiers described in `param_mods` prior to parsing the raw arguments with [[Module:parameters]]. '''WARNING:''' This structure is destructively modified, both by the "augmentation" process of adding separate-parameter equivalents of inline modifiers, and by the processing done by [[Module:parameters]] itself. (Nonetheless, substructures can safely be shared in this structure, and will be correctly handled.) * `termarg` ('''required'''): The argument containing the item with attached inline modifiers to be parsed. Usually a numeric value such as {1} or {2}. * `track_module` ('''recommended'''): The name of the calling module, for use in adding tracking pages that are used internally to track pages containing template invocations with certain properties. * `lang` ('''recommended'''): The language object for the language of the item or subitems, or the name of the argument to fetch the object from. It is not strictly necessary to specify this, as this function only initializes items based on inline modifiers and separate arguments and doesn't actually format the resulting items. However, if specified, it is used for certain purposes: *# It specifies the default for the `lang` property of returned objects if not otherwise set (e.g. by a language prefix). *# It is used to initialize an internal cache for speeding up language-code parsing (primarily useful if the same language code may appear in several subitems). The value of `lang` can be any of the following: * If a string or number, it is assumed to be requesting the value of `args` at that key. Note that if the string is in the form of a number (e.g. "3"), it is normalized to a number prior to fetching. * Otherwise, if a function, it is assumed to be a function to return the argument value given `args`, which is passed to the function as its only argument. * Otherwise, it is used directly. * `sc` ('''recommended'''): The script object for the item or subitems, or the name of the argument to fetch the object from. The possible values and their handling are the same as with `lang`. In general, as with `lang`, it is not strictly necessary to specify this. However, if specified, it is used to supply the default for the `sc` property of returned items if not otherwise set (e.g. by the {{para|sc}} parameter or `<sc:...>` inline modifier). The most common value is {"sc"}. * `make_separate_g_into_list`: Set this to {true} if separate gender parameters exist are are specified using {{para|g}}, {{para|g2}}, etc. instead of using a single comma-separated {{para|g}} field. 2. Other argument-related fields: * `adjust_params_before_arg_processing`: An optional function to further adjust the `params` structure prior to calling `process()` in [[Module:parameters]]. This should be used when there are mismatches between the format of a given property as an inline modifier and the corresponding property as a separate parameter (as with the {{para|g}} parameter and {{cd|<g:...>}} modifier, but this particular case is handled by the `make_separate_g_into_list` field). * `process_args_before_parsing`: An optional function to apply further processing to the processed `args` structure returned by [[Module:parameters]], before parsing inline modifiers. This is passed one argument, the processed arguments. It should make modifications in-place. * `term_dest`: The field to store the value of the item itself into, after inline modifiers and (if allowed) language prefixes are stripped off. Defaults to {"term"}. * `pre_normalize_modifiers`: As in `parse_inline_modifiers()`. * `allow_conflicting_inline_mods_and_separate_params`: If specified, don't throw an error if a value is specified for a given property using both an inline modifier and separate param; in this case, the inline modifier takes precedence. 3. Fields related to language prefixes: * `parse_lang_prefix`: If true, allow and parse off a language code prefix attached to items followed by a colon, such as {la:minūtia} or {grc:[[σκῶρ|σκατός]]}. Etymology-only languages are allowed. Inline modifiers can be attached to such items. The exact syntax allowed is as specified in the `parse_term_with_lang()` function in [[Module:parse utilities]]. If `allow_multiple_lang_prefixes` is given, a {{cd|+}}-sign-separated list of language prefixes can be attached to an item. The resulting language object is stored into the `termlang` field, and also into the `lang` field (or in the case of `allow_multiple_lang_prefixes`, the list of language objects is stored into the `termlangs` field, and the first specified object is stored in the `lang` field). * `allow_multiple_lang_prefixes`: If given in conjunction with `parse_lang_prefix`, multiple language code prefixes can be given, separated by a {{cd|+}} sign. See `parse_lang_prefix` above. * `allow_bad_lang_prefix`: If given in conjunction with `parse_lang_prefix`, unrecognized language prefixes do not trigger an error, but are simply ignored (and not stripped off the item). Note that, regardless of whether this is given, prefixes before a colon do not trigger an error if they do not have the form of a language prefix or if a space follows the colon. It is not recommended that this be given because typos in language prefixes will not trigger an error and will tend to remain unfixed. 4. Fields related to multiple subitems in the term: * `splitchar`: A Lua pattern. If specified, the user-specified argument can consist of multiple delimiter-separated subitems, each of which may be followed by inline modifiers. In this case, the first returned value is no longer an object describing the item, but instead an object with a `terms` field, whose value is a list describing the subitems (whose format is the same as the normal format of the item when `splitchar` is not specified). Each subitem object will have a `delimiter` field holding the actual delimiter occurring before the subitem, which is useful in the case where `splitchar` matches multiple possible characters. In this case, it is possible to specify that a given modifier can only occur after the last subitem and effectively modifies the whole collection of subitems by setting `overall = true` on the modifier. In this case, the modifier's value will be stored in the top-level object (the object with the `terms` field specifying the subitems). Note that splitting on delimiters will not happen in certain protected sequences (by default comma+whitespace; see below). In addition, the algorithm to split on delimiters is sensitive to inline modifier syntax and will not be confused by delimiters inside of inline modifiers or inside of square brackets, which do not trigger splitting (whether or not contained within protected sequences). * `escape_fun` and `unescape_fun`: As in `split_escaping()` and `split_alternating_runs_escaping()` in [[Module:parse utilities]]. They control the protected sequences that won't be split when `splitchar` is specified (see previous item). By default, `escape_comma_whitespace` and `unescape_comma_whitespace` are used, so that comma+whitespace sequences won't be split. * `subitem_param_handling`: How to handle separate parameters that are specified in the presence of multiple subitems. The possible values are {"only"} (only allow separate parameters if there aren't any subitems, otherwise throw an error), {"first"} (store the separate parameters in the first subitem) and {"last"} (store the separate parameters in the last subitem). The default is {"only"}. As a special case, an {{para|scN}} separate parameter will be stored into all subitems. * `subitem_separator_map`: Table mapping user-specified delimiters to displayed separators, stored in the `separator` field of the subitem. If not specified, it defaults to `default_subitem_separator_map`. Note that the presence of an item in this table does not mean that it can be used as a delimiter; only the delimiters specified using `splitchar` are recognized. Delimiters not in this map display as-is. Two values are returned, an object describing the item (or subitems) and the processed `args` structure. In the returned item, there will be one field set for each specified property (either through inline modifiers or separate parameters). If subitems are not allowed, the item directly has fields set on it for the specified properties. If subitems ''are'' allowed, the item contains a `terms` field, which is a list of subitem objects, each of which has fields set on it for the specified properties of that subitem. In addition, the following fields may be set on the item or each subitem: * `term`: The term portion of the item (minus inline modifiers and language prefixes). {nil} if no term was given. * `termlang`: If there is a language prefix, the corresponding language object is stored here (only if `parse_lang_prefix` is set and `allow_multiple_lang_prefixes` is not set). * `termlangs`: If there is are language prefixes and both `parse_lang_prefix` and `allow_multiple_lang_prefixes` are set, the list of corresponding language objects is stored here. * `lang`: The language object of the item. This is set when either (a) there is a language prefix parsed off (if multiple prefixes are allowed, this corresponds to the first one); (b) the `lang` property is allowed and specified; (c) neither (a) nor (b) apply and the `lang` field of the overall `data` object is set, providing a default value. * `sc`: The script object of the item. This is set when either (a) the `sc` property is allowed and specified; (b) `sc` isn't otherwise set and the `sc` field of the overall `data` object is set, providing a default value. * `delimiter`: If subitems are allowed, this specifies the delimiter used prior to the given subitem (e.g. {","}). * `separator`: If subitems are allowed, this specifies the displayed form of the delimiter to be shown before a given subitem. The mapping from user-specified delimiters to displayed separators is handled by `subitem_separator_map`; see above. The first subitem always has a blank string in the `separator` field. ]==] function export.parse_term_with_inline_modifiers_and_separate_params(data) validate_argument_related_fields(data) local raw_args, termarg, param_mods, args = data.raw_args, data.termarg, data.param_mods if raw_args then local params = data.params local termarg_spec = params[termarg] if type(termarg_spec) == "table" and termarg_spec.list then internal_error("Term spec in `data.params` must not have `list` set", termarg_spec) end export.augment_params_with_modifiers(params, param_mods, "always") if data.make_separate_g_into_list then -- HACK: g= is a list for compatibility, but sublist as an inline parameter. params.g = {list = true, item_dest = "genders", type = "genders", flatten = true} end local adjust_params_before_arg_processing = data.adjust_params_before_arg_processing if adjust_params_before_arg_processing then adjust_params_before_arg_processing(params) end args = process_params(raw_args, params) else args = data.processed_args end local process_args_before_parsing = data.process_args_before_parsing if process_args_before_parsing then process_args_before_parsing(args) end local term, lang_cache = args[termarg], data.lang_cache local lang = fetch_argument(args, data.lang) if lang and lang_cache then lang_cache[lang:getCode()] = lang end local sc = fetch_argument(args, data.sc) local term_dest = data.term_dest or "term" if not term then track("missing-term", data.track_module) end local termobj, splitchar = {}, data.splitchar if term then local function generate_obj(term, parse_err) return export.generate_obj_maybe_parsing_lang_prefix { term = term, termobj = splitchar and {} or termobj, term_dest = term_dest, paramname = termarg, parse_lang_prefix = data.parse_lang_prefix, parse_err = parse_err, allow_bad_lang_prefix = data.allow_bad_lang_prefix, allow_multiple_lang_prefixes = data.allow_multiple_lang_prefixes, lang_cache = lang_cache, } end parse_inline_modifiers(term, { paramname = termarg, param_mods = param_mods, generate_obj = generate_obj, splitchar = splitchar, preserve_splitchar = true, escape_fun = data.escape_fun, unescape_fun = data.unescape_fun, outer_container = splitchar and termobj or nil, pre_normalize_modifiers = data.pre_normalize_modifiers, }) end copy_separate_params_to_termobj_and_postprocess{ args = args, param_mods = param_mods, termobj = termobj, has_subitems = not not splitchar, lang = lang, sc = sc, subitem_param_handling = data.subitem_param_handling, subitem_separator_map = data.subitem_separator_map or export.default_subitem_separator_map, allow_conflicting_inline_mods_and_separate_params = data.allow_conflicting_inline_mods_and_separate_params, } if splitchar and termobj.terms[2] then track("parse-term-multiple-subitems", data.track_module) track("parse-term-multiple-subitems") end return termobj, args end return export ood13bkqgv139ip1rcvw68r9hr5w6hh Templat:seakar 10 262495 1349008 1083512 2026-04-08T16:58:13Z Swarabakti 18192 1349008 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|cognate}}</includeonly><!-- --><noinclude>:{{cog|id|akar}}{{documentation}}</noinclude> smi1qmdxygi3wy8fvqiv62a7ymosvid 1349010 1349008 2026-04-08T16:58:30Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kognat]] ke [[Templat:seakar]] 1349008 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|cognate}}</includeonly><!-- --><noinclude>:{{cog|id|akar}}{{documentation}}</noinclude> smi1qmdxygi3wy8fvqiv62a7ymosvid ʼbơ̆r 0 263076 1348960 1299151 2026-04-08T15:29:04Z Swarabakti 18192 1348960 wikitext text/x-wiki =={{bahasa|bdq}}== {{kepala|bdq}} {{-ragam-}} * {{ragam|bdq|'bơ̆r}} {{-n-|bdq}} # [[mulut]] adzu3sw0cwrhj3c0i7p8tp1eahk2cde Templat:seakar+ 10 263577 1349030 1083558 2026-04-08T17:11:26Z Swarabakti 18192 1349030 wikitext text/x-wiki [[Lampiran:Glosarium#kognat|Seakar]] dengan <includeonly>{{#invoke:etymology/templates|cognate}}</includeonly><!-- --><noinclude>{{cog|id|akar}}{{documentation}}</noinclude> a6rxxwp2b1nn2059xyq0ztcvswq48i3 1349031 1349030 2026-04-08T17:12:19Z Swarabakti 18192 1349031 wikitext text/x-wiki <noinclude>: </noinclude>[[Lampiran:Glosarium#kognat|Seakar]] dengan <includeonly>{{#invoke:etymology/templates|cognate}}</includeonly><!-- --><noinclude>{{cog|id|akar}}. {{documentation}}</noinclude> 1h5j0dk94l31y0jb76w16w1j40r7sc5 1349032 1349031 2026-04-08T17:12:37Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kognat+]] ke [[Templat:seakar+]] 1349031 wikitext text/x-wiki <noinclude>: </noinclude>[[Lampiran:Glosarium#kognat|Seakar]] dengan <includeonly>{{#invoke:etymology/templates|cognate}}</includeonly><!-- --><noinclude>{{cog|id|akar}}. {{documentation}}</noinclude> 1h5j0dk94l31y0jb76w16w1j40r7sc5 Templat:serapan 10 263582 1348997 1107947 2026-04-08T16:46:22Z Swarabakti 18192 1348997 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|borrowed}}</includeonly><noinclude>{{bor|und|und|term}}{{documentation}}</noinclude> fbvj70ebedv4eun4d2995lgurplzevs 1348998 1348997 2026-04-08T16:48:35Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:pinjaman]] ke [[Templat:serapan]]: tampaknya lebih umum (berdasarkan perbandingan sekilas di pencarian Google, "kata serapan" ~420rb hasil vs. "kata pinjaman" ~190rb hasil 1348997 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|borrowed}}</includeonly><noinclude>{{bor|und|und|term}}{{documentation}}</noinclude> fbvj70ebedv4eun4d2995lgurplzevs 1349002 1348998 2026-04-08T16:49:39Z Swarabakti 18192 1349002 wikitext text/x-wiki <includeonly>: {{#invoke:etymology/templates|borrowed}}</includeonly><noinclude>{{bor|und|und|term}}{{documentation}}</noinclude> mq0ed70fzw1wecgnwf89rcdg6239e7k 1349003 1349002 2026-04-08T16:50:09Z Swarabakti 18192 1349003 wikitext text/x-wiki <includeonly>: {{#invoke:etymology/templates|borrowed}}</includeonly><noinclude>{{bor|id|ms|istilah}}{{documentation}}</noinclude> 16he6yauqwn0adbr7ey65t4cgtz8wsc 1349004 1349003 2026-04-08T16:50:26Z Swarabakti 18192 1349004 wikitext text/x-wiki <includeonly>: {{#invoke:etymology/templates|borrowed}}</includeonly><noinclude>{{bor|id|en|term}}{{documentation}}</noinclude> pgazv26ppj6wibo3xec2h5l84okdefe Templat:inh+ 10 264729 1349132 1089856 2026-04-08T19:26:39Z Swarabakti 18192 1349132 wikitext text/x-wiki <includeonly>{{glossary|<!-- -->{{#ifeq:{{{nocap|}}}<!-- -->|1<!-- -->|d<!-- -->|D<!-- -->}}iwariskan}} dari <!-- -->{{inh<!-- -->|{{{1|<noinclude>und</noinclude>}}}<!-- -->|{{{2|<noinclude>und</noinclude>}}}<!-- -->|{{{3|}}}<!-- -->|{{{4|{{{alt|}}}}}}<!-- -->|{{{5|{{{t|{{{gloss|}}}}}}}}}<!-- -->|lit={{{lit|}}}<!-- -->|pos={{{pos|}}}<!-- -->|tr={{{tr|}}}<!-- -->|ts={{{ts|}}}<!-- -->|id={{{id|}}}<!-- -->|sc={{{sc|}}}<!-- -->|g={{{g|}}}<!-- -->|g2={{{g2|}}}<!-- -->|g3={{{g3|}}}<!-- -->|nocat={{{nocat|}}}<!-- -->|sort={{{sort|}}}<!-- -->}}</includeonly><!-- --><noinclude>{{documentation}}</noinclude> fr4ivs645dyxyrakeiw3dg7uygjjqt2 Templat:berasal 10 270007 1349012 1266845 2026-04-08T17:02:09Z Swarabakti 18192 tumpang perbarui karena modul sudah dimutakhirkan; tolong laporkan apabila ada galat (saya akan mencoba menyisir satu-satu ke pranala balik) 1349012 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|derived}}</includeonly><!-- --><noinclude>: {{der|id|id|asal}}{{documentation}}</noinclude> r39juj8qtqh3lyawqhndbxkm73vjy6c Endang 0 271542 1349061 1276294 2026-04-08T17:59:38Z Swarabakti 18192 1349061 wikitext text/x-wiki =={{bahasa|jv}}== {{kepala|jv}} {{-etimologi-}} : Kemungkinan besar dari {{der|jv|kaw|indaṅ|t=ibu}}, dari {{der|jv|poz-pro|q=Barat|*inda|t=ibu}}. {{-nama diri-|jv}} # {{bukan glos|nama untuk perempuan}} {{-rujukan-}} * {{R:map:ACD|*inda₂|id=26496|type=c}} meqp9tun5nh6yot2ye13x7s9juyw1n4 Ajeng 0 271543 1349060 1276288 2026-04-08T17:58:25Z Swarabakti 18192 1349060 wikitext text/x-wiki =={{bahasa|jv}}== {{kepala|jv}} {{-etimologi-}} :Dari {{sebut|jv|ajeng}}, dari {{der|jv|kaw|hajĕṅ}}, dari {{kat-afiks|jv|{{sebut|kaw|hayu}} + {{sebut|kaw|-jĕṅ}} ("sufiks kesopanan tingkat tinggi")}}, dari {{der|jv|sa|आयु}}.<!-- bukan dari ayu? cf. OJED, homonim kedua --> {{-nama diri-|jv}} # {{bukan glos|nama untuk perempuan}} mzikvidb2u53asudfp118rb2imrqoqx MediaWiki:Ipbreason-indef-dropdown 8 280756 1348919 2026-04-08T12:09:10Z OrangKalideres 35065 ←Membuat halaman berisi '* Alasan umum pemblokiran selamanya ** Akun vandalisme semata ** Suntingan mengganggu ** Spam pranala ke situs luar ** Menyalahgunakan beberapa akun ** Nama pengguna tak pantas ** Perilaku intimidasi / pelecehan ** Memberikan informasi palsu' 1348919 wikitext text/x-wiki * Alasan umum pemblokiran selamanya ** Akun vandalisme semata ** Suntingan mengganggu ** Spam pranala ke situs luar ** Menyalahgunakan beberapa akun ** Nama pengguna tak pantas ** Perilaku intimidasi / pelecehan ** Memberikan informasi palsu aw6n4hbkv17eoojk8vl7huv1z7zgb8w lambuik gigi pado lidah 0 280757 1348933 2026-04-08T12:57:40Z Ardzun 8096 ←Membuat halaman berisi '=={{bahasa|min}}== {{kepala|min}} {{-var-}} *{{l|min|lunak gigi pado lidah}} {{-pb-|min}} # ber[[lemah lembut]] kepada orang lain karena ada maksud pribadi' 1348933 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-var-}} *{{l|min|lunak gigi pado lidah}} {{-pb-|min}} # ber[[lemah lembut]] kepada orang lain karena ada maksud pribadi tmranzs1dmgjewm2tuxbhvhlctqgc08 1348958 1348933 2026-04-08T15:26:33Z Swarabakti 18192 1348958 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-ragam-}} * {{l|min|lunak gigi pado lidah}} {{-pb-|min}} # ber[[lemah lembut]] kepada orang lain karena ada maksud pribadi an983d4m5f98u9wl8npcitevoaew02c lunak gigi pado lidah 0 280758 1348934 2026-04-08T12:58:38Z Ardzun 8096 ←Membuat halaman berisi '=={{bahasa|min}}== {{kepala|min}} {{-var-}} *{{l|min|lambuik gigi pado lidah}} {{-pb-|min}} # ber[[lemah lembut]] kepada orang lain karena ada maksud pribadi' 1348934 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-var-}} *{{l|min|lambuik gigi pado lidah}} {{-pb-|min}} # ber[[lemah lembut]] kepada orang lain karena ada maksud pribadi eifm4sr2jcpipv2irovfnyyddcqgfm4 lobiah 0 280759 1348943 2026-04-08T13:31:40Z Ardzun 8096 [[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [min] 1348943 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-adj-|min}} # [[lebih]] hrndtvjqcq9ualx28sriflnmj5uvfy8 1348944 1348943 2026-04-08T13:32:08Z Ardzun 8096 /* {{bahasa|min}} */ 1348944 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-ragam-}} *{{l|min|labiah}} {{-adj-|min}} # [[lebih]] 1r4fyox5zoc962b53xm28kcizt0gzxk lusuah 0 280760 1348946 2026-04-08T13:34:17Z Ardzun 8096 [[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [min] 1348946 wikitext text/x-wiki =={{bahasa|min}}== {{kepala|min}} {{-adj-|min}} # [[lusuh]] nhiltg9l0l29p6bu8091ocymdmmr5po Templat:pinjaman 10 280761 1348999 2026-04-08T16:48:35Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:pinjaman]] ke [[Templat:serapan]]: tampaknya lebih umum (berdasarkan perbandingan sekilas di pencarian Google, "kata serapan" ~420rb hasil vs. "kata pinjaman" ~190rb hasil 1348999 wikitext text/x-wiki #ALIH [[Templat:serapan]] 9xb701nzk0pmb6ve10i4gwb12sepr38 Templat:kognat 10 280762 1349011 2026-04-08T16:58:30Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kognat]] ke [[Templat:seakar]] 1349011 wikitext text/x-wiki #ALIH [[Templat:seakar]] nrf594fl4jmi3vdayw6da06eojerk7f Templat:berasal/dokumentasi 10 280763 1349014 2026-04-08T17:03:26Z Swarabakti 18192 ←Membuat halaman berisi '{{subhalaman dokumentasi}} {{pintasan|Templat:der}}' 1349014 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:der}} 67ivcupxj5t0zvrsnymobitabx4ymgf 1349017 1349014 2026-04-08T17:04:31Z Swarabakti 18192 1349017 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:der}} ===Kegunaan=== Memunculkan kategori etimologi untuk istilah yang berasal dari bahasa lain. <includeonly>[[Kategori:Templat etimologi]]</includeonly> 2y8rjchizwmk0d1g293z9tmzhzq5mgb 1349022 1349017 2026-04-08T17:06:25Z Swarabakti 18192 1349022 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:der}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang berasal dari bahasa lain. <includeonly>[[Kategori:Templat etimologi]]</includeonly> c7rccmgp59wto7qa9f951ns7rg1tkf8 Templat:serapan/dokumentasi 10 280764 1349020 2026-04-08T17:05:44Z Swarabakti 18192 ←Membuat halaman berisi '{{subhalaman dokumentasi}} {{pintasan|Templat:bor}} ===Kegunaan=== Memunculkan kategori etimologi untuk istilah yang diserap dari bahasa lain. <includeonly>[[Kategori:Templat etimologi]]</includeonly>' 1349020 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:bor}} ===Kegunaan=== Memunculkan kategori etimologi untuk istilah yang diserap dari bahasa lain. <includeonly>[[Kategori:Templat etimologi]]</includeonly> a6m864vkqdwnahw3nnplqhwufaubniy 1349021 1349020 2026-04-08T17:06:04Z Swarabakti 18192 1349021 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:bor}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang diserap dari bahasa lain. <includeonly>[[Kategori:Templat etimologi]]</includeonly> c5yvfzebggk3kxmdwc4ozx1da3ebt0s Templat:seakar/dokumentasi 10 280765 1349025 2026-04-08T17:08:42Z Swarabakti 18192 ←Membuat halaman berisi '{{subhalaman dokumentasi}} {{pintasan|Templat:cog}} ===Kegunaan=== Memunculkan teks bahasa dan istilah yang seakar ([[kognat]]) pada bagian etimologi. <includeonly>[[Kategori:Templat etimologi]]</includeonly>' 1349025 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:cog}} ===Kegunaan=== Memunculkan teks bahasa dan istilah yang seakar ([[kognat]]) pada bagian etimologi. <includeonly>[[Kategori:Templat etimologi]]</includeonly> cno9vxy25yw821j1ii4yyq7l8tp9db1 1349027 1349025 2026-04-08T17:09:15Z Swarabakti 18192 1349027 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:cog}} ===Kegunaan=== Memunculkan teks untuk istilah yang seakar ([[kognat]]) pada bagian etimologi. <includeonly>[[Kategori:Templat etimologi]]</includeonly> fxa3iuaav9x97autrvttef5cn73u0x7 Templat:kognat+ 10 280766 1349033 2026-04-08T17:12:37Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:kognat+]] ke [[Templat:seakar+]] 1349033 wikitext text/x-wiki #ALIH [[Templat:seakar+]] ejjk6zsrjlu3qi0ps6cp7cu3wjs50vx Templat:seakar+/dokumentasi 10 280767 1349035 2026-04-08T17:13:13Z Swarabakti 18192 ←Membuat halaman berisi '{{subhalaman dokumentasi}} <includeonly>[[Kategori:Templat etimologi]]</includeonly>' 1349035 wikitext text/x-wiki {{subhalaman dokumentasi}} <includeonly>[[Kategori:Templat etimologi]]</includeonly> 1l63okgjfukbra6zncudauf5vkg4bjp Templat:warisan 10 280768 1349038 2026-04-08T17:16:51Z Swarabakti 18192 ←Membuat halaman berisi '<includeonly>{{#invoke:etymology/templates|inherited}}</includeonly><!-- --><noinclude>{{documentation}}</noinclude>' 1349038 wikitext text/x-wiki <includeonly>{{#invoke:etymology/templates|inherited}}</includeonly><!-- --><noinclude>{{documentation}}</noinclude> fdh1zxekppo7jmy7vjsur232m8k6wrm Templat:warisan/dokumentasi 10 280769 1349039 2026-04-08T17:17:27Z Swarabakti 18192 ←Membuat halaman berisi '{{subhalaman dokumentasi}} {{pintasan|Templat:inh}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang diwariskan dari bahasa leluhur. <includeonly>[[Kategori:Templat etimologi]]</includeonly>' 1349039 wikitext text/x-wiki {{subhalaman dokumentasi}} {{pintasan|Templat:inh}} ===Kegunaan=== Memunculkan teks dan kategori etimologi untuk istilah yang diwariskan dari bahasa leluhur. <includeonly>[[Kategori:Templat etimologi]]</includeonly> 6mycp2rbsok6h0bnr59mixgpoy3yr41 Templat:learned borrowing 10 280770 1349076 2026-04-08T18:23:32Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:learned borrowing]] ke [[Templat:serapan terencana]] 1349076 wikitext text/x-wiki #ALIH [[Templat:serapan terencana]] trr701wlsnsn6w9zohj3w1px37endbk Templat:semi-learned borrowing 10 280771 1349078 2026-04-08T18:23:39Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:semi-learned borrowing]] ke [[Templat:serapan semi-terencana]] 1349078 wikitext text/x-wiki #ALIH [[Templat:serapan semi-terencana]] rparyvy73im6gnzub1qml22klvl9l20 Templat:orthographic borrowing 10 280772 1349080 2026-04-08T18:25:01Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:orthographic borrowing]] ke [[Templat:serapan ejaan]] 1349080 wikitext text/x-wiki #ALIH [[Templat:serapan ejaan]] kk6z8ualogs9ml7rs5yl8yhjvgc6lu9 Templat:unadapted borrowing 10 280773 1349082 2026-04-08T18:25:25Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:unadapted borrowing]] ke [[Templat:serapan utuh]] 1349082 wikitext text/x-wiki #ALIH [[Templat:serapan utuh]] 9hgp2vwliz440laz20ym3h0yragyd3k Templat:calque 10 280774 1349084 2026-04-08T18:30:07Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:calque]] ke [[Templat:serapan terjemahan]] 1349084 wikitext text/x-wiki #ALIH [[Templat:serapan terjemahan]] tavmub705ntquh2fwtbxattuguv6bvj Templat:partial calque 10 280775 1349087 2026-04-08T18:31:01Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:partial calque]] ke [[Templat:serapan terjemahan sebagian]] 1349087 wikitext text/x-wiki #ALIH [[Templat:serapan terjemahan sebagian]] 3gvefjeu6hc9ukx9eqb3jjrrcu579gi Templat:semantic loan 10 280776 1349094 2026-04-08T18:36:03Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:semantic loan]] ke [[Templat:serapan semantik]] 1349094 wikitext text/x-wiki #ALIH [[Templat:serapan semantik]] 5pue50a7z5aq2hb37mhqras98fbha4q Templat:phono-semantic matching 10 280777 1349097 2026-04-08T18:37:55Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:phono-semantic matching]] ke [[Templat:pemadanan fono-semantik]] 1349097 wikitext text/x-wiki #ALIH [[Templat:pemadanan fono-semantik]] muohw41fqp9satnhwjw6t1k6vtytmhm Templat:transliteration 10 280778 1349101 2026-04-08T18:41:38Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:transliteration]] ke [[Templat:alih aksara]] 1349101 wikitext text/x-wiki #ALIH [[Templat:alih aksara]] ce59my92wgw550drmc1oz9xd440vow0 Templat:clipping 10 280781 1349126 2026-04-08T19:17:45Z Swarabakti 18192 Swarabakti memindahkan halaman [[Templat:clipping]] ke [[Templat:bentuk penggalan]] 1349126 wikitext text/x-wiki #ALIH [[Templat:bentuk penggalan]] 1u1q57wcx7mjqx56xobwu0xl42qys87 jujurly 0 280782 1349163 2026-04-09T05:49:41Z Swarabakti 18192 [[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [id] 1349163 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adv-|id}} # [[sejujurnya]] 1qrnr1yp49i8ru0v6la592jmb1jftao 1349167 1349163 2026-04-09T08:21:35Z Swarabakti 18192 /* {{bahasa|id}} */ 1349167 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-adv-|id}} # {{label|id|cakapan}} {{sinonim dari|id|sejujurnya}} rws0462mllq0w28wwjftw5ts4y998qp pemuka agama 0 280783 1349169 2026-04-09T09:12:52Z Swarabakti 18192 ←Membuat halaman berisi '=={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # [[orang]] yang memegang [[kepemimpinan]] atau menjadi [[panutan]] dalam suatu [[tradisi]] [[kepercayaan]]' 1349169 wikitext text/x-wiki =={{bahasa|id}}== {{kepala|id}} {{-n-|id}} # [[orang]] yang memegang [[kepemimpinan]] atau menjadi [[panutan]] dalam suatu [[tradisi]] [[kepercayaan]] lkgkfl5rbs81576uvi0k87oztidqdr8