site: extract bisheng-plugin-react

This commit is contained in:
Benjy Cui 2016-05-24 15:11:39 +08:00
parent 4afb1cc6dd
commit 38f9864732
5 changed files with 10 additions and 88 deletions

View File

@ -75,9 +75,10 @@
"babel-eslint": "^6.0.2", "babel-eslint": "^6.0.2",
"babel-jest": "^12.0.2", "babel-jest": "^12.0.2",
"babel-plugin-antd": "^0.4.0", "babel-plugin-antd": "^0.4.0",
"bisheng": "^0.3.0", "bisheng": "^0.4.0",
"bisheng-plugin-description": "^0.1.1", "bisheng-plugin-description": "^0.1.1",
"bisheng-plugin-toc": "0.1.0-beta.0", "bisheng-plugin-react": "^0.1.0",
"bisheng-plugin-toc": "0.2.0",
"dom-scroll-into-view": "^1.1.0", "dom-scroll-into-view": "^1.1.0",
"enquire.js": "^2.1.1", "enquire.js": "^2.1.1",
"es6-shim": "^0.35.0", "es6-shim": "^0.35.0",

View File

@ -1,58 +0,0 @@
'use strict';
const recast = require('recast');
const builders = recast.types.builders;
// WAITING: esprima will support JSX
const parseOptions = {
parser: require('esprima-fb'),
};
function isImport(node) {
return node.type === 'ImportDeclaration';
}
function isNotImport(node) {
return !isImport(node);
}
module.exports = (content) => {
if (this.cacheable) {
this.cacheable();
}
let imports = [];
const ast = recast.visit(recast.parse(content, parseOptions), {
visitArrayExpression(path) {
const node = path.node;
const firstItem = node.elements[0];
const secondItem = node.elements[1];
if (firstItem &&
firstItem.type === 'Literal' &&
firstItem.value === 'pre' &&
secondItem.properties[0].value.value === '__react') { // TODO
const codeAst = recast.parse(node.elements[2].elements[1].value, parseOptions);
const astProgramBody = codeAst.program.body;
const codeImports = astProgramBody.filter(isImport);
imports = imports.concat(codeImports);
const codeBody = astProgramBody.filter(isNotImport);
const lastIndex = codeBody.length - 1;
codeBody[lastIndex] = builders.returnStatement(
codeBody[lastIndex].expression.arguments[0]
);
return builders.functionExpression(null, [
builders.identifier('React'), // TODO
builders.identifier('ReactDOM'),
], builders.blockStatement(codeBody));
}
this.traverse(path);
},
});
ast.program.body = imports.concat(ast.program.body);
return recast.print(ast).code;
};

View File

@ -1,5 +1,4 @@
const React = require('react'); const React = require('react');
const ReactDOM = require('react-dom');
const Link = require('react-router').Link; const Link = require('react-router').Link;
const toReactComponent = require('jsonml-to-react-component'); const toReactComponent = require('jsonml-to-react-component');
const JsonML = require('jsonml.js/lib/utils'); const JsonML = require('jsonml.js/lib/utils');
@ -13,13 +12,7 @@ function isHeading(node) {
module.exports = () => { module.exports = () => {
return { return {
converters: [ converters: [
[(node) => React.isValidElement(node), (node, index) => { [(node) => JsonML.isElement(node) && isHeading(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), (node, index) => {
const children = JsonML.getChildren(node); const children = JsonML.getChildren(node);
return React.createElement(JsonML.getTagName(node), { return React.createElement(JsonML.getTagName(node), {
key: index, key: index,
@ -30,13 +23,14 @@ module.exports = () => {
<a href={`#${children}`} className="anchor" key="anchor">#</a>, <a href={`#${children}`} className="anchor" key="anchor">#</a>,
]); ]);
}], }],
[(node) => JsonML.getTagName(node) === 'video', (node, index) => [(node) => JsonML.isElement(node) && JsonML.getTagName(node) === 'video', (node, index) =>
<VideoPlayer video={JsonML.getAttributes(node)} key={index} />, <VideoPlayer video={JsonML.getAttributes(node)} key={index} />,
], ],
[(node) => JsonML.isElement(node) && JsonML.getTagName(node) === 'a' && !( [(node) => JsonML.isElement(node) && JsonML.getTagName(node) === 'a' && !(
JsonML.getAttributes(node).class || JsonML.getAttributes(node).class ||
(JsonML.getAttributes(node).href && (JsonML.getAttributes(node).href &&
JsonML.getAttributes(node).href.indexOf('http') === 0) JsonML.getAttributes(node).href.indexOf('http') === 0) ||
/^#/.test(JsonML.getAttributes(node).href)
), (node, index) => { ), (node, index) => {
return <Link to={JsonML.getAttributes(node).href} key={index}>{toReactComponent(JsonML.getChildren(node)[0])}</Link>; return <Link to={JsonML.getAttributes(node).href} key={index}>{toReactComponent(JsonML.getChildren(node)[0])}</Link>;
}], }],

View File

@ -6,6 +6,7 @@ module.exports = {
plugins: [ plugins: [
'bisheng-plugin-description', 'bisheng-plugin-description',
'bisheng-plugin-toc?maxDepth=2', 'bisheng-plugin-toc?maxDepth=2',
'bisheng-plugin-react?lang=__react',
'./site/bisheng-plugin-antd', './site/bisheng-plugin-antd',
], ],
webpackConfig(config) { webpackConfig(config) {
@ -14,11 +15,6 @@ module.exports = {
site: path.join(process.cwd(), 'site'), site: path.join(process.cwd(), 'site'),
}; };
config.module.loaders.forEach((loader) => {
if (loader.test.toString() !== '/\\.md$/') return;
loader.loaders.splice(1, 0, path.join(process.cwd(), 'site/bisheng-markdown-react-loader'));
});
config.babel.plugins.push([ config.babel.plugins.push([
require.resolve('babel-plugin-antd'), require.resolve('babel-plugin-antd'),
{ {

View File

@ -42,16 +42,6 @@ export default class Article extends React.Component {
render() { render() {
const props = this.props; const props = this.props;
const content = props.content; const content = props.content;
const jumper = (content.toc || []).map((node, index) => {
const headingText = getChildren(node)[0];
return (
<li key={index}>
<a href={`#${headingText}`}>
{props.utils.toReactComponent(headingText)}
</a>
</li>
);
});
const { meta, description } = content; const { meta, description } = content;
const { title, subtitle, chinese, english } = meta; const { title, subtitle, chinese, english } = meta;
@ -72,9 +62,8 @@ export default class Article extends React.Component {
) )
} }
{ {
(jumper.length > 0 && meta.toc !== false) ? !content.toc ? null :
<section className="toc"><ul>{jumper}</ul></section> : <section className="toc">{props.utils.toReactComponent(content.toc)}</section>
null
} }
{ {
this.getArticle(props.utils.toReactComponent( this.getArticle(props.utils.toReactComponent(