优化markd解析器;代码块支持更多的md语法高亮
parent
1ae0a3b8f7
commit
3c849fd301
|
@ -22,9 +22,14 @@ const INLINE = {
|
||||||
strong: [/__([\s\S]*?[^\s\\])__(?!_)/g, /\*\*([\s\S]*?[^\s\\])\*\*(?!\*)/g],
|
strong: [/__([\s\S]*?[^\s\\])__(?!_)/g, /\*\*([\s\S]*?[^\s\\])\*\*(?!\*)/g],
|
||||||
em: [/_([\s\S]*?[^\s\\])_(?!_)/g, /\*([\s\S]*?[^\s\\*])\*(?!\*)/g],
|
em: [/_([\s\S]*?[^\s\\])_(?!_)/g, /\*([\s\S]*?[^\s\\*])\*(?!\*)/g],
|
||||||
del: /~~([\s\S]*?[^\s\\~])~~/g,
|
del: /~~([\s\S]*?[^\s\\~])~~/g,
|
||||||
|
qlinkVar: /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/gm, // 引用声明
|
||||||
qlink: /\[([^\]]*?)\]\[(\d*?)\]/g, // 引用链接
|
qlink: /\[([^\]]*?)\]\[(\d*?)\]/g, // 引用链接
|
||||||
img: /\!\[([^\]]*?)\]\(([^)]*?)\)/g,
|
img: /\!\[([^\]]*?)\]\(([^)]*?)\)/g,
|
||||||
a: /\[([^\]]*?)\]\(([^)]*?)(\s+"([\s\S]*?)")*?\)/g
|
a: /\[([^\]]*?)\]\(([^)]*?)(\s+"([\s\S]*?)")*?\)/g,
|
||||||
|
head: /^(#{1,6} )(.*)$/gm,
|
||||||
|
quote: /^(>{1,} )(.*)$/gm,
|
||||||
|
task: /^([\-\+\*]) \[( |x)\] (.*)$/gm,
|
||||||
|
list: /^([ \t]*?([\-\+\*]|\d+\.) )(.*)$/gm
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseJs(code) {
|
function parseJs(code) {
|
||||||
|
@ -56,12 +61,23 @@ function rebuild(code) {
|
||||||
|
|
||||||
export function colorMd(code) {
|
export function colorMd(code) {
|
||||||
code = code
|
code = code
|
||||||
|
.replace(INLINE.head, '[cm]$1[/cm][tag]<strong>$2</strong>[/tag]')
|
||||||
|
.replace(INLINE.quote, '[cm]$1[/cm]<em>$2</em>')
|
||||||
|
.replace(
|
||||||
|
INLINE.task,
|
||||||
|
'[cm]$1 [[/cm][attr]$2[/attr][cm]][/cm] <strong>$3</strong>'
|
||||||
|
)
|
||||||
|
.replace(INLINE.list, '[cm]$1[/cm]<strong>$3</strong>')
|
||||||
.replace(INLINE.strong[0], '[cm]__[/cm]<strong>$1</strong>[cm]__[/cm]')
|
.replace(INLINE.strong[0], '[cm]__[/cm]<strong>$1</strong>[cm]__[/cm]')
|
||||||
.replace(INLINE.strong[1], '[cm]**[/cm]<strong>$1</strong>[cm]**[/cm]')
|
.replace(INLINE.strong[1], '[cm]**[/cm]<strong>$1</strong>[cm]**[/cm]')
|
||||||
.replace(INLINE.em[0], '[cm]_[/cm]<em>$1</em>[cm]_[/cm]')
|
.replace(INLINE.em[0], '[cm]_[/cm]<em>$1</em>[cm]_[/cm]')
|
||||||
.replace(INLINE.em[1], '[cm]*[/cm]<em>$1</em>[cm]*[/cm]')
|
.replace(INLINE.em[1], '[cm]*[/cm]<em>$1</em>[cm]*[/cm]')
|
||||||
.replace(INLINE.del, '[cm]~~[/cm]<del>$1</del>[cm]~~[/cm]')
|
.replace(INLINE.del, '[cm]~~[/cm]<del>$1</del>[cm]~~[/cm]')
|
||||||
.replace(INLINE.qlink, '[[attr]$1[/attr]]([link]$2[/link])')
|
.replace(
|
||||||
|
INLINE.qlinkVar,
|
||||||
|
'[[attr]$1[/attr]]: [link]$2[/link] [tag]$3[/tag]'
|
||||||
|
)
|
||||||
|
.replace(INLINE.qlink, '[[attr]$1[/attr]][[link]$2[/link]]')
|
||||||
.replace(INLINE.img, '![[attr]$1[/attr]]([link]$2[/link])')
|
.replace(INLINE.img, '![[attr]$1[/attr]]([link]$2[/link])')
|
||||||
.replace(INLINE.a, (m1, txt, link, m2, attr = '') => {
|
.replace(INLINE.a, (m1, txt, link, m2, attr = '') => {
|
||||||
if (attr) {
|
if (attr) {
|
||||||
|
|
|
@ -32,8 +32,7 @@ const Helper = {
|
||||||
isHr(str) {
|
isHr(str) {
|
||||||
var s = str[0]
|
var s = str[0]
|
||||||
if (HR_LIST.includes(s)) {
|
if (HR_LIST.includes(s)) {
|
||||||
var reg = new RegExp('^\\' + escape(s) + '{3,}$')
|
return str.slice(0, 3) === s.repeat(3) ? str.slice(3) : false
|
||||||
return reg.test(str)
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
@ -119,8 +118,8 @@ const Decoder = {
|
||||||
.replace(ESCAPE_RE, '$1') // 处理转义字符
|
.replace(ESCAPE_RE, '$1') // 处理转义字符
|
||||||
},
|
},
|
||||||
// 分割线
|
// 分割线
|
||||||
hr() {
|
hr(name = '') {
|
||||||
return '<fieldset class="md-hr"><legend></legend></fieldset>'
|
return `<fieldset class="md-hr"><legend name="${name}"></legend></fieldset>`
|
||||||
},
|
},
|
||||||
// 标题
|
// 标题
|
||||||
head(str) {
|
head(str) {
|
||||||
|
@ -227,7 +226,10 @@ class Tool {
|
||||||
} else {
|
} else {
|
||||||
var qlink
|
var qlink
|
||||||
if (isCodeBlock) {
|
if (isCodeBlock) {
|
||||||
it = it.replace(/</g, '<').replace(/>/g, '>')
|
it = it
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace('\\`\\`\\`', '```')
|
||||||
} else {
|
} else {
|
||||||
it = it
|
it = it
|
||||||
// 非代码块进行xss过滤
|
// 非代码块进行xss过滤
|
||||||
|
@ -243,8 +245,9 @@ class Tool {
|
||||||
}
|
}
|
||||||
return `<${name}${attr}>`
|
return `<${name}${attr}>`
|
||||||
})
|
})
|
||||||
}
|
// 不在代码块中, 才判断引用声明
|
||||||
qlink = Helper.isQLink(it)
|
qlink = Helper.isQLink(it)
|
||||||
|
}
|
||||||
|
|
||||||
if (qlink) {
|
if (qlink) {
|
||||||
Object.assign(links, qlink)
|
Object.assign(links, qlink)
|
||||||
|
@ -338,8 +341,10 @@ class Tool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 无属性标签
|
// 无属性标签
|
||||||
if (Helper.isHr(it)) {
|
|
||||||
html += Decoder.hr()
|
let hrName = Helper.isHr(it)
|
||||||
|
if (typeof hrName === 'string') {
|
||||||
|
html += Decoder.hr(hrName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +352,8 @@ class Tool {
|
||||||
it = Decoder.inline.call(this, it)
|
it = Decoder.inline.call(this, it)
|
||||||
|
|
||||||
// 标题只能是单行
|
// 标题只能是单行
|
||||||
var head = Decoder.head(it)
|
|
||||||
|
let head = Decoder.head(it)
|
||||||
if (head) {
|
if (head) {
|
||||||
isParagraph = false
|
isParagraph = false
|
||||||
html += head
|
html += head
|
||||||
|
|
|
@ -64,12 +64,11 @@ fieldset.md-hr {
|
||||||
border-top: 1px dashed var(--color-plain-3);
|
border-top: 1px dashed var(--color-plain-3);
|
||||||
|
|
||||||
legend {
|
legend {
|
||||||
padding: 0 5px;
|
|
||||||
color: var(--color-grey-1);
|
color: var(--color-grey-1);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
&::before {
|
&::before {
|
||||||
content: '华丽丽的分割线';
|
content: attr(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue