feat: Szenenwechsel und Gedichte übernehmen (P4)

- Ein leerer Absatz (nur Leerzeichen/br) zwischen zwei Textabsätzen wird
  zu '* * *'; mehrere ergeben einen Wechsel.
- Ornament-Absätze (***, ⁂ …) werden ebenfalls zu '* * *'.
- Leere divs (z. B. Springer ClearBoth) und reine Ankerabsätze zählen nicht.
- Gedichte (poem/verse/gedicht, z3998:poem) werden zum Zitatblock mit einer
  Zeile pro Vers und Leerzeile zwischen Strophen.
Roman: 239 Szenenwechsel und 2 Gedichte (vorher verloren bzw. als lose
Absätze); die Sachbücher sind praktisch unverändert. Bericht: layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-06 04:57:03 +02:00
commit 9b0f060af2

View file

@ -66,3 +66,24 @@ def test_adjacent_emphasis_is_merged(convert):
text = styled(body, convert=convert).chapter("001")
assert "<sup>2</sup>*×π*" in text
assert "*xy*" in text and "**ab**" in text and "*c* *d*" in text
def test_p4_scene_breaks(convert):
body = ('<h1>K</h1><p class="leerzeile">&#160;</p><p>Erster Absatz.</p><p class="leerzeile">&#160;</p>'
'<p class="leerzeile">&#160;</p><p>Neue Szene.</p><p>Weiter.</p><p class="centertext">***</p>'
'<p>Nach Ornament.</p><p>&#160;</p><h2>Abschnitt</h2><p>Text</p><p>⁂</p><p>Ende.</p>')
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
body_md = text.split("# K", 1)[1]
assert "Erster Absatz.\n\n* * *\n\nNeue Szene." in body_md
assert body_md.count("* * *") == 3 # two empties collapse into one; ***, ⁂ are ornaments; none before the heading
assert "Weiter.\n\n* * *\n\nNach Ornament." in body_md
assert "\\*" not in body_md
assert body_md.strip().startswith("Erster Absatz.") # no break at chapter start
def test_p4_poems_keep_lines_and_stanzas(convert):
body = ('<h1>G</h1><p>Davor.</p><div class="poem"><p>»Erste Zeile</p><p>zweite Zeile</p>'
'<p class="leerzeile">&#160;</p><p>Zweite Strophe«</p></div><p>Danach.</p>')
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert "> »Erste Zeile\\\n> zweite Zeile\n>\n> Zweite Strophe«" in text
assert "* * *" not in text