naive-ui/build/loaders/convert-md-to-demo.js

177 lines
4.4 KiB
JavaScript
Raw Normal View History

2019-09-17 19:24:39 +08:00
const marked = require('marked')
const fs = require('fs')
const path = require('path')
const createRenderer = require('./md-renderer')
2019-12-22 23:19:08 +08:00
const mdRenderer = createRenderer()
const codeRenderer = createRenderer(false)
// const prettier = require('prettier')
2019-09-17 19:24:39 +08:00
2020-12-16 02:16:59 +08:00
const demoBlock = fs
.readFileSync(path.resolve(__dirname, 'ComponentDemoTemplate.vue'))
.toString()
2019-09-17 19:24:39 +08:00
function getPartsOfDemo (tokens) {
let template = null
let script = null
let style = null
let title = null
2019-10-30 16:22:49 +08:00
// let content = null
const contentTokens = []
contentTokens.links = tokens.links
2019-09-17 19:24:39 +08:00
for (const token of tokens) {
if (token.type === 'heading' && token.depth === 1) {
title = token.text
2020-12-16 02:16:59 +08:00
} else if (
token.type === 'code' &&
(token.lang === 'template' || token.lang === 'html')
) {
2019-09-17 19:24:39 +08:00
template = token.text
2020-12-16 02:16:59 +08:00
} else if (
token.type === 'code' &&
(token.lang === 'script' || token.lang === 'js')
) {
2019-09-17 19:24:39 +08:00
script = token.text
2020-12-16 02:16:59 +08:00
} else if (
token.type === 'code' &&
(token.lang === 'style' || token.lang === 'css')
) {
2019-09-17 19:24:39 +08:00
style = token.text
2019-10-30 16:22:49 +08:00
} else {
contentTokens.push(token)
2019-09-17 19:24:39 +08:00
}
}
return {
2019-09-20 00:23:21 +08:00
template: template,
script: script,
style: style,
title: title,
content: marked.parser(contentTokens, {
renderer: mdRenderer
})
2019-09-17 19:24:39 +08:00
}
}
function mergeParts (parts) {
const mergedParts = {
...parts
}
mergedParts.title = parts.title
mergedParts.content = parts.content
2019-09-17 19:24:39 +08:00
mergedParts.code = ''
2019-09-20 00:23:21 +08:00
// console.log(parts)
2019-09-17 19:24:39 +08:00
if (parts.template) {
mergedParts.code += parts.template
}
if (parts.script) {
if (parts.template) mergedParts.code += '\n\n'
mergedParts.code += `<script>
${parts.script}
</script>`
}
if (parts.style) {
2019-09-20 00:33:13 +08:00
if (parts.template || parts.script) mergedParts.code += '\n\n'
2019-09-17 19:24:39 +08:00
mergedParts.code += `<style>
${parts.style}
</style>`
}
2020-12-16 02:16:59 +08:00
mergedParts.code = marked(
`\`\`\`html
2019-09-17 19:24:39 +08:00
${mergedParts.code}
2020-12-16 02:16:59 +08:00
\`\`\``,
{
renderer: codeRenderer
}
)
2019-09-17 19:24:39 +08:00
// console.log(mergedParts.code)
return mergedParts
}
2020-12-16 02:16:59 +08:00
const cssRuleRegex = /[^{\n]*\{[^}]*\}/g
// simulate scss style
// to remove dep of sass
// xxx {
// mystyle
// }
function genStyle (sourceStyle) {
const rules = sourceStyle.match(cssRuleRegex)
if (rules === null) return null
return (
'<style scoped>\n' +
rules
.map((rule) => {
return `.demo-card__view ${rule}
.naive-ui-doc ${rule}`
})
.join('\n') +
'</style>'
)
}
2020-09-04 01:06:39 +08:00
function genVueComponent (parts, fileName, relativeUrl, noRunning = false) {
const demoFileNameReg = /<!--DEMO_FILE_NAME-->/g
2020-09-04 01:06:39 +08:00
const relativeUrlReg = /<!--URL-->/g
const titleReg = /<!--TITLE_SLOT-->/g
2019-09-17 19:24:39 +08:00
const contentReg = /<!--CONTENT_SLOT-->/
const codeReg = /<!--CODE_SLOT-->/
const scriptReg = /<!--SCRIPT_SLOT-->/
2020-12-16 02:16:59 +08:00
const styleReg = /<!--STYLE_SLOT-->/
2019-09-17 19:24:39 +08:00
const demoReg = /<!--DEMO_SLOT-->/
let src = demoBlock
2020-09-03 23:40:38 +08:00
src = src.replace(demoFileNameReg, fileName)
2020-09-04 01:06:39 +08:00
src = src.replace(relativeUrlReg, relativeUrl)
2019-09-20 00:23:21 +08:00
if (parts.content) {
src = src.replace(contentReg, parts.content)
}
if (parts.title) {
src = src.replace(titleReg, parts.title)
}
if (parts.code) {
src = src.replace(codeReg, parts.code)
}
2019-12-13 23:55:19 +08:00
if (parts.script && !noRunning) {
src = src.replace(scriptReg, '<script>\n' + parts.script + '\n</script>')
2019-09-20 00:23:21 +08:00
}
if (parts.style) {
2020-12-16 02:16:59 +08:00
const style = genStyle(parts.style)
if (style !== null) {
src = src.replace(styleReg, style)
}
2019-09-20 00:23:21 +08:00
}
if (parts.template) {
src = src.replace(demoReg, parts.template)
}
return src.trim()
2019-09-17 19:24:39 +08:00
}
function getFileName (resourcePath) {
const dirs = resourcePath.split('/')
const fileNameWithExtension = dirs[dirs.length - 1]
2020-09-03 23:40:38 +08:00
return [fileNameWithExtension.split('.')[0], fileNameWithExtension]
}
2020-12-16 02:16:59 +08:00
function convertMd2Demo (text, { resourcePath, relativeUrl }) {
2019-12-13 23:55:19 +08:00
const noRunning = /<!--no-running-->/.test(text)
2019-09-17 19:24:39 +08:00
const tokens = marked.lexer(text)
const parts = getPartsOfDemo(tokens)
const mergedParts = mergeParts(parts)
2020-09-04 01:06:39 +08:00
const [fileName] = getFileName(resourcePath)
2020-12-16 02:16:59 +08:00
const vueComponent = genVueComponent(
mergedParts,
fileName,
relativeUrl,
noRunning
)
2019-09-17 19:24:39 +08:00
return vueComponent
}
module.exports = convertMd2Demo
2019-09-18 00:02:57 +08:00
// const startTime = new Date()
// for (let i = 0; i < 100; ++i) {
2019-10-30 16:22:49 +08:00
// const md = fs.readFileSync('./demo/documentation/components/input/enUS/lazyFocus.md').toString()
2019-09-20 00:23:21 +08:00
// convertMd2Demo(md)
2019-09-18 00:02:57 +08:00
// }
// const endTime = new Date()
// console.log(endTime - startTime)