mark解析器优化

master
yutent 2023-09-28 18:21:19 +08:00
parent 12630d66c0
commit 09356d0d92
3 changed files with 112 additions and 83 deletions

View File

@ -23,7 +23,7 @@ class Code extends Component {
default: '',
attribute: false,
observer(v) {
this.setCode(v.trim())
this.setCode(v)
}
},
lang: ''
@ -232,11 +232,11 @@ class Code extends Component {
txt = txt.trim().replace(/^[\r\n]|\s{2,}$/g, '')
if (txt.startsWith('<xmp>') && txt.endsWith('</xmp>')) {
txt = txt.slice(5, -6).trim()
txt = txt.slice(6, -7)
} else if (this.firstElementChild?.tagName === 'TEXTAREA') {
txt = this.firstElementChild.value.trim()
} else if (txt.startsWith('<pre>') && txt.endsWith('</pre>')) {
txt = trim(txt.slice(5, -6))
txt = trim(txt.slice(6, -7))
} else {
txt = trim(txt)
}

View File

@ -174,19 +174,19 @@ class Tool {
// 初始化字符串, 处理多余换行等
static init(str = '') {
var links = {}
var list = []
var lines = fixed(str).split('\n')
var isCodeBlock = false // 是否代码块
var isTable = false // 是否表格
var emptyLineLength = 0 //连续空行的数量
let links = {}
let list = []
let lines = fixed(str).split('\n')
let isCodeBlock = false // 是否代码块
let isTable = false // 是否表格
let emptyLines = 0 //连续空行的数量
for (let it of lines) {
let tmp = it.trim()
// 非空行
if (tmp) {
emptyLineLength = 0
emptyLines = 0
if (tmp.startsWith('```')) {
if (isCodeBlock) {
list.push('\n</xmp></wc-code>\n')
@ -244,32 +244,35 @@ class Tool {
}
}
} else {
if (list.length === 0) {
continue
}
if (isTable) {
isTable = false
list.push('</tbody>\n</table>\n')
continue
}
if (list.length === 0 || (!isCodeBlock && emptyLineLength > 1)) {
continue
}
emptyLineLength++
if (isCodeBlock || emptyLines < 2) {
emptyLines++
list.push(tmp)
}
}
}
return new this(list, links)
}
parse() {
let html = ''
let isCodeBlock = false // 是否代码块
let emptyLineLength = 0 //连续空行的数量
let emptyLines = 0 //连续空行的数量
let isBlockquote = false
let isTable = false
let tableAlign = null
let blockquoteLevel = 0
let isParagraph = false
let isQList = false
let qListTag = null
let isList = false
let listTagQueue = []
@ -281,8 +284,10 @@ class Tool {
for (let it of this.list) {
// 非空行
if (it) {
let lastLineIsEmpty = emptyLineLength > 0
emptyLineLength = 0
// 缓存上一个连续空行数
let lastEmptyLines = emptyLines
emptyLines = 0
if (~it.indexOf('<table>') || ~it.indexOf('</table>')) {
if (isList) {
@ -361,7 +366,6 @@ class Tool {
let hrName = Helper.isHr(it)
if (typeof hrName === 'string') {
html += Decoder.hr(hrName)
emptyLineLength = 0
continue
}
@ -385,15 +389,7 @@ class Tool {
}
// 有列表也先结束
if (isList) {
while (listTagQueue.length) {
let tag = listTagQueue.pop()
html += `${' '.repeat(
listTagQueue.length ? listTagQueue.length + 1 : 0
)}</${tag}>\n`
if (listTagQueue.length) {
html += `${' '.repeat(listTagQueue.length)}</li>\n`
}
}
html = this.#closeList(html, listTagQueue, isParagraph)
isList = false
}
isHtmlBlock = false
@ -411,12 +407,11 @@ class Tool {
// 若之前已经有一个未闭合的引用, 需要减去已有缩进级别, 避免产生新的引用标签
if (isBlockquote) {
loop = len - blockquoteLevel
} else {
}
while (loop > 0) {
loop--
tmp += '<blockquote class="md-quote">'
tmp += `\n<blockquote class="md-quote">`
}
blockquoteLevel = len
@ -424,12 +419,18 @@ class Tool {
return tmp
})
if (isParagraph) {
isParagraph = false
html = trimBr(html)
html += '</p>\n'
}
if (isBlockquote) {
// 没有新的缩进引用时, 才添加换行
if (innerQuote) {
// 之前有引用的列表时, 直接结束列表
if (isQuoteList) {
html += `</${quoteListStyle === 1 ? 'ul' : 'ol'}>\n`
html += `</${qListTag}>\n`
isQuoteList = false
}
}
@ -448,16 +449,18 @@ class Tool {
if (isQuoteList === false) {
isQuoteList = true
if (currListStyle === 1) {
qlist += '<ol>'
qListTag = 'ol'
} else {
qlist += '<ul>'
qListTag = 'ul'
}
qlist += `\n <${qListTag}>`
}
quoteListStyle = currListStyle
qlist += `<li>${tmp3}</li>`
html += tmp1 + qlist
isQList = true
} else {
if (innerQuote === false) {
html += '<br>'
@ -492,11 +495,9 @@ class Tool {
if (isParagraph) {
isParagraph = false
if (!isList) {
html = trimBr(html)
html += '</p>\n'
}
}
if (isList) {
// 大于上一个缩进
@ -536,24 +537,14 @@ class Tool {
// 无"> "前缀的引用, 继续拼到之前的, 并且不换行
if (isBlockquote) {
html += it
if (isQList) {
html = html.replace(/<\/li>\n*?$/, '') + ` ${it}</li>`
} else {
html += ' ' + it
}
continue
}
// 列表之后, 有段落时, 先结束列表
if (isList && lastLineIsEmpty) {
while (listTagQueue.length) {
let tag = listTagQueue.pop()
html += `${' '.repeat(
listTagQueue.length ? listTagQueue.length + 1 : 0
)}</${tag}>\n`
if (listTagQueue.length) {
html += `${' '.repeat(listTagQueue.length)}</li>\n`
}
}
isList = false
}
if (isHtmlBlock || isSingleLineHtml) {
if (isParagraph) {
isParagraph = false
@ -572,13 +563,24 @@ class Tool {
} else {
if (isList) {
if (isParagraph) {
html += it + `</p>\n${' '.repeat(listTagQueue.length)}</li>\n`
if (lastEmptyLines > 0) {
html = trimBr(html)
html += `<br>${it}`
continue
} else {
html = html.replace(/<\/li>\n*?$/, '') + `\n<p>${it}`
html += ` ${it}`
}
} else {
if (lastEmptyLines > 0) {
html = html.replace(/<\/li>\n*?$/, '') + `<p>${it}`
} else {
html = html.replace(/<\/li>\n*?$/, '') + ` ${it}</li>\n`
continue
}
}
} else {
if (isParagraph) {
html += `${it}\n`
html += ` ${it}\n`
} else {
html += `\n<p>${it}`
}
@ -590,42 +592,31 @@ class Tool {
if (isCodeBlock) {
html += it + '\n'
} else {
emptyLineLength++
emptyLines++
//
// 引用结束
if (isBlockquote) {
if (emptyLineLength > 0) {
if (isQList) {
html += `\n</${qListTag}>\n`
isQList = false
}
html = this.#closeQuotes(html, blockquoteLevel)
isBlockquote = false
emptyLineLength = 0
while (blockquoteLevel > 0) {
blockquoteLevel--
html += '</blockquote>\n'
}
}
continue
blockquoteLevel = 0
}
if (isList) {
if (emptyLineLength > 1) {
while (listTagQueue.length) {
let tag = listTagQueue.pop()
html += `${' '.repeat(
listTagQueue.length ? listTagQueue.length + 1 : 0
)}</${tag}>\n`
if (listTagQueue.length) {
html += `${' '.repeat(listTagQueue.length)}</li>\n`
}
}
if (isList && emptyLines > 1) {
html = this.#closeList(html, listTagQueue, isParagraph)
isList = false
emptyLineLength = 0
emptyLines = 0
if (isParagraph) {
isParagraph = false
}
continue
}
//
if (isParagraph) {
if (emptyLineLength > 1) {
emptyLineLength = 0
if (emptyLines > 1) {
emptyLines = 0
isParagraph = false
html = trimBr(html)
html += '</p>\n'
@ -637,6 +628,19 @@ class Tool {
}
}
// 引用结束
if (isBlockquote) {
html = this.#closeQuotes(html, blockquoteLevel)
blockquoteLevel = 0
}
if (isList) {
html = this.#closeList(html, listTagQueue, isParagraph)
if (isParagraph) {
isParagraph = false
}
}
if (isParagraph) {
html += '</p>'
}
@ -644,6 +648,29 @@ class Tool {
delete this.__LINKS__
return html.trim()
}
#closeList(html, tags, isParagraph) {
if (isParagraph) {
html = trimBr(html)
html += '</p>\n'
}
while (tags.length) {
let tag = tags.pop()
html += `${' '.repeat(tags.length ? tags.length + 1 : 0)}</${tag}>\n`
if (tags.length) {
html += `${' '.repeat(tags.length)}</li>\n`
}
}
return html
}
#closeQuotes(html, level) {
while (level > 0) {
level--
html += '</blockquote>\n'
}
return html
}
}
export default function (str) {

View File

@ -907,7 +907,9 @@ class MEditor extends Component {
}
}
mounted() {}
mounted() {
Addon.preview.call(this, this)
}
unmounted() {}