SOURCE

console 命令行工具 X clear

                    
>
console
index
const { stripScript, stripTemplate, genInlineComponentText } = require('./util')
const md = require('./config')

module.exports = function(source) {
	const content = md.render(source)

	const startTag = '<!--element-demo:'
	const startTagLen = startTag.length
	const endTag = ':element-demo-->'
	const endTagLen = endTag.length

	let componenetsString = ''
	let id = 0 // demo 的 id
	const output = [] // 输出的内容
	let start = 0 // 字符串开始位置

	let commentStart = content.indexOf(startTag)
	let commentEnd = content.indexOf(endTag, commentStart + startTagLen)
	while (commentStart !== -1 && commentEnd !== -1) {
		output.push(content.slice(start, commentStart))

		const commentContent = content.slice(
			commentStart + startTagLen,
			commentEnd
		)
		const html = stripTemplate(commentContent)
		const script = stripScript(commentContent)
		const demoComponentContent = genInlineComponentText(html, script)
		const demoComponentName = `element-demo${id}`
		output.push(
			`<template slot="source"><${demoComponentName} /></template>`
		)
		componenetsString += `${JSON.stringify(
			demoComponentName
		)}: ${demoComponentContent},`

		// 重新计算下一次的位置
		id++
		start = commentEnd + endTagLen
		commentStart = content.indexOf(startTag, start)
		commentEnd = content.indexOf(endTag, commentStart + startTagLen)
	}

	// 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签
	// todo: 优化这段逻辑
	let pageScript = ''
	if (componenetsString) {
		pageScript = `<script>
      export default {
        name: 'component-doc',
        components: {
          ${componenetsString}
        }
      }
    </script>`
	} else if (content.indexOf('<script>') === 0) {
		// 硬编码,有待改善
		start = content.indexOf('</script>') + '</script>'.length
		pageScript = content.slice(0, start)
	}

	output.push(content.slice(start))
	return `
    <template>
      <section class="content gcommon-doc">
        ${output.join('')}
      </section>
    </template>
    ${pageScript}
  `
}
// 
let variables = [
    {
        "key": "name",
        "type": "string",
        "default": "1"
    },
    {
        "key": "obj",
        "type": "object",
        "default": {
            "name": "11"
        }
    },
    {
        "key": "user",
        "type": "object",
        "default": {
            "obj": {
                "age": 20,
                "name": "liwei"
            }
        }
    },
    {
        "key": "list",
        "type": "object",
        "default": []
    }
];

let list = []
variables.forEach(item=>{
    if(isObject(item)) {
        item.prop = item.key;
        objFunc(item.default,item.prop)
    }else {
        list.push(item.key)
    }
})
// container
const mdContainer = require('markdown-it-container')
module.exports = (md) => {
	md.use(mdContainer, 'demo', {
		validate(params) {
			return params.trim().match(/^demo\s*(.*)$/)
		},
		render(tokens, idx) {
			const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/)
			if (tokens[idx].nesting === 1) {
				const description = m && m.length > 1 ? m[1] : ''
				const content =
					tokens[idx + 1].type === 'fence'
						? tokens[idx + 1].content
						: ''
				return `<demo-block>
        ${description ? `<div>${md.render(description)}</div>` : ''}
        <!--element-demo: ${content}:element-demo-->
        `
			}
			return '</demo-block>'
		}
	})

	md.use(mdContainer, 'tip')
	md.use(mdContainer, 'warning')
}
//fence
module.exports = (md) => {
	const defaultRender = md.renderer.rules.fence
	md.renderer.rules.fence = (tokens, idx, options, env, self) => {
		const token = tokens[idx]
		// 判断该 fence 是否在 :::demo 内
		const prevToken = tokens[idx - 1]
		const isInDemoContainer =
			prevToken &&
			prevToken.nesting === 1 &&
			prevToken.info.trim().match(/^demo\s*(.*)$/)
		if (token.info === 'html' && isInDemoContainer) {
			console.log(token.content)
			return `<template slot="highlight"><pre v-pre><code class="html">${md.utils.escapeHtml(
				token.content
			)}</code></pre></template>`
		}
		return defaultRender(tokens, idx, options, env, self)
	}
}
//
function objFunc(item,prop) {
    console.log(prop)
    for(key in item) {
        if(isObject2(item[key])) {
            console.log(item[key],'3')
            console.log(key,'yyy')
            item[prop] = prop+'.'+key
            objFunc(item[key],item[prop])
        }else {
            console.log(item[key],'4')
            item.prop = prop + '.'+ key;
            console.log(item.prop)
            list.push(item.prop)
        }
    }
}

function isObject2(value) {
     return value !== null && typeof(value) == 'object'&& !(value instanceof Array);
}

 function isObject(obj) {
     return obj.default !== null && obj.type == 'object'&& !(obj.default instanceof Array);
 }



 //config
const Config = require('markdown-it-chain')
const anchorPlugin = require('markdown-it-anchor')
const slugify = require('transliteration').slugify
const containers = require('./containers')
const overWriteFenceRule = require('./fence')

const config = new Config()

config.options
	.html(true)
	.end()
	.plugin('anchor')
	.use(anchorPlugin, [
		{
			level: 2,
			slugify: slugify,
			permalink: true,
			permalinkBefore: true
		}
	])
	.end()
	.plugin('containers')
	.use(containers)
	.end()

const md = config.toMd()
overWriteFenceRule(md)

module.exports = md
//uitls
const { compileTemplate } = require('@vue/component-compiler-utils')
const compiler = require('vue-template-compiler')

function stripScript(content) {
	const result = content.match(/<(script)>([\s\S]+)<\/\1>/)
	return result && result[2] ? result[2].trim() : ''
}

function stripStyle(content) {
	const result = content.match(/<(style)\s*>([\s\S]+)<\/\1>/)
	return result && result[2] ? result[2].trim() : ''
}

// 编写例子时不一定有 template。所以采取的方案是剔除其他的内容
function stripTemplate(content) {
	content = content.trim()
	if (!content) {
		return content
	}
	return content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim()
}

function pad(source) {
	return source.split(/\r?\n/).map((line) => `  ${line}`).join('\n')
}

function genInlineComponentText(template, script) {
	// https://github.com/vuejs/vue-loader/blob/423b8341ab368c2117931e909e2da9af74503635/lib/loaders/templateLoader.js#L46
	const finalOptions = {
		source: `<div>${template}</div>`,
		filename: 'inline-component', // TODO:这里有待调整
		compiler
	}
	const compiled = compileTemplate(finalOptions)
	// tips
	if (compiled.tips && compiled.tips.length) {
		compiled.tips.forEach((tip) => {
			console.warn(tip)
		})
	}
	// errors
	if (compiled.errors && compiled.errors.length) {
		console.error(
			`\n  Error compiling template:\n${pad(compiled.source)}\n` +
				compiled.errors.map((e) => `  - ${e}`).join('\n') +
				'\n'
		)
	}
	let demoComponentContent = `
    ${compiled.code}
  `
	// todo: 这里采用了硬编码有待改进
	script = script.trim()
	if (script) {
		script = script.replace(
			/export\s+default/,
			'const democomponentExport ='
		)
	} else {
		script = 'const democomponentExport = {}'
	}
	demoComponentContent = `(function() {
    ${demoComponentContent}
    ${script}
    return {
      render,
      staticRenderFns,
      ...democomponentExport
    }
  })()`
	return demoComponentContent
}

module.exports = {
	stripScript,
	stripStyle,
	stripTemplate,
	genInlineComponentText
}