from __future__ import annotations
import re
from html import escape
_HTML_TAGS = [
("", ""),
("", ""),
("", ""),
("", ""),
("", ""),
("
", ""), ("
", ""), ("
{escape(code)}")
return f"\x00CODEBLOCK{len(code_blocks) - 1}\x00"
text = _CODE_BLOCK_RE.sub(_save_code_block, text)
text = escape(text)
for pattern, replacement in _RE_MARKDOWN_TO_HTML:
try:
text = pattern.sub(replacement, text)
except re.error:
pass
text = _BULLET_LINE_RE.sub(r"\1• ", text)
text = _BLOCKQUOTE_RE.sub(r"\1", text) text = text.replace("*", "").replace("_", "") for i, block in enumerate(code_blocks): text = text.replace(f"\x00CODEBLOCK{i}\x00", block) return text.strip() def split_telegram_html_chunks(html: str, limit: int = 4096) -> list[str]: if len(html) <= limit: return [html] chunks: list[str] = [] tag_stack: list[str] = [] start = 0 i = 0 while i < len(html): if i - start >= limit: boundary = _find_safe_boundary(html, i, tag_stack) chunk = html[start:boundary] chunk = _close_open_tags(chunk, tag_stack) chunks.append(chunk) start = _skip_whitespace(html, boundary) i = start continue i += 1 if start < len(html): chunk = html[start:] chunk = _close_open_tags(chunk, tag_stack) chunks.append(chunk) return chunks def _find_safe_boundary(html: str, pos: int, tag_stack: list[str]) -> int: end = min(pos, len(html)) for i in range(end - 1, max(pos - 200, 0), -1): if html[i] == "\n": return i return end def _close_open_tags(chunk: str, tag_stack: list[str]) -> str: result = chunk for tag in reversed(tag_stack): close_tag = {"": "", "": "", "
": "", "": "", '', "
": "", "