feat(vant-markdown-loader): rEADME 中引入 demo 组件时支持设置 playground 属性

This commit is contained in:
HaoChuan9421 2021-03-12 18:01:24 +08:00
parent c2ac641ec1
commit 336727556e
3 changed files with 40 additions and 29 deletions

View File

@ -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>
`;
} }
); );

View File

@ -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();

View 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;