import TurndownService from 'turndown'; import { gfm } from 'turndown-plugin-gfm'; import { markdownToHtml } from './MarkdownView'; // Matched to the dialect the generator writes, so a save is not a rewrite. const turndown = new TurndownService({ headingStyle: 'atx', hr: '---', bulletListMarker: '-', codeBlockStyle: 'fenced', fence: '```', emDelimiter: '*', strongDelimiter: '**', linkStyle: 'inlined', }); // Tables, strikethrough and task lists. turndown.use(gfm); // Turndown pads list markers to four columns ("- item"); the generator // writes "- item", so the default would rewrite every bullet on first save. turndown.addRule('tightListItem', { filter: 'li', replacement: (content, node, options) => { const body = content .replace(/^\n+/, '') .replace(/\n+$/, '\n') // Continuation lines line up under the text, not under the marker. .replace(/\n/g, '\n '); const parent = node.parentNode as HTMLElement | null; let prefix = `${options.bulletListMarker} `; if (parent && parent.nodeName === 'OL') { const start = Number(parent.getAttribute('start') ?? 1); const index = Array.prototype.indexOf.call(parent.children, node); prefix = `${(Number.isFinite(start) ? start : 1) + index}. `; } const trailing = node.nextSibling && !/\n$/.test(body) ? '\n' : ''; return prefix + body + trailing; }, }); // Tiptap emits `