"""Mini-Markdown-Renderer für PM-Bodies — Python-Spiegelbild der
JS-Funktion ``renderPmBody`` in ``v2/screens/aktuelle-themen.html``.
Der Renderer interpretiert eine kleine Untermenge von Markdown:
- ``**bold**`` und ``__bold__`` → ``...``
- ``*italic*`` und ``_italic_`` → ``...`` (vorsichtig — nur
wenn nicht zwischen Ziffern oder Word-Charakters)
- Zeilen, die mit ``- `` oder ``* `` beginnen → ``
``
- Doppel-Newlines trennen Absätze → ``...
``
- Einzelne Newlines innerhalb eines Absatzes → ``
``
- HTML-Special-Chars (``&``, ``<``, ``>``) werden escaped.
Die Python-Variante existiert primär zum Testen. Im Produktiv-Frontend
wird die JS-Variante benutzt (kein Round-Trip zum Server).
"""
from __future__ import annotations
import re
# 1) HTML-Escape (analog zur JS-Variante, in dieser Reihenfolge)
def _html_escape(s: str) -> str:
return s.replace("&", "&").replace("<", "<").replace(">", ">")
# 2) Bold-Marker: **...** und __...__
_RE_BOLD_STAR = re.compile(r"\*\*([^*\n]+?)\*\*")
_RE_BOLD_UNDER = re.compile(r"__([^_\n]+?)__")
# 3) Italic-Marker: *…* und _…_, jeweils nicht zw. Word-Chars
_RE_ITALIC_STAR = re.compile(r"(? str:
"""Render Mini-Markdown zu HTML. Leere/None-Eingabe → leerer String."""
if not body:
return ""
s = _html_escape(body)
s = _RE_BOLD_STAR.sub(r"\1", s)
s = _RE_BOLD_UNDER.sub(r"\1", s)
s = _RE_ITALIC_STAR.sub(r"\1", s)
s = _RE_ITALIC_UNDER.sub(r"\1", s)
# Listen: konsekutive "- "/"* "-Zeilen zu einem zusammenfassen
out_lines = []
in_list = False
for line in s.split("\n"):
if _RE_BULLET.match(line):
if not in_list:
out_lines.append('')
in_list = True
out_lines.append("- " + _RE_BULLET.sub("", line) + "
")
else:
if in_list:
out_lines.append("
")
in_list = False
out_lines.append(line)
if in_list:
out_lines.append("
")
s = "\n".join(out_lines)
# Paragraphen-Split bei doppelten Newlines, einzelne →
paras = re.split(r"\n\s*\n", s)
rendered = []
for p in paras:
trimmed = p.strip()
if not trimmed:
continue
if trimmed.startswith("<"):
rendered.append(trimmed)
else:
rendered.append(
''
+ trimmed.replace("\n", "
")
+ "
"
)
return "\n".join(rendered)