This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

优化markd解析器;代码块支持更多的md语法高亮

old
宇天 2021-05-14 19:04:05 +08:00
parent 1ae0a3b8f7
commit 3c849fd301
3 changed files with 34 additions and 13 deletions

View File

@ -22,9 +22,14 @@ const INLINE = {
strong: [/__([\s\S]*?[^\s\\])__(?!_)/g, /\*\*([\s\S]*?[^\s\\])\*\*(?!\*)/g],
em: [/_([\s\S]*?[^\s\\])_(?!_)/g, /\*([\s\S]*?[^\s\\*])\*(?!\*)/g],
del: /~~([\s\S]*?[^\s\\~])~~/g,
qlinkVar: /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/gm, // 引用声明
qlink: /\[([^\]]*?)\]\[(\d*?)\]/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) {
@ -56,12 +61,23 @@ function rebuild(code) {
export function colorMd(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[1], '[cm]**[/cm]<strong>$1</strong>[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.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.a, (m1, txt, link, m2, attr = '') => {
if (attr) {

View File

@ -32,8 +32,7 @@ const Helper = {
isHr(str) {
var s = str[0]
if (HR_LIST.includes(s)) {
var reg = new RegExp('^\\' + escape(s) + '{3,}$')
return reg.test(str)
return str.slice(0, 3) === s.repeat(3) ? str.slice(3) : false
}
return false
},
@ -119,8 +118,8 @@ const Decoder = {
.replace(ESCAPE_RE, '$1') // 处理转义字符
},
// 分割线
hr() {
return '<fieldset class="md-hr"><legend></legend></fieldset>'
hr(name = '') {
return `<fieldset class="md-hr"><legend name="${name}"></legend></fieldset>`
},
// 标题
head(str) {
@ -227,7 +226,10 @@ class Tool {
} else {
var qlink
if (isCodeBlock) {
it = it.replace(/</g, '&lt;').replace(/>/g, '&gt;')
it = it
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace('\\`\\`\\`', '```')
} else {
it = it
// 非代码块进行xss过滤
@ -243,8 +245,9 @@ class Tool {
}
return `<${name}${attr}>`
})
// 不在代码块中, 才判断引用声明
qlink = Helper.isQLink(it)
}
qlink = Helper.isQLink(it)
if (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
}
@ -347,7 +352,8 @@ class Tool {
it = Decoder.inline.call(this, it)
// 标题只能是单行
var head = Decoder.head(it)
let head = Decoder.head(it)
if (head) {
isParagraph = false
html += head

View File

@ -64,12 +64,11 @@ fieldset.md-hr {
border-top: 1px dashed var(--color-plain-3);
legend {
padding: 0 5px;
color: var(--color-grey-1);
text-align: center;
font-size: 12px;
&::before {
content: '华丽丽的分割线';
content: attr(name);
}
}
}