mark解析器优化
parent
12630d66c0
commit
09356d0d92
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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++
|
||||||
|
list.push(tmp)
|
||||||
}
|
}
|
||||||
emptyLineLength++
|
|
||||||
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,10 +495,8 @@ 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,22 +537,12 @@ class Tool {
|
||||||
|
|
||||||
// 无"> "前缀的引用, 继续拼到之前的, 并且不换行
|
// 无"> "前缀的引用, 继续拼到之前的, 并且不换行
|
||||||
if (isBlockquote) {
|
if (isBlockquote) {
|
||||||
html += it
|
if (isQList) {
|
||||||
continue
|
html = html.replace(/<\/li>\n*?$/, '') + ` ${it}</li>`
|
||||||
}
|
} else {
|
||||||
|
html += ' ' + it
|
||||||
// 列表之后, 有段落时, 先结束列表
|
|
||||||
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHtmlBlock || isSingleLineHtml) {
|
if (isHtmlBlock || isSingleLineHtml) {
|
||||||
|
@ -572,13 +563,24 @@ 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 {
|
||||||
|
html += ` ${it}`
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
html = html.replace(/<\/li>\n*?$/, '') + `\n<p>${it}`
|
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) {
|
||||||
html += `${it}\n`
|
html += ` ${it}\n`
|
||||||
} else {
|
} else {
|
||||||
html += `\n<p>${it}`
|
html += `\n<p>${it}`
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
isBlockquote = false
|
html += `\n</${qListTag}>\n`
|
||||||
emptyLineLength = 0
|
isQList = false
|
||||||
while (blockquoteLevel > 0) {
|
|
||||||
blockquoteLevel--
|
|
||||||
html += '</blockquote>\n'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue
|
html = this.#closeQuotes(html, blockquoteLevel)
|
||||||
|
isBlockquote = false
|
||||||
|
blockquoteLevel = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isList) {
|
if (isList && emptyLines > 1) {
|
||||||
if (emptyLineLength > 1) {
|
html = this.#closeList(html, listTagQueue, isParagraph)
|
||||||
while (listTagQueue.length) {
|
isList = false
|
||||||
let tag = listTagQueue.pop()
|
emptyLines = 0
|
||||||
html += `${' '.repeat(
|
if (isParagraph) {
|
||||||
listTagQueue.length ? listTagQueue.length + 1 : 0
|
isParagraph = false
|
||||||
)}</${tag}>\n`
|
|
||||||
if (listTagQueue.length) {
|
|
||||||
html += `${' '.repeat(listTagQueue.length)}</li>\n`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isList = false
|
|
||||||
emptyLineLength = 0
|
|
||||||
}
|
}
|
||||||
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) {
|
||||||
|
|
|
@ -907,7 +907,9 @@ class MEditor extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted() {}
|
mounted() {
|
||||||
|
Addon.preview.call(this, this)
|
||||||
|
}
|
||||||
|
|
||||||
unmounted() {}
|
unmounted() {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue