([\s\S]*?)<\/ul>/gi, (m, body) => listToMd(body, false));
out = out
.replace(/
/gi, '\n')
.replace(/
/gi, '\n---\n')
.replace(//gi, '\n')
.replace(/<\/p>/gi, '\n')
.replace(/
/gi, '\n')
.replace(/<\/div>/gi, '\n')
.replace(/<[^>]+>/g, '');
return decodeEntities(out).replace(/[ \t]+\n/g, '\n').replace(/\n{3,}/g, '\n\n').trim();
}
function listToMd(body, ordered) {
let i = 0;
const items = [];
for (const m of body.matchAll(/
- ([\s\S]*?)<\/li>/gi)) {
i += 1;
const text = stripTags(m[1]).trim();
items.push(ordered ? `${i}. ${text}` : `- ${text}`);
}
return `\n${items.join('\n')}\n`;
}
function tableToMd(body) {
const rows = [];
for (const rowM of body.matchAll(/
([\s\S]*?)<\/tr>/gi)) {
const cells = [];
for (const cellM of rowM[1].matchAll(/<(td|th)[^>]*>([\s\S]*?)<\/\1>/gi)) {
cells.push(stripTags(cellM[2]).trim().replace(/\|/g, '\\|'));
}
rows.push(cells);
}
if (!rows.length) return '';
const width = Math.max(...rows.map((r) => r.length));
const pad = (r) => { while (r.length < width) r.push(''); return r; };
const lines = [`| ${pad(rows[0]).join(' | ')} |`, `|${' --- |'.repeat(width)}`];
for (const row of rows.slice(1)) lines.push(`| ${pad(row).join(' | ')} |`);
return `\n${lines.join('\n')}\n`;
}
function stripTags(html) {
return decodeEntities(String(html).replace(/<[^>]+>/g, ''));
}
module.exports = { htmlToMarkdown };