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 ?
:
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) {