diff --git a/README.md b/README.md index 38bd785..666c63d 100644 --- a/README.md +++ b/README.md @@ -44,19 +44,13 @@ md-components: \`\`\` ``` -### 示例 - - -#### 示例样式 - -```scss -.ant-card { - border-color: black; - text-align: center; - width: 200px; -} +支持行内组件: +```md +我是一个行内组件\`md-components:Button{"type":"link","onClick":"$onClick","children":"我是一个行内按钮"}\` ``` +### 示例 + #### 示例代码 - 这里填写示例标题 @@ -67,7 +61,7 @@ md-components: const { default: MarkdownComponentsRender } = _MarkdownComponentsRender; const { default: mdUrl } = md; const { default: Fetch } = _ReactFetch; -const { Card, Button, App } = antd; +const { Card, Button, App, Flex } = antd; const BaseExample = () => { const { message } = App.useApp(); @@ -77,15 +71,17 @@ const BaseExample = () => { ignoreSuccessState render={({ data }) => { return ( - { - message.info('你好'); - } - }}> - {data} - + + { + message.info('你好'); + } + }}> + {data} + + ); }}> ); diff --git a/doc/base.js b/doc/base.js index 34b8af3..ad4f0b1 100644 --- a/doc/base.js +++ b/doc/base.js @@ -1,7 +1,7 @@ const { default: MarkdownComponentsRender } = _MarkdownComponentsRender; const { default: mdUrl } = md; const { default: Fetch } = _ReactFetch; -const { Card, Button, App } = antd; +const { Card, Button, App, Flex } = antd; const BaseExample = () => { const { message } = App.useApp(); @@ -11,15 +11,17 @@ const BaseExample = () => { ignoreSuccessState render={({ data }) => { return ( - { - message.info('你好'); - } - }}> - {data} - + + { + message.info('你好'); + } + }}> + {data} + + ); }}> ); diff --git a/doc/example.md b/doc/example.md index 42f5ccc..1e1c89d 100644 --- a/doc/example.md +++ b/doc/example.md @@ -22,4 +22,6 @@ md-components: type: primary children: 我是一个按钮 onClick: $onClick -``` \ No newline at end of file +``` + +我是一个行内的组件`md-components:Button{"type":"link","onClick":"$onClick","children":"我是一个行内按钮"}`测试行内按钮 \ No newline at end of file diff --git a/doc/style.scss b/doc/style.scss index 9c12ac9..e69de29 100644 --- a/doc/style.scss +++ b/doc/style.scss @@ -1,5 +0,0 @@ -.ant-card { - border-color: black; - text-align: center; - width: 200px; -} diff --git a/doc/summary.md b/doc/summary.md index 94515af..e9a9930 100644 --- a/doc/summary.md +++ b/doc/summary.md @@ -24,4 +24,9 @@ md-components: children: 我是一个按钮 onClick: $onClick \`\`\` +``` + +支持行内组件: +```md +我是一个行内组件\`md-components:Button{"type":"link","onClick":"$onClick","children":"我是一个行内按钮"}\` ``` \ No newline at end of file diff --git a/package.json b/package.json index 14e6363..6d35a89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kne/markdown-components-render", - "version": "0.1.5", + "version": "0.1.6", "description": "渲染markdown文本,支持components.", "syntax": { "esmodules": true diff --git a/src/index.js b/src/index.js index f3e3cb1..3972bff 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import React, { useMemo, Fragment } from 'react'; +import React, { useMemo, Fragment, createElement } from 'react'; import markdown from 'markdown-it'; import mdComponents from './markdown-it-components'; import compileVariables from './compileVariables'; @@ -23,23 +23,23 @@ const MarkdownComponentsRender = ({ children = '', render: customRender, ...prop md.use(mdComponents); const html = md.render(children); - const root = document.createElement('div'); - root.innerHTML = typeof htmlTransform === 'function' ? htmlTransform(html) : html; - return [].slice.call(root.children).map((element, index) => { - if (element.className === 'yaml-components' && element.dataset.components) { - const componentsData = JSON.parse(element.dataset.components); - if (!componentsData['md-components']) { - return null; - } - const { type, props } = componentsData['md-components']; - const MdComponent = components[type]; - if (!MdComponent) { - return null; + + return htmlParser(typeof htmlTransform === 'function' ? htmlTransform(html) : html, { + replace(element) { + if (element.attribs && element.attribs.class === 'md-components' && element.attribs['data-components']) { + const componentsData = JSON.parse(element.attribs['data-components']); + if (!componentsData['md-components']) { + return null; + } + const { type, props } = componentsData['md-components']; + const MdComponent = components[type]; + if (!MdComponent) { + return null; + } + return ; } - return ; + return element; } - - return {htmlParser(element.outerHTML)}; }); }); diff --git a/src/markdown-it-components.js b/src/markdown-it-components.js index a366734..aeb0289 100644 --- a/src/markdown-it-components.js +++ b/src/markdown-it-components.js @@ -22,6 +22,36 @@ const validate = ajv.compile(mdComponentsSchema); const mdComponents = function (md) { const defaultFence = md.renderer.rules.fence; + const defaultCodeInline = md.renderer.rules.code_inline; + + md.renderer.rules.code_inline = function (tokens, idx, options, env, self) { + const token = tokens[idx]; + const regex = /^md-components:(.+)\{(.+)}$/; + try { + if (regex.test(token.content)) { + const matcher = token.content.match(regex); + const componentsType = matcher[1], + props = JSON.parse(`{${matcher[2]}}`); + const jsonData = { + 'md-components': { + type: componentsType, + props: props + } + }; + if (validate(jsonData)) { + const element = document.createElement('code'); + element.setAttribute('class', 'md-components'); + element.dataset.components = JSON.stringify(jsonData); + return element.outerHTML; + } + } + } catch (e) { + console.warn(e); + } + + return defaultCodeInline(tokens, idx, options, env, self); + }; + md.renderer.rules.fence = function (tokens, idx, options, env, self) { const token = tokens[idx]; if (token.info.trim() === 'yml') { @@ -29,11 +59,13 @@ const mdComponents = function (md) { const jsonData = yaml.load(token.content); if (validate(jsonData)) { const element = document.createElement('pre'); - element.setAttribute('class', 'yaml-components'); + element.setAttribute('class', 'md-components'); element.dataset.components = JSON.stringify(jsonData); return element.outerHTML; } - } catch (e) {} + } catch (e) { + console.warn(e); + } } return defaultFence(tokens, idx, options, env, self); };