From 859338b02a883e15aeaedb6f678541d0e3f11cf8 Mon Sep 17 00:00:00 2001 From: Suyi Date: Wed, 19 Jan 2022 21:54:26 +0800 Subject: [PATCH] feat: replace markdown-it with remark (#31) --- config/config.ts | 2 - package.json | 10 ++++- src/component/Markdown/index.tsx | 69 ++++++++++++-------------------- src/page/about/index.tsx | 4 +- 4 files changed, 35 insertions(+), 50 deletions(-) diff --git a/config/config.ts b/config/config.ts index 4fad68b..249b99a 100644 --- a/config/config.ts +++ b/config/config.ts @@ -96,7 +96,6 @@ export default defineConfig({ '//unpkg.com/antd@4.x/dist/antd.js', '//unpkg.com/@ant-design/icons@4.x/dist/index.umd.js', '//unpkg.com/dayjs@1.x/dayjs.min.js', - '//unpkg.com/markdown-it@8.x/dist/markdown-it.js', '//unpkg.com/react-markdown-editor-lite@1.x/lib/index.js', ] : [ @@ -105,7 +104,6 @@ export default defineConfig({ '//unpkg.com/antd@4.x/dist/antd.min.js', '//unpkg.com/@ant-design/icons@4.x/dist/index.umd.min.js', '//unpkg.com/dayjs@1.x/dayjs.min.js', - '//unpkg.com/markdown-it@8.x/dist/markdown-it.min.js', '//unpkg.com/react-markdown-editor-lite@1.x/lib/index.js', ], diff --git a/package.json b/package.json index eeef7cb..21e2ebe 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,14 @@ "dependencies": { "dotenv": "^10.0.0", "react": "17.x", - "react-dom": "17.x" + "react-dom": "17.x", + "rehype-attr": "^2.0.7", + "rehype-raw": "^6.1.1", + "rehype-sanitize": "^5.0.1", + "rehype-stringify": "^9.0.2", + "remark-parse": "^10.0.1", + "remark-rehype": "^10.1.0", + "unified": "^10.1.1" }, "devDependencies": { "@ant-design/icons": "^4.7.0", @@ -81,7 +88,6 @@ "dayjs": "^1.10.7", "egg-ci": "^1.19.0", "lint-staged": "^10.0.7", - "markdown-it": "^12.3.0", "prettier": "^2.2.0", "react-markdown-editor-lite": "^1.3.2", "semantic-release": "^18.0.1", diff --git a/src/component/Markdown/index.tsx b/src/component/Markdown/index.tsx index a6de29e..10206a5 100644 --- a/src/component/Markdown/index.tsx +++ b/src/component/Markdown/index.tsx @@ -1,52 +1,30 @@ import React from 'react'; -import MarkdownIt from 'markdown-it'; +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkRehype from 'remark-rehype'; +import rehypeRaw from 'rehype-raw'; +import rehypeAttr from 'rehype-attr'; +import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; +import rehypeStringify from 'rehype-stringify'; + import MdEditor from 'react-markdown-editor-lite'; // import 'react-markdown-editor-lite/esm/index.less'; import * as styles from './index.less'; -const mdParser = new MarkdownIt('commonmark', { - html: false, -}); - -const getAttributes = (content: string = 'image') => { - const attrs = content.split(' '); - const alt = attrs.shift(); - - const attributes = attrs.reduce((prev: string[], curr) => { - const [key, value] = curr.split('='); - - if (!key) { - return prev; - } - - if (!value) { - return prev.concat(`${key}`); - } - - return prev.concat(`${key}="${value}"`); - }, []); - - return { - alt, - attributes, - }; -}; - -mdParser.renderer.rules.image = function (tokens, index) { - const token = tokens[index]; - const srcIndex = token.attrIndex('src'); - - if (!token.attrs) { - return ''; - } - - const src = token.attrs[srcIndex][1]; - const content = mdParser.utils.escapeHtml(token.content); - const { alt, attributes } = getAttributes(content); - - return `${alt}`; -}; +const processor = unified() + .use(remarkParse) + .use(remarkRehype, { allowDangerousHtml: true }) + .use(rehypeRaw) + .use(rehypeAttr, { properties: 'attr' }) + .use(rehypeSanitize, { + ...defaultSchema, + attributes: { + ...defaultSchema.attributes, + img: [...(defaultSchema?.attributes?.img || []), ['style']], + }, + }) + .use(rehypeStringify); const Markdown: React.FC = (props) => { const { value = '', type, onChange, customClassName = '' } = props; @@ -84,7 +62,10 @@ const Markdown: React.FC = (props) => { readOnly={type === 'render'} view={view} value={value} - renderHTML={(text) => mdParser.render(text)} + renderHTML={async (text) => { + const content: any = await processor.process(text); + return content.value; + }} onChange={(data) => { onChange && onChange(data.text); }} diff --git a/src/page/about/index.tsx b/src/page/about/index.tsx index f4a76a9..e3ad150 100644 --- a/src/page/about/index.tsx +++ b/src/page/about/index.tsx @@ -29,8 +29,8 @@ CNode 的 SLA 保证是,一个9,即 90.000000%。 ## 贡献者 > egg-cnode - -[![contributors](https://ergatejs.implements.io/badges/contributors/cnodejs/egg-cnode.svg?owner=cnodejs&repo=egg-cnode&type=svg&width=1232&size=64&padding=8)](https://github.com/cnodejs/egg-cnode/graphs/contributors) + +[![contributors](https://ergatejs.implements.io/badges/contributors/cnodejs/egg-cnode.svg?owner=cnodejs&repo=egg-cnode&type=svg&width=1232&size=64&padding=8)](https://github.com/cnodejs/egg-cnode/graphs/contributors) `; const AboutPage: React.FC = (props) => {