contentpanel - template formatting improved

This commit is contained in:
2026-09-06 05:17:37 +02:00
parent 2d88c64e48
commit 055b6d10c4
6 changed files with 90 additions and 31 deletions
@@ -139,7 +139,7 @@ class PipelineTests(unittest.TestCase):
self.assertEqual(xml.count(DATE_TOKEN), 1)
self.assertEqual(xml.count(BODY_TOKEN), 1)
def test_original_line_breaks_use_word_elements(self):
def test_original_line_breaks_use_word_elements(self):
with tempfile.TemporaryDirectory() as temp:
target = Path(temp) / 'lines.docx'
fill_template(TEMPLATE, target, 'Gruß', _date_label('2026-09-02'), ['Von Herzen\nEure Gastgeber'])
@@ -148,10 +148,34 @@ class PipelineTests(unittest.TestCase):
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
paragraph = next(p for p in document.findall('.//w:p', ns) if p.find('.//w:br', ns) is not None)
self.assertEqual(len(paragraph.findall('.//w:br', ns)), 1)
self.assertEqual([t.text for t in paragraph.findall('.//w:t', ns)], ['Von Herzen', 'Eure Gastgeber'])
self.assertEqual(paragraph.find('w:pPr/w:jc', ns).get('{' + ns['w'] + '}val'), 'left')
def test_template_fill_creates_multiple_paragraphs(self):
self.assertEqual([t.text for t in paragraph.findall('.//w:t', ns)], ['Von Herzen', 'Eure Gastgeber'])
self.assertEqual(paragraph.find('w:pPr/w:jc', ns).get('{' + ns['w'] + '}val'), 'left')
def test_bullet_lines_become_hanging_list_paragraphs(self):
with tempfile.TemporaryDirectory() as temp:
target = Path(temp) / 'bullets.docx'
fill_template(TEMPLATE, target, 'Einladung', _date_label('2026-09-04'), [
'Einleitung.',
'SEPTEMBER\n•05.09.2026: Erster Stichpunkt.\n• Zweiter Stichpunkt.\nOKTOBER\n• Dritter Stichpunkt.',
'Abschluss.',
])
with zipfile.ZipFile(target) as archive:
document = ET.fromstring(archive.read('word/document.xml'))
ns = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
q = lambda name: '{' + ns['w'] + '}' + name
bullets = [paragraph for paragraph in document.findall('.//w:p', ns)
if ''.join(paragraph.itertext()).startswith('•')]
self.assertEqual(len(bullets), 3)
self.assertTrue({'SEPTEMBER', 'OKTOBER'} <= {''.join(p.itertext()) for p in document.findall('.//w:p', ns)})
for paragraph in bullets:
self.assertIsNotNone(paragraph.find('w:r/w:tab', ns))
self.assertEqual(paragraph.find('w:pPr/w:tabs/w:tab', ns).get(q('pos')), '480')
indent = paragraph.find('w:pPr/w:ind', ns)
self.assertEqual((indent.get(q('left')), indent.get(q('hanging'))), ('480', '360'))
self.assertEqual(bullets[0].find('w:pPr/w:spacing', ns).get(q('after')), '0')
self.assertIsNone(bullets[1].find('w:pPr/w:spacing', ns))
def test_template_fill_creates_multiple_paragraphs(self):
with tempfile.TemporaryDirectory() as temp:
target = Path(temp) / "filled.docx"
paragraphs = [f"Absatz {i}: Inhalt für den Aushang." for i in range(1, 8)]
@@ -32,11 +32,13 @@ class RenderingTests(unittest.TestCase):
cls.document = cls.output / "verified.docx"
with zipfile.ZipFile(TEMPLATE) as archive:
(cls.output / "original-logo.png").write_bytes(archive.read("word/media/image1.png"))
paragraphs = [
("Dies ist ein langer Testabsatz zur Prüfung von Schriftgröße, Zeilenumbruch und Seitenaufteilung. " * 12).strip()
for _ in range(3)
] + ["Erste Gedichtzeile\nZweite Gedichtzeile\n\nVon Herzen\nEure Gastgeber",
"Abschlussmarker: Dieser letzte Absatz muss vollständig auf der letzten Seite erscheinen."]
paragraphs = [
("Dies ist ein langer Testabsatz zur Prüfung von Schriftgröße, Zeilenumbruch und Seitenaufteilung. " * 12).strip()
for _ in range(3)
] + ["• Ein längerer Stichpunkt, dessen zweite Zeile unter dem Text und nicht unter dem Aufzählungszeichen beginnt.\n"
"• Ein zweiter Stichpunkt bestätigt den gleichmäßigen Abstand der Liste.",
"Erste Gedichtzeile\nZweite Gedichtzeile\n\nVon Herzen\nEure Gastgeber",
"Abschlussmarker: Dieser letzte Absatz muss vollständig auf der letzten Seite erscheinen."]
fill_template(TEMPLATE, cls.document,
"Verabschiedung von Diakon Georg aus der Gemeinde Reinickendorf",
_date_label("2026-09-02"), paragraphs)