on 99bdb21 help sign in
urbit.org/components/Markdown.js
94 lines 2.2 kB history raw
1import remark from "remark";
2import gfm from "remark-gfm";
3import slug from "remark-slug";
4import heading from "remark-heading-id";
5import remarkprism from "remark-prism";
6import normalize from "mdurl/encode";
7import merge from "deepmerge";
8import github from "hast-util-sanitize/lib/github";
9import remarkParse from "remark-parse";
10import remarkRehype, { defaultHandlers, all } from "remark-rehype";
11import rehypeStringify from "rehype-stringify";
12import rehypeRaw from "rehype-raw";
14// img is wrapped in figure so that images can be extra wide in the blog posts
15function img(h, node) {
16 var props = { src: normalize(node.url), alt: node.alt };
17 if (node.title !== null && node.title !== undefined) {
18 props.title = node.title;
19 }
20 return {
21 type: "element",
22 tagName: "figure",
23 properties: {},
24 children: [
25 {
26 type: "element",
27 tagName: "img",
28 properties: props,
29 },
30 ],
31 };
34function a(h, node) {
35 const url = node.url;
37 if (
38 url.includes("https://urbit.org") ||
39 url.startsWith("/") ||
40 url.startsWith("#")
41 ) {
42 return {
43 type: "element",
44 tagName: "a",
45 properties: {
46 href: url,
47 },
48 children: all(h, node),
49 };
50 } else {
51 return {
52 type: "element",
53 tagName: "a",
54 properties: {
55 target: "_blank",
56 rel: "noopener",
57 href: url,
58 },
59 children: all(h, node),
60 };
61 }
64const handlers = defaultHandlers;
65handlers.link = a;
66handlers.image = img;
68const options = {
69 allowDangerousHtml: true,
70 handlers: handlers,
71 sanitize: merge(github, {
72 // remove user-content from github.json to remark-slug work as expected
73 clobberPrefix: "",
74 attributes: { "*": ["className"] },
75 }),
76};
78// Converts markdown strings into markdown HTML/React components
79export default async function Markdown({ post }, disablePlugins) {
80 const result = await remark()
81 .use(remarkParse)
82 .use(remarkprism, {
83 plugins: !disablePlugins ? ["show-invisibles"] : [],
84 })
85 .use(gfm)
86 .use(slug)
87 .use(heading)
88 .use(remarkRehype, options)
89 .use(rehypeRaw)
90 .use(rehypeStringify)
91 .process(post.content);
93 return result.toString();