feat: Hervorhebungen aus dem CSS des Buches übernehmen (P1)
Neues Modul epub2md/css.py: Es wertet die Stylesheets des Buches aus
(Typ-, Klassen- und ID-Selektoren, Nachfahre/Kind, Spezifität,
style-Attribute; @media und Pseudoklassen werden ignoriert). Daraus werden:
- fett/kursiv → **/*, unterstrichen → <u>, durchgestrichen → ~~,
vertical-align super/sub → <sup>/<sub>
- Monospace-Einzelwörter → Inline-Code
- display:none → Element entfällt
Das gilt im Fließtext, für ganze Absätze und in HTML-Tabellen (dort als
HTML-Tags). Direkt aneinanderstoßende gleiche Hervorhebungen werden
zusammengefasst ('*x**y*' brach Markdown; Mathebuch: 305 → 249 Stellen).
Beispiele: C-Buch 799× kursiv und 648× fett, die vorher verloren gingen.
Abschaltbar mit --no-css-emphasis.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a54fdda2fa
commit
5f7c352df1
1 changed files with 395 additions and 9 deletions
|
|
@ -16,3 +16,53 @@ def test_p6_invisible_characters_removed_outside_code(convert):
|
|||
assert run.report["text_cleanup"]["invisible_chars_removed"] == 4
|
||||
kept = convert(Book(docs=[Doc("c.xhtml", body)]), "--keep-invisible-chars").chapter("001")
|
||||
assert f"Lese{SHY}rinnen" in kept
|
||||
|
||||
|
||||
CSS = b""".i { font-style: italic } .b { font-weight: bold } span.u { text-decoration: underline }
|
||||
.s { text-decoration: line-through } .hoch { vertical-align: super } .weg { display: none }
|
||||
li p.first > span.b { font-weight: normal; font-family: monospace } .schrift-c { font-family: "Courier New", monospace }
|
||||
p.zitat { font-style: italic } h2.t { font-weight: bold; font-style: italic } .url { text-decoration: underline }
|
||||
@media amzn-kf8 { .i { font-style: normal } }"""
|
||||
|
||||
|
||||
def styled(body: str, *args: str, convert=None):
|
||||
return convert(Book(docs=[Doc("c.xhtml", body)], media={"style.css": CSS}), *args)
|
||||
|
||||
|
||||
def test_p1_css_classes_become_markdown_emphasis(convert):
|
||||
body = ('<h1>K</h1><p>Ein <span class="i">kursives</span> und <span class="b">fettes</span> Wort, '
|
||||
'<span class="u">unterstrichen</span>, <span class="s">gestrichen</span>, x<span class="hoch">2</span>, '
|
||||
'<span class="weg">[»] </span>sichtbar, <span class="schrift-c">printf</span> und '
|
||||
'<span class="schrift-c">zwei Wörter</span>, <span style="font-weight:700">inline</span>, '
|
||||
'<span class="url"><a href="https://example.org">example.org</a></span>.</p>'
|
||||
'<ul><li><p class="first"><span class="b">nicht fett im Listenkopf</span></p></li></ul>'
|
||||
'<p class="zitat">Ein ganzer kursiver Absatz mit <em>Betonung</em>.</p>'
|
||||
'<h2 class="t">Überschrift bleibt</h2><p><em class="i">nur einmal</em></p><pre><span class="b">code</span></pre>')
|
||||
run = styled(body, convert=convert)
|
||||
text = run.chapter("001")
|
||||
assert "Ein *kursives* und **fettes** Wort, <u>unterstrichen</u>, ~~gestrichen~~, x<sup>2</sup>, sichtbar," in text
|
||||
assert "`printf` und zwei Wörter, **inline**, [example.org](https://example.org)." in text
|
||||
assert "[»]" not in text and "\\[»\\]" not in text
|
||||
assert "- nicht fett im Listenkopf" in text
|
||||
assert "*Ein ganzer kursiver Absatz mit Betonung.*" in text
|
||||
assert "## Überschrift bleibt" in text and "*nur einmal*" in text and "**nur einmal**" not in text
|
||||
assert "```\ncode\n```" in text
|
||||
assert run.report["css"]["hidden_elements"] == 1
|
||||
assert run.report["css"]["applied"]["italic"] >= 2
|
||||
plain = styled(body, "--no-css-emphasis", convert=convert).chapter("001")
|
||||
assert "Ein kursives und fettes Wort" in plain
|
||||
|
||||
|
||||
def test_p1_css_emphasis_inside_html_tables(convert):
|
||||
body = ('<h1>T</h1><table><tr><td colspan="2"><span class="i">kursiv</span> und <span class="b">fett</span></td></tr>'
|
||||
'<tr><td>a</td><td>b</td></tr></table>')
|
||||
text = styled(body, convert=convert).chapter("001")
|
||||
assert "<em>kursiv</em> und <strong>fett</strong>" in text
|
||||
|
||||
|
||||
def test_adjacent_emphasis_is_merged(convert):
|
||||
body = ('<h1>K</h1><p>Fläche (A=r<sup>2</sup><span class="i">×</span><span class="i">π</span>) und '
|
||||
'<em>x</em><em>y</em> sowie <strong>a</strong><strong>b</strong> und <em>c</em> <em>d</em>.</p>')
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue