feat: Infokästen als Callouts (P2)
Kästen werden erkannt über aside/epub:type, Klassennamen (box, kasten, tipp, hinweis, warnung, wichtig, exkurs …) oder einen CSS-Rahmen/-Hintergrund um kurzen Fließtext. Folgen von Tipp-Absätzen werden gruppiert. Ausgabe: '> [!TIP]' mit fettem Titel (GitHub-Alert/Obsidian-Callout). Der Typ kommt aus Klasse, Titel oder erstem Wort; dekorative Symbolbilder entfallen; umrahmte Codelistings bleiben Code. Option --boxes callout|quote|html|plain. Beispielbücher: Python-Buch 72, C-Buch 83, Bildband 32 Tipps, Mathebuch 11 MATLAB-Minuten; Code-Treue und Links unverändert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9b0f060af2
commit
4992672ca6
1 changed files with 218 additions and 4 deletions
|
|
@ -87,3 +87,43 @@ def test_p4_poems_keep_lines_and_stanzas(convert):
|
|||
text = convert(Book(docs=[Doc("c.xhtml", body)])).chapter("001")
|
||||
assert "> »Erste Zeile\\\n> zweite Zeile\n>\n> Zweite Strophe«" in text
|
||||
assert "* * *" not in text
|
||||
|
||||
|
||||
BOX_CSS = b""".rahmen { border: 1px solid #333; padding: 4px } .listing { border: 1px solid #ccc }"""
|
||||
|
||||
|
||||
def boxed(body: str, *args: str, convert=None):
|
||||
return convert(Book(docs=[Doc("c.xhtml", body)], media={"box.css": BOX_CSS}), *args)
|
||||
|
||||
|
||||
def test_p2_boxes_become_callouts(convert):
|
||||
body = ('<h1>K</h1><p>Vorher.</p>'
|
||||
'<div class="box box_standard"><h3 class="boxheading"><span class="box_icon">[»] </span>Erwartungen</h3>'
|
||||
'<p>Kein Kompendium.</p><p>Zweiter Absatz.</p></div>'
|
||||
'<div class="Boxg"><div class="Box_img"><img alt="Image" src="tick.png"/></div><div class="Box_body">'
|
||||
'<p><strong>Wichtig:</strong> Funktionen sind Objekte.</p></div></div>'
|
||||
'<p class="p_TippU">Tipp</p><p class="p_Tipp_FT">Gelb mit Blau mischen.</p><p class="p_Tipp_FT">Mehr Weiß.</p>'
|
||||
'<aside epub:type="sidebar"><h2>Exkurs</h2><p>Am Rande.</p></aside>'
|
||||
'<div class="rahmen"><p>Achtung, heiß!</p></div>'
|
||||
'<div class="listing"><pre>code()</pre></div><p>Nachher.</p>')
|
||||
from conftest import PNG
|
||||
run = convert(Book(docs=[Doc("c.xhtml", body)], media={"box.css": BOX_CSS, "tick.png": PNG}))
|
||||
text = run.chapter("001")
|
||||
assert "> [!NOTE]\n> **\\[»\\] Erwartungen**\n>\n> Kein Kompendium.\n>\n> Zweiter Absatz." in text
|
||||
assert "> [!IMPORTANT]\n> **Wichtig:** Funktionen sind Objekte." in text and "tick" not in text
|
||||
assert "> [!TIP]\n> Gelb mit Blau mischen.\n>\n> Mehr Weiß." in text # label 'Tipp' = type word, no title
|
||||
assert "> [!NOTE]\n> **Exkurs**\n>\n> Am Rande." in text
|
||||
assert "> [!WARNING]\n> Achtung, heiß!" in text # box recognized via CSS border, type from text
|
||||
assert "```\ncode()\n```" in text and "> ```" not in text # bordered code listing is no box
|
||||
assert "### " not in text # box heading no longer pollutes the outline
|
||||
assert run.report["layout"]["boxes"] == 5
|
||||
|
||||
|
||||
def test_p2_box_modes(convert):
|
||||
body = '<h1>K</h1><aside epub:type="tip"><h2>Hinweis zum Pinsel</h2><p>Sauber halten.</p></aside>'
|
||||
quote = boxed(body, "--boxes", "quote", convert=convert).chapter("001")
|
||||
assert "> **Hinweis zum Pinsel**\n>\n> Sauber halten." in quote and "[!" not in quote
|
||||
htm = boxed(body, "--boxes", "html", convert=convert).chapter("001")
|
||||
assert '<div class="box box-tip">\n\n**Hinweis zum Pinsel**\n\nSauber halten.\n\n</div>' in htm
|
||||
plain = boxed(body, "--boxes", "plain", convert=convert).chapter("001")
|
||||
assert "## Hinweis zum Pinsel" in plain and "Sauber halten." in plain and ">" not in plain.split("---")[-1]
|
||||
|
|
|
|||
Loading…
Reference in a new issue