mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-21 22:09:16 +08:00
feat(vant-markdown-loader): rEADME 中引入 demo 组件时支持设置 playground 属性
This commit is contained in:
parent
c2ac641ec1
commit
336727556e
@ -1,22 +1,33 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const parser = require('./md-parser');
|
||||||
|
|
||||||
|
function hyphenate(str) {
|
||||||
|
return str.replace(/\B([A-Z])/g, '-$1').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = function extraDemo(content) {
|
module.exports = function extraDemo(content) {
|
||||||
|
const markdownDir = path.dirname(this.resourcePath);
|
||||||
const demoLinks = [];
|
const demoLinks = [];
|
||||||
|
|
||||||
/*
|
|
||||||
* 提取 README 中的 demo 文件路径,例如下面的内容,就会提取为 ['./demo-link/index.vue']
|
|
||||||
* ```demo
|
|
||||||
* ./demo-link/index.vue
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
content = content.replace(
|
content = content.replace(
|
||||||
/<pre><code class="language-demo">([\s\S]*?)<\/code><\/pre>/g,
|
/<demo-code([\s\S]*?)>([\s\S]*?)<\/demo-code>/g,
|
||||||
function (_, link) {
|
function (_, attrs, link) {
|
||||||
link = link.trim(); // 去换行符
|
link = link.trim(); // 去换行符
|
||||||
demoLinks.push(link);
|
const tag = hyphenate(path.basename(link, '.vue'));
|
||||||
const demoFileName = path.basename(link, '.vue'); // 获取文件名
|
const fullLink = path.join(markdownDir, link);
|
||||||
const tag = demoFileName.replace(/\B([A-Z])/g, '-$1').toLowerCase(); // 驼峰转连字符
|
demoLinks.indexOf(fullLink) === -1 && demoLinks.push(fullLink);
|
||||||
return `<${tag} />`;
|
const demoContent = fs.readFileSync(fullLink, { encoding: 'utf8' });
|
||||||
|
const demoParseredContent = parser.render(
|
||||||
|
'```html\n' + demoContent + '\n```'
|
||||||
|
);
|
||||||
|
return `
|
||||||
|
<demo-playground${attrs}
|
||||||
|
origin-code="${escape(demoContent)}"
|
||||||
|
code-snippet="${escape(demoParseredContent)}">
|
||||||
|
<${tag} />
|
||||||
|
</demo-playground>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,24 +1,20 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const loaderUtils = require('loader-utils');
|
const loaderUtils = require('loader-utils');
|
||||||
const MarkdownIt = require('markdown-it');
|
|
||||||
const markdownItAnchor = require('markdown-it-anchor');
|
|
||||||
const frontMatter = require('front-matter');
|
const frontMatter = require('front-matter');
|
||||||
const highlight = require('./highlight');
|
const parser = require('./md-parser');
|
||||||
const linkOpen = require('./link-open');
|
const linkOpen = require('./link-open');
|
||||||
const cardWrapper = require('./card-wrapper');
|
const cardWrapper = require('./card-wrapper');
|
||||||
const extractDemo = require('./extract-demo');
|
const extractDemo = require('./extract-demo');
|
||||||
const sideEffectTags = require('./side-effect-tags');
|
const sideEffectTags = require('./side-effect-tags');
|
||||||
const { slugify } = require('transliteration');
|
|
||||||
|
|
||||||
function camelize(str) {
|
function camelize(str) {
|
||||||
return str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''));
|
return str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
function wrapper(content) {
|
function wrapper(content) {
|
||||||
const markdownDir = path.dirname(this.resourcePath);
|
|
||||||
let demoLinks;
|
let demoLinks;
|
||||||
let styles;
|
let styles;
|
||||||
[content, demoLinks] = extractDemo(content);
|
[content, demoLinks] = extractDemo.call(this, content);
|
||||||
[content, styles] = sideEffectTags(content);
|
[content, styles] = sideEffectTags(content);
|
||||||
content = cardWrapper(content);
|
content = cardWrapper(content);
|
||||||
return `
|
return `
|
||||||
@ -31,9 +27,7 @@ function wrapper(content) {
|
|||||||
<script>
|
<script>
|
||||||
${demoLinks
|
${demoLinks
|
||||||
.map((link) => {
|
.map((link) => {
|
||||||
const absPath = path.join(markdownDir, link); // 获取 demo 文件的完整路径
|
return `import ${camelize(path.basename(link, '.vue'))} from '${link}';`;
|
||||||
const demoFileName = path.basename(link, '.vue');
|
|
||||||
return `import ${camelize(demoFileName)} from '${absPath}';`;
|
|
||||||
})
|
})
|
||||||
.join('\n')}
|
.join('\n')}
|
||||||
|
|
||||||
@ -67,14 +61,6 @@ ${styles.join('\n')}
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parser = new MarkdownIt({
|
|
||||||
html: true,
|
|
||||||
highlight,
|
|
||||||
}).use(markdownItAnchor, {
|
|
||||||
level: 2,
|
|
||||||
slugify,
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = function (source) {
|
module.exports = function (source) {
|
||||||
let options = loaderUtils.getOptions(this) || {};
|
let options = loaderUtils.getOptions(this) || {};
|
||||||
this.cacheable && this.cacheable();
|
this.cacheable && this.cacheable();
|
||||||
|
14
packages/vant-markdown-loader/src/md-parser.js
Normal file
14
packages/vant-markdown-loader/src/md-parser.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const MarkdownIt = require('markdown-it');
|
||||||
|
const markdownItAnchor = require('markdown-it-anchor');
|
||||||
|
const highlight = require('./highlight');
|
||||||
|
const { slugify } = require('transliteration');
|
||||||
|
|
||||||
|
const parser = new MarkdownIt({
|
||||||
|
html: true,
|
||||||
|
highlight,
|
||||||
|
}).use(markdownItAnchor, {
|
||||||
|
level: 2,
|
||||||
|
slugify,
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = parser;
|
Loading…
x
Reference in New Issue
Block a user