createSidebar.js 2.4 KB
Newer Older
D
DCloud_LXH 已提交
1 2
const fs = require('fs')
const path = require('path')
D
DCloud_LXH 已提交
3 4
const MarkdownIt = require('markdown-it')
const glob = require('glob')
D
DCloud_LXH 已提交
5 6
const createMarkdownArray = require('./createMarkdownArray')
const { isExternal } = require('../utils')
D
DCloud_LXH 已提交
7
const createSiteMap = require('./createSiteMap')
D
DCloud_LXH 已提交
8 9 10 11

const links = []

function parseBar(tab, file, options) {
D
DCloud_LXH 已提交
12 13 14
	const textName = options.text || 'text'
	const linkName = options.link || 'link'
	const contents = []
D
DCloud_LXH 已提交
15

16
	new MarkdownIt().parse(fs.readFileSync(file, { encoding: 'utf-8' }).replace(/<!--([\s\S]*?)-->/g, '').replace(/\t/g, '  ')).forEach(token => {
D
DCloud_LXH 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
		if (token.type === 'inline') {
			let text
			let link
			let config = {}
			token.children.forEach(child => {
				switch (child.type) {
					case 'text':
						text = text || child.content
						break
					case 'link_open':
						link = link || new Map(child.attrs).get('href')
						break
					case 'code_inline':
						try {
							config = JSON.parse(child.content)
						} catch (error) {}
						break
D
DCloud_LXH 已提交
34

D
DCloud_LXH 已提交
35 36 37 38
					default:
						break
				}
			})
D
DCloud_LXH 已提交
39

D
DCloud_LXH 已提交
40 41 42 43 44 45 46
			if (link && !isExternal(link)) {
				if (!link.startsWith('/')) {
					const linkFirstItem = link.split('/')[0]
					if (tab.indexOf(linkFirstItem) === -1) {
						link = path.join(tab, link).replace(/\\/g, '/')
					}
				}
D
DCloud_LXH 已提交
47

D
DCloud_LXH 已提交
48 49 50 51 52 53 54 55 56 57
				link = path
					.join(
						'/',
						link
							.replace(/\.md\b/, '')
							.replace(/\bREADME\b/, '')
							.replace(/\/index/, '/')
							.replace(/\?id=/, '#')
					)
					.replace(/\\/g, '/')
D
DCloud_LXH 已提交
58

D
DCloud_LXH 已提交
59 60
				links.push(link)
			}
D
DCloud_LXH 已提交
61

D
DCloud_LXH 已提交
62 63 64 65 66 67 68 69
			contents.push({
				level: token.level,
				[textName]: text,
				[linkName]: link,
				...config,
			})
		}
	})
D
DCloud_LXH 已提交
70

D
DCloud_LXH 已提交
71
	return createMarkdownArray(contents, options.children)
D
DCloud_LXH 已提交
72 73
}

D
DCloud_LXH 已提交
74 75
module.exports = function () {
	const sidebar = {}
D
DCloud_LXH 已提交
76

D
DCloud_LXH 已提交
77 78 79 80 81 82 83 84
	// 需要反向,vuepress 在匹配路由的时候,会按照数组的顺序匹配,所以需要将最长的路径放在最前面,否则 / 路径会第一个被匹配,导致右侧栏不跟随路由变化
	const tabs = glob
		.GlobSync(path.resolve(__dirname, '../../**/_sidebar.md'))
		.found.map(file => {
			const tab = file.match(/\/docs([\s\S]+)_sidebar.md/)[1]
			return tab
		})
		.reverse()
D
DCloud_LXH 已提交
85

D
DCloud_LXH 已提交
86 87 88 89 90 91
	;(process.env.DOCS_LITE ? [] : tabs).forEach(tab => {
		sidebar[tab] = parseBar(tab, path.join(__dirname, '../../', tab, '_sidebar.md'), {
			text: 'title',
			link: 'path',
		})
	})
D
DCloud_LXH 已提交
92

D
DCloud_LXH 已提交
93 94 95 96
	createSiteMap(links, () => (links.length = 0))

	return tabs.length ? sidebar : false
}