from conftest import PNG, SVG, Book, Doc from epub2md.linkcheck import check_links def link_book() -> Book: a = ('

A

Siehe Kapitel B, Ziel in B, ' 'unten und kaputt.

' '

Zweites H1

Unten.

') b = '

B

Text

Ziel

zurück

' return Book(docs=[Doc("a.xhtml", a), Doc("b.xhtml", b)]) def test_internal_links_are_rewritten(convert): run = convert(link_book()) names = [p.name for p in run.chapters()] assert names == ["001-a.md", "002-zweites-h1.md", "003-b.md"] a = run.chapter("001") assert "[Kapitel B](003-b.md)" in a assert "[Ziel in B](003-b.md#ziel)" in a assert "[unten](002-zweites-h1.md#unten)" in a # anchor ended up in the split-off chapter assert "kaputt" in a and "gibtsnicht" not in a # unresolved: text kept, no broken link assert 'Ziel' in run.chapter("003") assert "[zurück](001-a.md#start)" in run.chapter("003") assert run.report["unresolved_links"][0]["href"] == "gibtsnicht.xhtml#x" assert any(w["code"] == "unresolved-link" for w in run.report["warnings"]) assert run.report["output_link_check"]["broken_count"] == 0 readme = (run.out / "README.md").read_text(encoding="utf-8") assert "[A](chapters/001-a.md)" in readme def test_images_are_extracted_once_with_relative_links(convert): body = ('

Bilder

Foto' '
Abbildung 1: Ein Foto.
' '

Nochmal

' '
Nur Unterschrift
') book = Book(docs=[Doc("c.xhtml", body)], media={"img/foto eins.png": PNG, "img/grafik.svg": SVG}) run = convert(book) text = run.chapter("001") assert '![Foto](../media/images/0001-foto.png "Titel")' in text assert "*Abbildung 1: Ein Foto.*" in text assert "![Nochmal](../media/images/0001-foto.png)" in text assert "![Nur Unterschrift](../media/images/0002-grafik.svg)" in text images = sorted(p.name for p in (run.out / "media" / "images").iterdir()) assert images == ["0001-foto.png", "0002-grafik.svg"] assert (run.out / "media/images/0002-grafik.svg").read_bytes() == SVG assert run.report["output_link_check"]["broken_count"] == 0 def test_image_strategies(convert): book = Book(docs=[Doc("c.xhtml", '

B

a

')], media={"img/a.png": PNG}) flat = convert(book, "--images", "flat") assert "![a](../media/a.png)" in flat.chapter("001") orig = convert(book, "--images", "original-path") assert "![a](../media/img/a.png)" in orig.chapter("001") assert (orig.out / "media/img/a.png").exists() none = convert(book, "--no-extract-media") assert not (none.out / "media").exists() assert "Bild: a" in none.chapter("001") def test_link_checker_detects_problems(): files = { "chapters/001-a.md": '# A\n\nText [ok](002-b.md#y) [kaputt](002-b.md#nein) [fehlt](003.md) ' "![bild](../media/images/a.png) [ext](https://example.org)\n\n```\n[nicht](geprüft.md)\n```\n", "chapters/002-b.md": '# B\n\nText [rück](001-a.md#x) [heading](#b)\n', } broken = check_links(files, {"media/images/a.png"}) assert {b["link"] for b in broken} == {"002-b.md#nein", "003.md"} def test_link_checker_ignores_escaped_brackets(): """An escaped \\[ must not start a link that swallows the following paragraphs.""" files = { "a.md": '\\[»\\] Hinweis\n\nText [kaputt](fehlt.md) und \\[1\\]\n\n[ok](#x)\n', } broken = check_links(files, set()) assert [b["link"] for b in broken] == ["fehlt.md"] def test_link_checker_handles_image_links(): files = {"a.md": "[![Abb.](bild.png)](fehlt.md) [![ok](bild.png)](#x) \n"} broken = check_links(files, {"bild.png"}) assert [b["link"] for b in broken] == ["fehlt.md"]