diff --git a/package.json b/package.json index 3e85a9817f..67d2b19a03 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "warning": "~2.1.0" }, "devDependencies": { - "antd-md-loader": "0.1.0-beta.18", + "antd-md-loader": "~0.1.0", "atool-build": "^0.6.5", "babel-cli": "^6.2.0", "babel-core": "^6.2.1", @@ -97,9 +97,9 @@ "eslint-plugin-react": "^4.0.0", "eslint-tinker": "^0.3.1", "gh-pages": "^0.11.0", - "highlight.js": "^9.2.0", "history": "^1.17.0", "jest-cli": "~0.8.0", + "jsonml-to-react-component": "~0.1.0", "jsonp": "^0.2.0", "lesshint": "^1.2.1", "lodash": "^4.1.0", diff --git a/site/component/Article/index.jsx b/site/component/Article/index.jsx index 90618d3e8a..e0bcd6cac2 100644 --- a/site/component/Article/index.jsx +++ b/site/component/Article/index.jsx @@ -25,12 +25,15 @@ export default class Article extends React.Component { } imgToPreview(node) { - if (!this.isPreviewImg(node.children)) { - return node; + if (node[0] === 'p' && + node[1][0] === 'innerHTML' && + this.isPreviewImg(node[1][1])) { + const imgs = node.slice(1) + .map((n) => n[1]) + .filter((img) => img); + return ; } - - const imgs = node.children.split(/\r|\n/); - return ; + return node; } isVideo(string) { @@ -38,49 +41,57 @@ export default class Article extends React.Component { } enhanceVideo(node) { - if (!this.isVideo(node.children)) { - return node; + if (node[0] === 'innerHTML' && this.isVideo(node[1])) { + return ; } - - return ; + return node; } render() { const { content, location } = this.props; const jumper = content.description.filter((node) => { - return node.type === 'h2'; + return node[0] === 'h2'; }).map((node) => { return ( -
  • - +
  • +
  • ); }); - content.description = content.description - .map(this.imgToPreview) - .map(this.enhanceVideo); + const { meta, intro } = content; + const description = content.description + .map(this.imgToPreview) + .map(this.enhanceVideo); return (

    - { content.meta.chinese || content.meta.english } + { meta.chinese || meta.english } { - !content.meta.subtitle ? null : - { content.meta.subtitle } + !meta.subtitle ? null : + { meta.subtitle } }

    { - !content.intro ? null : - content.intro.map(utils.objectToComponent.bind(null, location.pathname)) + !intro ? null : + utils.jsonmlToComponent( + location.pathname, + ['section', { className: 'markdown' }].concat(intro) + ) } { jumper.length > 0 ?
      { jumper }
    : null } - { content.description.map(utils.objectToComponent.bind(null, location.pathname)) } + { + utils.jsonmlToComponent( + location.pathname, + ['section', { className: 'markdown' }].concat(description) + ) + }
    ); } diff --git a/site/component/ComponentDoc/index.jsx b/site/component/ComponentDoc/index.jsx index 5a4e37cca3..6c589c4e8b 100644 --- a/site/component/ComponentDoc/index.jsx +++ b/site/component/ComponentDoc/index.jsx @@ -82,7 +82,13 @@ export default class ComponentDoc extends React.Component {

    {meta.chinese || meta.english}

    - { description.map(utils.objectToComponent.bind(null, location.pathname)) } + { + utils.jsonmlToComponent( + location.pathname, + ['section', { className: 'markdown' }] + .concat(description) + ) + }

    代码演示 { rightChildren } } -
    - { (doc.api || []).map(utils.objectToComponent.bind(null, location.pathname)) } -
    + { + utils.jsonmlToComponent( + location.pathname, + ['section', { + className: 'markdown api-container', + }].concat(doc.api || []) + ) + } ); } diff --git a/site/component/Demo/index.jsx b/site/component/Demo/index.jsx index e184637ed2..e65468bbcf 100644 --- a/site/component/Demo/index.jsx +++ b/site/component/Demo/index.jsx @@ -33,8 +33,7 @@ export default class Demo extends React.Component { [className]: className, expand: codeExpand, }); - const introChildren = intro.map(utils.objectToComponent.bind(null, pathname)); - + const introChildren = utils.jsonmlToComponent(pathname, ['div'].concat(intro)); return (
    diff --git a/site/component/utils.js b/site/component/utils.js index 18b8d9a0bc..d034c1c18f 100644 --- a/site/component/utils.js +++ b/site/component/utils.js @@ -1,79 +1,30 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Link } from 'react-router'; -import hljs from 'highlight.js'; +import toReactComponent from 'jsonml-to-react-component'; function isHeading(type) { return /h[1-6]/i.test(type); } -function mdLangToHljsLang(lang) { - return lang.toLowerCase() === 'jsx' ? - 'javascript' : - lang; -} - -export function objectToComponent(pathname, object, index) { - if (object === null) return; - - if (React.isValidElement(object)) { - return React.cloneElement(object, { key: index }); - } - - if (typeof object === 'function') { - return React.cloneElement(object(React, ReactDOM), { key: index }); - } - - if (typeof object === 'string') { - return { object }; - } - - const children = object.children; - - if (object.type === 'html') { - return React.createElement('div', { - className: 'markdown', - key: index, - dangerouslySetInnerHTML: { __html: children } - }); - } - - if (isHeading(object.type)) { - return React.createElement(object.type, { - key: index, - id: children, - }, [ - , - #, - ]); - } - - if (object.type === 'code') { - const highlightedCode = hljs.highlight( - mdLangToHljsLang(object.props.lang), - children - ).value; - return ( -
    -
    -          
    -        
    -
    - ); - } - - if (typeof children === 'string') { - return React.createElement(object.type, { - key: index, - dangerouslySetInnerHTML: { __html: children } - }); - } - - return React.createElement( - object.type, { key: index }, - children && children.map(objectToComponent.bind(null, pathname)) // `hr` has no children - ); +export function jsonmlToComponent(pathname, jsonml) { + return toReactComponent([ + [(node) => React.isValidElement(node), (node, index) => { + return React.cloneElement(node, { key: index }); + }], + [(node) => typeof node === 'function', (node, index) => { + return React.cloneElement(node(React, ReactDOM), { key: index }); + }], + [(node) => isHeading(node[0]), (node, index) => { + return React.createElement(node[0], { + key: index, + id: node[1], + }, [ + , + #, + ]); + }], + ], jsonml); } export function setTitle(title) {