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

View File

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

View File

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