prpm-dbp 0.4.0 → 0.5.1
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 +34 -0
- package/package.json +1 -1
- package/src/kamus.js +9 -2
- package/src/pedoman.js +112 -0
- package/src/tukar.js +31 -0
package/SKILL.md
CHANGED
|
@@ -116,6 +116,40 @@ Ejaan yang disimpan begini ditandakan datang daripada pengguna, bukan daripada D
|
|
|
116
116
|
|
|
117
117
|
Bagi nama berasal Arab, ejaan Jawinya memang ejaan Arab asal, jadi ia nampak seperti dikekalkan. Bagi nama bukan Arab ia ditransliterasi penuh: `Kuala Lumpur` menjadi `کوالا لومڤور`.
|
|
118
118
|
|
|
119
|
+
## Peraturan Pedoman DBP
|
|
120
|
+
|
|
121
|
+
Satu fail sahaja dalam pakej ini **menjana** ejaan dan bukan mencarinya: `src/pedoman.js`. Ia dibenarkan kerana setiap peraturan di dalamnya datang daripada *Pedoman Umum Ejaan Jawi Bahasa Melayu* terbitan DBP, dan dirujuk pada seksyennya.
|
|
122
|
+
|
|
123
|
+
**§14.1 — kata sendi `di` dan `ke` ditulis sebagai satu kata dengan kata yang mengikutinya.**
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
di Mekah -> دمکة bukan د مکة
|
|
127
|
+
ke sekolah -> کسکوله bukan ک سکوله
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Nota seksyen yang sama: jika kata berikutnya bermula dengan alif, hamzah dibubuh di atas alif itu. `di Asrama` menjadi `دأسراما`, bukan `داسراما`.
|
|
131
|
+
|
|
132
|
+
Kodpoint hamzah (U+0623) disahkan secara empirik daripada dataset, bukan diandaikan: `abai` bermula `ا` U+0627, `diabaikan` bermula `د` + `أ` U+0623. Corak sama pada `diambil`, `diajar`, `diurus`.
|
|
133
|
+
|
|
134
|
+
Bentuk bercantum tidak wujud sebagai entri kamus, jadi pembacaan songsang memisahkannya semula dan memulihkan hamzah kepada alif. Peraturan ini simetri.
|
|
135
|
+
|
|
136
|
+
Kata sendi **tidak** dicantum apabila kata berikutnya belum disahkan, kerana hasilnya akan menjadi Jawi bercantum dengan teks Rumi bertanda.
|
|
137
|
+
|
|
138
|
+
**§11 — kata serapan Arab, dua peringkat:**
|
|
139
|
+
|
|
140
|
+
| Seksyen | Jenis | Cara eja | Contoh |
|
|
141
|
+
|---|---|---|---|
|
|
142
|
+
| §11.1 | istilah khusus | ikut ejaan asal Arab | `wuduk`, `Qur'an`, `sunah`, `hadis`, `tayamum` |
|
|
143
|
+
| §11.2 | kata umum yang sudah terserap | ikut kaedah kata jati Melayu | `sabun` |
|
|
144
|
+
|
|
145
|
+
Pakej tidak perlu memilih antara dua ini. DBP sudah memilih, dan pilihan itu terkandung dalam ejaan yang dipulangkan PRPM. Ia didokumenkan supaya tiada siapa "membetulkan" `صلاة` kepada ejaan fonetik Melayu kemudian hari.
|
|
146
|
+
|
|
147
|
+
**§11.6 — alif maqsurah dikekalkan.** `takwa` تقوى, `fatwa` فتوى, `Musa`, `Isa`. Ia diganti dengan alif hanya apabila dibentuk kata terbitan: `ketakwaan`, `memfatwakan`, `pendakwaan`. Perbezaan itu membawa maklumat, jadi `ى` **tidak pernah dilipat** semasa perbandingan. Melipatnya akan membuat `تقوي` yang salah dibandingkan sama dengan `تقوى` yang betul.
|
|
148
|
+
|
|
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
|
+
|
|
151
|
+
**§17.1 — kata ulang penuh menggunakan angka dua Arab `٢`**, bukan sempang: `rama-rama` menjadi `رام٢`. Sempang digunakan hanya apabila bahagian yang diulang berubah bentuk (§17.2).
|
|
152
|
+
|
|
119
153
|
## Rantai kepercayaan
|
|
120
154
|
|
|
121
155
|
Setiap ejaan Jawi yang dikeluarkan membawa asal-usulnya. Jangan runtuhkan lapisan ini.
|
package/package.json
CHANGED
package/src/kamus.js
CHANGED
|
@@ -187,8 +187,7 @@ export async function cariKamus(kata, { timeout = 25000 } = {}) {
|
|
|
187
187
|
const LIPATAN = new Map([
|
|
188
188
|
['ك', 'ک'], // ك Arabic Kaf -> ک Keheh
|
|
189
189
|
['ڪ', 'ک'], // ڪ Swash Kaf -> ک Keheh
|
|
190
|
-
['ی', 'ي'], // ی Farsi Yeh -> ي Arabic Yeh
|
|
191
|
-
['ى', 'ي'], // ى Alef Maksura -> ي Arabic Yeh
|
|
190
|
+
['ی', 'ي'], // ی Farsi Yeh -> ي Arabic Yeh (varian bentuk semata-mata)
|
|
192
191
|
['ڬ', 'ݢ'], // ڬ Gaf varian -> ݢ Gaf Jawi Melayu
|
|
193
192
|
['ە', 'ه'], // ە Ae -> ه Ha
|
|
194
193
|
['ہ', 'ه'], // ہ Heh Goal -> ه Ha
|
|
@@ -204,6 +203,14 @@ export function normalisasiJawi(teks) {
|
|
|
204
203
|
.trim()
|
|
205
204
|
}
|
|
206
205
|
|
|
206
|
+
// SENGAJA TIDAK DILIPAT: ى (U+0649, alif maqsurah) kepada ي (U+064A).
|
|
207
|
+
// Pedoman DBP §11.6: alif maqsurah dalam ejaan asal Arab DIKEKALKAN dalam
|
|
208
|
+
// ejaan Jawi — takwa تقوى, fatwa فتوى, Musa, Isa. Melipatnya akan membuat
|
|
209
|
+
// تقوي (salah) dibandingkan sama dengan تقوى (betul), lalu menyembunyikan
|
|
210
|
+
// kesilapan sebenar. §11.6 juga menyatakan huruf itu diganti dengan alif
|
|
211
|
+
// apabila dibentuk kata terbitan (ketakwaan, memfatwakan), jadi perbezaan
|
|
212
|
+
// itu memang membawa maklumat.
|
|
213
|
+
|
|
207
214
|
// SENGAJA TIDAK DILIPAT: پ (U+067E, pe Parsi) kepada ڽ (U+06BD, nya).
|
|
208
215
|
// Sesetengah enjin transliterasi negeri mengeluarkan پ di tempat ڽ, tetapi
|
|
209
216
|
// itu huruf yang SALAH, bukan varian bentuk. Melipatnya akan menyembunyikan
|
package/src/pedoman.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Peraturan daripada Pedoman Umum Ejaan Jawi Bahasa Melayu (DBP).
|
|
3
|
+
*
|
|
4
|
+
* Ini satu-satunya tempat dalam pakej yang MENJANA ejaan dan bukan sekadar
|
|
5
|
+
* mencarinya. Ia dibenarkan kerana setiap peraturan di sini datang daripada
|
|
6
|
+
* dokumen rasmi DBP dan dirujuk pada seksyennya, bukan direka.
|
|
7
|
+
*
|
|
8
|
+
* Sumber: Pedoman Umum Ejaan Jawi Bahasa Melayu, Dewan Bahasa dan Pustaka.
|
|
9
|
+
* Berasaskan Pedoman Ejaan Jawi yang Disempurnakan (1986, ed. 3 1993),
|
|
10
|
+
* hasil Konvensyen Tulisan Jawi Peringkat Kebangsaan 1984, diselaraskan
|
|
11
|
+
* 1991 dan 1993, disahkan Jawatankuasa Teknikal Ejaan Jawi 1993-1994.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const ALIF = 'ا' // ا
|
|
15
|
+
const ALIF_HAMZAH = 'أ' // أ
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* §14.1 — Kata sendi nama `di` dan `ke` ditulis sebagai SATU KATA dengan
|
|
19
|
+
* kata yang mengikutinya.
|
|
20
|
+
*
|
|
21
|
+
* Nota §14.1: jika kata yang mengikutinya bermula dengan huruf alif, huruf
|
|
22
|
+
* hamzah dibubuh di atas alif itu.
|
|
23
|
+
*
|
|
24
|
+
* Kodpoint hamzah disahkan secara empirik daripada dataset, bukan diandaikan:
|
|
25
|
+
* abai ا U+0627 ...
|
|
26
|
+
* diabaikan د + أ U+0623 ...
|
|
27
|
+
* Corak sama pada diambil, diajar, diurus.
|
|
28
|
+
*/
|
|
29
|
+
export const KATA_SENDI = new Map([
|
|
30
|
+
['di', 'د'], // د
|
|
31
|
+
['ke', 'ک'], // ک
|
|
32
|
+
])
|
|
33
|
+
|
|
34
|
+
export function bolehCantumSendi(kata) {
|
|
35
|
+
return KATA_SENDI.has(String(kata).toLowerCase())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Cantumkan kata sendi dengan ejaan Jawi kata yang mengikutinya.
|
|
40
|
+
* Pulangkan null jika kata itu bukan kata sendi yang dicakupi.
|
|
41
|
+
*/
|
|
42
|
+
export function cantumSendi(kataSendi, jawiSelepas) {
|
|
43
|
+
const awalan = KATA_SENDI.get(String(kataSendi).toLowerCase())
|
|
44
|
+
if (!awalan || !jawiSelepas) return null
|
|
45
|
+
|
|
46
|
+
const selepas = jawiSelepas.startsWith(ALIF)
|
|
47
|
+
? ALIF_HAMZAH + jawiSelepas.slice(ALIF.length)
|
|
48
|
+
: jawiSelepas
|
|
49
|
+
|
|
50
|
+
return { jawi: awalan + selepas, rujukan: 'Pedoman DBP §14.1' }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* §11 — Kata serapan Arab dieja dalam dua cara berbeza:
|
|
55
|
+
* §11.1 istilah khusus -> ikut ejaan asal bahasa Arab (wuduk, Qur'an,
|
|
56
|
+
* sunah, hadis, tayamum, wuquf, reda)
|
|
57
|
+
* §11.2 kata umum yang -> ikut cara mengeja kata jati Melayu (sabun)
|
|
58
|
+
* sudah terserap
|
|
59
|
+
*
|
|
60
|
+
* Pakej ini tidak perlu memilih antara dua ini: DBP sudah memilih, dan
|
|
61
|
+
* pilihan itu terkandung dalam ejaan yang dipulangkan PRPM. Peraturan ini
|
|
62
|
+
* didokumenkan di sini supaya tiada siapa "membetulkan" صلاة kepada ejaan
|
|
63
|
+
* fonetik Melayu kemudian hari.
|
|
64
|
+
*/
|
|
65
|
+
export const NOTA_SERAPAN_ARAB = 'Pedoman DBP §11.1 dan §11.2'
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Songsangan §14.1: pisahkan kata sendi yang bercantum.
|
|
69
|
+
*
|
|
70
|
+
* Bentuk bercantum seperti دمکة tidak wujud sebagai entri kamus, jadi
|
|
71
|
+
* pembacaan songsang mesti mencubanya sendiri. Hamzah dipulihkan kepada
|
|
72
|
+
* alif kerana hamzah itu ditambah oleh peraturan, bukan sebahagian ejaan
|
|
73
|
+
* kata dasar.
|
|
74
|
+
*/
|
|
75
|
+
export function pisahSendi(jawi) {
|
|
76
|
+
const calon = []
|
|
77
|
+
for (const [rumi, awalan] of KATA_SENDI) {
|
|
78
|
+
if (!jawi.startsWith(awalan) || jawi.length <= awalan.length) continue
|
|
79
|
+
let baki = jawi.slice(awalan.length)
|
|
80
|
+
if (baki.startsWith(ALIF_HAMZAH)) baki = ALIF + baki.slice(ALIF_HAMZAH.length)
|
|
81
|
+
calon.push({ sendi: rumi, baki, rujukan: 'Pedoman DBP §14.1' })
|
|
82
|
+
}
|
|
83
|
+
return calon
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* §10 — Senarai perkataan yang dikecualikan daripada beberapa aturan
|
|
88
|
+
* pengejaan biasa. Ejaannya tidak menurut pola suku kata, jadi ia mesti
|
|
89
|
+
* datang daripada kamus dan tidak boleh "dibetulkan" oleh mana-mana
|
|
90
|
+
* peraturan pola.
|
|
91
|
+
*/
|
|
92
|
+
export const KECUALI_POLA = new Set([
|
|
93
|
+
'ada', 'apa', 'beta', 'bin', 'binti', 'dari', 'daripada', 'ini', 'itu',
|
|
94
|
+
'jika', 'kepada', 'kita', 'lima', 'maka', 'pada', 'demikian',
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* §17.1 — Kata ulang penuh ditulis dengan tanda angka dua Arab (٢),
|
|
99
|
+
* bukan dengan sempang seperti dalam Rumi.
|
|
100
|
+
* rama-rama -> رام٢
|
|
101
|
+
* §17.2 — Apabila bahagian yang diulang berubah bentuk (kata ulang
|
|
102
|
+
* berimbuhan atau berentak), tanda sempang digunakan.
|
|
103
|
+
*/
|
|
104
|
+
export const ANGKA_DUA = '\u0662'
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* §11.6 — Alif maqsurah dalam ejaan asal Arab dikekalkan (takwa تقوى,
|
|
108
|
+
* fatwa فتوى, Musa, Isa), TETAPI diganti dengan alif apabila dibentuk kata
|
|
109
|
+
* terbitan dengan akhiran atau partikel (ketakwaan, memfatwakan,
|
|
110
|
+
* pendakwaan). Kerana itu ia tidak boleh dilipat semasa perbandingan.
|
|
111
|
+
*/
|
|
112
|
+
export const NOTA_MAQSURAH = 'Pedoman DBP §11.6'
|
package/src/tukar.js
CHANGED
|
@@ -12,6 +12,7 @@ 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 { bolehCantumSendi, cantumSendi, pisahSendi } from './pedoman.js'
|
|
15
16
|
|
|
16
17
|
// Baris tanda vokal Arab (fathah, kasrah, dammah, sukun, syaddah, tanwin,
|
|
17
18
|
// alef superscript). Jawi Melayu TIDAK menggunakannya; teks al-Quran dan
|
|
@@ -185,8 +186,27 @@ export async function keJawi(teks, cache, opts = {}) {
|
|
|
185
186
|
keluar.push(penanda[0] + cebis + penanda[1])
|
|
186
187
|
}
|
|
187
188
|
|
|
189
|
+
// Pedoman DBP §14.1: kata sendi di dan ke bercantum dengan kata berikutnya.
|
|
190
|
+
// Dibuat sebagai lulusan kedua supaya logik carian di atas kekal mudah.
|
|
191
|
+
const sendiDicantum = []
|
|
192
|
+
for (let k = 1; k < keluar.length - 2; k += 2) {
|
|
193
|
+
const asal = bahagian[k]
|
|
194
|
+
if (!bolehCantumSendi(asal)) continue
|
|
195
|
+
if (!/^\s+$/.test(keluar[k + 1])) continue
|
|
196
|
+
const seterusnya = keluar[k + 2]
|
|
197
|
+
// Hanya cantum bila kata berikutnya benar-benar bertukar, bukan ditanda.
|
|
198
|
+
if (!seterusnya || seterusnya.startsWith(penanda[0])) continue
|
|
199
|
+
const gabung = cantumSendi(asal, seterusnya)
|
|
200
|
+
if (!gabung) continue
|
|
201
|
+
sendiDicantum.push({ sendi: asal, jawi: gabung.jawi, rujukan: gabung.rujukan })
|
|
202
|
+
keluar[k] = gabung.jawi
|
|
203
|
+
keluar[k + 1] = ''
|
|
204
|
+
keluar[k + 2] = ''
|
|
205
|
+
}
|
|
206
|
+
|
|
188
207
|
return {
|
|
189
208
|
teks: keluar.join(''),
|
|
209
|
+
sendiDicantum,
|
|
190
210
|
disahkanDbp: dbp.length,
|
|
191
211
|
dariDataset,
|
|
192
212
|
dariNama,
|
|
@@ -212,6 +232,7 @@ export function keRumi(teksJawi, cache, { penanda = ['«', '»'], dataset = null
|
|
|
212
232
|
const tidakDikenali = []
|
|
213
233
|
const kabur = []
|
|
214
234
|
const arab = []
|
|
235
|
+
const sendiDipisah = []
|
|
215
236
|
const bahagian = teksJawi.split(PECAH_JAWI)
|
|
216
237
|
const keluar = []
|
|
217
238
|
|
|
@@ -249,6 +270,15 @@ export function keRumi(teksJawi, cache, { penanda = ['«', '»'], dataset = null
|
|
|
249
270
|
}
|
|
250
271
|
|
|
251
272
|
if (!padanan) {
|
|
273
|
+
// Pedoman DBP §14.1 songsang: bentuk bercantum seperti دمکة tiada
|
|
274
|
+
// dalam kamus, jadi cuba pisahkan kata sendi di hadapan.
|
|
275
|
+
let dipisah = null
|
|
276
|
+
for (const calon of pisahSendi(bahagian[i])) {
|
|
277
|
+
const jumpa = peta.get(normalisasiJawi(calon.baki))
|
|
278
|
+
if (jumpa?.length === 1) { dipisah = calon.sendi + ' ' + jumpa[0]; break }
|
|
279
|
+
}
|
|
280
|
+
if (dipisah) { keluar.push(dipisah); sendiDipisah.push(bahagian[i]); continue }
|
|
281
|
+
|
|
252
282
|
tidakDikenali.push(bahagian[i])
|
|
253
283
|
keluar.push(penanda[0] + bahagian[i] + penanda[1])
|
|
254
284
|
continue
|
|
@@ -267,6 +297,7 @@ export function keRumi(teksJawi, cache, { penanda = ['«', '»'], dataset = null
|
|
|
267
297
|
tidakDikenali: [...new Set(tidakDikenali)],
|
|
268
298
|
kabur,
|
|
269
299
|
arab: [...new Set(arab)],
|
|
300
|
+
sendiDipisah,
|
|
270
301
|
saizPeta: peta.size,
|
|
271
302
|
lengkap: tidakDikenali.length === 0,
|
|
272
303
|
}
|