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>&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>&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 ‎ is what [[Module:affix]] has always done
default_separator = data.allow_semicolon_separator and " +‎ " 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 = " +‎ ", 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 = " +‎ ", 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 = " +‎ ", 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 " +‎ " 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 " +‎ " 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 " +‎ " 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 = " — " .. 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> ", "")
: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