前言
在 Element Plus 上看一个关于 docs 优化的 issue ,试着把它实现下。
问题-关键
问题:组件库官网在介绍组件时会实现相关示例和注意事项,同时也会列举组件 API 来提供给开发者使用,想要的效果是能不能自动实现从组件 API 跳转至相关的示例?
关键:示例在说明时会加上使用到的 API,这个就是核心,组件 API 和示例产生纽带的关键。
实现
Element Plus 官网 docs 使用第三库 markdown-it 解析 md 文档,以下简单通过插件实现跳转功能。
import type MarkdownIt from 'markdown-it'
const rControl = /[\u0000-\u001F]/g
const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g
const rCombining = /[\u0300-\u036F]/g
// 处理示例标题的方法
function slugify(str: string): string {
return (
str
.normalize('NFKD')
.replace(rCombining, '')
.replace(rControl, '')
.replace(rSpecial, '-')
.replace(/-{2,}/g, '-')
.replace(/^-+|-+$/g, '')
.replace(/^(\d)/, '_$1')
.toLowerCase()
)
}
export default (md: MarkdownIt) => {
// 匹配到对应的规则时替换为 a 标签通过锚点跳转
md.renderer.rules.api = (tokens, idx) => {
const { content, info } = tokens[idx]
return `<a href="#${info}">${content}</a>`
}
// add api rluer
md.core.ruler.push('api', (state) => {
const head: string[] = [],
description: string[][] = [],
map = {}
for (let i = 0; i < state.tokens.length; i++) {
const { type, tag, info } = state.tokens[i]
// 收集示例标题
if (type === 'heading_open' && tag === 'h2') {
const { content } = state.tokens[i + 1]
if (content.endsWith('API')) break
head.push(slugify(content))
}
// 收集描述关键字
if (type === 'container_demo_open' && info.startsWith('demo')) {
const matchArr = info.match(/`[a-zA-Z-]+`/g)
let res: string[] = []
if (matchArr && matchArr.length > 0) {
res = matchArr.map((item) => item.slice(1, -1))
}
description.push(res)
}
for (const [idx, item] of description.entries()) {
map[head[idx]] = item
}
}
// 收集示例标题和描述关键字建立为对象结构
for (const [idx, item] of description.entries()) {
map[head[idx]] = item
}
for (let j = 0; j < state.tokens.length; j++) {
const { type } = state.tokens[j]
if (type === 'tr_open' && state.tokens[j + 2]['content'] !== 'Name') {
let { content, children } = state.tokens[j + 2]
if (content.includes('`')) {
content = content.slice(1, -1)
}
for (const key in map) {
if (map[key].includes(content) && children) {
children.length = 0
children.push({
type: 'api',
content,
info: key,
} as any)
}
}
}
}
})
}
问题
- 表格第一列的参数超过一个的问题;
- 相关描述关键字有重复,导致跳转位置在最后一个;
Attributes、Events、Slots等有重复属性问题;
解决方法:在组件属性上用标识符。
如果需要新增标识符的话,想到了一种半自动的解决方案:在需要跳转的属性上加上标识符来指定跳转的位置,这样更容易开发者理解。
希望可以给大家带来一些思考。