prpm-dbp 0.11.1 → 0.13.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/SKILL.md +27 -1
- package/bin/cli.js +9 -0
- package/package.json +1 -1
- package/src/pedoman.js +15 -0
- package/src/tukar.js +33 -1
package/SKILL.md
CHANGED
|
@@ -176,6 +176,7 @@ Ia mati secara lalai kerana ketepatannya diukur, bukan diandaikan. Diuji terhada
|
|
|
176
176
|
| `di-` | 2,435 | 92% |
|
|
177
177
|
| `se-` | 1,605 | 90% |
|
|
178
178
|
| `ke-` | 976 | 88% |
|
|
179
|
+
| `-kan` | 3,046 | 92% |
|
|
179
180
|
|
|
180
181
|
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.
|
|
181
182
|
|
|
@@ -187,7 +188,9 @@ $ npx prpm-dbp jawi nota.txt --pedoman
|
|
|
187
188
|
dijana ikut Pedoman, BELUM disahkan DBP (1): Abadinya=اباديڽ [Pedoman DBP §15.1]
|
|
188
189
|
```
|
|
189
190
|
|
|
190
|
-
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`).
|
|
191
|
+
Peraturan yang dilaksanakan: §13.5-13.7 (awalan `di-`, `se-`, `ke-`), §13.9 (akhiran `-kan`), §13.10 (tiga cara akhiran `-an`), §13.11 (tiga cara akhiran `-i`), §15.1 (kata ganti singkat `ku`, `mu`, `nya`).
|
|
192
|
+
|
|
193
|
+
**Awas terhadap nota panduan tidak rasmi.** Nota sekolah sering menyatakan "huruf alif ditambah semula apabila menerima imbuhan" sebagai peraturan menyeluruh. Diuji terhadap data sebenar, itu tidak benar: `suka` سوک menjadi `sukakan` سوککن dan `lukanya` لوکڽ, kedua-duanya tanpa alif. Penambahan alif berlaku bagi `-an` dan `-i` sahaja, menurut Catatan §13.10(ii) dan §13.11(i).
|
|
191
194
|
|
|
192
195
|
**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.
|
|
193
196
|
|
|
@@ -272,6 +275,29 @@ Siri yang sama membezakan kaf Arab daripada kaf Jawi secara eksplisit, iaitu per
|
|
|
272
275
|
|
|
273
276
|
Buku itu berhak cipta terpelihara (PNM). Ia dirujuk di sini sebagai pengesahan, bukan disalin.
|
|
274
277
|
|
|
278
|
+
## Homograf
|
|
279
|
+
|
|
280
|
+
Ejaan Jawi menggunakan empat huruf vokal berbanding enam dalam Rumi, jadi perkataan berbeza kerap berkongsi ejaan. Diukur pada 64,251 ejaan Jawi dalam data: **2,009 (3%) ialah homograf**.
|
|
281
|
+
|
|
282
|
+
Panduan DBP membahagikannya kepada dua:
|
|
283
|
+
|
|
284
|
+
| Jenis | Layanan | Contoh |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| **Hakiki** | **dibenarkan kekal**, tidak dibezakan | `biru`/`biro` بيرو, `burung`/`borong` بوروڠ, `satu`/`sato` ساتو |
|
|
287
|
+
| **Tidak hakiki** | dibezakan dengan alif | `kampung` کامڤوڠ / `kempung` کمڤوڠ |
|
|
288
|
+
|
|
289
|
+
Jenis kedua ialah Pedoman §8.17 (juga Klinik Jawi Siri ke-35): alif melambangkan [a] di suku kata tertutup untuk membezakannya daripada pepet yang tidak dilambangkan. **Ejaan DBP sudah mengandungi peraturan ini**, jadi pakej tidak perlu menjananya. Sembilan pasangan rujukan diuji, kesemuanya dibezakan dengan betul.
|
|
290
|
+
|
|
291
|
+
Jenis pertama pula tidak boleh diselesaikan oleh mana-mana peraturan. Itulah sebab `rumi` melaporkan semua calon dan enggan memilih: bagi homograf hakiki, DBP sendiri menyatakan kekaburan itu dibenarkan dan hanya konteks ayat boleh menyelesaikannya.
|
|
292
|
+
|
|
293
|
+
`--homograf` menandakan perkataan yang ejaan Jawinya dikongsi, supaya penulis tahu sebelum menghantar bahawa pembaca akan bergantung pada konteks:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
$ npx prpm-dbp jawi nota.txt --homograf
|
|
297
|
+
اݢام ايت ساتو دان بوروڠ تربڠ.
|
|
298
|
+
homograf, ejaan Jawi dikongsi (3): اݢام=agama/igama, ساتو=satu/sato, بوروڠ=burung/borong
|
|
299
|
+
```
|
|
300
|
+
|
|
275
301
|
## Rantai kepercayaan
|
|
276
302
|
|
|
277
303
|
Setiap ejaan Jawi yang dikeluarkan membawa asal-usulnya. Jangan runtuhkan lapisan ini.
|
package/bin/cli.js
CHANGED
|
@@ -36,6 +36,7 @@ const BANTUAN = `prpm-dbp — semak Bahasa Melayu dan Jawi terhadap PRPM DBP
|
|
|
36
36
|
Pilihan: --refresh --had <n> --delay <ms> --json --cepat
|
|
37
37
|
--pedoman jana imbuhan ikut peraturan DBP (88-98% tepat, hasil ditanda)
|
|
38
38
|
--luar-talian jangan sentuh rangkaian langsung (wajib untuk laluan permintaan app)
|
|
39
|
+
--homograf tandakan perkataan yang ejaan Jawinya dikongsi perkataan lain
|
|
39
40
|
|
|
40
41
|
Cache: ${CACHE_PATH}
|
|
41
42
|
`
|
|
@@ -51,6 +52,7 @@ function huraiArgs(argv) {
|
|
|
51
52
|
else if (a === '--cepat') pilihan.cepat = true
|
|
52
53
|
else if (a === '--pedoman') pilihan.pedoman = true
|
|
53
54
|
else if (a === '--luar-talian') pilihan.luarTalian = true
|
|
55
|
+
else if (a === '--homograf') pilihan.homograf = true
|
|
54
56
|
else if (a === '--jenis') pilihan.jenis = argv[++i]
|
|
55
57
|
else if (a === '--had') pilihan.had = Number(argv[++i])
|
|
56
58
|
else if (a === '--delay') pilihan.delay = Number(argv[++i])
|
|
@@ -164,6 +166,7 @@ async function main() {
|
|
|
164
166
|
...opts,
|
|
165
167
|
cubaDasar: !pilihan.cepat,
|
|
166
168
|
janaImbuhan: pilihan.pedoman,
|
|
169
|
+
semakHomograf: pilihan.homograf,
|
|
167
170
|
})
|
|
168
171
|
await saveCache(cache)
|
|
169
172
|
if (pilihan.json) { keluar(h); break }
|
|
@@ -183,6 +186,12 @@ async function main() {
|
|
|
183
186
|
h.dijanaPedoman.map((x) => `${x.kata}=${x.jawi} [${x.rujukan}]`).join(', '),
|
|
184
187
|
)
|
|
185
188
|
}
|
|
189
|
+
if (h.homograf?.length) {
|
|
190
|
+
console.error(
|
|
191
|
+
`homograf, ejaan Jawi dikongsi (${h.homograf.length}): ` +
|
|
192
|
+
h.homograf.map((x) => `${x.jawi}=${x.dikongsi.join('/')}`).join(', '),
|
|
193
|
+
)
|
|
194
|
+
}
|
|
186
195
|
if (h.akronim.length) {
|
|
187
196
|
console.error(`akronim, dikekalkan Rumi (${h.akronim.length}): ${h.akronim.join(', ')}`)
|
|
188
197
|
}
|
package/package.json
CHANGED
package/src/pedoman.js
CHANGED
|
@@ -185,6 +185,21 @@ export function imbuhAkhiranI(jawiDasar, rumiDasar) {
|
|
|
185
185
|
return { jawi: jawiDasar + YA, rujukan: 'Pedoman DBP §13.11(iii)' }
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/**
|
|
189
|
+
* §13.9 — Akhiran -kan ditulis kaf-nun, dilekatkan terus tanpa perubahan
|
|
190
|
+
* pada kata dasar.
|
|
191
|
+
*
|
|
192
|
+
* Nota panduan sekolah sering menyatakan "huruf alif ditambah semula apabila
|
|
193
|
+
* menerima imbuhan". Itu terlalu menyeluruh: diuji terhadap data sebenar,
|
|
194
|
+
* suka سوک menjadi sukakan سوککن dan lukanya لوکڽ, tanpa alif. Penambahan
|
|
195
|
+
* alif berlaku bagi -an dan -i sahaja, menurut Catatan §13.10(ii) dan
|
|
196
|
+
* §13.11(i).
|
|
197
|
+
*/
|
|
198
|
+
export function imbuhAkhiranKan(jawiDasar) {
|
|
199
|
+
if (!jawiDasar) return null
|
|
200
|
+
return { jawi: jawiDasar + 'کن', rujukan: 'Pedoman DBP §13.9' }
|
|
201
|
+
}
|
|
202
|
+
|
|
188
203
|
/**
|
|
189
204
|
* §15.1 — Kata ganti singkat ditulis serangkai dengan kata di depannya.
|
|
190
205
|
* ku -> kaf-wau mu -> mim-wau nya -> nya
|
package/src/tukar.js
CHANGED
|
@@ -14,6 +14,7 @@ import { cariDataset, muatDataset } from './dataset.js'
|
|
|
14
14
|
import { cariNama, mungkinAkronim, mungkinNamaKhas } from './nama.js'
|
|
15
15
|
import {
|
|
16
16
|
imbuhAkhiranAn,
|
|
17
|
+
imbuhAkhiranKan,
|
|
17
18
|
imbuhAkhiranI,
|
|
18
19
|
imbuhAwalan,
|
|
19
20
|
imbuhGanti,
|
|
@@ -113,6 +114,11 @@ async function janaIkutPedoman(kata, cache, opts, gunaDataset) {
|
|
|
113
114
|
if (hasil) return hasil
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
if (kata.endsWith('kan') && kata.length > 5) {
|
|
118
|
+
const hasil = imbuhAkhiranKan(await ejaan(kata.slice(0, -3)))
|
|
119
|
+
if (hasil) return hasil
|
|
120
|
+
}
|
|
121
|
+
|
|
116
122
|
if (kata.endsWith('an') && kata.length > 4) {
|
|
117
123
|
const dasar = kata.slice(0, -2)
|
|
118
124
|
const hasil = imbuhAkhiranAn(await ejaan(dasar), dasar)
|
|
@@ -212,7 +218,13 @@ export function pilihCalon(masuk) {
|
|
|
212
218
|
* Perkataan yang tidak disahkan dibalut penanda, tidak pernah direka.
|
|
213
219
|
*/
|
|
214
220
|
export async function keJawi(teks, cache, opts = {}) {
|
|
215
|
-
const {
|
|
221
|
+
const {
|
|
222
|
+
penanda = ['«', '»'],
|
|
223
|
+
cubaDasar = true,
|
|
224
|
+
gunaDataset = true,
|
|
225
|
+
janaImbuhan = false,
|
|
226
|
+
semakHomograf = false,
|
|
227
|
+
} = opts
|
|
216
228
|
const belumDisahkan = []
|
|
217
229
|
const terbitanSah = []
|
|
218
230
|
const dariDataset = []
|
|
@@ -306,6 +318,25 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
306
318
|
keluar.push(penanda[0] + cebis + penanda[1])
|
|
307
319
|
}
|
|
308
320
|
|
|
321
|
+
// Amaran homograf. Ejaan Jawi yang dikongsi dua perkataan Rumi akan taksa
|
|
322
|
+
// apabila dibaca semula. Menurut panduan DBP, homograf HAKIKI (kongsi
|
|
323
|
+
// vokal wau/ya, kata Melayu lawan kata asing, bentuk berimbuhan) memang
|
|
324
|
+
// dibenarkan kekal dan tidak dibezakan. Jadi ini bukan ralat: ia maklumat
|
|
325
|
+
// supaya penulis tahu konteks ayat perlu menanggung beban perbezaan itu.
|
|
326
|
+
const homograf = []
|
|
327
|
+
if (semakHomograf) {
|
|
328
|
+
const songsang = petaSongsang(cache, await muatDataset())
|
|
329
|
+
for (const [k, cebis] of bahagian.entries()) {
|
|
330
|
+
if (k % 2 === 0) continue
|
|
331
|
+
const hasil = keluar[k]
|
|
332
|
+
if (!hasil || hasil.startsWith(penanda[0])) continue
|
|
333
|
+
const pilihan = pilihCalon(songsang.get(normalisasiJawi(hasil)))
|
|
334
|
+
if (pilihan && pilihan.calon.length > 1) {
|
|
335
|
+
homograf.push({ kata: cebis, jawi: hasil, dikongsi: pilihan.calon })
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
309
340
|
// Pedoman DBP §14.1: kata sendi di dan ke bercantum dengan kata berikutnya.
|
|
310
341
|
// Dibuat sebagai lulusan kedua supaya logik carian di atas kekal mudah.
|
|
311
342
|
const sendiDicantum = []
|
|
@@ -331,6 +362,7 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
331
362
|
dariDataset,
|
|
332
363
|
dariNama,
|
|
333
364
|
kataUlang,
|
|
365
|
+
homograf,
|
|
334
366
|
dijanaPedoman,
|
|
335
367
|
namaKhas: [...new Set(namaKhas)],
|
|
336
368
|
akronim: [...new Set(akronim)],
|