import { chunkMarkdownIR, markdownToIR, type MarkdownLinkSpan, type MarkdownIR, } from "../markdown/ir.js"; import { renderMarkdownWithMarkers } from "../markdown/render.js"; export type TelegramFormattedChunk = { html: string; text: string; }; function escapeHtml(text: string): string { return text.replace(/&/g, "&").replace(//g, ">"); } function escapeHtmlAttr(text: string): string { return escapeHtml(text).replace(/"/g, """); } function buildTelegramLink(link: MarkdownLinkSpan, _text: string) { const href = link.href.trim(); if (!href) return null; if (link.start === link.end) return null; const safeHref = escapeHtmlAttr(href); return { start: link.start, end: link.end, open: ``, close: "", }; } function renderTelegramHtml(ir: MarkdownIR): string { return renderMarkdownWithMarkers(ir, { styleMarkers: { bold: { open: "", close: "" }, italic: { open: "", close: "" }, strikethrough: { open: "", close: "" }, code: { open: "", close: "" }, code_block: { open: "
", close: "
" }, }, escapeText: escapeHtml, buildLink: buildTelegramLink, }); } export function markdownToTelegramHtml(markdown: string): string { const ir = markdownToIR(markdown ?? "", { linkify: true, headingStyle: "none", blockquotePrefix: "", }); return renderTelegramHtml(ir); } export function markdownToTelegramChunks( markdown: string, limit: number, ): TelegramFormattedChunk[] { const ir = markdownToIR(markdown ?? "", { linkify: true, headingStyle: "none", blockquotePrefix: "", }); const chunks = chunkMarkdownIR(ir, limit); return chunks.map((chunk) => ({ html: renderTelegramHtml(chunk), text: chunk.text, })); } export function markdownToTelegramHtmlChunks(markdown: string, limit: number): string[] { return markdownToTelegramChunks(markdown, limit).map((chunk) => chunk.html); }