Files
Chaim bfec8bdaa3
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 6s
Add dafna-decision-template skill — knowledge for template-based DOCX export
Documents the rules and decisions behind building DOCX files from דפנה's
decision template (טיוטת החלטה.dotx). The implementation lives in
mcp-server/src/legal_mcp/services/analysis_docx_exporter.py; this skill
captures the "why" so future improvements don't need to rediscover it.

Contents:
  SKILL.md                       5 critical rules, style mapping table,
                                 export flow, line classification,
                                 dash policy, placeholder handling,
                                 troubleshooting, future TODOs
  references/dotx-to-docx.md     why python-docx can't open .dotx +
                                 the conversion recipe
  references/rtl-runs.md         why <w:rtl/> is required on every run
                                 (otherwise Hebrew falls back to
                                 Times New Roman)
  references/style-mapping.md    XML dump of every template style,
                                 with the Title-via-theme gotcha
  references/line-classification.md  the 7 regex categories in
                                 _classify_line() with real examples

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 18:57:57 +00:00

156 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# מיפוי סגנונות — `טיוטת החלטה.dotx`
מבוסס על ניתוח `word/styles.xml` של הטמפלט. כל הגדרות מצוטטות מה-XML
המקורי.
## סגנונות בסיסיים (Word-idioms)
### `Normal` (styleId: `a1`)
ברירת המחדל לפסקאות רגילות. **כל שאר הסגנונות יורשים ממנו**
(`basedOn="a1"`).
```xml
<rPr>
<rFonts ascii="Times New Roman" hAnsi="Times New Roman" cs="David"/>
<sz val="26"/> <!-- 13pt -->
<szCs val="26"/>
</rPr>
<pPr>
<bidi/> <!-- RTL -->
<spacing before="120" after="120" line="360" lineRule="auto"/>
<ind left="-454"/> <!-- negative left indent -->
<jc val="both"/> <!-- justify -->
</pPr>
```
**מה זה אומר לך:**
- עברית תצא ב-David 13pt (דרך `cs`)
- לטינית תצא ב-Times New Roman 13pt (דרך `ascii`)
- יישור justify (דו-צדדי), RTL
- מרווח 1.5 שורות (`line=360` = 1.5 × 240)
### `Heading 1` (styleId: `10`, name: `heading 1`)
לכותרת ראשית (כמו "ניתוח משפטי וכתיבת עמדה בערר X").
```xml
<basedOn val="a1"/> <!-- יורש מ-Normal → cs="David" -->
<rPr><rFonts asciiTheme="majorHAnsi" .../><sz val="40"/></rPr> <!-- 20pt -->
```
Heading 1 **אינו** מציין cs fonts מפורשות, אבל יורש `cs="David"` מ-Normal.
זה מבדיל אותו מ-`Title`, שמפנה ל-theme ריק.
### `Heading 2` (styleId: `2`)
לכותרות מקטעים ותת-מקטעים.
```xml
<basedOn val="a1"/>
<pPr><keepNext/><spacing before="160"/><ind left="-567"/></pPr>
<rPr><b/><bCs/><u val="single"/></rPr> <!-- bold + underline -->
```
### `Title` (styleId: `a5`) — ⚠️ הימנע
```xml
<rPr><rFonts asciiTheme="majorHAnsi" cstheme="majorBidi" .../></rPr>
```
מפנה ל-theme. ב-`theme1.xml`: `majorFont.cs = ""` (ריק). → עברית נופלת
ל-`majorFont.latin = "Aptos Display"`. **השתמש ב-Heading 1 במקום.**
### `Subtitle` (styleId: `a7`) — ⚠️ אותה בעיה של Title
לא בשימוש.
## סגנונות תוכן
### `Quote` (styleId: `a9`)
```xml
<basedOn val="a1"/>
<pPr><spacing before="0" after="0" line="276"/>
<ind left="680" right="170"/></pPr> <!-- הזחה דו-צדדית -->
<rPr><b/><bCs/></rPr> <!-- bold -->
```
לציטוטי פסיקה. הזחה פנימה, bold.
### `List Paragraph` (styleId: `a0`)
```xml
<basedOn val="a1"/>
<pPr>
<numPr><numId val="1"/></numPr> <!-- auto-numbering -->
<spacing after="0"/>
<ind left="-125" hanging="357"/>
</pPr>
<rPr><rFonts ascii="David" hAnsi="David"/><sz val="28"/></rPr> <!-- 14pt -->
```
**numId=1 מפנה ל-abstractNumId=16**, שמוגדר כ-`decimal` עם `lvlText="%1."`.
כלומר Word יוסיף "1.", "2.", "3." אוטומטית לפני הטקסט.
**חשוב:** `List Paragraph` הוא היחיד בטמפלט עם numbering אוטומטי. אין
bullet style מוכן. לרשימות עם (א)(ב), **הסר את ה-numPr** ברמת הפסקה:
```python
from docx.oxml.ns import qn
def _strip_numpr(paragraph):
pPr = paragraph._p.get_or_add_pPr()
for numPr in pPr.findall(qn("w:numPr")):
pPr.remove(numPr)
```
## סגנונות נוספים בטמפלט (לא בשימוש כרגע)
| styleId | שם | מה |
|---------|----|----|
| `P00`, `P11`, `P22` | תבניות מותאמות אישית | ישן, נראה שלא בשימוש פעיל |
| `12`, `21`, `31` | פיסקת רשימה 1/2/3 | ללא numPr — שימוש ויזואלי בלבד |
| `-` | פיסקת רשימה - ללא מספור | מיועד ל-bullets ללא מספור |
| `14` | ציטוט1 | וריאציה ישנה של Quote |
| `af2` / `af4` | header / footer | לכותרות עליונות/תחתונות |
## theme (`word/theme/theme1.xml`)
```xml
<majorFont>
<latin typeface="Aptos Display"/>
<cs typeface=""/> <!-- ריק! -->
</majorFont>
<minorFont>
<latin typeface="Aptos"/>
<cs typeface=""/> <!-- ריק! -->
</minorFont>
```
**ה-cs ריק ב-theme** — זו הסיבה ש-`Title` (שמפנה ל-theme) לא עובד
לעברית. אל תסמוך על theme; השתמש ב-styles שמגדירים cs מפורש (Normal +
כל מה שיורש ממנו).
## numbering definitions
`word/numbering.xml` כולל ~22 abstractNum מוגדרים. הרלוונטי לנו:
```
numId=1 → abstractNumId=16 → numFmt=decimal, lvlText="%1."
```
יש גם hebrew1 (`numFmt=hebrew1` = א., ב., ג.) ב-`abstractNumId=0, 1`.
אף סגנון מוכן לא מפנה אליהם. אם תרצה בעתיד רשימה ממוספרת בעברית עם
Word auto-numbering — יש להזריק `numPr` ידנית עם `numId=29` (שמפנה
ל-abstractNumId=0).
## גדלים — רפרנס מהיר
| style | ascii | cs (עברית) |
|-------|-------|-----------|
| Normal | 13pt | 13pt |
| Heading 1 | 20pt | 18pt |
| Heading 2 | 13pt (ירושה) + bold + underline | אותו דבר |
| Title | 28pt (Aptos Display — לא עברית!) | — |
| List Paragraph | 14pt (David) | 14pt |
| Quote | 13pt (ירושה) + bold | 13pt |
## טיפ
כדי לבדוק את כל הסגנונות שבמסמך:
```python
from docx import Document
d = Document("skills/docx/decision_template.docx")
for s in sorted(d.styles, key=lambda x: x.name):
print(s.type, s.name, s.style_id)
```