Skip to content

Commit 2cc7d0c

Browse files
hurujiQuilljou
authored andcommitted
feat: ✨ 💄 highlight & title (#6)
* feat: ✨ 💄 highlight & title * refactor: doc loader: title => demo
1 parent e2cf584 commit 2cc7d0c

File tree

11 files changed

+215
-6
lines changed

11 files changed

+215
-6
lines changed

docs/assets/style/base.styl

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ html, body
77
background: white
88
font-family -apple-system,"Helvetica Neue",Helvetica,Arial,"PingFang SC","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft Yahei",sans-serif
99
-webkit-font-smoothing antialiased
10+
margin 0
1011
input
1112
outline: 0

docs/assets/style/md.styl

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
font-size: $fontsize-medium
55
line-height: 1.6
66
color: $color-grey
7+
pre code
8+
border: 1px solid #e7e7e7
9+
color: #666
10+
background-color: #f9f8f8
11+
border-radius: 4px
12+
display: block
13+
overflow-x: auto
14+
color: #6e6b5e
15+
padding: .5em
716
p
817
margin: 1.2em 0
918
.anchor

docs/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<head>
55
<meta charset="UTF-8">
66
<title>Title</title>
7+
<link href="https://cdn.bootcss.com/highlight.js/9.7.0/styles/atom-one-dark.min.css" rel="stylesheet">
78
</head>
89

910
<body>

docs/markdown/button.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
### 示例
66

7-
- 按钮类型
7+
- 按钮类型
8+
89

910
默认类型为 `button`,还可设置为 `submit` 用于表单中
1011

12+
::: demo 按钮类型
13+
1114
```jsx
1215
import { Button } from 'cube-react';
1316

@@ -18,7 +21,7 @@ class Demo extends React.Component {
1821
}
1922
ReactDOM.render( <Demo/> , mountNode);
2023
```
21-
24+
:::
2225
- 按钮状态
2326

2427
默认正常,可设置激活、禁用状态

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"eslint-plugin-prettier": "^3.0.1",
6161
"eslint-plugin-react": "^7.12.4",
6262
"file-loader": "^2.0.0",
63+
"highlight.js": "^9.15.6",
6364
"html-loader": "^0.5.5",
6465
"html-webpack-plugin": "^3.2.0",
6566
"husky": "^1.2.0",
@@ -68,6 +69,7 @@
6869
"lint-staged": "^8.1.5",
6970
"loader-utils": "^1.1.0",
7071
"markdown-it": "^8.4.2",
72+
"markdown-it-container": "^2.0.0",
7173
"markdown-loader": "^4.0.0",
7274
"mini-css-extract-plugin": "^0.4.5",
7375
"prettier": "^1.15.2",

scripts/loaders/doc/index.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const MarkDownItContainer = require('markdown-it-container')
2+
const hljs = require('highlight.js')
3+
const md = require('markdown-it')({
4+
highlight (str, lang) {
5+
if (lang && hljs.getLanguage(lang)) {
6+
try {
7+
return hljs.highlight(lang, str).value;
8+
// eslint-disable-next-line
9+
} catch (__) {}
10+
}
11+
return '';
12+
}
13+
})
14+
15+
md.use(MarkDownItContainer, 'demo', {
16+
17+
validate(params) {
18+
return params.trim().match(/^demo\s+(.+)$/);
19+
},
20+
21+
render() {
22+
return ''
23+
}
24+
});
25+
26+
module.exports = function docLoader(source){
27+
return md.render(source)
28+
}

scripts/loaders/example/core.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const extractor = require('./extractor');
2+
const generator = require('./generator')
3+
4+
const template = (funcCompoents, titles) =>
5+
`
6+
import React from 'react';
7+
import ReactDom from 'react-dom';
8+
9+
const renderFuncs = [${funcCompoents}]
10+
const nodes = ${titles}
11+
12+
export default class ExamplePages extends React.Component {
13+
componentDidMount() {
14+
document.head.innerHTML = document.head.innerHTML + '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no, viewport-fit=cover">'
15+
}
16+
render() {
17+
return (
18+
<div>
19+
{renderFuncs.map((item, index) => {
20+
return (
21+
<div key={index}>
22+
{nodes[index] ? (<div>{nodes[index]}</div>) : null}
23+
<div>{item()}</div>
24+
</div>
25+
)
26+
})}
27+
</div>
28+
)
29+
}
30+
}
31+
`
32+
33+
module.exports = function core(source) {
34+
const nodes = extractor(source);
35+
const funcCompoents = nodes.filter(node => node.type === 'code').map(node => generator(node.content)).join(',')
36+
const titles = nodes.map(node => node.type === 'title' ? node.content : '')
37+
38+
const result = template(funcCompoents, JSON.stringify(titles))
39+
return result;
40+
}

scripts/loaders/example/extractor.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const md = require('markdown-it')()
2+
const MarkDownItContainer = require('markdown-it-container')
3+
4+
md.use(MarkDownItContainer, 'demo')
5+
module.exports = function extractor(source) {
6+
const tokens = md.parse(source)
7+
const nodes = [];
8+
tokens.forEach((token) => {
9+
const { tag, info, content } = token
10+
const matched = info.trim().match(/^demo\s+(.+)/)
11+
if(matched) {
12+
nodes.push({
13+
type: 'title',
14+
content: matched[1]
15+
})
16+
}
17+
if(tag === 'code' && info === 'jsx') {
18+
nodes.push({
19+
type: 'code',
20+
content
21+
})
22+
}
23+
});
24+
25+
return nodes;
26+
};

scripts/loaders/example/generator.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Inspired By https://github.com/benjycui/bisheng/blob/master/packages/bisheng-plugin-react/lib/transformer.js
3+
*/
4+
5+
const babel = require('@babel/core')
6+
const types = require('@babel/types');
7+
const generator = require('@babel/generator').default;
8+
const traverse = require('@babel/traverse').default;
9+
const babelConfig = require('../../../babel.config')
10+
11+
// babelConfig = babelConfig({env: () => ''})
12+
// babelConfig.presets[0][1].modules = 'commonjs'
13+
14+
function requireGenerator(varName, moduleName) {
15+
return types.variableDeclaration('var', [
16+
types.variableDeclarator(
17+
types.identifier(varName),
18+
types.callExpression(types.identifier('require'), [
19+
types.stringLiteral(moduleName),
20+
]),
21+
),
22+
]);
23+
}
24+
25+
26+
27+
module.exports = function generate(source) {
28+
const {
29+
ast: codeAst
30+
} = babel.transformSync(source, {
31+
ast: true,
32+
code: false,
33+
filename: 'hackFile.js',
34+
...babelConfig
35+
})
36+
37+
let renderReturn = null;
38+
traverse(codeAst, {
39+
CallExpression(callPath) {
40+
const callPathNode = callPath.node;
41+
if (
42+
callPathNode.callee &&
43+
callPathNode.callee.object &&
44+
callPathNode.callee.object.name === 'ReactDOM' &&
45+
callPathNode.callee.property &&
46+
callPathNode.callee.property.name === 'render'
47+
) {
48+
renderReturn = types.returnStatement(callPathNode.arguments[0]);
49+
50+
callPath.remove();
51+
}
52+
},
53+
});
54+
55+
const astProgramBody = codeAst.program.body;
56+
// if (!noreact) {
57+
astProgramBody.unshift(requireGenerator('ReactDOM', 'react-dom'));
58+
astProgramBody.unshift(requireGenerator('React', 'react'));
59+
// }
60+
// ReactDOM.render always at the last of preview method
61+
if (renderReturn) {
62+
astProgramBody.push(renderReturn);
63+
}
64+
65+
const codeBlock = types.BlockStatement(astProgramBody);
66+
const previewFunction = types.functionDeclaration(
67+
types.Identifier('MarkdownSFC'),
68+
[],
69+
codeBlock,
70+
);
71+
72+
return generator(types.program([previewFunction]), {}, source).code;
73+
}

scripts/loaders/example/index.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const loaderUtils = require('loader-utils');
2+
const path = require('path')
3+
4+
const markdownCompilerPath = path.resolve(__dirname, './core.js')
5+
6+
module.exports = function mdLoader() {
7+
const filePath = this.resourcePath;
8+
9+
const result =
10+
`module.exports = require(${
11+
loaderUtils.stringifyRequest(
12+
this,
13+
`!babel-loader!${
14+
markdownCompilerPath
15+
}!${
16+
filePath
17+
}${this.resourceQuery || ''}`
18+
)
19+
});`;
20+
21+
return result;
22+
}
23+

scripts/webpack.doc.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const path = require('path');
2-
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
32
const HtmlWebpackPlugin = require('html-webpack-plugin');
43
const webpack = require('webpack');
54

@@ -39,10 +38,14 @@ module.exports = {
3938
oneOf: [
4039
{
4140
resourceQuery: /render/,
42-
use: path.resolve(__dirname, './docs')
41+
use: path.resolve(__dirname, './loaders/example')
4342
},
4443
{
45-
use: ['html-loader', 'markdown-loader']
44+
use: [
45+
'html-loader',
46+
path.resolve(__dirname, './loaders/doc')
47+
// 'markdown-loader'
48+
]
4649
}
4750
]
4851
// use: ['html-loader', 'markdown-loader']
@@ -54,7 +57,7 @@ module.exports = {
5457
]
5558
},
5659
resolve: {
57-
extensions: ['.ts', '.js', '.jsx', '.tsx', '.styl', '.scss', '.css', 'md'],
60+
extensions: ['.ts', '.js', '.jsx', '.tsx', '.styl', '.scss', '.css', '.md', '.yml'],
5861
alias: {
5962
"cube-react": require.resolve('../src/index.ts')
6063
}

0 commit comments

Comments
 (0)