---
name: otzaria-book-format
description: >
  המרת טקסטים למבנה ספר של אוצריא והוספת המטא-דאטה שלהם. השתמש בסקיל הזה כשצריך
  להכניס ספר חדש לספריית otzaria-library או להכין קובץ לאוצריא ממקור אחר — HTML,
  Markdown, DOCX/PDF-OCR, ויקי, אתר, JSON או טקסט גולמי: חלוקה לשורות, כותרות
  ותוכן עניינים, הערות שוליים, ניקוי תגי HTML ו-CSS למה שהקורא מכיר, שם קובץ
  ומיקום בקטגוריה, רשומת מטא-דאטה (`all_metadata.json`, `ForDB/*.csv`, מחבר,
  תקופה, דור, תיאור ב־`sefaria_metadata_changes.csv`), קבצי לוואי (`_links.json`, `_alt_toc.json`, `_headings.json`),
  וולידציה של התוצאה. גם לשאלות "איך הפורמט עובד", "איזה תגים נתמכים", "למה
  אוצריא קוראת שורה-שורה", "איך לתקן ספר שנראה שבור". Triggers: להמיר ספר לאוצריא,
  להכניס ספר לספרייה, פורמט אוצריא, מבנה ספר, כותרות, הערות שוליים, מטאדאטה,
  otzaria book format, convert to otzaria.
  אל תשתמש בו ליצירת קישורי מפרש לספר בסיס (זה otzaria-commentary-linker) או
  לכתיבה ל-DB חי (otzaria-db-linker).
---

# המרת טקסט למבנה אוצריא + מטא-דאטה

<div dir="rtl">

## המטרה

לקחת טקסט ממקור כלשהו ולהוציא **ספר תקין של אוצריא**: קובץ `.txt` שעומד בחוזה
ה-markup, שם קובץ ומיקום נכונים, מטא-דאטה מלאה, וקבצי לוואי אם צריך.

## מודל היסוד — שורה היא היחידה

**כל שורה פיזית בקובץ היא יחידת תוכן עצמאית**, והקורא מרנדר כל שורה בנפרד
(`flutter_widget_from_html` מעל Flutter). מזה נובע כל השאר:

| נובע | פירוש |
|---|---|
| קישורים | קישור מצביע על שורה (או טווח שורות) — לכן חלוקה נכונה לשורות היא קריטית |
| תוכן עניינים | נבנה מתגי `<h1>`–`<h6>`, כל אחד תופס שורה שלמה |
| חיפוש, סימניות, הערות אישיות | לפי מספר שורה — פסקה שנשברה מזיזה את כולם |
| עיצוב | **אין CSS גלובלי, אין class-ים, אין JS.** כל עיצוב inline ומתחיל מחדש בכל שורה |
| תג לא מאוזן | אינו ממשיך לשורה הבאה (ובמצב קריאה רציף — דולף) |

הסיבה, מדיון המפתחים: הרינדור פר-שורה נובע מהקישורים ומהצורך לטעון ספרים עצומים
בלי עץ DOM אחד; מגבלות התגים הן של `flutter_widget_from_html` — ממיר HTML→Widgets,
לא דפדפן.

## הצינור

```
מקור → שורות בלוק → כותרות והיררכיה → הערות שוליים → ניקוי תגים/CSS
     → שם קובץ ומיקום → מטא-דאטה → קבצי לוואי → ולידציה
```

```bash
cd .claude/skills/otzaria-book-format/scripts

# 1. המרה (HTML / Markdown / טקסט גולמי)
python -X utf8 to_otzaria.py --in source.html --out "שם הספר.txt" \
       --title "שם הספר" --author "שם המחבר"

#    הערות inline → קובץ הערות נפרד + links (המנגנון של ספריא)
python -X utf8 to_otzaria.py --in source.html --out "ספר.txt" --title "ספר" \
       --split-footnotes --links-dir ../links

#    טקסט גולמי עם כותרות לפי תבנית
python -X utf8 to_otzaria.py --in raw.txt --format txt --out "ספר.txt" --title "ספר" \
       --heading-pattern "^סימן [א-ת]" --heading-level 2

# 2. סקירה — עץ כותרות, מספרי שורות, ספירת הערות
python -X utf8 inspect_book.py "ספר.txt" --toc --stats

# 3. ולידציה — 0 שגיאות זה התנאי למסירה
python -X utf8 validate_book.py "ספר.txt"

# 4. מטא-דאטה — בדיקת התנגשות שם, יצירת רשומה, מיזוג
python -X utf8 make_metadata.py --title "שם הספר" --check-name --repo D:/otzaria-library
python -X utf8 make_metadata.py --title "שם הספר" --author "מחבר" --era אחרונים \
       --pub-date 1902 --pub-place ירושלים \
       --merge D:/otzaria-library/all_metadata.json
#    תיאור → שורה ב־ForDB/sefaria_metadata_changes.csv בלבד (לא ב־JSON: heDesc שם נזרק בשקט)
python -X utf8 make_metadata.py --title "שם הספר" --author "מחבר" --category-path "…/…" \
       --he-short-desc "…" --he-desc "…" \
       --desc-csv D:/otzaria-library/ForDB/sefaria_metadata_changes.csv

# 5. קבצי לוואי (אם יש)
python -X utf8 validate_sidecars.py --links "…/ספר_links.json" --book "ספר.txt"
```

`to_otzaria.py` מיישם את חוזה ה-markup: מחיקת תגיות בלי טקסט קריא, בלוק→שורה,
מיפוי inline לתגיות שהקורא מכיר, unwrap ללא-מוכר (בלי לאבד טקסט), כיווץ רווח לבן,
אימות `href`/`src`, רשימות וטבלאות בשורה אחת, ונרמול רמות כותרת לרצף היררכי.

## כללי הפלט

1. **שורה 1 = `<h1>שם הספר</h1>`** לבדה. **שורה 2 = שם המחבר, או ריקה.**
2. **כל שורה מאוזנת בפני עצמה.** רשימה/טבלה/`<details>`/`<ruby>` — כל המבנה בשורה אחת.
3. **כותרת = שורה שלמה**, `<hN>` בתחילתה. טקסט שנשאר אחרי `</hN>` נבלע לתוך שם
   הכותרת בתוכן העניינים.
4. **היררכיית כותרות רציפה** — h2→h3→h4, בלי דילוגים. כותרת שרמתה גדולה ביותר מ-1
   מההורה נשארת בלי הורה והעץ נשבר. `to_otzaria.py` מנרמל אוטומטית; `validate_book.py`
   מסמן דילוג כשגיאה.
5. **גוף הספר הוא טקסט מקור** — מותר לקטע, לאחד ולסמן; אסור להוסיף מילים, לפתוח
   קיצורים או "לתקן" לשון. נוסח **כותרות** דווקא כן מותר לנרמל.
6. **הערות שוליים** — inline (`<sup class="footnote-marker">N</sup><i class="footnote">…</i>`
   צמודים) או קובץ `הערות על <ספר>.txt` + `_links.json`. מנגנון אחד לכל הספר.
7. **מלכודת ההיפוך RTL** — `<sup>`/`<sub>` לא-מספריים, `display:inline-block`
   ו-`<img>` הם "תיבות": **אחת בלבד בשורה**, אחרת הטקסט מוצג הפוך.
8. **שם הקובץ** = השם אחרי ניקוי (בלי ניקוד ובלי `\ / : * " ״ ? < > |`);
   ה-`<h1>` שומר את הצורה המלאה עם גרשיים. **הם לא חייבים להיות זהים.**
9. **המיקום בתיקיות הוא הקטגוריה** — אין שדה קטגוריה בקובץ.
10. בקבצי קישורים: `"Conection Type"` עם n אחת; יעד ספריא חייב `ref_2`; אין לקשר
    לשורת כותרת.

## מלכודות שחוזרות בכל המרה

| מלכודת | תיקון |
|---|---|
| פסקה שנשברה לשתי שורות | `\n` בתוך יחידת תוכן → רווח; שבירה ויזואלית ב-`<br>` |
| רשימה/טבלה על כמה שורות | כל המבנה בשורה אחת |
| תג פתוח בסוף שורה | לפרסר מחדש כל שורה ולסגור |
| הערות שפוצלו לפני החילוץ | לחלץ הערות **לפני** פיצול השורות |
| כותרת עם טקסט אחריה | לפצל לשתי שורות |
| דילוג רמות כותרת | לנרמל לרצף |
| שתי "תיבות" בשורה | לפצל לשתי שורות |
| `&lt;`/`&gt;` שפוענחו פעמיים | unescape פעם אחת, בשלב הנכון |
| שם קובץ עם גרשיים/ניקוד | `sanitize_filename`; הגרשיים נשארים ב-`<h1>` |
| שם שכבר תפוס | `make_metadata.py --check-name` לפני שמוסיפים |

## Scripts

| סקריפט | תפקיד |
|---|---|
| `to_otzaria.py` | המרה למבנה אוצריא (HTML/Markdown/טקסט), כולל פיצול הערות ונרמול כותרות |
| `validate_book.py` | ולידציה של קובץ ספר — exit 1 על שגיאה |
| `inspect_book.py` | עץ כותרות, מספרי שורות, סטטיסטיקה, חיפוש שורה |
| `make_metadata.py` | רשומת מטא-דאטה, בדיקת התנגשות שם, מיזוג ל-`all_metadata.json`, שורות ForDB, שורת תיאור ל־`sefaria_metadata_changes.csv` |
| `validate_sidecars.py` | ולידציה של `_links.json` / `_alt_toc.json` / `_headings.json` |

## References

- **`references/conversion.md`** — הצינור המלא וחוזה ה-markup: אילו תגיות נמחקות,
  אילו נשמרות ולאיזו תגית ממופות, כללי `href`/`src`, ומה מותר לשנות בגוף הספר.
- **`references/book-file.md`** — הפורמט עצמו: כותרות ותוכן עניינים, הערות שוליים,
  קישורי `book://`, התגים ותכונות ה-CSS הנתמכים והלא-נתמכים, מלכודת ההיפוך, מצב
  קריאה רציף, שמות שמורים.
- **`references/metadata.md`** — שדות `all_metadata.json`, קובצי `ForDB/`, היכן נכתב תיאור (`sefaria_metadata_changes.csv`), ניקוי
  שמות וגרשיים, קטגוריות ומיקום, דורות, רישיונות.
- **`references/sidecars.md`** — `_links.json` (רגיל, עוגן-מילה, טווח), `_alt_toc.json`,
  `_headings.json`: סכימה, סוגי קשר, כללי ספריא.

כל טענה ב-references מסומנת במקורה: «בקוד» (repo התוכנה), «לפי המדריך»
(`עריכת ספר באוצריא.txt` שבספרייה), או סקריפט/מסמך ב-repo הספרייה.

## גבולות מול סקילים אחרים

| משימה | הסקיל |
|---|---|
| התאמת שורות מפרש לספר בסיס ויצירת `_links.json` | `otzaria-commentary-linker` |
| QA לקישורים קיימים | `otzaria-commentary-linker-qa` |
| כתיבת `_links.json` מוכן ל-`seforim.db` חי | `otzaria-db-linker` |
| בדיקה שספר נקלט נכון ב-DB | `otzaria-db-ingestion-audit` |
| עיבוד ספר דיקטה (OCR, זיהוי כותרות, מוסכמות דיקטה) | `dicta-book-pipeline` |
| **המרה למבנה אוצריא + מטא-דאטה** | **הסקיל הזה** |

</div>
