Files
2026-04-04 13:29:23 +05:30

150 lines
6.7 KiB
Markdown

<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
# RTF Viewer — Project Context
## What this project is
A Next.js app that converts legacy RTF files containing Vedic scriptures (Bhagavad-gītā, Śrīmad-Bhāgavatam, Caitanya-caritāmṛta, letters, magazines, etc.) into structured, browsable content with proper Unicode Sanskrit.
The original RTF files use **custom font encodings** (Indevr, ScaGoudy, RM Devanagari, Balaram, etc.) where ASCII characters map to Devanagari glyphs and IAST diacritical marks. These render correctly in RTF readers with the fonts installed, but the text is not copyable or searchable as real Unicode.
## Goals
1. **Preserve original formatting** — RTF files viewable in-browser via pre-converted HTML with custom fonts injected
2. **Structured JSON extraction** — Parse the HTML into per-verse JSON files with proper Unicode (Devanagari + IAST transliteration)
3. **Chapter/verse browsing UI** — Next.js pages for navigating books → chapters → verses
## Architecture
```
public/
rtfs/ → Original RTF files (~430MB total, 17 files)
html/ → HTML converted from RTF (textutil + @font-face injection)
fonts/ → Custom TTF fonts (Balaram, ScaGoudy, Indevr, etc.)
app/
page.tsx → Home page listing all RTF documents
view/[slug]/ → Full HTML viewer (iframe-based, for raw browsing)
books/bg/ → Bhagavad-gītā structured viewer
page.tsx → Chapter index
[chapter]/
page.tsx → Chapter page with all verses + sidebar index
verse-index.tsx → Client component for scroll-tracking sidebar
app/lib/books/
bg/
intro.json → Book metadata (title, author, chapters list)
chapters/01/verses/
01.json → Per-verse structured data
02.json
...
scripts/
bg_extract.py → Python script to parse bg.html → JSON
inject-fonts.py → Inject @font-face rules into converted HTML
```
## Font Encoding
### ScaGoudy → IAST Unicode mapping
The ScaGoudy font uses Latin characters to render IAST diacritical marks. The extraction script decodes these:
| ScaGoudy | IAST | Example |
|----------|------|---------|
| `ä` | `ā` | `mämakäù` → `māmakāḥ` |
| `å` | `ṛ` | `dhåtaräñöra` → `dhṛtarāṣṭra` |
| `ñ` | `ṣ` | `kñetre` → `kṣetre` |
| `ö` | `ṭ` | `öra` → `ṭra` |
| `ë` | `ṇ` | `päëòaväù` → `pāṇḍavāḥ` |
| `ò` | `ḍ` | same example |
| `ç`/`Ç` | `ś`/`Ś` | `paçya` → `paśya` |
| `ì` | `ṅ` | `saìgamya` → `saṅgamya` |
| `ï` | `ñ` | `saïjaya` → `sañjaya` |
| `ü` | `ū` | `vyüòham` → `vyūḍham` |
| `é` | `ī` | `abravét` → `abravīt` |
| `à` | `ṁ` | `vyüòhaà` → `vyūḍhaṁ` |
| `ù` | `ḥ` | `samavetäù` → `samavetāḥ` |
### Indevr font
Used for Devanagari verses. ASCII characters render as Devanagari glyphs. We do NOT extract this text — instead we generate proper Unicode Devanagari from the IAST transliteration using the `indic-transliteration` Python library.
### Devanagari anusvāra normalization
After IAST → Devanagari conversion, we normalize only:
- `ङ्` before velars (क, ख, ग, घ) → `ं` (e.g., `सङ्ग` → `संग`)
- `ञ्` before palatals (च, छ, ज, झ) → `ं` (e.g., `सञ्ज` → `संज`)
We do NOT normalize `ण्ड`, `न्त`, `म्ब` etc. — these are standard conjuncts and must stay as-is (e.g., `पाण्डव`, `कुन्ति`).
## Verse JSON schema
```json
{
"chapter": 1,
"verse": 1,
"reference": "Bg 1.1",
"devanagari": "धृतराष्ट्र उवाच\nधर्मक्षेत्रे कुरुक्षेत्रे समवेता युयुत्सवः\nमामकाः पाण्डवाश् चैव किम् अकुर्वत संजय",
"transliteration": "dhṛtarāṣṭra uvāca\ndharma-kṣetre kuru-kṣetre\nsamavetā yuyutsavaḥ\nmāmakāḥ pāṇḍavāś caiva\nkim akurvata sañjaya",
"synonyms": [
{ "word": "dhṛtarāṣṭraḥ", "meanings": ["King Dhṛtarāṣṭra"] }
],
"translation": "<b>Dhṛtarāṣṭra said:</b> O Sañjaya, after assembling...",
"purport": ["<i>Bhagavad-gītā</i> is the widely read...", "paragraph 2..."]
}
```
**Key rules:**
- **`devanagari`**: 2-line verse structure (pādas paired). Speaker attributions (e.g., "उवाच") stay on their own line.
- **`transliteration`**: One pāda per line (4+ lines). Never pair pādas.
- **`synonyms`**: Array of `{ word: string, meanings: string[] }`. Parsed from `"word—meaning; word—meaning"` format.
- **`translation`** and **`purport`**: HTML strings preserving `<b>`, `<i>`, `<a>` tags. Purport is an array of paragraphs.
- Multi-verse entries (e.g., texts 16-18) are stored as a single file named by the first verse number.
## HTML parsing (bg_extract.py)
The script walks `<p>` tags using CSS classes as a state machine:
| CSS class | Content | Action |
|-----------|---------|--------|
| `p11` | Chapter title | Start new chapter |
| `p25` | Verse ref (`Bg 1.1`) | Start new verse |
| `p26` | `TEXT 1` header | Confirm verse |
| `p28` | Devanagari (Indevr font) | **Skip** — derive from transliteration |
| `p29` | Transliteration pāda | Collect into `_padas` list |
| `p30` | Synonyms | Parse word—meaning pairs |
| `p31`/`p33` | TRANSLATION / PURPORT header | Transition state |
| `p32` | Translation text | Extract with HTML |
| `p6`/`p12`/`p13` | Purport paragraphs | Collect with HTML |
| `p24`/`p34` | "Collier" end marker | Finalize verse |
## RTF → HTML conversion
- **Tool**: macOS `textutil` (NOT LibreOffice — it substitutes font names incorrectly, e.g., Indevr → RM Devanagari)
- **Prerequisite**: Custom fonts must be installed in `~/Library/Fonts/` before conversion
- **Post-processing**: `scripts/inject-fonts.py` adds `@font-face` declarations so browsers can load the custom fonts
```bash
# Convert a single RTF
textutil -convert html -output public/html/NAME.html public/rtfs/NAME.RTF
# Inject fonts into all HTML files
python3 scripts/inject-fonts.py
```
## Current progress
- [x] RTF → HTML conversion (all 17 files)
- [x] Font injection for browser rendering
- [x] Full HTML viewer (iframe-based)
- [x] BG extraction script (Chapter 1 complete — 46 verses in 39 files)
- [x] BG chapter viewer with verse sidebar
- [ ] BG chapters 2-18
- [ ] SB, CC, and other books
- [ ] Individual verse pages (`/books/bg/[chapter]/[verse]`)