From 856d23c8e57d24a9fbcb7d7cc6beb46e3ae99235 Mon Sep 17 00:00:00 2001 From: yutent Date: Mon, 24 Apr 2023 10:28:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96markdown=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/markd/core.js | 100 +++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/src/markd/core.js b/src/markd/core.js index add3ef0..2ed4d70 100644 --- a/src/markd/core.js +++ b/src/markd/core.js @@ -152,7 +152,7 @@ const Decoder = { var stat = todoChecked === 1 ? 'checked' : '' var txt = todoChecked === 1 ? `${word}` : word - return `\n
${txt}
\n` + return `\n
${txt}
` } return false } @@ -194,7 +194,7 @@ class Tool { emptyLineLength = 0 if (tmp.startsWith('```')) { if (isCodeBlock) { - list.push('\n\n\n') + list.push('\n\n') } else { list.push( tmp.replace(/^```([\w\#\-]*?)$/, `\n`) @@ -265,22 +265,22 @@ class Tool { } parse() { - var html = '' - var isCodeBlock = false // 是否代码块 - var emptyLineLength = 0 //连续空行的数量 - var isBlockquote = false - var isTable = false - var tableAlign = null - var blockquoteLevel = 0 - var isParagraph = false + let html = '' + let isCodeBlock = false // 是否代码块 + let emptyLineLength = 0 //连续空行的数量 + let isBlockquote = false + let isTable = false + let tableAlign = null + let blockquoteLevel = 0 + let isParagraph = false - var isList = false - var orderListLevel = -1 - var unorderListLevel = -1 + let isList = false + let orderListLevel = -1 + let unorderListLevel = -1 - var isQuoteList = false // 引用中的列表, 只支持一层级 - var quoteListStyle = 0 // 1有序, 2 无序 - var isHtmlBlock = false // 是否原生html代码块 + let isQuoteList = false // 引用中的列表, 只支持一层级 + let quoteListStyle = 0 // 1有序, 2 无序 + let isHtmlBlock = false // 是否原生html代码块 // for (let it of this.list) { @@ -350,6 +350,11 @@ class Tool { 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) @@ -358,10 +363,24 @@ class Tool { let head = Decoder.head(it) if (head) { html = trimBr(html) + // 有段落先结束 if (isParagraph) { isParagraph = false 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 continue @@ -450,39 +469,40 @@ class Tool { let tmp = Helper.ltrim(it) let ltrim = it.length - tmp.length let word = tmp.replace(LIST_RE, '').trim() - let level = Math.floor(ltrim / 2) - let tag = listChecked > 0 ? 'ol' : 'ul' + let level = Math.floor(ltrim / 2) //缩进级别 + let tag = listChecked === 1 ? 'ol' : 'ul' if (isList) { + let _level = listChecked === 1 ? orderListLevel : unorderListLevel + + // 大于上一个缩进 + if (level > _level) { + // 需要先把上一个列表的结束符去掉 + html = html.trim().replace(/<\/li>$/, '') + html += `\n<${tag}>\n<li>${word}</li>\n` + } + // 跟上一个平级 + else if (level === _level) { + html += `<li>${word}</li>\n` + } + // 比上一个缩进要小 + else { + html += `</${tag}>\n</li>\n<li>${word}</li>\n` + } + if (listChecked === 1) { - if (level > orderListLevel) { - html = html.replace(/<\/li>$/, '') - html += `<${tag}><li>${word}</li>` - } else if (level === orderListLevel) { - html += `<li>${word}</li>` - } else { - html += `</${tag}></li><li>${word}</li>` - } orderListLevel = level } else { - if (level > unorderListLevel) { - 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}>` + html += `<${tag}>\n` if (listChecked === 1) { orderListLevel = level } else { unorderListLevel = level } - html += `<li>${word}</li>` + html += `<li>${word}</li>\n` } isList = true @@ -503,13 +523,13 @@ class Tool { if (isParagraph) { html += `${it}\n` } else { - if (isHtmlBlock || SINGLE_LINE_HTML_RE.test(it)) { + if (isHtmlBlock || isSingleLineHtml) { html += `${it}\n` - } else if (MULTI_LINE_HTML_RE.test(it)) { + } else if (isMultiLineHtml) { isHtmlBlock = !isHtmlBlock html += `${it}\n` } else { - html += `\n<p>\n${it}` + html += `\n<p>${it}` isParagraph = true } } @@ -556,7 +576,7 @@ class Tool { emptyLineLength = 0 isParagraph = false html = trimBr(html) - html += '\n</p>\n' + html += '</p>\n' } else { html += '<br>' }