prpm-dbp 0.14.0 → 0.15.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 +13 -0
- package/bin/cli.js +24 -0
- package/package.json +1 -1
- package/src/prpm.js +15 -0
- package/src/tukar.js +14 -3
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`, `--cepat`, `--pedoman`.
|
|
135
|
+
Pilihan: `--refresh`, `--had <n>`, `--delay <ms>`, `--json`, `--cepat`, `--pedoman`, `--luar-talian`, `--homograf`, `--konteks`.
|
|
136
|
+
|
|
137
|
+
Merumikan ialah keputusan peringkat ayat, bukan peringkat perkataan. `مڠيکوت` ialah ejaan sah bagi `mengikut` dan `mengekot` sekali gus, kedua-duanya entri PRPM sebenar. Gunakan `--konteks` supaya ayat dan makna setiap calon dipaparkan bersama, berserta bilangan rujukan korpus DBP yang mengisih calon lazim ke hadapan.
|
|
136
138
|
|
|
137
139
|
`--luar-talian` tidak pernah menyentuh rangkaian. Wajib untuk laluan permintaan aplikasi: dokumen penuh dari cache mengambil 0.19 saat, manakala satu perkataan baharu daripada PRPM mengambil beberapa saat.
|
|
138
140
|
|
package/SKILL.md
CHANGED
|
@@ -17,6 +17,19 @@ Model boleh hasilkan Jawi yang nampak betul tetapi salah, dan pembaca tidak dapa
|
|
|
17
17
|
|
|
18
18
|
0c. **PRPM sendiri boleh tersilap.** Entri `menyebuk` membawa sebutan dan definisi yang betul tetapi ejaan Jawi `مڽبوت`, iaitu ejaan `menyebut`. Pakej menandakannya dalam medan `mencurigakan` apabila huruf akhir Jawi tidak sepadan dengan hujung Rumi. Tandaan itu bermakna semak sendiri di PRPM, bukan buang.
|
|
19
19
|
|
|
20
|
+
0d. **Merumikan ialah keputusan peringkat AYAT, bukan peringkat perkataan.** Jangan tukar token demi token dan anggap ia selesai. Ejaan Jawi menggunakan empat huruf vokal berbanding enam dalam Rumi, jadi satu ejaan kerap membawa lebih daripada satu bacaan sah. `مڠيکوت` ialah `mengikut` **dan** `mengekot`, dua-duanya entri PRPM sebenar dengan sebutan sendiri. Kamus mengesahkan kedua-duanya wujud; hanya ayat menentukan yang mana dimaksudkan.
|
|
21
|
+
|
|
22
|
+
Gunakan `--konteks` supaya ayat dan makna setiap calon dipaparkan bersama:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
مڠيکوت -> mengikut atau mengekot
|
|
26
|
+
ayat: itu mengikut|mengekot sukatan pelajaran.
|
|
27
|
+
mengikut 2439 rujukan pergi bersama-sama dgn, menurut, mengiring
|
|
28
|
+
mengekot 6 rujukan merapatkan paha dan tangan ke badan
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Bilangan rujukan itu datang daripada panel korpus DBP sendiri, bukan anggaran. Ia **mengisih** calon supaya yang lazim dilihat dahulu; ia **tidak memilih**. Perkataan jarang tetap betul apabila ayat menghendakinya.
|
|
32
|
+
|
|
20
33
|
1. **Jangan hantar Jawi yang belum disemak.** Setiap perkataan Jawi dalam output mesti datang dari PRPM atau ditanda belum disahkan.
|
|
21
34
|
2. **Tanda, jangan sekat.** Kalau satu perkataan tiada dalam PRPM, hantar kerja itu dan senaraikan perkataan berkenaan di hujung. Jangan tahan seluruh dokumen sebab satu nama khas.
|
|
22
35
|
3. **Sebut sumber.** PRPM ada beberapa kamus. Bila petik definisi, sebut kamus mana (Kamus Dewan Edisi Keempat, Kamus Pelajar Edisi Kedua, dan lain-lain).
|
package/bin/cli.js
CHANGED
|
@@ -37,6 +37,7 @@ 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
39
|
--homograf tandakan perkataan yang ejaan Jawinya dikongsi perkataan lain
|
|
40
|
+
--konteks papar ayat dan makna setiap calon bagi kekaburan (rumi)
|
|
40
41
|
|
|
41
42
|
Cache: ${CACHE_PATH}
|
|
42
43
|
`
|
|
@@ -53,6 +54,7 @@ function huraiArgs(argv) {
|
|
|
53
54
|
else if (a === '--pedoman') pilihan.pedoman = true
|
|
54
55
|
else if (a === '--luar-talian') pilihan.luarTalian = true
|
|
55
56
|
else if (a === '--homograf') pilihan.homograf = true
|
|
57
|
+
else if (a === '--konteks') pilihan.konteks = true
|
|
56
58
|
else if (a === '--jenis') pilihan.jenis = argv[++i]
|
|
57
59
|
else if (a === '--had') pilihan.had = Number(argv[++i])
|
|
58
60
|
else if (a === '--delay') pilihan.delay = Number(argv[++i])
|
|
@@ -225,6 +227,28 @@ async function main() {
|
|
|
225
227
|
if (h.tidakDikenali.length) {
|
|
226
228
|
console.error(`tidak dikenali (${h.tidakDikenali.length}): ${h.tidakDikenali.join(', ')}`)
|
|
227
229
|
}
|
|
230
|
+
if (pilihan.konteks && h.kabur.length) {
|
|
231
|
+
// Kekaburan hanya boleh diselesaikan oleh ayat, bukan oleh kamus.
|
|
232
|
+
// Papar ayat penuh berserta makna setiap calon supaya keputusan
|
|
233
|
+
// itu boleh dibuat tanpa membuka PRPM satu per satu.
|
|
234
|
+
const ayat = h.teks.split(/(?<=[.!?])\s+/)
|
|
235
|
+
console.error('\n--- konteks untuk kekaburan ---')
|
|
236
|
+
for (const k of h.kabur) {
|
|
237
|
+
const pilihanTeks = k.calon.join('|')
|
|
238
|
+
const induk = ayat.find((a) => a.includes(pilihanTeks)) ?? ''
|
|
239
|
+
console.error(`\n${k.jawi} -> ${k.calon.join(' atau ')}`)
|
|
240
|
+
if (induk) console.error(` ayat: ${induk.trim()}`)
|
|
241
|
+
for (const c of k.calon) {
|
|
242
|
+
const rec = cache[c]
|
|
243
|
+
const def = (rec?.entri?.[0]?.definisi ?? '').slice(0, 70)
|
|
244
|
+
const kerap = rec?.rujukanKorpus
|
|
245
|
+
console.error(
|
|
246
|
+
` ${c.padEnd(12)} ${kerap != null ? String(kerap).padStart(5) + ' rujukan' : ' kekerapan tidak diketahui'}` +
|
|
247
|
+
(def ? ` ${def}` : ''),
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
228
252
|
if (h.arab.length) console.error(`teks Arab dibiarkan (${h.arab.length}): ${h.arab.join(' ')}`)
|
|
229
253
|
for (const k of h.kabur) console.error(`kabur: ${k.jawi} -> ${k.calon.join(', ')}`)
|
|
230
254
|
break
|
package/package.json
CHANGED
package/src/prpm.js
CHANGED
|
@@ -34,6 +34,15 @@ const DEFINISI = /<b>Definisi\s*:\s*<\/b>([\s\S]*?)(?=<b>\(|$)/
|
|
|
34
34
|
const SUMBER = /<b>\(([^)]+)\)<\/b>/
|
|
35
35
|
const TIADA_TESAURUS = /Tiada maklumat tesaurus untuk kata/
|
|
36
36
|
|
|
37
|
+
// Panel "Juga ditemukan dalam" menyenaraikan bilangan rujukan perkataan itu
|
|
38
|
+
// dalam setiap korpus DBP. Jumlahnya ialah isyarat kekerapan yang BERSUMBER,
|
|
39
|
+
// bukan tekaan: mengikut 2439 rujukan berbanding mengekot 6.
|
|
40
|
+
//
|
|
41
|
+
// Digunakan untuk MENGISIH calon yang kabur, bukan untuk memilih. Perkataan
|
|
42
|
+
// jarang tetap betul apabila ayat menghendakinya.
|
|
43
|
+
const PANEL_KORPUS = /Juga ditemukan dalam:([\s\S]*?)Perkhidmatan/
|
|
44
|
+
const KIRAAN_KORPUS = /<i>\((\d+)\)<\/i>/g
|
|
45
|
+
|
|
37
46
|
const ENTITIES = { amp: '&', lt: '<', gt: '>', quot: '"', '#39': "'", nbsp: ' ' }
|
|
38
47
|
|
|
39
48
|
export function stripTags(raw) {
|
|
@@ -65,11 +74,17 @@ export function parse(kata, page) {
|
|
|
65
74
|
})
|
|
66
75
|
}
|
|
67
76
|
|
|
77
|
+
const panel = page.match(PANEL_KORPUS)
|
|
78
|
+
const rujukanKorpus = panel
|
|
79
|
+
? [...panel[1].matchAll(KIRAAN_KORPUS)].reduce((jum, m) => jum + Number(m[1]), 0)
|
|
80
|
+
: null
|
|
81
|
+
|
|
68
82
|
const semuaJawi = entri.map((e) => e.jawi).filter(Boolean)
|
|
69
83
|
const unik = [...new Set(semuaJawi)]
|
|
70
84
|
return {
|
|
71
85
|
kata,
|
|
72
86
|
dijumpai: entri.length > 0,
|
|
87
|
+
rujukanKorpus,
|
|
73
88
|
jawi: unik[0] ?? null,
|
|
74
89
|
jawiVarian: unik.slice(1),
|
|
75
90
|
entri,
|
package/src/tukar.js
CHANGED
|
@@ -226,10 +226,21 @@ export function petaSongsang(cache, dataset = null) {
|
|
|
226
226
|
* Apabila tiada calon lapisan 1, calon yang belum diketahui digunakan dan
|
|
227
227
|
* sumbernya dilabel, tidak dipulangkan secara senyap.
|
|
228
228
|
*/
|
|
229
|
-
export function pilihCalon(masuk) {
|
|
229
|
+
export function pilihCalon(masuk, cache = null) {
|
|
230
230
|
if (!masuk) return null
|
|
231
231
|
if (Array.isArray(masuk)) return { calon: masuk, sumber: 'campur' }
|
|
232
|
-
|
|
232
|
+
|
|
233
|
+
// Isih ikut kekerapan korpus DBP apabila diketahui: calon yang lebih
|
|
234
|
+
// lazim didahulukan supaya pembaca melihatnya dahulu. Ini MENGISIH,
|
|
235
|
+
// bukan memilih; semua calon tetap dipulangkan.
|
|
236
|
+
const isih = (senarai) => {
|
|
237
|
+
if (!cache || senarai.length < 2) return senarai
|
|
238
|
+
return [...senarai].sort(
|
|
239
|
+
(a, b) => (cache[b]?.rujukanKorpus ?? 0) - (cache[a]?.rujukanKorpus ?? 0),
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (masuk.layak?.length) return { calon: isih(masuk.layak), sumber: 'dbp' }
|
|
233
244
|
if (masuk.entah?.length) return { calon: masuk.entah, sumber: 'dataset' }
|
|
234
245
|
if (masuk.tolak?.length) return { calon: masuk.tolak, sumber: 'rujukan' }
|
|
235
246
|
return null
|
|
@@ -452,7 +463,7 @@ export function keRumi(teksJawi, cache, { penanda = ['«', '»'], dataset = null
|
|
|
452
463
|
}
|
|
453
464
|
if (!bolehGabung) continue
|
|
454
465
|
const frasa = bahagian.slice(i, akhir + 1).join(' ').replace(/\s+/g, ' ')
|
|
455
|
-
const jumpa = pilihCalon(peta.get(normalisasiJawi(frasa)))
|
|
466
|
+
const jumpa = pilihCalon(peta.get(normalisasiJawi(frasa)), cache)
|
|
456
467
|
if (jumpa) { padanan = jumpa.calon; hujung = akhir; break }
|
|
457
468
|
}
|
|
458
469
|
|