Urdu content editor on Tiptap (structured editing, with the source view) #58

Merged
anas merged 2 commits from feature/tiptap-editor into main 2026-10-08 23:13:21 +00:00
Owner

Closes #28 (writing tools; document import stays #33).

The editor (revision page, tab ایڈیٹر; tab سورس keeps the raw Divan text). Built on Tiptap 3's free MIT core (@tiptap/core, @tiptap/pm, @tiptap/extensions), no paid add-ons.

  • Verse units of misras laid out like the site: 1 misra = مصرع, 2 = شعر (side by side), 3 or more = بند. These are the same rules as Divan text, so the editor and the text always agree.
  • Enter:
    • adds a misra, or moves into a new couplet's empty second misra;
    • on an empty misra, starts a new couplet.
  • Toolbar:
    • شعر, پیراگراف, باب کا عنوان, ذیلی عنوان;
    • مطلع / حسن مطلع / مقطع (toggle on the current couplet);
    • لغت کا ربط (link the selected word, asking for its dictionary form), حاشیہ, نسخہ;
    • واپس / دوبارہ (undo/redo);
    • Roman-to-Urdu typing and the Urdu keyboard, which now type into the editor too.
  • کلام کا خاکہ: the work's data points (title, poet, genre, radif, …) as editable rows, with suggested names.
  • Saving: always sends Divan text, so diffs, review, git history and the guide are unchanged.

Divan text

  • Lines keep segments, so the editor knows where each link, footnote and variant sits.
  • toText writes a document back.
  • All 11,087 works round-trip unchanged, both through toText and through the editor's conversion (checked in full; a test covers links, notes, variants and labels). npm test: 36 pass.

Fixes found while testing

  • Selecting text in the editor no longer opens the reader's word sidebar or selection menu.
  • The toolbar keeps the editor's selection.

Tested in headless Chrome as a moderator on Ghalib's ghazal:

  1. the editor opens as 11 couplets with the data points;
  2. a real double-click on وصال, then لغت کا ربط, links it (dotted underline);
  3. مقطع is set on the last couplet;
  4. a new couplet is typed with Enter (exactly two misras);
  5. the source tab shows [[وصال]], {{مقطع}} and the new couplet;
  6. saving, then reloading, keeps the link.

The test draft and account were removed; the owner's own drafts were left alone.

Client JavaScript for the editor (about 300 KB with ProseMirror) loads only on the revision page.

🤖 Generated with Claude Code

Closes #28 (writing tools; document import stays #33). **The editor** (revision page, tab **ایڈیٹر**; tab **سورس** keeps the raw Divan text). Built on Tiptap 3's free MIT core (`@tiptap/core`, `@tiptap/pm`, `@tiptap/extensions`), no paid add-ons. - **Verse units** of misras laid out like the site: 1 misra = مصرع, 2 = شعر (side by side), 3 or more = بند. These are the same rules as Divan text, so the editor and the text always agree. - **Enter**: - adds a misra, or moves into a new couplet's empty second misra; - on an empty misra, starts a new couplet. - **Toolbar**: - شعر, پیراگراف, باب کا عنوان, ذیلی عنوان; - مطلع / حسن مطلع / مقطع (toggle on the current couplet); - لغت کا ربط (link the selected word, asking for its dictionary form), حاشیہ, نسخہ; - واپس / دوبارہ (undo/redo); - Roman-to-Urdu typing and the Urdu keyboard, which now type into the editor too. - **کلام کا خاکہ**: the work's data points (title, poet, genre, radif, …) as editable rows, with suggested names. - **Saving**: always sends Divan text, so diffs, review, git history and the guide are unchanged. **Divan text** - Lines keep **segments**, so the editor knows where each link, footnote and variant sits. - `toText` writes a document back. - **All 11,087 works round-trip unchanged**, both through `toText` and through the editor's conversion (checked in full; a test covers links, notes, variants and labels). `npm test`: 36 pass. **Fixes found while testing** - Selecting text in the editor no longer opens the reader's word sidebar or selection menu. - The toolbar keeps the editor's selection. **Tested** in headless Chrome as a moderator on Ghalib's ghazal: 1. the editor opens as 11 couplets with the data points; 2. a real double-click on وصال, then لغت کا ربط, links it (dotted underline); 3. مقطع is set on the last couplet; 4. a new couplet is typed with Enter (exactly two misras); 5. the source tab shows `[[وصال]]`, `{{مقطع}}` and the new couplet; 6. saving, then reloading, keeps the link. The test draft and account were removed; the owner's own drafts were left alone. Client JavaScript for the editor (about 300 KB with ProseMirror) loads only on the revision page. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
anas added 1 commit 2026-10-08 22:53:19 +00:00
- web/src/lib/editor.ts (Tiptap 3 MIT core): verse units of misras (1 = مصرع, 2 = شعر, 3+ = بند, as in
  Divan text) with مطلع/حسن مطلع/مقطع labels, prose paragraphs, chapter headings and sub-headings, a
  dictionary-link mark, footnotes and variant readings; Enter adds a misra (or moves into the next
  empty one), Enter on an empty misra starts a new unit.
- Revision page: editor and source tabs over the same text, the work's data points as rows, a
  toolbar (couplet, paragraph, headings, labels, dictionary link, footnote, variant, undo/redo,
  Roman typing, Urdu keyboard). Saving always sends Divan text.
- Divan text: inline segments keep where links, footnotes and variants sit; toText writes a
  document back. All 11,087 works round-trip unchanged through toText and through the editor.
- The Urdu keyboard and Roman typing type into rich editors; the reader's word sidebar and
  selection menu stay out of editors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anas added 1 commit 2026-10-08 22:58:15 +00:00
anas merged commit 73cf7c5c4c into main 2026-10-08 23:13:21 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: anas/divan#58
No description provided.