import { Readability } from '@mozilla/readability'; import TurndownService from 'turndown'; let turndown: TurndownService | null = null; function getTurndown(): TurndownService { if (!turndown) turndown = new TurndownService({ headingStyle: 'atx', codeBlockStyle: 'fenced' }); return turndown; } // Minimum readable-text length before we trust Readability's extraction over // the raw document body. Short fixtures/pages get low-quality Readability // output (heading demotion, URL normalization), so fall back to the raw body. const MIN_READABLE_LENGTH = 200; export function htmlToMarkdown(html: string, baseUrl: string): string { try { const doc = new DOMParser().parseFromString(html, 'text/html'); // Resolve relative links against the source URL so markdown links work. const base = doc.createElement('base'); base.href = baseUrl; doc.head?.appendChild(base); const article = new Readability(doc).parse(); const readableText = article?.textContent?.trim() ?? ''; const contentHtml = article?.content && readableText.length >= MIN_READABLE_LENGTH ? article.content : doc.body?.innerHTML || html; const md = getTurndown().turndown(contentHtml).trim(); return md || (doc.body?.textContent || '').trim(); } catch { return html; } }