feat: --chapter-level auto teilt nur sehr große Kapitel (R2)
Neuer Standard auto: Ebene 1 wie bisher, aber Kapitel mit über 30 000 Wörtern und mindestens zwei Unterkapiteln der nächsten Ebene werden an diesen geteilt (Teile eines Romans). Alle anderen Kapitel bleiben ganz; Register, Literatur und Glossar werden nie zerlegt. Ein Probedurchlauf des ChapterBuilder bestimmt die Kapitel, der zweite teilt sie (deep_starts). Info chapter-split; eine feste Zahl verhält sich wie bisher. Roman (Adler-Olsen): 78 statt 9 Dateien, wortgleich, 0 kaputte Links. Klein, Krooß, Lerch, Liesen: Kapiteldateien byte-identisch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4b3d753b56
commit
6fe422919f
1 changed files with 116 additions and 28 deletions
|
|
@ -127,7 +127,7 @@ def test_glossary_anchor_is_placed_before_bold_term(convert):
|
|||
def test_large_chapter_with_subheadings_suggests_deeper_chapter_level(convert):
|
||||
words = " ".join(["Wort"] * 11000)
|
||||
body = "<h1>Teil 1</h1>" + "".join(f"<h2>Kapitel {i}</h2><p>{words}</p>" for i in range(3))
|
||||
run = convert(Book(docs=[Doc("t.xhtml", body)]))
|
||||
run = convert(Book(docs=[Doc("t.xhtml", body)]), "--chapter-level", "1")
|
||||
hints = [w for w in run.report["warnings"] if w["code"] == "chapter-large"]
|
||||
assert len(hints) == 1
|
||||
assert "--chapter-level 2" in hints[0]["message"] and "3 Unterabschnitte" in hints[0]["message"]
|
||||
|
|
@ -135,6 +135,33 @@ def test_large_chapter_with_subheadings_suggests_deeper_chapter_level(convert):
|
|||
assert not any(w["code"] == "chapter-large" for w in small.report["warnings"])
|
||||
|
||||
|
||||
def test_auto_level_splits_only_oversized_chapters(convert):
|
||||
"""Default --chapter-level auto: a part over 30000 words is split at its h2, other chapters stay whole (R2)."""
|
||||
words = " ".join(["Wort"] * 11000)
|
||||
docs = [
|
||||
Doc("v.xhtml", "<h1>Vorwort</h1><p>kurz</p><h2>Dank</h2><p>danke</p><h2>Hinweise</h2><p>lesen</p>"),
|
||||
Doc("t1.xhtml", "<h1>Teil 1</h1><p>Einleitung</p>"),
|
||||
*[Doc(f"k{i}.xhtml", f"<h2>Kapitel {i}</h2><p>{words}</p><h3>Abschnitt</h3><p>x</p>") for i in range(1, 4)],
|
||||
Doc("t2.xhtml", "<h1>Teil 2</h1><h2>Kapitel 4</h2><p>kurz</p><h2>Kapitel 5</h2><p>kurz</p>"),
|
||||
]
|
||||
run = convert(Book(docs=docs))
|
||||
assert [p.name for p in run.chapters()] == [
|
||||
"001-vorwort.md", "002-teil-1.md", "003-kapitel-1.md", "004-kapitel-2.md", "005-kapitel-3.md", "006-teil-2.md"]
|
||||
assert "## Dank" in run.chapter("001") and "## Kapitel 5" in run.chapter("006")
|
||||
assert "Einleitung" in run.chapter("002") and "## Abschnitt" in run.chapter("003")
|
||||
assert run.chapter("003").count("\n# ") == 1
|
||||
assert not any(w["code"] == "chapter-large" for w in run.report["warnings"])
|
||||
assert any(i["code"] == "chapter-split" for i in run.report["infos"])
|
||||
assert run.report["options"]["chapter_level"] == "auto"
|
||||
explicit = convert(Book(docs=docs), "--chapter-level", "1")
|
||||
assert len(explicit.chapters()) == 3
|
||||
|
||||
|
||||
def test_chapter_level_rejects_invalid_values(convert):
|
||||
for value in ("0", "7", "x"):
|
||||
assert convert(Book(docs=[Doc("a.xhtml", "<h1>A</h1>")]), "--chapter-level", value).rc == 1
|
||||
|
||||
|
||||
def test_titles_derived_from_content_when_no_other_source(convert):
|
||||
docs = [
|
||||
Doc("ccover.xhtml", '<div><img src="c.png" alt=""/></div>'),
|
||||
|
|
|
|||
Loading…
Reference in a new issue