S08: Teilgebiet 01 Iterationen B5 (Trainings als Tabelle) und B6 (Bullet-Einzuege verkleinert) abgeschlossen. B5: Trainings-Bullet-Liste in cv.md durch Pandoc-Multiline-Tabelle ersetzt analog Ausbildung. B6: build/post-process-docx.py um dritte Modifikation erweitert die direkt die numbering.xml manipuliert weil Pandoc die Werte aus reference.docx ignoriert. Bullet-Einzuege auf E1 0,25/0,35 cm und E2 0,80/0,40 cm gesetzt. Word-Konvention dokumentiert: Einzug-links zeigt (left - hanging). teilgebiete/01-lebenslauf.md und agent-prompt.md fuer S09 fortgeschrieben.
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
S08
|
||||
Teilgebiet 01 Iteration B4 fuer DOCX umgesetzt. Heading 1/2/3 in destengsblue (build/build-reference-docx.py Funktion set_heading_colors mit explizitem color val=0B5394, themeColor accent1 entfernt). Heading-Bottom-Borders direkt am Stil verworfen, weil Word die Border bei hanging-Indent linksbuendig statt zentriert rendert und der right-Indent sowohl Text als auch Border begrenzt. 21 Markdown-HRs aus cv.md entfernt - Quelle der wahrgenommenen Doppellinien war Pandocs DOCX-Konvertierung von --- Zeilen zu VML-rect mit o:hr=t (Embossed-Look). Tabellen-Strich-Zeilen blieben unangetastet. Zwischenfall: NTFS-Mount-Stale-Read der cv.md (20043 statt 20201 Bytes) haette fast die Live-Datei truncated, sofortige Wiederherstellung aus git show HEAD und HR-Removal erneut mit git-Version als Input. H2-Trennlinien via Post-Processing eingefuehrt (build/post-process-docx.py um Logik erweitert): nach jedem H2 wird ein leerer Trenn-Absatz mit linksbuendiger Bottom-Border eingefuegt, schwarz (000000), 8,6 cm Linienlaenge (right-Indent 4196 dxa), 1,25 pt Dicke (sz=10). Sandbox-Verifikation 7 H2 zu 7 Trenner. Visuelle Bestaetigung durch Thomas. teilgebiete/01-lebenslauf.md um Iteration-B4-Block ergaenzt (B4.1 Farben, B4.2 Heading-Border-Sackgasse, B4.3 HR-Removal inkl. Zwischenfall, B4.4 H2-Trennlinien) und Naechste-Schritte-Liste auf C/D verkuerzt.
|
||||
Teilgebiet 01 Iterationen B5 (Trainings als Tabelle) und B6 (Bullet-Einzuege verkleinert) abgeschlossen. B5: Trainings-Bullet-Liste in cv.md durch Pandoc-Multiline-Tabelle ersetzt analog Ausbildung. B6: build/post-process-docx.py um dritte Modifikation erweitert die direkt die numbering.xml manipuliert weil Pandoc die Werte aus reference.docx ignoriert. Bullet-Einzuege auf E1 0,25/0,35 cm und E2 0,80/0,40 cm gesetzt. Word-Konvention dokumentiert: Einzug-links zeigt (left - hanging). teilgebiete/01-lebenslauf.md und agent-prompt.md fuer S09 fortgeschrieben.
|
||||
|
||||
@@ -85,34 +85,34 @@ Setze zwischen sinnvollen Zwischenständen Checkpoints (z.B. nach "Marketing.md
|
||||
|
||||
## Aktueller Stand / Nächste Aufgabe
|
||||
|
||||
**Letzte Session:** S07 (2026-04-26)
|
||||
**Letzte Session:** S08 (2026-04-26)
|
||||
|
||||
**Was wurde gemacht:**
|
||||
- **PDF-Build-Fehler endgültig behoben.** Pandoc-3.x-`\def\LTcaptype{none}`-Bug ([Issue #11201](https://github.com/jgm/pandoc/issues/11201)). Fix: `\newcounter{none}` im Template. **Iteration A inhaltlich abgeschlossen.**
|
||||
- **Build-UX-Fix:** `build/build.ps1` mit `Start-Sleep -Seconds 3` pro fehlschlagendem Schritt.
|
||||
- **Iteration B durchgezogen — `reference.docx` programmatisch via `build/build-reference-docx.py`** (Python-Stdlib, holt Pandoc-Default-Reference, entpackt ZIP, modifiziert XML mit ElementTree, repackt). Inhalt:
|
||||
- **B1 — Schriften, Tabellen:** Theme major+minor auf Calibri (Pandoc-3.x-Default war Aptos Display/Aptos), Stil `Table` mit `tblBorders=none` auf allen Sides.
|
||||
- **B1.5 — Schriftgrößen analog PDF:** DocDefault Body 11 pt, Heading 1/2/3 auf 15/13/12 pt.
|
||||
- **B2 — Header, Footer, Page-Setup:** Header (Name links, Lebenslauf rechts) ab Seite 2, leerer Header für Seite 1 via `titlePg`. Footer (Seite n / m) auf allen Seiten inkl. Seite 1 (zwei `footerReference`-Einträge, default + first auf gleicher rId). Page-Setup A4 mit 2.2/2.5 cm Rändern, Tab-Stop 9072 dxa.
|
||||
- **B3 — Schusterjungen/Witwen-Schutz für Headings:** DocDefault `widowControl`, Heading 1/2/3 und `FirstParagraph` (für Kenntnisse-Subsection-Labels) mit `keepNext` + `keepLines`.
|
||||
- **Iteration B3.5 — 3-3-Regel für Listen-Bullets** über neues Post-Processing-Skript `build/post-process-docx.py`. Erster Versuch (Compact-Stil mit keepNext) hat Listen komplett unteilbar gemacht — Folge: Job-Stationen begannen jedes Mal auf neuer Seite, ungenutzte Seitenenden. Auf Wunsch von Thomas Per-Bullet-Logik: bei Listen mit ≥ 6 Bullets bekommen die ersten 2 und die N-3-/N-2-Bullets `keepNext`, dazwischen darf getrennt werden (= mind. 3 Bullets vor und nach jedem Umbruch). Bei < 6 Bullets bleibt alles zusammen. `build.ps1` ruft das Skript automatisch nach DOCX-Build als Schritt [3/3] auf. Sandbox-Verifikation: 26 Listen, 184 Bullets, 93 keepNext-Markierungen, Pattern z.B. `KK......KK.` für 11-Bullet-Liste. Auf Thomas' System visuell bestätigt: Listen werden sauber an guten Stellen getrennt, keine ungenutzten Seitenenden mehr.
|
||||
**Was wurde gemacht:** Iteration B fuer das DOCX abgeschlossen, plus zwei zusätzliche Anpassungen:
|
||||
- **B4.1 — Heading-Farben in destengsblue** (`build/build-reference-docx.py` Funktion `set_heading_colors`, color val=`0B5394`, themeColor accent1 entfernt). H1, H2, H3 alle in destengsblue.
|
||||
- **B4.2 — Heading-Trennlinien direkt am Stil verworfen.** Bottom-Border + Indent-Trick (`hanging`) erzeugte in Word linksbündige statt zentrierte Linien. Wichtige Lehre: Words `right`-Indent begrenzt sowohl Text als auch Border — eine Border *schmaler als der Heading-Text* ist über den Stil selbst nicht abbildbar.
|
||||
- **B4.3 — Markdown-HRs aus cv.md entfernt** (21 alleinstehende `---`-Zeilen). Quelle der wahrgenommenen „Doppellinien": Pandoc-DOCX-Konvertierung von `---` zu VML-`<v:rect ... o:hr="t"/>` (Embossed-Look). Tabellen-Strich-Zeilen blieben unangetastet. **Vorfall:** Sandbox-NTFS-Stale-Read der cv.md (20043 statt 20201 Bytes) hätte fast die Live-Datei truncated, sofortige Wiederherstellung aus `git show HEAD` + HR-Removal erneut mit der git-Version als Input.
|
||||
- **B4.4 — H2-Trennlinien via Post-Processing** (`build/post-process-docx.py` um Funktion erweitert): nach jedem H2-Absatz ein leerer Trenn-Absatz mit linksbündiger Bottom-Border, schwarz (`000000`), 8,6 cm Linienlänge (right-Indent 4196 dxa), 1,25 pt dick (sz=10).
|
||||
- **B5 — Trainings als Tabelle** (cv.md): Trainings-Bullet-Liste durch Pandoc-Multiline-Tabelle ersetzt (analog Ausbildung), Inhalte normal nicht fett.
|
||||
- **B6 — Bullet-Einzüge verkleinert** (`build/post-process-docx.py` modifiziert `numbering.xml` direkt; Pandoc IGNORIERT die `numbering.xml`-Werte der reference.docx, daher MUSS das im Post-Processing passieren). E1: Einzug 0,25 cm + Sondereinzug 0,35 cm (left=340/hanging=198 dxa); E2: Einzug 0,80 cm + Sondereinzug 0,40 cm (left=681/hanging=227 dxa). Word-Konvention: „Einzug links" = `(left - hanging)` = Bullet-Position; „Sondereinzug Hängend" = `hanging`.
|
||||
|
||||
**Nächste Aufgabe:** Teilgebiet 01 — verbleibende Iterationen:
|
||||
1. **B4 — Heading-Farben auf DesTEngS-Blau und/oder Trennlinien analog PDF.** Bringt das DOCX optisch näher ans PDF (für Direktverwendung; bei Consulting-Agenturen, die das Layout ohnehin überschreiben, eher Kosmetik). Erstes Aufgabe der nächsten Session.
|
||||
2. **C — Foto-Einbindung** in cv.md mit Pandoc-Image-Syntax und Template-Anpassung für Position/Größe (z.B. oben rechts neben Name, ca. 3 cm).
|
||||
3. **D — Hyphenation-Feintuning für PDF** — kurze Wortteile am Zeilenanfang mit höherer Penalty oder `\hyphenation`-Ausnahmen reduzieren.
|
||||
1. **C — Foto-Einbindung** in cv.md mit Pandoc-Image-Syntax und Template-Anpassung für Position/Größe (z.B. oben rechts neben Name, ca. 3 cm).
|
||||
2. **D — Hyphenation-Feintuning für PDF** — kurze Wortteile am Zeilenanfang mit höherer Penalty oder `\hyphenation`-Ausnahmen reduzieren.
|
||||
|
||||
Nach D): Status von Teilgebiet 01 in `zentral-index.md` auf „abgeschlossen" setzen (R2-OK von Thomas). Anschließend nächstes Teilgebiet nach Priorität (laut Index Teilgebiet 02 „Zeugnis von ASMPT").
|
||||
|
||||
**Offene Punkte (unverändert seit S04):** Zuschnitt und Festpreise der KI-Produkte (marketing.md Abschnitt 2), KMU-Direkthonorarsatz festlegen (marketing.md Abschnitt 2), Vergütungsmodell-Wahl bei erstem konkreten Fall (Notiz in marketing.md Abschnitt 2).
|
||||
|
||||
**Hinweise für die nächste Session:**
|
||||
- **Sandbox-Pandoc ist 2.9.x, Thomas' System läuft Pandoc 3.x.** Output-Unterschiede zwischen den Versionen können Build-Probleme verursachen. Sandbox-Pandoc emittiert weder die calc-basierten Spaltenbreiten (`p{... * \real{...}}`) noch `\def\LTcaptype{none}` — beides Pandoc-3.x-Eigenheiten. Sandbox-Verifikation des kompletten Pipeline-Laufs mit `pandoc cv.md → PDF` deckt diese Bugs nicht ab. Bei Fehlern, die nur auf Thomas' System auftreten, **synthetisch das Pandoc-3.x-Output-Fragment in einer Mini-Tex-Datei nachbauen** und damit gegen das Template kompilieren.
|
||||
- **Sandbox-Reads über den NTFS-Mount können stale/inkonsistent sein.** Wenn Sandbox-Reads Schäden zeigen, die unplausibel sind, **nicht panisch reagieren** — erst Thomas via PowerShell verifizieren lassen, bevor Reparaturmaßnahmen ergriffen werden.
|
||||
- **Sandbox-Schreibvorgänge sind zuverlässig** (Write-Tool und Heredoc via Bash). Bei längeren Skript-Dateien (>100 Zeilen) bleibt Heredoc trotzdem die robustere Wahl.
|
||||
- **Word-Indent-Konvention (S08-Lehre):** Word zeigt im Absatz-Dialog „Einzug links" als `(left - hanging)`, NICHT als `left`. „Sondereinzug Hängend" ist `hanging`. Daher gilt: `left = (gewünschter Einzug + gewünschter Hanging-Indent)` in dxa.
|
||||
- **Word-Border-Limit (S08-Lehre):** Words paragraph-Border folgt den Indents; eine Border *schmaler als der Heading-Text* geht NICHT über `<w:ind right="...">` auf dem Heading-Stil, weil der right-Indent auch den Text begrenzt. Lösung wenn nötig: separater Trenn-Absatz nach dem Heading via Post-Processing.
|
||||
- **Pandoc IGNORIERT die `numbering.xml` der reference.docx (S08-Lehre).** Wer Bullet-Einzüge ändern will, muss das im Post-Processing tun, nicht in `build-reference-docx.py`.
|
||||
- **Pandoc generiert für Markdown-`---` im DOCX VML-Horizontal-Lines (`<v:rect o:hr="t"/>`)** — sehen aus wie Doppellinien (Embossed). Im PDF rendert Pandoc dieselbe Quelle als saubere zentrierte Halblinie. Wenn man saubere DOCX-Trennung braucht: HRs in cv.md entfernen oder Pandoc-Lua-Filter für DOCX-Build.
|
||||
- **Sandbox-NTFS-Stale-Reads sind häufiger und kritischer als gedacht (S08-Lehre).** Sandbox kann auch git-Status, Datei-Existenz und Datei-Inhalte verzerrt sehen, ohne dass die echte Datei betroffen ist. **Bei jedem Sandbox-Schreiben auf eine grössere NTFS-Mount-Datei: ERST git-Version verifizieren und als Input verwenden, NICHT blind dem Sandbox-Read trauen.** Bei seltsamen git-status-Outputs aus der Sandbox: erst Thomas auf PowerShell `git status` ausführen lassen.
|
||||
- **Edit-Tool truncated regelmäßig** (mehrfach in S07 und S08 erlebt — Skript-Dateien, `.checkpoint-pending.txt`, `agent-prompt.md`, `teilgebiete/01-lebenslauf.md`). Faustregel: Bei jedem Edit auf NTFS-Mount-Datei nach `Edit` mit `wc -c` und `tail -c 80` verifizieren. Bei längeren Edits oder wenn das Risiko hoch ist: lieber per Heredoc/Python aus der git-Version neu schreiben.
|
||||
- **Sandbox-Pandoc ist 2.9.x, Thomas' System läuft Pandoc 3.x.** Output-Unterschiede zwischen den Versionen können Build-Probleme verursachen. Sandbox-Pandoc emittiert weder die calc-basierten Spaltenbreiten (`p{... * \real{...}}`) noch `\def\LTcaptype{none}` — beides Pandoc-3.x-Eigenheiten. Bei Fehlern, die nur auf Thomas' System auftreten, **synthetisch das Pandoc-3.x-Output-Fragment in einer Mini-Tex-Datei nachbauen** und damit gegen das Template kompilieren.
|
||||
- **Sandbox kann nichts an `.git/` schreiben** (NTFS-Permission-Issue): Lock-Files, korrupte Index — alles muss von PowerShell aus repariert werden.
|
||||
- **`checkpoint.ps1` ist robust** gegen Anführungszeichen, Pipes, Whitespace-Anomalien und Index-Lock-Reste. `.checkpoint-pending.txt` darf ganz normal Sonderzeichen enthalten.
|
||||
- **`build.ps1` pausiert bei Fehler 3 Sekunden pro fehlgeschlagenem Schritt.** Nicht überrascht sein, wenn ein fehlerhafter Lauf entsprechend länger braucht.
|
||||
- **`build/build-reference-docx.py` muss VOR `build.ps1` manuell aufgerufen werden, wenn `templates/reference.docx` neu gebaut werden soll.** Das Skript ist nicht in `build.ps1` integriert (würde jeden Build verlangsamen und Pandoc-Default-Reference jedes Mal neu ziehen). Wenn jemand die `reference.docx` von Hand in Word editiert, gehen die Änderungen beim nächsten Skript-Lauf verloren — Stile gehören also ins Skript, nicht in Word.
|
||||
- **Edit-Tool kann Dateien beim Schreiben über den NTFS-Mount truncatieren** (mehrfach in S07 erlebt am Python-Skript und an `build.ps1`). `mcp__workspace__bash` mit `cat <<'EOF' > path` ist die zuverlässige Alternative für längere Dateien (>~150 Zeilen). Nach jedem Edit auf NTFS-Mount-Datei: `wc -l` und `tail -c 60` zur Verifikation.
|
||||
- **DOCX-Pipeline ist jetzt 3-stufig:** (1) `build/build-reference-docx.py` baut die `reference.docx` (manuell aufrufen, wenn Stile geändert werden sollen), (2) `build/build.ps1` baut PDF und DOCX, (3) `build/post-process-docx.py` wird automatisch aus `build.ps1` aufgerufen für die 3-3-Listen-Bullet-Regel. Wer das Bullet-Verhalten ändern will, fasst das Post-Processing-Skript an, nicht die reference.docx.
|
||||
- **DOCX-Pipeline ist jetzt 3-stufig mit drei Post-Processing-Modifikationen:** (1) `build/build-reference-docx.py` baut die `reference.docx` (manuell aufrufen, wenn Stile geändert werden sollen), (2) `build/build.ps1` baut PDF und DOCX, (3) `build/post-process-docx.py` wird automatisch aus `build.ps1` aufgerufen und macht: 3-3-Listen-Bullet-Regel, H2-Trennlinien-Einfügung, Bullet-Einzug-Anpassung in `numbering.xml`. Wer das Bullet-Verhalten oder Trennlinien ändern will, fasst das Post-Processing-Skript an.
|
||||
|
||||
Binary file not shown.
@@ -4,32 +4,32 @@ post-process-docx.py
|
||||
====================
|
||||
|
||||
Wird auf das von Pandoc erzeugte DOCX angewendet, NACH `build.ps1`. Macht
|
||||
zwei XML-Modifikationen, die ein Stil oder die `reference.docx` nicht
|
||||
drei XML-Modifikationen, die ein Stil oder die `reference.docx` nicht
|
||||
abbilden koennen:
|
||||
|
||||
1. 3-3-Regel fuer Listen-Bullets (B3.5):
|
||||
- Eine Liste ist eine Sequenz aufeinanderfolgender Absaetze mit
|
||||
<w:numPr>-Eigenschaft im Body (nicht innerhalb von Tabellen-Zellen).
|
||||
- Bei einer Liste mit weniger als 6 Bullets: alle Bullets bekommen
|
||||
<w:keepNext/> (Liste bleibt unteilbar - bei <6 ist die 3-3-Regel
|
||||
sowieso nur durch Zusammenhalten aller erfuellbar).
|
||||
<w:keepNext/>.
|
||||
- Bei einer Liste mit 6 oder mehr Bullets: die ersten 2 und die
|
||||
drittletzten und vorletzten Bullets bekommen <w:keepNext/>.
|
||||
Damit gilt: nach Bullet 1 darf nicht getrennt werden (1+2+3 zusammen),
|
||||
und nach Bullet N-3 darf nicht getrennt werden (N-2+N-1+N zusammen).
|
||||
Trennen ist erlaubt zwischen den Bullets in der Mitte.
|
||||
Bullets in Tabellen-Zellen werden uebersprungen.
|
||||
|
||||
2. H2-Trennlinie (S08):
|
||||
- Nach jedem H2-Absatz wird ein leerer Trenn-Absatz eingefuegt.
|
||||
- Trenn-Absatz: linksbuendige Bottom-Border, schwarz (000000),
|
||||
1,25 pt (sz=10), 8,6 cm Linienlaenge (right-Indent 4196 dxa bei
|
||||
9072 dxa Textbreite).
|
||||
- Run-Properties auf sz=2 (1 pt), damit der Absatz selbst minimale
|
||||
Hoehe hat.
|
||||
- Ein schmaler-als-Heading-Border ist ueber den Heading-Stil selbst
|
||||
nicht moeglich, weil Words right-Indent sowohl Text als auch
|
||||
Border begrenzt. Deshalb separater Trenn-Absatz.
|
||||
1,25 pt (sz=10), 8,6 cm Linienlaenge.
|
||||
|
||||
3. Bullet-Einzuege (S08):
|
||||
- Pandoc erzeugt fuer alle Bullet-Listen abstractNum-Eintraege mit
|
||||
festen Defaults (E1 left/hanging=480 dxa, E2 left=1200/hanging=480 dxa).
|
||||
Pandoc IGNORIERT die numbering.xml-Werte der reference.docx.
|
||||
- Im Post-Processing wird numbering.xml so modifiziert, dass alle
|
||||
abstractNum-Eintraege die kompakteren Wunschwerte bekommen.
|
||||
- Word-Konvention: "Einzug links" (im Absatz-Dialog) zeigt
|
||||
(left - hanging) = Bullet-Position; "Sondereinzug Haengend" = hanging.
|
||||
Daher rechnen wir: left = (gewuenschter Einzug + gewuenschter Hanging) in dxa.
|
||||
|
||||
Voraussetzungen: nur Python-Stdlib.
|
||||
"""
|
||||
@@ -47,11 +47,6 @@ DOCX_FILE = BASE_DIR / "output" / "Lebenslauf_Dr-Ing_Thomas_Langer.docx"
|
||||
|
||||
W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
|
||||
|
||||
# H2-Trenn-Absatz: linksbuendige Bottom-Border, schwarz, 8,6 cm lang, 1,25 pt dick.
|
||||
# Textbreite = PAGE_W - MARGIN_LEFT - MARGIN_RIGHT = 11906 - 1417 - 1417 = 9072 dxa
|
||||
# 8,6 cm = 8,6 * 567 dxa/cm = 4876 dxa
|
||||
# right-Indent = 9072 - 4876 = 4196 dxa
|
||||
# Border sz ist in 1/8 pt: 1,25 pt * 8 = 10
|
||||
H2_SEP_XML = (
|
||||
'<w:p>'
|
||||
'<w:pPr>'
|
||||
@@ -67,6 +62,23 @@ H2_SEP_XML = (
|
||||
|
||||
H2_STYLE_RE = re.compile(r'<w:pStyle\s+w:val="Heading2"\s*/?>')
|
||||
|
||||
# Bullet-Einzuege (1 cm = 567 dxa)
|
||||
# Word zeigt "Einzug links" = (left - hanging), "Sondereinzug Haengend" = hanging.
|
||||
# E1: Einzug 0,25 cm + Sondereinzug 0,35 cm -> hanging=198, left=142+198=340
|
||||
# E2: Einzug 0,80 cm + Sondereinzug 0,40 cm -> hanging=227, left=454+227=681
|
||||
# E3+: proportional zur E2 (jeweils +0,55 cm fuer Einzug), hanging analog E2
|
||||
BULLET_INDENTS = {
|
||||
0: {"left": 340, "hanging": 198},
|
||||
1: {"left": 681, "hanging": 227},
|
||||
2: {"left": 993, "hanging": 227},
|
||||
3: {"left": 1305, "hanging": 227},
|
||||
4: {"left": 1617, "hanging": 227},
|
||||
5: {"left": 1929, "hanging": 227},
|
||||
6: {"left": 2241, "hanging": 227},
|
||||
7: {"left": 2553, "hanging": 227},
|
||||
8: {"left": 2865, "hanging": 227},
|
||||
}
|
||||
|
||||
def log(msg):
|
||||
print(f"[post-process-docx] {msg}", flush=True)
|
||||
|
||||
@@ -80,8 +92,6 @@ def has_keep_next(p_xml):
|
||||
return "<w:keepNext" in p_xml
|
||||
|
||||
def add_keep_next(p_xml):
|
||||
"""Fuegt <w:keepNext/> in das pPr-Element ein. Falls kein pPr existiert,
|
||||
wird es angelegt. Idempotent."""
|
||||
if has_keep_next(p_xml):
|
||||
return p_xml
|
||||
if "<w:pPr>" in p_xml:
|
||||
@@ -98,8 +108,6 @@ TBL_OPEN = "<w:tbl>"
|
||||
TBL_CLOSE = "</w:tbl>"
|
||||
|
||||
def process_document_xml(xml):
|
||||
"""Tokenisiert den Body, wendet 3-3-Regel auf Bullet-Listen an und
|
||||
fuegt nach jedem H2-Heading einen Trenn-Absatz ein."""
|
||||
out = []
|
||||
bullet_run = []
|
||||
table_depth = 0
|
||||
@@ -165,6 +173,42 @@ def process_document_xml(xml):
|
||||
flush_run()
|
||||
return "".join(out), stats
|
||||
|
||||
def process_numbering_xml(xml):
|
||||
"""In allen abstractNum-Eintraegen die Bullet-Einzuege ersetzen."""
|
||||
import xml.etree.ElementTree as ET
|
||||
W = "{%s}" % W_NS
|
||||
ET.register_namespace("w", W_NS)
|
||||
root = ET.fromstring(xml)
|
||||
|
||||
stats = {"abstractNums": 0, "lvls_modified": 0}
|
||||
|
||||
for absnum in root.findall(W+"abstractNum"):
|
||||
stats["abstractNums"] += 1
|
||||
for lvl in absnum.findall(W+"lvl"):
|
||||
ilvl_str = lvl.get(W+"ilvl")
|
||||
try:
|
||||
ilvl = int(ilvl_str)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
target = BULLET_INDENTS.get(ilvl)
|
||||
if target is None:
|
||||
continue
|
||||
pPr = lvl.find(W+"pPr")
|
||||
if pPr is None:
|
||||
pPr = ET.SubElement(lvl, W+"pPr")
|
||||
ind = pPr.find(W+"ind")
|
||||
if ind is None:
|
||||
ind = ET.SubElement(pPr, W+"ind")
|
||||
ind.set(W+"left", str(target["left"]))
|
||||
ind.set(W+"hanging", str(target["hanging"]))
|
||||
if W+"firstLine" in ind.attrib:
|
||||
del ind.attrib[W+"firstLine"]
|
||||
stats["lvls_modified"] += 1
|
||||
|
||||
XML_DECL = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'
|
||||
new_xml = XML_DECL + ET.tostring(root, encoding="unicode")
|
||||
return new_xml, stats
|
||||
|
||||
def main():
|
||||
if not DOCX_FILE.exists():
|
||||
sys.stderr.write(f"FEHLER: {DOCX_FILE} existiert nicht. "
|
||||
@@ -176,11 +220,16 @@ def main():
|
||||
members = {name: z.read(name) for name in z.namelist()}
|
||||
|
||||
doc_xml = members["word/document.xml"].decode("utf-8")
|
||||
new_xml, stats = process_document_xml(doc_xml)
|
||||
new_doc_xml, doc_stats = process_document_xml(doc_xml)
|
||||
members["word/document.xml"] = new_doc_xml.encode("utf-8")
|
||||
|
||||
if new_xml == doc_xml:
|
||||
log(" keine Aenderung")
|
||||
members["word/document.xml"] = new_xml.encode("utf-8")
|
||||
num_stats = {"abstractNums": 0, "lvls_modified": 0}
|
||||
if "word/numbering.xml" in members:
|
||||
num_xml = members["word/numbering.xml"].decode("utf-8")
|
||||
new_num_xml, num_stats = process_numbering_xml(num_xml)
|
||||
members["word/numbering.xml"] = new_num_xml.encode("utf-8")
|
||||
else:
|
||||
log(" Hinweis: word/numbering.xml nicht im DOCX (keine Listen?)")
|
||||
|
||||
with zipfile.ZipFile(DOCX_FILE, "w", zipfile.ZIP_DEFLATED) as z:
|
||||
order = sorted(members.keys(),
|
||||
@@ -188,12 +237,14 @@ def main():
|
||||
for name in order:
|
||||
z.writestr(name, members[name])
|
||||
|
||||
log(f" Listen gefunden: {stats['lists']}")
|
||||
log(f" Bullets in Listen: {stats['bullets_in_lists']}")
|
||||
log(f" keepNext gesetzt: {stats['bullets_keepnext']}")
|
||||
log(f" Bullets in Tabellen uebersprungen: {stats['skipped_in_tables']}")
|
||||
log(f" H2-Headings gefunden: {stats['h2_headings']}")
|
||||
log(f" H2-Trenn-Absaetze eingefuegt: {stats['separators_added']}")
|
||||
log(f" Listen gefunden: {doc_stats['lists']}")
|
||||
log(f" Bullets in Listen: {doc_stats['bullets_in_lists']}")
|
||||
log(f" keepNext gesetzt: {doc_stats['bullets_keepnext']}")
|
||||
log(f" Bullets in Tabellen uebersprungen: {doc_stats['skipped_in_tables']}")
|
||||
log(f" H2-Headings gefunden: {doc_stats['h2_headings']}")
|
||||
log(f" H2-Trenn-Absaetze eingefuegt: {doc_stats['separators_added']}")
|
||||
log(f" numbering.xml abstractNum-Eintraege: {num_stats['abstractNums']}")
|
||||
log(f" numbering.xml lvls modifiziert: {num_stats['lvls_modified']}")
|
||||
log("Fertig.")
|
||||
return 0
|
||||
|
||||
|
||||
Binary file not shown.
@@ -169,16 +169,16 @@ endobj
|
||||
|
||||
endobj
|
||||
78 0 obj
|
||||
<< /S /GoTo /D (none.1) >>
|
||||
<< /S /GoTo /D (none.2) >>
|
||||
endobj
|
||||
80 0 obj
|
||||
81 0 obj
|
||||
(\376\377\000K\000e\000n\000n\000t\000n\000i\000s\000s\000e)
|
||||
|
||||
endobj
|
||||
81 0 obj
|
||||
<< /S /GoTo /D [ 82 0 R /Fit ] >>
|
||||
82 0 obj
|
||||
<< /S /GoTo /D [ 83 0 R /Fit ] >>
|
||||
endobj
|
||||
85 0 obj
|
||||
86 0 obj
|
||||
<< /Filter /FlateDecode /Length 3132 >>
|
||||
stream
|
||||
x<EFBFBD><EFBFBD>[͎#<23>
|
||||
@@ -195,31 +195,31 @@ r
|
||||
P<EFBFBD>2<EFBFBD>Eu<07><EFBFBD>=5٩yv<79><76><EFBFBD><EFBFBD>7U<37><55>ucȓ<63>}<7D>v<EFBFBD>ҙf<D299>E<EFBFBD>f<EFBFBD><66>8<EFBFBD>3<EFBFBD><33>$<24><>2<EFBFBD><32>Z<EFBFBD><5A><EFBFBD>Y<EFBFBD><59><EFBFBD><EFBFBD>4b<34>)<29><><EFBFBD>~<7E>*@<40>I:<0E>C<EFBFBD>i<EFBFBD>T<EFBFBD><54>]H<>f<EFBFBD>q<><71><EFBFBD><EFBFBD>W<EFBFBD><57>zE 8ab4<62>7<EFBFBD><37><EFBFBD>k<EFBFBD><6B><EFBFBD>_<EFBFBD><0C>B<EFBFBD>%L^m<><6D>nJU(<28><>:2<><32>UI<55>d<EFBFBD>)Z
|
||||
0w<>D,<2C><>2<EFBFBD><32>i<EFBFBD>l[<5B><>#<23><>4㖊<34>sx<73>K.<2E>q# | ||||