From 6b17ad76bae35673cf65ebd59cac6f02270096d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?=
Date: Mon, 10 Feb 2020 03:11:19 +0800
Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84markdown=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/markd/index.wc | 52 ++++++++-----
src/markd/parser.js | 181 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 213 insertions(+), 20 deletions(-)
create mode 100644 src/markd/parser.js
diff --git a/src/markd/index.wc b/src/markd/index.wc
index 626053a..ffa58e3 100644
--- a/src/markd/index.wc
+++ b/src/markd/index.wc
@@ -11,6 +11,8 @@
}
.markd {
padding: 10px;
+ // white-space: pre-wrap;
+ // word-wrap: break-word;
}
a {
text-decoration: underline;
@@ -27,6 +29,12 @@ em {
strong {
color: nth($cd, 3);
}
+a {
+ strong,
+ em {
+ color: inherit;
+ }
+}
em,
strong,
del {
@@ -39,17 +47,15 @@ img {
max-width: 100%;
}
-blockquote {
- &.md-quote {
- margin: 10px 0;
- padding: 5px 10px;
- border-left: 5px solid nth($ct, 1);
- background: #f2faf7;
- color: nth($cgr, 1);
-
- p {
- margin: 0;
- }
+blockquote.md-quote {
+ margin: 10px 0;
+ padding: 5px 10px;
+ line-height: 1.5;
+ border-left: 5px solid nth($ct, 1);
+ background: #f2faf7;
+ color: nth($cgr, 1);
+ p {
+ margin: 0;
}
}
@@ -171,14 +177,13 @@ h6 {
padding: 0 5px;
}
a {
- visibility: hidden;
- position: absolute;
- left: -25px;
- width: 25px;
- padding: 0 3px;
- font-weight: bold;
text-decoration: none;
- text-align: center;
+ color: #333;
+
+ &::before {
+ content: '# ';
+ color: nth($ct, 1);
+ }
}
&:hover a {
visibility: visible;
@@ -225,7 +230,12 @@ table {
}
code.inline {
+ display: inline-block;
+ margin: 0 2px;
+ padding: 0 3px;
color: nth($co, 3);
+ background: nth($cp, 1);
+ border-radius: 2px;
}
@@ -233,7 +243,8 @@ code.inline {
import $ from '../utils'
import '../code/index'
-import parser from './core'
+// import parser from './core'
+import parser from './parser'
export default class Markd {
props = {}
@@ -246,7 +257,8 @@ export default class Markd {
}
mounted() {
- this.__BOX__.innerHTML = parser.safe(this.textContent)
+ // this.__BOX__.innerHTML = parser.safe(this.textContent)
+ this.__BOX__.innerHTML = parser(this.textContent)
this.textContent = ''
}
}
diff --git a/src/markd/parser.js b/src/markd/parser.js
new file mode 100644
index 0000000..f026972
--- /dev/null
+++ b/src/markd/parser.js
@@ -0,0 +1,181 @@
+/**
+ * markdown解析器
+ * @author yutent
+ * @date 2020/02/07 17:14:19
+ */
+
+'use strict'
+const HR_LIST = ['=', '-', '_', '*']
+const log = console.log
+
+const Helper = {
+ // 是否分割线
+ isHr(str) {
+ var s = str[0]
+ if (HR_LIST.includes(s)) {
+ return str.startsWith(s.repeat(3))
+ }
+ return false
+ }
+}
+
+const Tool = {
+ // 初始化字符串, 处理多余换行等
+ init(str) {
+ // 去掉\r, 将\t转为空格(2个)
+ str = str.replace(/\r/g, '').replace(/\t/g, ' ')
+ var list = []
+ var lines = str.split('\n')
+ var isCodeBlock = false // 是否代码块
+ var emptyLineLength = 0 //连续空行的数量
+
+ for (let it of lines) {
+ let tmp = it.trim()
+ // 空行
+ if (!tmp) {
+ if (list.length === 0 || (!isCodeBlock && emptyLineLength > 0)) {
+ continue
+ }
+ emptyLineLength++
+ list.push(tmp)
+ } else {
+ emptyLineLength = 0
+ if (tmp.startsWith('```')) {
+ if (isCodeBlock) {
+ list.push('')
+ } else {
+ list.push(tmp.replace(/^```([\w\#\-]*?)$/, ''))
+ }
+ isCodeBlock = !isCodeBlock
+ } else {
+ list.push(it)
+ }
+ }
+ }
+ log(list)
+ this.list = list
+ return this
+ },
+
+ parse() {
+ var html = ''
+ var isCodeBlock = false // 是否代码块
+ var emptyLineLength = 0 //连续空行的数量
+ var isBlockquote = false
+ var blockquoteLevel = 0
+ var isParagraph = false
+
+ //
+ for (let it of this.list) {
+ // 空行
+ if (!it) {
+ // 如果是在代码中, 直接拼接, 并加上换行
+ if (isCodeBlock) {
+ html += it + '\n'
+ } else {
+ emptyLineLength++
+
+ // 引用结束
+ if (isBlockquote) {
+ isBlockquote = false
+ html += ''
+ if (emptyLineLength > 0) {
+ while (blockquoteLevel > 0) {
+ emptyLineLength = 0
+ blockquoteLevel--
+ html += ''
+ }
+ }
+ continue
+ }
+
+ //
+ if (isParagraph) {
+ isParagraph = false
+ html += '
'
+ } /* else {
+ html += '
'
+ } */
+ }
+ } else {
+ // wc-code标签直接拼接
+ if (~it.indexOf('wc-code')) {
+ html += it
+ isCodeBlock = !isCodeBlock
+ } else {
+ // 同上代码块的处理
+ if (isCodeBlock) {
+ html += it + '\n'
+ continue
+ }
+
+ it = it
+ .replace(/`(.*?)`/g, '$1
')
+ .replace(/(\-\-|\*\*)(.*?)\1/g, '$2')
+ .replace(/(\-|\*)(.*?)\1/g, '$2')
+ .replace(/\!\[([^]*?)\]\(([^)]*?)\)/g, '')
+ .replace(/\[([^]*?)\]\(([^)]*?)\)/g, '$1')
+
+ //
+ if (it.startsWith('>')) {
+ html += it.replace(/^(>+) /, m => {
+ let len = m.trim().length
+ let tmp = ''
+ if (isBlockquote) {
+ // 若之前已经有一个未闭合的引用, 需要减去已有缩进级别, 避免产生新的引用标签
+ len = len - blockquoteLevel
+ } else {
+ blockquoteLevel = len
+ }
+ log('bq: ', blockquoteLevel, it)
+ while (len > 0) {
+ len--
+ tmp += ''
+ }
+ return tmp
+ })
+
+ if (isBlockquote) {
+ html += '
'
+ }
+ isParagraph = false
+ isBlockquote = true
+ continue
+ }
+
+ if (isBlockquote) {
+ html += it
+ continue
+ }
+
+ //
+ if (it.startsWith('#')) {
+ isParagraph = false
+ let end = ''
+ html += it.replace(/^#{1,6} /, m => {
+ let level = m.trim().length
+ end = ``
+ return ``
+ })
+ html += end
+
+ continue
+ }
+
+ // log('it => ', isParagraph, it)
+ if (isParagraph) {
+ html += `${it}
`
+ } else {
+ html += `${it}
`
+ }
+ isParagraph = true
+ }
+ }
+ }
+ return html
+ }
+}
+
+export default function(str) {
+ return Tool.init(str).parse()
+}