From 138c58b9cbc40a7030c081a8798dc0f53d582ef2 Mon Sep 17 00:00:00 2001 From: ecency Date: Mon, 6 Jul 2026 19:40:31 +0000 Subject: [PATCH] fix(publish): require GFM adjacency for translate table detection --- apps/web/src/api/translation.ts | 18 +++++++++++------- .../src/specs/api/translate-markdown.spec.ts | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/apps/web/src/api/translation.ts b/apps/web/src/api/translation.ts index a46ac0f590..bfb340e61d 100644 --- a/apps/web/src/api/translation.ts +++ b/apps/web/src/api/translation.ts @@ -263,13 +263,17 @@ const isSkippableBlock = (block: string): boolean => { ) { return true; } - // Tables: a pipe row plus a |---| separator row. Cell-safe translation is - // out of scope, so the whole block is passed through. - return ( - lines.some((line) => line.includes("|")) && - lines.some( - (line) => line.includes("|") && line.includes("-") && TABLE_SEPARATOR_LINE.test(line) - ) + // Tables: a |---| separator row directly below a pipe row (the GFM shape). + // Cell-safe translation is out of scope, so the whole block is passed + // through; requiring adjacency keeps prose that merely contains pipe + // characters translatable. + return lines.some( + (line, i) => + i > 0 && + line.includes("|") && + line.includes("-") && + TABLE_SEPARATOR_LINE.test(line) && + lines[i - 1].includes("|") ); }; diff --git a/apps/web/src/specs/api/translate-markdown.spec.ts b/apps/web/src/specs/api/translate-markdown.spec.ts index f377f602b6..456b598e16 100644 --- a/apps/web/src/specs/api/translate-markdown.spec.ts +++ b/apps/web/src/specs/api/translate-markdown.spec.ts @@ -277,4 +277,18 @@ it("preserves leading indentation on marker-less continuation lines", async () = ).rejects.toThrow("translate-cancelled"); expect(calls).toBe(1); }); +it("still skips a real GFM table (separator directly under the header row)", async () => { + const table = "| a | b |\n|---|---|\n| 1 | 2 |"; + const result = await translateMarkdown(`Intro.\n\n${table}`, "es", "en"); + + expect(result).toBe(`\u00abIntro.\u00bb\n\n${table}`); + }); + + it("translates prose containing pipes and a stray separator-like line", async () => { + const block = "El valor |x| es absoluto\nnota al margen\n|---|"; + const result = await translateMarkdown(block, "es", "en"); + + expect(result).toContain("\u00ab"); + expect(post).toHaveBeenCalled(); + }); });