优化代码着色;优化markd解析,更好的支持html+md混编;优化pager样式
parent
9565a65686
commit
c8d6dc664b
|
@ -62,12 +62,13 @@ export function colorHtml(code) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return `[tag]<${tag + attr}>[/tag]`
|
return `[tag]<${tag}[/tag]${attr}[tag]>[/tag]`
|
||||||
})
|
})
|
||||||
.replace(TAG_END_EXP, (m, tag) => {
|
.replace(TAG_END_EXP, (m, tag) => {
|
||||||
return `[tag]</${tag}>[/tag]`
|
return `[tag]</${tag}>[/tag]`
|
||||||
})
|
})
|
||||||
.replace(TAG_CM_EXP, '[cm]<!--$1-->[cm]')
|
.replace(TAG_CM_EXP, '[cm]<!--$1-->[cm]')
|
||||||
|
|
||||||
return rebuild(code)
|
return rebuild(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,4 +197,4 @@ const SVG_PATH = {
|
||||||
|
|
||||||
export default SVG_PATH
|
export default SVG_PATH
|
||||||
// console.log(Object.keys(SVG_PATH).length)
|
// console.log(Object.keys(SVG_PATH).length)
|
||||||
// console.log(Object.keys(SVG_PATH))
|
// console.log(Object.keys(SVG_PATH).join(','))
|
||||||
|
|
|
@ -5,12 +5,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const HR_LIST = ['=', '-', '_', '*']
|
const HR_LIST = ['=', '-', '_', '*']
|
||||||
const LIST_REG = /^(([\+\-\*])|(\d+\.))\s/
|
const LIST_RE = /^(([\+\-\*])|(\d+\.))\s/
|
||||||
const TODO_REG = /^\-\s\[(x|\s)\]\s/
|
const TODO_RE = /^\-\s\[(x|\s)\]\s/
|
||||||
const ESCAPE_REG = /\\([-+*_`])/g
|
const ESCAPE_RE = /\\([-+*_`])/g
|
||||||
const QLINK_REG = /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/
|
const QLINK_RE = /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/
|
||||||
const TAG_REG = /<([\w\-]+)([\w\W]*?)>/g
|
const TAG_RE = /<([\w\-]+)([\w\W]*?)>/g
|
||||||
const ATTR_REG = /^[\s\S]*?(style="[^"]*?")[\s\S]*?$/
|
const ATTR_RE = /\s*?on[a-zA-Z]+="[^"]*?"\s*?/g
|
||||||
|
const CODEBLOCK_RE = /```(.*?)([\w\W]*?)```/g
|
||||||
|
const BLOCK_RE = /<([\w\-]+)([^>]*?)>([\w\W]*?)<\/\1>/g
|
||||||
|
const IS_DOM_RE = /^<([\w\-]+)[^>]*?>.*?<\/\1>$/
|
||||||
|
const STYLE_RE = /<style[^>]*?>([\w\W]*?)<\/style>/g
|
||||||
|
|
||||||
const INLINE = {
|
const INLINE = {
|
||||||
code: /`([^`]*?[^`\\\s])`/g,
|
code: /`([^`]*?[^`\\\s])`/g,
|
||||||
|
@ -36,7 +40,7 @@ const Helper = {
|
||||||
// 是否列表, -1不是, 1为有序列表, 0为无序列表
|
// 是否列表, -1不是, 1为有序列表, 0为无序列表
|
||||||
isList(str) {
|
isList(str) {
|
||||||
var v = str.trim()
|
var v = str.trim()
|
||||||
if (LIST_REG.test(v)) {
|
if (LIST_RE.test(v)) {
|
||||||
var n = +v[0]
|
var n = +v[0]
|
||||||
if (n === n) {
|
if (n === n) {
|
||||||
return 1
|
return 1
|
||||||
|
@ -49,7 +53,7 @@ const Helper = {
|
||||||
// 是否任务列表
|
// 是否任务列表
|
||||||
isTodo(str) {
|
isTodo(str) {
|
||||||
var v = str.trim()
|
var v = str.trim()
|
||||||
if (TODO_REG.test(v)) {
|
if (TODO_RE.test(v)) {
|
||||||
return v[3] === 'x' ? 1 : 0
|
return v[3] === 'x' ? 1 : 0
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
|
@ -61,13 +65,17 @@ const Helper = {
|
||||||
return str.replace(/^\s+/, '')
|
return str.replace(/^\s+/, '')
|
||||||
},
|
},
|
||||||
isQLink(str) {
|
isQLink(str) {
|
||||||
if (QLINK_REG.test(str)) {
|
if (QLINK_RE.test(str)) {
|
||||||
return { [RegExp.$1]: { l: RegExp.$2, t: RegExp.$3 } }
|
return { [RegExp.$1]: { l: RegExp.$2, t: RegExp.$3 } }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
isTable(str) {
|
isTable(str) {
|
||||||
return /^\|.+?\|$/.test(str)
|
return /^\|.+?\|$/.test(str)
|
||||||
|
},
|
||||||
|
// 是否原生dom节点
|
||||||
|
isNativeDom(str) {
|
||||||
|
return IS_DOM_RE.test(str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +115,7 @@ const Decoder = {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.replace(ESCAPE_REG, '$1') // 处理转义字符
|
.replace(ESCAPE_RE, '$1') // 处理转义字符
|
||||||
},
|
},
|
||||||
// 分割线
|
// 分割线
|
||||||
hr() {
|
hr() {
|
||||||
|
@ -138,7 +146,7 @@ const Decoder = {
|
||||||
task(str) {
|
task(str) {
|
||||||
var todoChecked = Helper.isTodo(str)
|
var todoChecked = Helper.isTodo(str)
|
||||||
if (~todoChecked) {
|
if (~todoChecked) {
|
||||||
var word = str.replace(TODO_REG, '').trim()
|
var word = str.replace(TODO_RE, '').trim()
|
||||||
var stat = todoChecked === 1 ? 'checked' : ''
|
var stat = todoChecked === 1 ? 'checked' : ''
|
||||||
var txt = todoChecked === 1 ? `<del>${word}</del>` : word
|
var txt = todoChecked === 1 ? `<del>${word}</del>` : word
|
||||||
|
|
||||||
|
@ -155,12 +163,22 @@ function fixed(str) {
|
||||||
.replace(/\t/g, ' ')
|
.replace(/\t/g, ' ')
|
||||||
.replace(/\u00a0/g, ' ')
|
.replace(/\u00a0/g, ' ')
|
||||||
.replace(/\u2424/g, '\n')
|
.replace(/\u2424/g, '\n')
|
||||||
.replace(TAG_REG, (m, name, attr) => {
|
.replace(TAG_RE, (m, name, attr) => {
|
||||||
let tmp = attr.replace(/\n/g, '⨨☇') // 标签内的换行, 转为一组特殊字符, 方便后面还原
|
// 标签内的换行, 转为一组特殊字符, 方便后面还原
|
||||||
if (tmp !== attr) {
|
return `<${name + attr.replace(/\n/g, '⨨☇')}>`
|
||||||
tmp = ' ' + tmp
|
})
|
||||||
}
|
.replace(BLOCK_RE, (m, tag, attr, txt) => {
|
||||||
return `<${name + tmp}>`
|
return `<${tag + attr}>${txt.replace(/\n/g, '⨨⤶')}</${tag}>`
|
||||||
|
})
|
||||||
|
.replace(CODEBLOCK_RE, (m, lang, txt) => {
|
||||||
|
// 还原换行
|
||||||
|
let rollback = txt.replace(/⨨⤶/g, '\n').replace(/⨨☇/g, '\n')
|
||||||
|
return '```' + lang + rollback + '```'
|
||||||
|
})
|
||||||
|
.replace(BLOCK_RE, (m, tag, attr, txt) => {
|
||||||
|
return `<${tag + attr.replace(/(⨨☇)+/g, ' ')}>${txt
|
||||||
|
.replace(/⨨⤶/g, ' ')
|
||||||
|
.replace(/(⨨☇)+/g, ' ')}</${tag}>`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +197,8 @@ class Tool {
|
||||||
var isTable = false // 是否表格
|
var isTable = false // 是否表格
|
||||||
var emptyLineLength = 0 //连续空行的数量
|
var emptyLineLength = 0 //连续空行的数量
|
||||||
|
|
||||||
|
// console.log(lines)
|
||||||
|
|
||||||
for (let it of lines) {
|
for (let it of lines) {
|
||||||
let tmp = it.trim()
|
let tmp = it.trim()
|
||||||
|
|
||||||
|
@ -206,20 +226,21 @@ class Tool {
|
||||||
} else {
|
} else {
|
||||||
var qlink
|
var qlink
|
||||||
if (isCodeBlock) {
|
if (isCodeBlock) {
|
||||||
it = it
|
it = it.replace(/</g, '<').replace(/>/g, '>')
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
.replace(/⨨☇/g, '\n') // 代码块要还原回换行
|
|
||||||
} else {
|
} else {
|
||||||
it = it
|
it = it
|
||||||
.replace(/(⨨☇)+/g, ' ') // 非代码块直接转为空格, 并进行xss过滤
|
// 非代码块进行xss过滤
|
||||||
.replace(INLINE.code, (m, txt) => {
|
.replace(INLINE.code, (m, txt) => {
|
||||||
return `\`${txt.replace(/</g, '<').replace(/>/g, '>')}\``
|
return `\`${txt.replace(/</g, '<').replace(/>/g, '>')}\``
|
||||||
})
|
})
|
||||||
.replace(/<(\/?)script[^>]*?>/g, '<$1script>')
|
.replace(/<(\/?)script[^>]*?>/g, '<$1script>')
|
||||||
.replace(TAG_REG, (m, name, attr) => {
|
.replace(TAG_RE, (m, name, attr = '') => {
|
||||||
attr = attr.replace(ATTR_REG, '$1').trim()
|
// 过滤所有onXX=""事件属性
|
||||||
return `<${name} ${attr}>`
|
attr = attr.replace(ATTR_RE, ' ').trim()
|
||||||
|
if (attr) {
|
||||||
|
attr = ' ' + attr
|
||||||
|
}
|
||||||
|
return `<${name}${attr}>`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
qlink = Helper.isQLink(it)
|
qlink = Helper.isQLink(it)
|
||||||
|
@ -412,7 +433,7 @@ class Tool {
|
||||||
// 左侧空格长度
|
// 左侧空格长度
|
||||||
let tmp = Helper.ltrim(it)
|
let tmp = Helper.ltrim(it)
|
||||||
let ltrim = it.length - tmp.length
|
let ltrim = it.length - tmp.length
|
||||||
let word = tmp.replace(LIST_REG, '').trim()
|
let word = tmp.replace(LIST_RE, '').trim()
|
||||||
let level = Math.floor(ltrim / 2)
|
let level = Math.floor(ltrim / 2)
|
||||||
let tag = listChecked > 0 ? 'ol' : 'ul'
|
let tag = listChecked > 0 ? 'ol' : 'ul'
|
||||||
|
|
||||||
|
@ -458,6 +479,11 @@ class Tool {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Helper.isNativeDom(it)) {
|
||||||
|
html += it
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (isParagraph) {
|
if (isParagraph) {
|
||||||
html += `${it}<br>`
|
html += `${it}<br>`
|
||||||
} else {
|
} else {
|
||||||
|
@ -506,7 +532,14 @@ class Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// console.log(html)
|
|
||||||
|
// 修正内嵌样式
|
||||||
|
html = html.replace(STYLE_RE, (m, code) => {
|
||||||
|
return `<style>${code
|
||||||
|
.replace(/<br>/g, '')
|
||||||
|
.replace(/<p>/g, '')
|
||||||
|
.replace(/<\/p>/g, '')}</style>`
|
||||||
|
})
|
||||||
delete this.list
|
delete this.list
|
||||||
delete this.__LINKS__
|
delete this.__LINKS__
|
||||||
return html
|
return html
|
||||||
|
|
|
@ -34,16 +34,25 @@
|
||||||
background: var(--color-teal-1);
|
background: var(--color-teal-1);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.jump {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
border: 2px solid var(--color-plain-2);
|
border: 1px solid var(--color-grey-2);
|
||||||
border-radius: 4px;
|
border-radius: 3px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
transition: box-shadow 0.15s linear;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: 0 0 0 2px var(--color-plain-a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +149,7 @@ const LAYOUT_DICT = {
|
||||||
curr: n => `<span class="curr item">${n}</span>`,
|
curr: n => `<span class="curr item">${n}</span>`,
|
||||||
info: (t, p) => `<span class="item">共 ${t}条, ${p}页</span>`,
|
info: (t, p) => `<span class="item">共 ${t}条, ${p}页</span>`,
|
||||||
jump: n =>
|
jump: n =>
|
||||||
`<section class="item"><input maxlength="6" value="${n}"><wc-button data-act="go" class="item">Go</wc-button></section>`
|
`<section class="item jump"><input maxlength="6" value="${n}"><wc-button data-act="go" class="item">Go</wc-button></section>`
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Reference in New Issue