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>
5.4 KiB
מיפוי סגנונות — טיוטת החלטה.dotx
מבוסס על ניתוח word/styles.xml של הטמפלט. כל הגדרות מצוטטות מה-XML
המקורי.
סגנונות בסיסיים (Word-idioms)
Normal (styleId: a1)
ברירת המחדל לפסקאות רגילות. כל שאר הסגנונות יורשים ממנו
(basedOn="a1").
<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").
<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)
לכותרות מקטעים ותת-מקטעים.
<basedOn val="a1"/>
<pPr><keepNext/><spacing before="160"/><ind left="-567"/></pPr>
<rPr><b/><bCs/><u val="single"/></rPr> <!-- bold + underline -->
Title (styleId: a5) — ⚠️ הימנע
<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)
<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)
<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 ברמת הפסקה:
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)
<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 |
טיפ
כדי לבדוק את כל הסגנונות שבמסמך:
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)