a tool for shared writing and social publishing
1import { unified } from "unified"; 2import remarkGfm from "remark-gfm"; 3import remarkParse from "remark-parse"; 4import remarkRehype from "remark-rehype"; 5import rehypeStringify from "rehype-stringify"; 6 7import { visit } from "unist-util-visit"; 8import rehypeParse from "rehype-parse"; 9import rehypeRemark from "rehype-remark"; 10import remarkStringify from "remark-stringify"; 11 12function remarkTightListify() { 13 return (tree: any) => { 14 visit(tree, "list", (node) => { 15 node.spread = false; 16 for (const child of node.children) { 17 if (child.type === "listItem") { 18 child.spread = false; 19 } 20 } 21 }); 22 }; 23} 24 25export function markdownToHtml(markdown: string): string { 26 markdown = markdown.replace(/\n(?=[^\n])/g, "\n\n"); 27 return String( 28 unified() 29 .use(remarkParse) // Parse markdown content to a syntax tree 30 .use(remarkGfm) 31 .use(remarkRehype) // Turn markdown syntax tree to HTML syntax tree, ignoring embedded HTML 32 .use(rehypeStringify) // Serialize HTML syntax tree 33 .processSync(markdown), 34 ); 35} 36 37export function htmlToMarkdown(html: string): string { 38 return String( 39 unified() 40 .use(rehypeParse) // Parse HTML to a syntax tree 41 .use(rehypeRemark) // Turn HTML syntax tree to markdown syntax tree 42 .use(remarkGfm) 43 .use(remarkTightListify) 44 .use(remarkStringify, { 45 bullet: "-", // change default list marker from '*' 46 }) // Serialize HTML syntax tree 47 .processSync(html), 48 ); 49}