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}