"""app/mdlite.py — tiny, dependency-free Markdown → HTML for streamed model text.
Handles what small models actually emit: **bold**, *italic*, `code`, # headings,
- / * bullet lists, 1. numbered lists, and blank-line paragraphs. Everything is
HTML-escaped first, so it is safe to render model output.
"""
from __future__ import annotations
import html
import re
_BOLD = re.compile(r"\*\*(.+?)\*\*")
_ITALIC = re.compile(r"(? str:
s = html.escape(text)
s = _BOLD.sub(r"\1", s)
s = _ITALIC.sub(r"\1", s)
s = _CODE.sub(r"\1", s)
return s
def md_to_html(text: str) -> str:
text = (text or "").strip()
if not text:
return ""
lines = text.split("\n")
out: list[str] = []
i = 0
while i < len(lines):
line = lines[i].rstrip()
if not line.strip():
i += 1
continue
h = _H.match(line)
if h:
out.append(f"
" + inline(" ".join(para)) + "
") return "\n".join(out) __all__ = ["md_to_html", "inline"]