7.1
Normalisasi Ayah dan `preBismillah`
Di dalam operate, array verses dibangun dari arab.ayahs.map (crawler/script.js:116-1201). Iterasi itu bukan sekadar penyalinan: setiap ayat diubah menjadi objek baru dengan bentuk yang seragam, sementara teks dan tafsirnya diambil dari tiga edisi lain serta dari berkas lokal. Hasilnya adalah satu objek ayah dengan kunci number, meta, text, translation, audio, dan tafsir.
Empat edisi dan pembagian perannya
Keempat edisi diminta sekaligus lewat parameter editions pada satu URL, dengan urutan tetap (crawler/script.js:13-162). Respons mentah dikonversi lebih dulu dengan mengganti \\u menjadi %u sebelum JSON.parse (crawler/script.js:53-553), sehingga isi ayat tersimpan sebagai rangkaian persen selama proses berjalan. Konversi balik ke bentuk \\u baru dilakukan saat berkas ditulis (crawler/script.js:2034).
| Edisi | Variabel hasil destructuring | Bagian objek ayah yang diisi |
|---|---|---|
quran-simple-enhanced | simple | text.arab untuk ayat yang tidak diproses preBismillahHandler |
ar.alafasy | arab | kerangka iterasi, number, meta, audio, text.arab ayat pertama |
en.transliteration | transliteration | text.transliteration.en |
en.sahih | english | translation.en |
../data/quran-tafsir.json | temp | text.id, tafsir.id.short, tafsir.id.long |
Berkas temp dimuat sebagai konstanta tingkat modul (crawler/script.js:105) dan menjadi kunci pencarian per ayat: temp diindeks dengan \${arab.number}.${ayah.numberInSurah}``, yaitu gabungan nomor surah dan nomor ayat di dalam surah (crawler/script.js:116-1201).
graph TD
REQ["request editions: quran-simple-enhanced,ar.alafasy,en.transliteration,en.sahih"]
PARSE["JSON.parse → data[0..3]"]
SIMPLE["simple"]
ARAB["arab"]
TRANS["transliteration"]
ENG["english"]
TEMP["temp: quran-tafsir.json"]
MAP["arab.ayahs.map"]
OUT["satu objek ayah di verses"]
REQ --> PARSE
PARSE --> SIMPLE
PARSE --> ARAB
PARSE --> TRANS
PARSE --> ENG
ARAB --> MAP
SIMPLE --> MAP
TRANS --> MAP
ENG --> MAP
TEMP --> MAP
MAP --> OUT
style REQ fill:#f59e0b,color:#000
style PARSE fill:#f59e0b,color:#000
style ARAB fill:#336791,color:#fff
style SIMPLE fill:#8b5cf6,color:#fff
style TRANS fill:#8b5cf6,color:#fff
style ENG fill:#8b5cf6,color:#fff
style TEMP fill:#8b5cf6,color:#fff
style MAP fill:#2d7d46,color:#fff
style OUT fill:#2d7d46,color:#fff
%% fig: Empat edisi menuju satu objek ayah
%% desc: Satu request mengambil empat edisi, lalu setiap array ayah digabung per posisi oleh arab.ayahs.map menjadi objek verses.Peta field per ayat
| Field | Sumber | Transformasi |
|---|---|---|
number.inQuran / number.inSurah | ayah.number dan ayah.numberInSurah | disalin apa adanya |
meta.juz, page, manzil, ruku, hizbQuarter | ayah | disalin apa adanya |
meta.sajda | ayah.sajda | dinormalkan menjadi { recommended, obligatory } |
text.arab | simple.ayahs[idx].text | preBismillahHandler bila ayat pertama, selain itu trim() |
text.transliteration.en | transliteration.ayahs[idx].text | trim() |
translation.en | english.ayahs[idx].text | trim() |
translation.id | activeAyah.text.id | trim() |
audio.primary / audio.secondary | ayah.audio dan ayah.audioSecondary | disalin apa adanya |
tafsir.id.short / tafsir.id.long | tafsir.short dan tafsir.long dari temp | trim() |
Field number (crawler/script.js:121-1246), meta (crawler/script.js:125-1407), text (crawler/script.js:141-148), translation (crawler/script.js:149-152), audio (crawler/script.js:153-156), dan tafsir (crawler/script.js:157-162) mengikuti tabel di atas tanpa perhitungan tambahan selain pemotongan spasi.
⚠️ Perataan antar edisi memakai
idxdari iterasiarab.ayahs, bukan nomor ayat. Jika salah satu edisi mengembalikan jumlah ayat yang berbeda, ayat berikutnya pada edisi itu akan bergeser satu posisi dan teksnya tetap masuk tanpa error.
Konversi sajda
ayah.sajda tidak selalu berbentuk sama. Ketika bernilai objek, hanya recommended dan obligatory yang diambil, sedangkan id dibuang. Ketika bernilai boolean, kedua field diisi dengan nilai boolean tersebut (crawler/script.js:131-13912). Hasilnya selalu objek dua field, seperti yang terlihat pada berkas keluaran (data/quran.json:37-4713).
Pembersihan tag HTML pada tafsir
Ada dua jalur tafsir yang diperlakukan berbeda. Tafsir tingkat surah, yaitu keterangan dari sumber kedua, dibersihkan dari tag HTML dengan replace(/(<([^>]+)>)/gi, ''); untuk surah 13 dan 55, kata Makkiyyah di dalamnya juga diganti menjadi Madaniyyah, lalu hasilnya di-trim (crawler/script.js:88-9614). Tafsir tingkat ayat tidak melewati pembersihan itu: short dan long hanya di-trim (crawler/script.js:157-16211).
Menghapus basmalah pembuka
Pada keluaran, basmalah disimpan satu kali di tingkat surah lewat field preBismillah, yang bernilai null untuk surah 1 dan surah 9 (crawler/script.js:97-10715). Karena itu teks Arab ayat pertama tidak boleh memuat basmalah lagi. Pembersihannya hanya dijalankan ketika arab.number !== 1 dan idx === 0 (crawler/script.js:141-1488); ayat pertama surah 1 dibiarkan utuh karena basmalah di sana adalah ayat pertama itu sendiri.
preBismillahHandler menyimpan dua varian basmalah dalam bentuk persen sebagai kunci replacer, masing-masing dengan turunan RegExp ber-flag gi (crawler/script.js:40-4716). Handler mencari kunci yang terkandung di dalam ayat melalui ayah.includes(key), mengambil pasangan regEx-nya, menjalankan ayah.replace(regEx, ''), lalu trim(). Varian kedua berbeda pada penulisan harakat, sehingga satu pola saja tidak cukup.
graph TD
A{"arab.number !== 1 dan idx === 0"}
A -- ya --> B["preBismillahHandler(arabText)"]
A -- tidak --> Z["arabText.trim()"]
B --> C{"Object.entries(replacer).find: ayah.includes(key)"}
C -- ketemu --> D["ayah.replace(regEx, '') dengan flag gi"]
C -- tidak ketemu --> E["regEx undefined: teks tidak diubah"]
D --> F["trim()"]
E --> F
F --> G["text.arab"]
Z --> G
G --> H["preBismillah tingkat surah memuat basmalah"]
style A fill:#f59e0b,color:#000
style B fill:#f59e0b,color:#000
style D fill:#2d7d46,color:#fff
style G fill:#2d7d46,color:#fff
style H fill:#336791,color:#fff
style E fill:#dc2626,color:#fff
%% fig: Jalur keputusan preBismillahHandler
%% desc: Hanya ayat pertama pada surah selain surah 1 yang dibersihkan, dan pembersihan gagal secara diam bila tidak ada kunci yang cocok.⚠️ Bila tidak ada kunci yang cocok,
regExbernilaiundefineddan teks dikembalikan tanpa perubahan tanpa pesan apa pun. Basmalah akan tetap muncul ditext.arabayat pertama sekaligus dipreBismillah, sehingga pengulangan ini hanya bisa terdeteksi dengan memeriksa data hasilnya.
Dua ketergantungan perlu diperhatikan sebelum menjalankan ulang normalisasi ini. Berkas ../data/quran-tafsir.json yang dipakai sebagai temp tidak disertakan di repository, karena namanya masuk daftar abaikan (.gitignore:2-2). Tanpa berkas itu, pengambilan activeAyah gagal dan galat ditangkap oleh blok catch milik operate (crawler/script.js:169-17917); mekanisme pengulangan antrean surah dibahas di Crawler: Pipeline Pengambilan Data.