From e9f33e01740542aca05875555ef84872684eb045 Mon Sep 17 00:00:00 2001 From: Adam Teichert Date: Tue, 16 Dec 2025 13:02:24 -0700 Subject: [PATCH] markdown tables headings have scope of col; raw html tables are not changed --- src/services/htmlMarkdownUtils.test.ts | 49 ++++++++++++++++++++++++++ src/services/htmlMarkdownUtils.ts | 14 ++++++++ 2 files changed, 63 insertions(+) diff --git a/src/services/htmlMarkdownUtils.test.ts b/src/services/htmlMarkdownUtils.test.ts index e466c35..3fd5eca 100644 --- a/src/services/htmlMarkdownUtils.test.ts +++ b/src/services/htmlMarkdownUtils.test.ts @@ -34,4 +34,53 @@ describe('markdownToHtmlNoImages', () => { const html = markdownToHtmlNoImages(markdown); expect(html).toMatch(/\s*'); + expect(html).toContain(''); + }); + + it('does not add an extra empty header row', () => { + const markdown = ` +| Header | +| --- | +| Cell |`; + const html = markdownToHtmlNoImages(markdown); + expect(html).not.toContain(''); + const thCount = (html.match(/'); + expect(html).not.toContain(''); + + // Markdown table should have scope="col" + expect(html).toContain(''); + }); }); diff --git a/src/services/htmlMarkdownUtils.ts b/src/services/htmlMarkdownUtils.ts index b53ef5d..24209f5 100644 --- a/src/services/htmlMarkdownUtils.ts +++ b/src/services/htmlMarkdownUtils.ts @@ -47,6 +47,20 @@ marked.use( marked.use({ extensions: [mermaidExtension] }); +// We use a custom renderer instead of a regex replace because regex is too aggressive. +// It would add scope="col" to raw HTML tables (which we want to leave alone). +// The renderer only applies to markdown tables. +marked.use({ + renderer: { + tablecell({ text, header, align }) { + const type = header ? "th" : "td"; + const alignAttr = align ? ` align="${align}"` : ""; + const scopeAttr = header ? ' scope="col"' : ""; + return `<${type}${scopeAttr}${alignAttr}>${text}\n`; + }, + }, +}); + export function extractImageSources(htmlString: string) { const srcUrls = []; const regex = /]+src=["']?([^"'>]+)["']?/g;
My Table<\/caption>/); }); + + it('adds scope="col" to table headers', () => { + const markdown = ` +| Header 1 | Header 2 | +| --- | --- | +| Cell 1 | Cell 2 |`; + const html = markdownToHtmlNoImages(markdown); + expect(html).toContain('
Header 1Header 2 { + const markdown = ` + + + + + + + + + + + +
Raw Header
Raw Cell
+ +| MD Header | +| --- | +| MD Cell |`; + const html = markdownToHtmlNoImages(markdown); + + // Raw table should be untouched (or at least not have scope="col" added if it wasn't there) + expect(html).toContain('
Raw HeaderRaw HeaderMD Header