epub2md/tests/test_tables_lists.py
dschlueter 0dad1f7b2d fix: doppelte Tabellen-Anker und Bild-Links im Linkcheck
- Komplexe Tabellen mit verlinkter id erzeugten den Anker zweimal
  (<a id> und <table id>), also ungültiges HTML.
- Der Linkcheck übersah das äußere Ziel von Bild-Links
  [![alt](img)](ziel) und startete Links an escapten \[-Klammern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 20:24:47 +02:00

72 lines
3.8 KiB
Python

from conftest import Book, Doc
def test_nested_lists_keep_structure(convert):
body = ("<h1>L</h1><ul><li>Eins<ol><li>Unterpunkt A</li><li>Unterpunkt B<ul><li>tief</li></ul></li></ol></li>"
"<li>Zwei</li></ul><ol start=\"4\"><li>vier</li><li>fünf</li></ol>")
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert "- Eins\n\n 1. Unterpunkt A\n\n 2. Unterpunkt B\n\n - tief\n\n- Zwei" in text
assert "4. vier\n5. fünf" in text
def test_simple_table_as_gfm(convert):
body = ("<h1>T</h1><table><caption>Tabelle 1: Werte</caption><thead><tr><th>Name</th><th>Wert</th></tr></thead>"
"<tbody><tr><td><em>a</em></td><td>1 | 2</td></tr><tr><td>b</td><td><code>x</code></td></tr></tbody></table>")
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert "*Tabelle 1: Werte*" in text
assert "| Name | Wert |\n| --- | --- |\n| *a* | 1 \\| 2 |\n| b | `x` |" in text
def test_complex_table_kept_as_html_with_warning(convert):
body = ("<h1>T</h1><table><tr><th colspan=\"2\">Kopf</th></tr><tr><td rowspan=\"2\">A</td><td><p>Zeile 1</p>"
"<p>Zeile 2</p></td></tr><tr><td><strong>B</strong></td></tr></table>")
run = convert(Book(docs=[Doc("c.xhtml", body)]))
text = run.chapter("001")
assert '<th colspan="2">Kopf</th>' in text
assert '<td rowspan="2">A</td>' in text
assert "Zeile 1" in text and "Zeile 2" in text and "<strong>B</strong>" in text
assert "\n\n" not in text.split("<table>")[1].split("</table>")[0] # HTML block must not be interrupted
assert any(w["code"] == "table-html" for w in run.report["warnings"])
def test_commonmark_uses_html_tables(convert):
body = "<h1>T</h1><table><tr><th>a</th></tr><tr><td>b</td></tr></table><p><del>alt</del></p>"
text = convert(Book(docs=[Doc("c.xhtml", body)]), "--format", "commonmark").chapter("001")
assert "<table>" in text and "| a |" not in text
assert "<del>alt</del>" in text
def test_definition_list_blockquote_and_inline_semantics(convert):
body = ("<h1>D</h1><dl><dt>Term</dt><dd>Erklärung.</dd></dl><blockquote><p>Zitat</p><p>weiter</p></blockquote>"
"<p>H<sub>2</sub>O, x<sup>2</sup>, <q>Zitat</q>, <s>weg</s>, <u>unter</u><br/>neue Zeile</p><hr/>")
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert "**Term:** Erklärung." in text
assert "> Zitat\n>\n> weiter" in text
assert "H<sub>2</sub>O, x<sup>2</sup>, „Zitat“, ~~weg~~, <u>unter</u>\\\nneue Zeile" in text
assert "* * *" in text
def test_markdown_special_characters_are_escaped(convert):
body = "<h1>E</h1><p>1. kein Listenpunkt</p><p># keine Überschrift</p><p>a*b*c [x](y) &lt;tag&gt; $5</p>"
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert "1\\. kein Listenpunkt" in text
assert "\\# keine Überschrift" in text
assert "a\\*b\\*c \\[x\\](y) \\<tag> \\$5" in text
def test_unknown_elements_are_reported_and_keep_html(convert):
body = ("<h1>U</h1><p>Vor <foo-widget data-x=\"1\" onclick=\"evil()\" style=\"x\">Inhalt bleibt</foo-widget>"
" nach.</p>")
run = convert(Book(docs=[Doc("c.xhtml", body)]))
assert "Vor Inhalt bleibt nach." in run.chapter("001")
assert run.report["unsupported_elements"] == {"foo-widget": 1}
kept = convert(Book(docs=[Doc("c.xhtml", body)]), "--keep-html")
assert '<foo-widget data-x="1">Inhalt bleibt</foo-widget>' in kept.chapter("001")
assert "evil" not in kept.chapter("001")
def test_complex_table_anchor_is_emitted_once(convert):
body = ('<h1>T</h1><p><a href="#t1">Tabelle 1</a></p><table id="t1"><tr><td colspan="2">a</td></tr>'
"<tr><td>b</td><td>c</td></tr></table>")
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
assert text.count('id="t1"') == 1