mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-21 21:56:46 +00:00
fix(telegram): preserve spacing before numbered sections
This commit is contained in:
@@ -95,6 +95,33 @@ describe("markdownToTelegramHtml", () => {
|
||||
expect(res).toBe("<tg-spoiler><b>secret</b> text</tg-spoiler>");
|
||||
});
|
||||
|
||||
it("preserves spacing between Telegram bullet blocks and following numbered sections", () => {
|
||||
const input = [
|
||||
"2. Main invariants:",
|
||||
"",
|
||||
" • Raw Log is source of truth.",
|
||||
" • Autonomy starts only with report/draft.",
|
||||
"3. Cognee is a candidate:",
|
||||
"",
|
||||
" • bake-off first;",
|
||||
" • decide keep/adopt/hybrid later.",
|
||||
"4. Project Flow slices:",
|
||||
].join("\n");
|
||||
|
||||
const res = markdownToTelegramHtml(input, { wrapFileRefs: false });
|
||||
|
||||
expect(res).toContain("report/draft.\n\n3. Cognee");
|
||||
expect(res).toContain("keep/adopt/hybrid later.\n\n4. Project");
|
||||
});
|
||||
|
||||
it("does not insert Telegram list boundary spacing inside fenced code", () => {
|
||||
const input = ["```", " • literal bullet", "3. literal number", "```"].join("\n");
|
||||
|
||||
const res = markdownToTelegramHtml(input, { wrapFileRefs: false });
|
||||
|
||||
expect(res).toBe("<pre><code> • literal bullet\n3. literal number\n</code></pre>");
|
||||
});
|
||||
|
||||
it("does not treat single pipe as spoiler", () => {
|
||||
const res = markdownToTelegramHtml("( ̄_ ̄|) face");
|
||||
expect(res).not.toContain("tg-spoiler");
|
||||
|
||||
@@ -72,11 +72,50 @@ function renderTelegramHtml(ir: MarkdownIR): string {
|
||||
});
|
||||
}
|
||||
|
||||
function leadingWhitespaceLength(line: string): number {
|
||||
return line.match(/^[ \t]*/)?.[0]?.length ?? 0;
|
||||
}
|
||||
|
||||
function isTelegramBulletLine(line: string): boolean {
|
||||
return /^[ \t]*(?:[•*+-])[ \t]+\S/.test(line);
|
||||
}
|
||||
|
||||
function isTelegramListBoundaryLine(line: string): boolean {
|
||||
return /^[ \t]*(?:\d+\.|#{1,6})[ \t]+\S/.test(line);
|
||||
}
|
||||
|
||||
function preserveTelegramListBoundarySpacing(markdown: string): string {
|
||||
const lines = markdown.split("\n");
|
||||
const out: string[] = [];
|
||||
let inFence = false;
|
||||
|
||||
for (const line of lines) {
|
||||
const normalizedLine = line.replace(/\r$/, "");
|
||||
const isFenceLine = /^[ \t]*(?:```|~~~)/.test(normalizedLine);
|
||||
if (!inFence && out.length > 0) {
|
||||
const previous = out[out.length - 1] ?? "";
|
||||
if (
|
||||
isTelegramBulletLine(previous) &&
|
||||
isTelegramListBoundaryLine(normalizedLine) &&
|
||||
leadingWhitespaceLength(normalizedLine) <= leadingWhitespaceLength(previous)
|
||||
) {
|
||||
out.push("");
|
||||
}
|
||||
}
|
||||
out.push(line);
|
||||
if (isFenceLine) {
|
||||
inFence = !inFence;
|
||||
}
|
||||
}
|
||||
|
||||
return out.join("\n");
|
||||
}
|
||||
|
||||
export function markdownToTelegramHtml(
|
||||
markdown: string,
|
||||
options: { tableMode?: MarkdownTableMode; wrapFileRefs?: boolean } = {},
|
||||
): string {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
const ir = markdownToIR(preserveTelegramListBoundarySpacing(markdown ?? ""), {
|
||||
linkify: true,
|
||||
enableSpoilers: true,
|
||||
headingStyle: "none",
|
||||
@@ -458,7 +497,7 @@ export function markdownToTelegramChunks(
|
||||
limit: number,
|
||||
options: { tableMode?: MarkdownTableMode } = {},
|
||||
): TelegramFormattedChunk[] {
|
||||
const ir = markdownToIR(markdown ?? "", {
|
||||
const ir = markdownToIR(preserveTelegramListBoundarySpacing(markdown ?? ""), {
|
||||
linkify: true,
|
||||
enableSpoilers: true,
|
||||
headingStyle: "none",
|
||||
|
||||
Reference in New Issue
Block a user