feat: Titel überschriftsloser Seiten aus dem Inhalt ableiten (QA R3)

Seiten ohne Überschrift, NAV-Eintrag und <title> werden am Inhalt erkannt:
- Bild am Buchanfang -> Cover
- Buchtitel und Autor -> Titelseite
- ©/ISBN/urheberrechtlich -> Impressum
- sonst die ersten acht Wörter
Erst danach greift der Dateiname. Im Roman-Beispiel werden aus
cinnertitle/cimprint so 'Titelseite' und 'Impressum'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-10-05 20:46:34 +02:00
commit 3ac5e1a8cc

View file

@ -133,3 +133,22 @@ def test_large_chapter_with_subheadings_suggests_deeper_chapter_level(convert):
assert "--chapter-level 2" in hints[0]["message"] and "3 Unterabschnitte" in hints[0]["message"]
small = convert(Book(docs=[Doc("t.xhtml", "<h1>Teil</h1><h2>A</h2><p>x</p><h2>B</h2><p>y</p>")]))
assert not any(w["code"] == "chapter-large" for w in small.report["warnings"])
def test_titles_derived_from_content_when_no_other_source(convert):
docs = [
Doc("ccover.xhtml", '<div><img src="c.png" alt=""/></div>'),
Doc("cinner.xhtml", "<p>Erika Musterfrau</p><p>Testbuch</p><p>Roman</p>"),
Doc("cimp.xhtml", "<p>© 2024 Testverlag</p><p>Das Werk ist urheberrechtlich geschützt.</p>"),
Doc("cwid.xhtml", "<p>Für Anna, die immer an mich geglaubt hat, und für alle anderen.</p>"),
Doc("c1.xhtml", "<h1>Eins</h1><p>Text</p>"),
]
from conftest import PNG
run = convert(Book(docs=docs, nav=[("Eins", "c1.xhtml")], media={"c.png": PNG}))
names = [p.name for p in run.chapters()]
assert names == ["001-cover.md", "002-titelseite.md", "003-impressum.md",
"004-fuer-anna-die-immer-an-mich-geglaubt-hat.md", "005-eins.md"]
types = {c["file"]: c["types"] for c in run.report["chapters"]}
assert "cover" in types["chapters/001-cover.md"]
assert "titlepage" in types["chapters/002-titelseite.md"]
assert "colophon" in types["chapters/003-impressum.md"]