"""Model markdown → Telegram HTML, chunking, and the status line for drafts.""" from __future__ import annotations import html import re from typing import Any __all__ = ["LIMIT", "chunks", "status_label", "to_html"] LIMIT = 4000 _FENCE = re.compile(r"```[^\n]*\n(.*?)(?:```|$)", re.DOTALL) _INLINE_CODE = re.compile(r"(`[^`\n]+`)") _HEADING = re.compile(r"^#{1,6}\s+(.+)$", re.MULTILINE) _BOLD = re.compile(r"\*\*(.+?)\*\*|__(.+?)__", re.DOTALL) _ITALIC = re.compile(r"(? str: out: list[str] = [] pos = 0 for match in _FENCE.finditer(text): out.append(_inline(text[pos : match.start()])) out.append(f"
{html.escape(match.group(1).rstrip())}")
pos = match.end()
out.append(_inline(text[pos:]))
return "".join(out).strip()
def _inline(text: str) -> str:
parts = _INLINE_CODE.split(text)
for i, part in enumerate(parts):
if i % 2:
parts[i] = f"{html.escape(part[1:-1])}"
continue
s = html.escape(part, quote=False)
s = _HEADING.sub(r"\1", s)
s = _BOLD.sub(lambda m: f"{m.group(1) or m.group(2)}", s)
s = _ITALIC.sub(r"\1", s)
s = _ITALIC_U.sub(r"\1", s)
s = _STRIKE.sub(r"