import { NodeHtmlMarkdown } from 'node-html-markdown'; // Factory translator for td/th: adds ' | ' separator between cells in the same row // Uses postprocess to trim block-level whitespace (e.g.

inside ) before the pipe const cellTranslator = (ctx: any) => ({ surroundingNewlines: false, postfix: ctx.node.nextElementSibling ? ' | ' : '', postprocess: ({ content }: { content: string }) => content.trim(), }); // Cleans up dangling pipes from empty cells in a row const cleanRowPipes = ({ content }: { content: string }) => content .replace(/ \|(\s*\|)+/g, ' |') // consecutive pipes from empty middle cells .replace(/ \|\s*$/, '') // trailing pipe from empty last cell .replace(/^\s*\| /, ''); // leading pipe from empty first cell // Create instance with custom translators for email HTML const nhm = new NodeHtmlMarkdown( { // Ignore non-content elements ignore: ['head', 'script', 'style', 'meta', 'link'], }, { // Custom translators - unwrap table elements (email layout tables) // Single-cell rows render as plain text; multi-cell rows use ' | ' between cells table: { preserveWhitespace: true }, thead: {}, tbody: {}, tr: { postfix: '\n', postprocess: cleanRowPipes }, th: cellTranslator, td: cellTranslator, } ); /** * Convert HTML to Markdown using node-html-markdown * Optimized for email HTML which often uses tables for layout */ export function htmlToMarkdown(html: string): string { return nhm.translate(html); }