prpm-dbp 0.5.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/SKILL.md +38 -1
- package/bin/cli.js +14 -2
- package/package.json +1 -1
- package/src/pedoman.js +105 -0
- package/src/tukar.js +101 -2
package/README.md
CHANGED
|
@@ -132,7 +132,9 @@ Pengguna kemudian menarik versi baharu dengan `npx skills update`.
|
|
|
132
132
|
| `banding <kata...>` | silang semak PRPM lawan KamusDBP |
|
|
133
133
|
| `cache` | status cache, `--buang <kata>` untuk padam satu |
|
|
134
134
|
|
|
135
|
-
Pilihan: `--refresh`, `--had <n>`, `--delay <ms>`, `--json`.
|
|
135
|
+
Pilihan: `--refresh`, `--had <n>`, `--delay <ms>`, `--json`, `--cepat`, `--pedoman`.
|
|
136
|
+
|
|
137
|
+
`--pedoman` membenarkan penjanaan imbuhan menurut peraturan DBP apabila kamus tiada jawapan. Ketepatannya diukur 88-98% terhadap 66,000 perkataan sebenar, jadi ia mati secara lalai dan hasilnya sentiasa ditanda.
|
|
136
138
|
|
|
137
139
|
## Guna sebagai library
|
|
138
140
|
|
package/SKILL.md
CHANGED
|
@@ -148,7 +148,44 @@ Pakej tidak perlu memilih antara dua ini. DBP sudah memilih, dan pilihan itu ter
|
|
|
148
148
|
|
|
149
149
|
**§10 — enam belas perkataan dikecualikan daripada aturan pola:** `ada`, `apa`, `beta`, `bin`, `binti`, `dari`, `daripada`, `ini`, `itu`, `jika`, `kepada`, `kita`, `lima`, `maka`, `pada`, `demikian`. Ejaannya mesti datang daripada kamus dan tidak boleh dibetulkan oleh mana-mana peraturan pola.
|
|
150
150
|
|
|
151
|
-
**§17.1 — kata ulang penuh menggunakan angka dua Arab `٢`**, bukan sempang
|
|
151
|
+
**§17.1 — kata ulang penuh menggunakan angka dua Arab `٢`**, bukan sempang dan bukan kata dasar ditulis dua kali.
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
Cikgu-cikgu -> چيقݢو٢
|
|
155
|
+
murid-murid -> موريد٢
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Kata dasar dicari dalam kamus seperti biasa, jadi ejaannya tetap datang daripada sumber. Hanya penambahan `٢` itu dijana oleh peraturan. Peraturan ini simetri: `چيقݢو٢` dibaca semula sebagai `cikgu-cikgu`.
|
|
159
|
+
|
|
160
|
+
§17.2 mengecualikan kata ulang yang **berubah bentuk** (berimbuhan atau berentak) seperti `bermaaf-maafan`. Di situ sempang kekal dan peraturan `٢` tidak terpakai, jadi padanan menuntut kedua-dua bahagian benar-benar serupa.
|
|
161
|
+
|
|
162
|
+
## Penjanaan imbuhan (pilihan, mati secara lalai)
|
|
163
|
+
|
|
164
|
+
`--pedoman` membenarkan pakej **menjana** ejaan kata berimbuhan menurut §13 dan §15, apabila tiada sumber lain mempunyai jawapan. Ejaan kata dasar tetap dicari dalam kamus; hanya imbuhan yang dijana.
|
|
165
|
+
|
|
166
|
+
Ia mati secara lalai kerana ketepatannya diukur, bukan diandaikan. Diuji terhadap 66,000 perkataan sebenar:
|
|
167
|
+
|
|
168
|
+
| Imbuhan | Kes diuji | Betul |
|
|
169
|
+
|---|---|---|
|
|
170
|
+
| `-mu` | 333 | 98% |
|
|
171
|
+
| `-nya` | 3,697 | 97% |
|
|
172
|
+
| `di-` | 2,435 | 92% |
|
|
173
|
+
| `se-` | 1,605 | 90% |
|
|
174
|
+
| `ke-` | 976 | 88% |
|
|
175
|
+
|
|
176
|
+
Sebahagian kegagalan itu artifak ukuran (`tamu` bukan `ta`+`mu`), jadi ketepatan sebenar lebih tinggi. Walaupun begitu, 98% tidak cukup untuk menjana ejaan secara senyap dalam alat yang seluruh tujuannya menghalang Jawi yang nampak betul tetapi salah.
|
|
177
|
+
|
|
178
|
+
Bila dihidupkan, hasilnya **tetap ditanda** dan dilaporkan dalam medan `dijanaPedoman` berserta rujukan seksyennya:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
$ npx prpm-dbp jawi nota.txt --pedoman
|
|
182
|
+
«اباديڽ» ککل.
|
|
183
|
+
dijana ikut Pedoman, BELUM disahkan DBP (1): Abadinya=اباديڽ [Pedoman DBP §15.1]
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Peraturan yang dilaksanakan: §13.5-13.7 (awalan `di-`, `se-`, `ke-`), §13.10 (tiga cara akhiran `-an`), §13.11 (tiga cara akhiran `-i`), §15.1 (kata ganti singkat `ku`, `mu`, `nya`).
|
|
187
|
+
|
|
188
|
+
**Kodpoint setiap imbuhan disahkan empirik daripada dataset, bukan dibaca daripada peraturan.** Hamzah dalam akhiran ialah `ء` U+0621 berdiri sendiri, manakala dalam awalan ia `أ` U+0623 di atas alif. Peraturan bertulis tidak membezakan dua itu.
|
|
152
189
|
|
|
153
190
|
## Rantai kepercayaan
|
|
154
191
|
|
package/bin/cli.js
CHANGED
|
@@ -33,7 +33,8 @@ const BANTUAN = `prpm-dbp — semak Bahasa Melayu dan Jawi terhadap PRPM DBP
|
|
|
33
33
|
npx prpm-dbp cache [--buang <kata>] status cache
|
|
34
34
|
npx prpm-dbp install [--link] pasang sebagai Claude Code skill
|
|
35
35
|
|
|
36
|
-
Pilihan: --refresh
|
|
36
|
+
Pilihan: --refresh --had <n> --delay <ms> --json --cepat
|
|
37
|
+
--pedoman jana imbuhan ikut peraturan DBP (88-98% tepat, hasil ditanda)
|
|
37
38
|
|
|
38
39
|
Cache: ${CACHE_PATH}
|
|
39
40
|
`
|
|
@@ -47,6 +48,7 @@ function huraiArgs(argv) {
|
|
|
47
48
|
else if (a === '--json') pilihan.json = true
|
|
48
49
|
else if (a === '--link') pilihan.link = true
|
|
49
50
|
else if (a === '--cepat') pilihan.cepat = true
|
|
51
|
+
else if (a === '--pedoman') pilihan.pedoman = true
|
|
50
52
|
else if (a === '--had') pilihan.had = Number(argv[++i])
|
|
51
53
|
else if (a === '--delay') pilihan.delay = Number(argv[++i])
|
|
52
54
|
else if (a === '--buang') pilihan.buang = argv[++i]
|
|
@@ -150,7 +152,11 @@ async function main() {
|
|
|
150
152
|
|
|
151
153
|
case 'jawi': {
|
|
152
154
|
const teks = await readFile(baki[0], 'utf8')
|
|
153
|
-
const h = await keJawi(teks, cache, {
|
|
155
|
+
const h = await keJawi(teks, cache, {
|
|
156
|
+
...opts,
|
|
157
|
+
cubaDasar: !pilihan.cepat,
|
|
158
|
+
janaImbuhan: pilihan.pedoman,
|
|
159
|
+
})
|
|
154
160
|
await saveCache(cache)
|
|
155
161
|
if (pilihan.json) { keluar(h); break }
|
|
156
162
|
console.log(h.teks)
|
|
@@ -163,6 +169,12 @@ async function main() {
|
|
|
163
169
|
h.adaEntriTanpaJawi.join(', '),
|
|
164
170
|
)
|
|
165
171
|
}
|
|
172
|
+
if (h.dijanaPedoman.length) {
|
|
173
|
+
console.error(
|
|
174
|
+
`dijana ikut Pedoman, BELUM disahkan DBP (${h.dijanaPedoman.length}): ` +
|
|
175
|
+
h.dijanaPedoman.map((x) => `${x.kata}=${x.jawi} [${x.rujukan}]`).join(', '),
|
|
176
|
+
)
|
|
177
|
+
}
|
|
166
178
|
if (h.namaKhas.length) {
|
|
167
179
|
console.error(
|
|
168
180
|
`nama khas belum disahkan (${h.namaKhas.length}): ${h.namaKhas.join(', ')}\n` +
|
package/package.json
CHANGED
package/src/pedoman.js
CHANGED
|
@@ -110,3 +110,108 @@ export const ANGKA_DUA = '\u0662'
|
|
|
110
110
|
* pendakwaan). Kerana itu ia tidak boleh dilipat semasa perbandingan.
|
|
111
111
|
*/
|
|
112
112
|
export const NOTA_MAQSURAH = 'Pedoman DBP §11.6'
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* §17.1 — Kata ulang PENUH ditulis sebagai kata dasar diikuti angka dua
|
|
116
|
+
* Arab. Kata dasar tidak ditulis dua kali.
|
|
117
|
+
*
|
|
118
|
+
* kanak-kanak -> کانق٢ murid-murid -> موريد٢
|
|
119
|
+
*
|
|
120
|
+
* §17.2 — Ini TIDAK terpakai apabila bahagian yang diulang berubah bentuk
|
|
121
|
+
* (kata ulang berimbuhan atau berentak). Di situ sempang digunakan. Kerana
|
|
122
|
+
* itu padanan di bawah menuntut kedua-dua bahagian benar-benar serupa.
|
|
123
|
+
*/
|
|
124
|
+
export function pisahKataUlang(kata) {
|
|
125
|
+
const m = /^(.+)-\1$/i.exec(String(kata))
|
|
126
|
+
return m ? m[1] : null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function binaKataUlang(jawiDasar) {
|
|
130
|
+
if (!jawiDasar) return null
|
|
131
|
+
return { jawi: jawiDasar + ANGKA_DUA, rujukan: 'Pedoman DBP §17.1' }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Songsangan §17.1: kata dasar + ٢ menjadi kata dasar berulang penuh. */
|
|
135
|
+
export function pisahUlangJawi(jawi) {
|
|
136
|
+
if (!jawi.endsWith(ANGKA_DUA)) return null
|
|
137
|
+
const dasar = jawi.slice(0, -ANGKA_DUA.length)
|
|
138
|
+
return dasar ? dasar : null
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const HAMZAH = 'ء' // ء berdiri sendiri, BUKAN أ U+0623 seperti dalam awalan
|
|
142
|
+
const NUN = 'ن'
|
|
143
|
+
const YA = 'ي'
|
|
144
|
+
const WAU = 'و'
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* §13.10 — Tiga cara mengeja akhiran -an, bergantung pada huruf akhir kata
|
|
148
|
+
* dasar dalam ejaan JAWI (bukan Rumi):
|
|
149
|
+
* (i) selepas wau -> alif-nun tinjau -> تينجاوان
|
|
150
|
+
* (ii) selepas alif -> hamzah-nun buka -> بوکاءن
|
|
151
|
+
* (iii) selain itu -> nun sumpit -> سومڤيتن
|
|
152
|
+
*
|
|
153
|
+
* Catatan §13.10(ii): kata dasar yang berakhir dengan suku kata terbuka
|
|
154
|
+
* bervokal [a] tetapi tidak ditulis dengan alif perlu ditambah alif dahulu.
|
|
155
|
+
* Itulah sebabnya buka (بوک) menjadi بوکاءن dan bukan بوکءن.
|
|
156
|
+
*
|
|
157
|
+
* Kodpoint disahkan empirik daripada dataset, bukan diandaikan.
|
|
158
|
+
*/
|
|
159
|
+
export function imbuhAkhiranAn(jawiDasar, rumiDasar) {
|
|
160
|
+
if (!jawiDasar) return null
|
|
161
|
+
if (jawiDasar.endsWith(WAU)) return { jawi: jawiDasar + ALIF + NUN, rujukan: 'Pedoman DBP §13.10(i)' }
|
|
162
|
+
if (jawiDasar.endsWith(ALIF)) return { jawi: jawiDasar + HAMZAH + NUN, rujukan: 'Pedoman DBP §13.10(ii)' }
|
|
163
|
+
// Kata dasar berakhir vokal [a] dalam Rumi tetapi tanpa alif dalam Jawi:
|
|
164
|
+
// alif ditambah dahulu, menurut Catatan §13.10(ii).
|
|
165
|
+
if (/a$/i.test(rumiDasar ?? '')) {
|
|
166
|
+
return { jawi: jawiDasar + ALIF + HAMZAH + NUN, rujukan: 'Pedoman DBP §13.10(ii) Catatan' }
|
|
167
|
+
}
|
|
168
|
+
return { jawi: jawiDasar + NUN, rujukan: 'Pedoman DBP §13.10(iii)' }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* §13.11 — Tiga cara mengeja akhiran -i:
|
|
173
|
+
* (i) selepas alif -> hamzah-ya
|
|
174
|
+
* (ii) selepas wau -> hamzah-ya
|
|
175
|
+
* (iii) selain itu -> ya
|
|
176
|
+
*/
|
|
177
|
+
export function imbuhAkhiranI(jawiDasar, rumiDasar) {
|
|
178
|
+
if (!jawiDasar) return null
|
|
179
|
+
if (jawiDasar.endsWith(ALIF) || jawiDasar.endsWith(WAU)) {
|
|
180
|
+
return { jawi: jawiDasar + HAMZAH + YA, rujukan: 'Pedoman DBP §13.11(i)' }
|
|
181
|
+
}
|
|
182
|
+
if (/a$/i.test(rumiDasar ?? '')) {
|
|
183
|
+
return { jawi: jawiDasar + ALIF + HAMZAH + YA, rujukan: 'Pedoman DBP §13.11(i) Catatan' }
|
|
184
|
+
}
|
|
185
|
+
return { jawi: jawiDasar + YA, rujukan: 'Pedoman DBP §13.11(iii)' }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* §15.1 — Kata ganti singkat ditulis serangkai dengan kata di depannya.
|
|
190
|
+
* ku -> kaf-wau mu -> mim-wau nya -> nya
|
|
191
|
+
* §13.5, §13.6, §13.7 — Awalan di-, se-, ke- ditulis rapat; jika kata dasar
|
|
192
|
+
* bermula dengan alif, hamzah dibubuh di atas alif itu (alif berhamzah).
|
|
193
|
+
*/
|
|
194
|
+
export const AKHIRAN_GANTI = new Map([
|
|
195
|
+
['nya', 'ڽ'],
|
|
196
|
+
['ku', 'كو'.replace('ك', 'ک')],
|
|
197
|
+
['mu', 'مو'],
|
|
198
|
+
])
|
|
199
|
+
|
|
200
|
+
export const AWALAN = new Map([
|
|
201
|
+
['di', 'د'],
|
|
202
|
+
['se', 'س'],
|
|
203
|
+
['ke', 'ک'],
|
|
204
|
+
])
|
|
205
|
+
|
|
206
|
+
export function imbuhAwalan(awalan, jawiDasar) {
|
|
207
|
+
const huruf = AWALAN.get(String(awalan).toLowerCase())
|
|
208
|
+
if (!huruf || !jawiDasar) return null
|
|
209
|
+
const dasar = jawiDasar.startsWith(ALIF) ? ALIF_HAMZAH + jawiDasar.slice(ALIF.length) : jawiDasar
|
|
210
|
+
return { jawi: huruf + dasar, rujukan: `Pedoman DBP §13.5-13.7 (${awalan}-)` }
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function imbuhGanti(ganti, jawiDasar) {
|
|
214
|
+
const huruf = AKHIRAN_GANTI.get(String(ganti).toLowerCase())
|
|
215
|
+
if (!huruf || !jawiDasar) return null
|
|
216
|
+
return { jawi: jawiDasar + huruf, rujukan: 'Pedoman DBP §15.1' }
|
|
217
|
+
}
|
package/src/tukar.js
CHANGED
|
@@ -12,7 +12,18 @@ import { lookup } from './prpm.js'
|
|
|
12
12
|
import { normalisasiJawi } from './kamus.js'
|
|
13
13
|
import { cariDataset, muatDataset } from './dataset.js'
|
|
14
14
|
import { cariNama, mungkinNamaKhas } from './nama.js'
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
imbuhAkhiranAn,
|
|
17
|
+
imbuhAkhiranI,
|
|
18
|
+
imbuhAwalan,
|
|
19
|
+
imbuhGanti,
|
|
20
|
+
binaKataUlang,
|
|
21
|
+
bolehCantumSendi,
|
|
22
|
+
cantumSendi,
|
|
23
|
+
pisahKataUlang,
|
|
24
|
+
pisahSendi,
|
|
25
|
+
pisahUlangJawi,
|
|
26
|
+
} from './pedoman.js'
|
|
16
27
|
|
|
17
28
|
// Baris tanda vokal Arab (fathah, kasrah, dammah, sukun, syaddah, tanwin,
|
|
18
29
|
// alef superscript). Jawi Melayu TIDAK menggunakannya; teks al-Quran dan
|
|
@@ -72,6 +83,53 @@ export function calonDasar(kata) {
|
|
|
72
83
|
return [...calon]
|
|
73
84
|
}
|
|
74
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Jana ejaan kata berimbuhan menurut peraturan Pedoman.
|
|
88
|
+
*
|
|
89
|
+
* Ejaan kata DASAR tetap dicari dalam kamus; hanya imbuhan yang dijana.
|
|
90
|
+
* Diukur terhadap 66k perkataan sebenar: -mu 98%, -nya 97%, di- 92%,
|
|
91
|
+
* se- 90%, ke- 88%. Kerana itu ia mati secara lalai dan hasilnya sentiasa
|
|
92
|
+
* ditanda.
|
|
93
|
+
*/
|
|
94
|
+
async function janaIkutPedoman(kata, cache, opts, gunaDataset) {
|
|
95
|
+
const ejaan = async (dasar) => {
|
|
96
|
+
const rec = await lookup(dasar, cache, opts)
|
|
97
|
+
if (rec?.jawi) return rec.jawi
|
|
98
|
+
if (!gunaDataset) return null
|
|
99
|
+
return (await cariDataset(dasar))?.jawi ?? null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const [awalan] of AWALAN_URUTAN) {
|
|
103
|
+
if (!kata.startsWith(awalan) || kata.length - awalan.length < 3) continue
|
|
104
|
+
const jawiDasar = await ejaan(kata.slice(awalan.length))
|
|
105
|
+
const hasil = imbuhAwalan(awalan, jawiDasar)
|
|
106
|
+
if (hasil) return hasil
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
for (const ganti of ['nya', 'mu', 'ku']) {
|
|
110
|
+
if (!kata.endsWith(ganti) || kata.length - ganti.length < 3) continue
|
|
111
|
+
const dasar = kata.slice(0, -ganti.length)
|
|
112
|
+
const hasil = imbuhGanti(ganti, await ejaan(dasar))
|
|
113
|
+
if (hasil) return hasil
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (kata.endsWith('an') && kata.length > 4) {
|
|
117
|
+
const dasar = kata.slice(0, -2)
|
|
118
|
+
const hasil = imbuhAkhiranAn(await ejaan(dasar), dasar)
|
|
119
|
+
if (hasil) return hasil
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (kata.endsWith('i') && kata.length > 3) {
|
|
123
|
+
const dasar = kata.slice(0, -1)
|
|
124
|
+
const hasil = imbuhAkhiranI(await ejaan(dasar), dasar)
|
|
125
|
+
if (hasil) return hasil
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const AWALAN_URUTAN = [['di'], ['se'], ['ke']]
|
|
132
|
+
|
|
75
133
|
/**
|
|
76
134
|
* Cari kata dasar yang sah bagi kata berimbuhan.
|
|
77
135
|
*
|
|
@@ -126,7 +184,7 @@ export function petaSongsang(cache, dataset = null) {
|
|
|
126
184
|
* Perkataan yang tidak disahkan dibalut penanda, tidak pernah direka.
|
|
127
185
|
*/
|
|
128
186
|
export async function keJawi(teks, cache, opts = {}) {
|
|
129
|
-
const { penanda = ['«', '»'], cubaDasar = true, gunaDataset = true } = opts
|
|
187
|
+
const { penanda = ['«', '»'], cubaDasar = true, gunaDataset = true, janaImbuhan = false } = opts
|
|
130
188
|
const belumDisahkan = []
|
|
131
189
|
const terbitanSah = []
|
|
132
190
|
const dariDataset = []
|
|
@@ -134,6 +192,8 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
134
192
|
const adaEntriTanpaJawi = []
|
|
135
193
|
const dariNama = []
|
|
136
194
|
const namaKhas = []
|
|
195
|
+
const kataUlang = []
|
|
196
|
+
const dijanaPedoman = []
|
|
137
197
|
const bahagian = teks.split(PECAH_RUMI)
|
|
138
198
|
const keluar = []
|
|
139
199
|
|
|
@@ -159,6 +219,33 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
159
219
|
}
|
|
160
220
|
}
|
|
161
221
|
|
|
222
|
+
// Pedoman DBP §17.1: kata ulang penuh ialah kata dasar + angka dua Arab.
|
|
223
|
+
// Kata dasar dicari seperti biasa, jadi ejaannya tetap datang daripada
|
|
224
|
+
// kamus; hanya penambahan ٢ itu yang dijana oleh peraturan.
|
|
225
|
+
const dasarUlang = pisahKataUlang(cebis)
|
|
226
|
+
if (dasarUlang) {
|
|
227
|
+
const recDasar = await lookup(dasarUlang.toLowerCase(), cache, opts)
|
|
228
|
+
const jawiDasar = recDasar?.jawi ?? (gunaDataset ? (await cariDataset(dasarUlang.toLowerCase()))?.jawi : null)
|
|
229
|
+
const ulang = binaKataUlang(jawiDasar)
|
|
230
|
+
if (ulang) {
|
|
231
|
+
kataUlang.push({ kata: cebis, dasar: dasarUlang, jawi: ulang.jawi, rujukan: ulang.rujukan })
|
|
232
|
+
keluar.push(ulang.jawi)
|
|
233
|
+
continue
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Penjanaan imbuhan menurut Pedoman. MATI secara lalai: diukur 88-98%
|
|
238
|
+
// tepat terhadap 66k perkataan sebenar, dan pakej ini tidak menjana
|
|
239
|
+
// ejaan yang mungkin salah tanpa kebenaran eksplisit.
|
|
240
|
+
if (janaImbuhan) {
|
|
241
|
+
const j = await janaIkutPedoman(cebis.toLowerCase(), cache, opts, gunaDataset)
|
|
242
|
+
if (j) {
|
|
243
|
+
dijanaPedoman.push({ kata: cebis, jawi: j.jawi, rujukan: j.rujukan })
|
|
244
|
+
keluar.push(penanda[0] + j.jawi + penanda[1])
|
|
245
|
+
continue
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
162
249
|
// Nama khas yang pengguna sudah sahkan sendiri.
|
|
163
250
|
const nm = await cariNama(cebis)
|
|
164
251
|
if (nm?.jawi) {
|
|
@@ -210,6 +297,8 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
210
297
|
disahkanDbp: dbp.length,
|
|
211
298
|
dariDataset,
|
|
212
299
|
dariNama,
|
|
300
|
+
kataUlang,
|
|
301
|
+
dijanaPedoman,
|
|
213
302
|
namaKhas: [...new Set(namaKhas)],
|
|
214
303
|
adaEntriTanpaJawi: [...new Set(adaEntriTanpaJawi)],
|
|
215
304
|
belumDisahkan: [...new Set(belumDisahkan)],
|
|
@@ -270,6 +359,16 @@ export function keRumi(teksJawi, cache, { penanda = ['«', '»'], dataset = null
|
|
|
270
359
|
}
|
|
271
360
|
|
|
272
361
|
if (!padanan) {
|
|
362
|
+
// Pedoman DBP §17.1 songsang: kata dasar + ٢ menjadi kata berulang.
|
|
363
|
+
const dasarUlang = pisahUlangJawi(bahagian[i])
|
|
364
|
+
if (dasarUlang) {
|
|
365
|
+
const jumpaUlang = peta.get(normalisasiJawi(dasarUlang))
|
|
366
|
+
if (jumpaUlang?.length === 1) {
|
|
367
|
+
keluar.push(jumpaUlang[0] + '-' + jumpaUlang[0])
|
|
368
|
+
continue
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
273
372
|
// Pedoman DBP §14.1 songsang: bentuk bercantum seperti دمکة tiada
|
|
274
373
|
// dalam kamus, jadi cuba pisahkan kata sendi di hadapan.
|
|
275
374
|
let dipisah = null
|