"""A tiny, safe Markdown subset → HTML, for admin feedback replies. Everything is HTML-escaped FIRST, then a small whitelist of structures is introduced: bold (**…**), bullet lists (- / *), headings (#/##/###), paragraphs, and line breaks. No links, no attributes, no inline styles, no raw HTML passthrough — so the output is safe to render and to email. Authored only by admins, but sanitized on principle regardless. """ from __future__ import annotations import html import re _BULLET_RE = re.compile(r"^\s*[-*]\s+") _HEADING_RE = re.compile(r"^\s*(#{1,3})\s+") _BOLD_RE = re.compile(r"\*\*(.+?)\*\*") _HEADING_TAG = {1: "h3", 2: "h4", 3: "h5"} def _inline(s: str) -> str: """Escape, then apply the only inline transform we allow: **bold**.""" s = html.escape(s, quote=False) return _BOLD_RE.sub(r"\1", s) def render_reply_html(text: str) -> str: """Render the supported Markdown subset to sanitized HTML (or '' if empty).""" text = (text or "").replace("\r\n", "\n").replace("\r", "\n").strip() if not text: return "" out: list[str] = [] for block in re.split(r"\n\s*\n", text): lines = [ln for ln in block.split("\n")] nonempty = [ln for ln in lines if ln.strip()] if not nonempty: continue if all(_BULLET_RE.match(ln) for ln in nonempty): items = "".join("
  • " + _inline(_BULLET_RE.sub("", ln)) + "
  • " for ln in nonempty) out.append("") elif len(nonempty) == 1 and _HEADING_RE.match(nonempty[0]): level = len(_HEADING_RE.match(nonempty[0]).group(1)) content = _HEADING_RE.sub("", nonempty[0]) tag = _HEADING_TAG[level] out.append(f"<{tag}>" + _inline(content) + f"") else: out.append("

    " + "
    ".join(_inline(ln) for ln in nonempty) + "

    ") return "".join(out)