diff --git a/src/markd/index.wc b/src/markd/index.wc
index ffa58e3..506f340 100644
--- a/src/markd/index.wc
+++ b/src/markd/index.wc
@@ -1,5 +1,5 @@
-
+
@@ -243,7 +253,7 @@ code.inline {
import $ from '../utils'
import '../code/index'
-// import parser from './core'
+import core from './core'
import parser from './parser'
export default class Markd {
@@ -257,9 +267,16 @@ export default class Markd {
}
mounted() {
- // this.__BOX__.innerHTML = parser.safe(this.textContent)
+ // this.__BOX__.innerHTML = core.safe(this.textContent)
this.__BOX__.innerHTML = parser(this.textContent)
this.textContent = ''
+
+ $.bind(this.__BOX__, 'click', ev => {
+ if (ev.target.className === 'md-head-link') {
+ var ot = ev.target.offsetTop
+ document.documentElement.scrollTop = ot
+ }
+ })
}
}
diff --git a/src/markd/parser.js b/src/markd/parser.js
index f026972..f3be4b7 100644
--- a/src/markd/parser.js
+++ b/src/markd/parser.js
@@ -6,6 +6,8 @@
'use strict'
const HR_LIST = ['=', '-', '_', '*']
+const LIST_REG = /^(([\+\-\*])|(\d+\.))\s/
+const TODO_REG = /^\[(x|\s)\]\s/
const log = console.log
const Helper = {
@@ -16,12 +18,42 @@ const Helper = {
return str.startsWith(s.repeat(3))
}
return false
+ },
+ // 是否列表, -1不是, 1为有序列表, 0为无序列表
+ isList(str) {
+ var v = str.trim()
+ if (LIST_REG.test(v)) {
+ var n = +v[0]
+ if (n === n) {
+ return 1
+ } else {
+ return 0
+ }
+ }
+ return -1
+ },
+ // 是否任务列表
+ isTodo(str) {
+ var v = str.trim()
+ if (TODO_REG.test(v)) {
+ return v[1] === 'x' ? 1 : 0
+ }
+ return -1
+ },
+ ltrim(str) {
+ if (str.trimStart) {
+ return str.trimStart()
+ }
+ return str.replace(/^\s+/, '')
}
}
-const Tool = {
+class Tool {
+ constructor(list) {
+ this.list = list
+ }
// 初始化字符串, 处理多余换行等
- init(str) {
+ static init(str) {
// 去掉\r, 将\t转为空格(2个)
str = str.replace(/\r/g, '').replace(/\t/g, ' ')
var list = []
@@ -52,10 +84,9 @@ const Tool = {
}
}
}
- log(list)
- this.list = list
- return this
- },
+
+ return new this(list)
+ }
parse() {
var html = ''
@@ -65,6 +96,10 @@ const Tool = {
var blockquoteLevel = 0
var isParagraph = false
+ var isList = false
+ var orderListLevel = -1
+ var unorderListLevel = -1
+
//
for (let it of this.list) {
// 空行
@@ -78,10 +113,9 @@ const Tool = {
// 引用结束
if (isBlockquote) {
isBlockquote = false
- html += ''
if (emptyLineLength > 0) {
+ emptyLineLength = 0
while (blockquoteLevel > 0) {
- emptyLineLength = 0
blockquoteLevel--
html += ''
}
@@ -89,13 +123,25 @@ const Tool = {
continue
}
+ if (isList) {
+ while (orderListLevel > -1 || unorderListLevel > -1) {
+ if (orderListLevel > unorderListLevel) {
+ html += ''
+ orderListLevel--
+ } else {
+ html += ''
+ unorderListLevel--
+ }
+ }
+ isList = false
+ continue
+ }
+
//
if (isParagraph) {
isParagraph = false
html += '
'
- } /* else {
- html += '
'
- } */
+ }
}
} else {
// wc-code标签直接拼接
@@ -109,35 +155,45 @@ const Tool = {
continue
}
+ // 无属性标签
+ if (Helper.isHr(it)) {
+ html += ''
+ continue
+ }
+
+ // 优先处理一些常规样式
it = it
.replace(/`(.*?)`/g, '$1
')
.replace(/(\-\-|\*\*)(.*?)\1/g, '$2')
- .replace(/(\-|\*)(.*?)\1/g, '$2')
+ .replace(/(\-|\_|\*)(.*?)\1/g, '$2')
+ .replace(/~~(.*?)~~/g, '$1')
.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 += '
'
}
+ html += it.replace(/^(>+) /, (p, m) => {
+ let len = m.length
+ let tmp = ''
+ let loop = len
+ // 若之前已经有一个未闭合的引用, 需要减去已有缩进级别, 避免产生新的引用标签
+ if (isBlockquote) {
+ loop = len - blockquoteLevel
+ } else {
+ }
+
+ while (loop > 0) {
+ loop--
+ tmp += ''
+ }
+
+ blockquoteLevel = len
+ return tmp
+ })
+
isParagraph = false
isBlockquote = true
continue
@@ -148,17 +204,79 @@ const Tool = {
continue
}
- //
+ // 标题只能是单行
if (it.startsWith('#')) {
isParagraph = false
- let end = ''
- html += it.replace(/^#{1,6} /, m => {
- let level = m.trim().length
- end = ``
- return ``
- })
- html += end
+ html += it.replace(/^(#{1,6}) (.*)/, (p, m1, m2) => {
+ m2 = m2.trim()
+ let level = m1.trim().length
+ let hash = m2.replace(/\s/g, '').replace(/<\/?[^>]*?>/g, '')
+
+ if (level === 1) {
+ return `${m2}
`
+ } else {
+ return `${m2}`
+ }
+ })
+
+ continue
+ }
+
+ // 列表
+ let listChecked = Helper.isList(it)
+ if (~listChecked) {
+ // 左侧空格长度
+ let tmp = Helper.ltrim(it)
+ let ltrim = it.length - tmp.length
+ let word = tmp.replace(LIST_REG, '').trim()
+ let level = Math.floor(ltrim / 2)
+ let tag = listChecked > 0 ? 'ol' : 'ul'
+
+ if (!isList) {
+ html += `<${tag}>`
+ if (listChecked === 1) {
+ orderListLevel = level
+ } else {
+ unorderListLevel = level
+ }
+ html += `${word}`
+ } else {
+ if (listChecked === 1) {
+ if (level > orderListLevel) {
+ html = html.replace(/<\/li>$/, '')
+ html += `<${tag}>${word}`
+ } else if (level === orderListLevel) {
+ html += `${word}`
+ } else {
+ html += `${tag}>${word}`
+ }
+ orderListLevel = level
+ } else {
+ if (level > unorderListLevel) {
+ html = html.replace(/<\/li>$/, '')
+ html += `<${tag}>${word}`
+ } else if (level === unorderListLevel) {
+ html += `${word}`
+ } else {
+ html += `${tag}>${word}`
+ }
+ unorderListLevel = level
+ }
+ }
+
+ isList = true
+ continue
+ }
+
+ // 任务
+ let todoChecked = Helper.isTodo(it)
+ if (~todoChecked) {
+ let word = it.replace(TODO_REG, '').trim()
+ let stat = todoChecked === 1 ? 'checked' : ''
+ let txt = todoChecked === 1 ? `${word}` : word
+
+ html += ``
continue
}