优化markdown解析

master
yutent 2023-04-24 10:28:09 +08:00
parent fa19555622
commit 856d23c8e5
1 changed files with 60 additions and 40 deletions

View File

@ -152,7 +152,7 @@ const Decoder = {
var stat = todoChecked === 1 ? 'checked' : '' var stat = todoChecked === 1 ? 'checked' : ''
var txt = todoChecked === 1 ? `<del>${word}</del>` : word var txt = todoChecked === 1 ? `<del>${word}</del>` : word
return `\n<section><wc-checkbox readonly ${stat}>${txt}</wc-checkbox></section>\n` return `\n<section><wc-checkbox readonly ${stat}>${txt}</wc-checkbox></section>`
} }
return false return false
} }
@ -194,7 +194,7 @@ class Tool {
emptyLineLength = 0 emptyLineLength = 0
if (tmp.startsWith('```')) { if (tmp.startsWith('```')) {
if (isCodeBlock) { if (isCodeBlock) {
list.push('\n</xmp></wc-code>\n\n') list.push('\n</xmp></wc-code>\n')
} else { } else {
list.push( list.push(
tmp.replace(/^```([\w\#\-]*?)$/, `\n<wc-code lang="$1"><xmp>`) tmp.replace(/^```([\w\#\-]*?)$/, `\n<wc-code lang="$1"><xmp>`)
@ -265,22 +265,22 @@ class Tool {
} }
parse() { parse() {
var html = '' let html = ''
var isCodeBlock = false // 是否代码块 let isCodeBlock = false // 是否代码块
var emptyLineLength = 0 //连续空行的数量 let emptyLineLength = 0 //连续空行的数量
var isBlockquote = false let isBlockquote = false
var isTable = false let isTable = false
var tableAlign = null let tableAlign = null
var blockquoteLevel = 0 let blockquoteLevel = 0
var isParagraph = false let isParagraph = false
var isList = false let isList = false
var orderListLevel = -1 let orderListLevel = -1
var unorderListLevel = -1 let unorderListLevel = -1
var isQuoteList = false // 引用中的列表, 只支持一层级 let isQuoteList = false // 引用中的列表, 只支持一层级
var quoteListStyle = 0 // 1有序, 2 无序 let quoteListStyle = 0 // 1有序, 2 无序
var isHtmlBlock = false // 是否原生html代码块 let isHtmlBlock = false // 是否原生html代码块
// //
for (let it of this.list) { for (let it of this.list) {
@ -350,6 +350,11 @@ class Tool {
continue continue
} }
// 处理常规样式之前, 先判断是否为原生html文本
// 避免处理完常规样式之后生成的html干扰结果
let isSingleLineHtml = SINGLE_LINE_HTML_RE.test(it)
let isMultiLineHtml = !isSingleLineHtml && MULTI_LINE_HTML_RE.test(it)
// 优先处理一些常规样式 // 优先处理一些常规样式
it = Decoder.inline.call(this, it) it = Decoder.inline.call(this, it)
@ -358,10 +363,24 @@ class Tool {
let head = Decoder.head(it) let head = Decoder.head(it)
if (head) { if (head) {
html = trimBr(html) html = trimBr(html)
// 有段落先结束
if (isParagraph) { if (isParagraph) {
isParagraph = false isParagraph = false
html += '</p>' html += '</p>'
} }
// 有列表也先结束
if (isList) {
while (orderListLevel > -1 || unorderListLevel > -1) {
if (orderListLevel > unorderListLevel) {
html += '</ol>\n'
orderListLevel--
} else {
html += '</ul>\n'
unorderListLevel--
}
}
isList = false
}
html += head html += head
continue continue
@ -450,39 +469,40 @@ class Tool {
let tmp = Helper.ltrim(it) let tmp = Helper.ltrim(it)
let ltrim = it.length - tmp.length let ltrim = it.length - tmp.length
let word = tmp.replace(LIST_RE, '').trim() let word = tmp.replace(LIST_RE, '').trim()
let level = Math.floor(ltrim / 2) let level = Math.floor(ltrim / 2) //缩进级别
let tag = listChecked > 0 ? 'ol' : 'ul' let tag = listChecked === 1 ? 'ol' : 'ul'
if (isList) { if (isList) {
if (listChecked === 1) { let _level = listChecked === 1 ? orderListLevel : unorderListLevel
if (level > orderListLevel) {
html = html.replace(/<\/li>$/, '') // 大于上一个缩进
html += `<${tag}><li>${word}</li>` if (level > _level) {
} else if (level === orderListLevel) { // 需要先把上一个列表的结束符去掉
html += `<li>${word}</li>` html = html.trim().replace(/<\/li>$/, '')
} else { html += `\n<${tag}>\n<li>${word}</li>\n`
html += `</${tag}></li><li>${word}</li>`
} }
orderListLevel = level // 跟上一个平级
} else { else if (level === _level) {
if (level > unorderListLevel) { html += `<li>${word}</li>\n`
html = html.replace(/<\/li>$/, '')
html += `<${tag}><li>${word}</li>`
} else if (level === unorderListLevel) {
html += `<li>${word}</li>`
} else {
html += `</${tag}></li><li>${word}</li>`
} }
unorderListLevel = level // 比上一个缩进要小
else {
html += `</${tag}>\n</li>\n<li>${word}</li>\n`
} }
} else {
html += `<${tag}>`
if (listChecked === 1) { if (listChecked === 1) {
orderListLevel = level orderListLevel = level
} else { } else {
unorderListLevel = level unorderListLevel = level
} }
html += `<li>${word}</li>` } else {
html += `<${tag}>\n`
if (listChecked === 1) {
orderListLevel = level
} else {
unorderListLevel = level
}
html += `<li>${word}</li>\n`
} }
isList = true isList = true
@ -503,13 +523,13 @@ class Tool {
if (isParagraph) { if (isParagraph) {
html += `${it}\n` html += `${it}\n`
} else { } else {
if (isHtmlBlock || SINGLE_LINE_HTML_RE.test(it)) { if (isHtmlBlock || isSingleLineHtml) {
html += `${it}\n` html += `${it}\n`
} else if (MULTI_LINE_HTML_RE.test(it)) { } else if (isMultiLineHtml) {
isHtmlBlock = !isHtmlBlock isHtmlBlock = !isHtmlBlock
html += `${it}\n` html += `${it}\n`
} else { } else {
html += `\n<p>\n${it}` html += `\n<p>${it}`
isParagraph = true isParagraph = true
} }
} }
@ -556,7 +576,7 @@ class Tool {
emptyLineLength = 0 emptyLineLength = 0
isParagraph = false isParagraph = false
html = trimBr(html) html = trimBr(html)
html += '\n</p>\n' html += '</p>\n'
} else { } else {
html += '<br>' html += '<br>'
} }