This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

优化代码着色;优化markd解析,更好的支持html+md混编;优化pager样式

old
宇天 2021-04-28 18:46:09 +08:00
parent 9565a65686
commit c8d6dc664b
4 changed files with 75 additions and 32 deletions

View File

@ -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) => {
return `[tag]</${tag}>[/tag]`
})
.replace(TAG_CM_EXP, '[cm]<!--$1-->[cm]')
return rebuild(code)
}

View File

@ -197,4 +197,4 @@ const SVG_PATH = {
export default SVG_PATH
// console.log(Object.keys(SVG_PATH).length)
// console.log(Object.keys(SVG_PATH))
// console.log(Object.keys(SVG_PATH).join(','))

View File

@ -5,12 +5,16 @@
*/
const HR_LIST = ['=', '-', '_', '*']
const LIST_REG = /^(([\+\-\*])|(\d+\.))\s/
const TODO_REG = /^\-\s\[(x|\s)\]\s/
const ESCAPE_REG = /\\([-+*_`])/g
const QLINK_REG = /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/
const TAG_REG = /<([\w\-]+)([\w\W]*?)>/g
const ATTR_REG = /^[\s\S]*?(style="[^"]*?")[\s\S]*?$/
const LIST_RE = /^(([\+\-\*])|(\d+\.))\s/
const TODO_RE = /^\-\s\[(x|\s)\]\s/
const ESCAPE_RE = /\\([-+*_`])/g
const QLINK_RE = /^\[(\d+)\]: ([\S]+)\s*?((['"])[\s\S]*?\4)?\s*?$/
const TAG_RE = /<([\w\-]+)([\w\W]*?)>/g
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 = {
code: /`([^`]*?[^`\\\s])`/g,
@ -36,7 +40,7 @@ const Helper = {
// 是否列表, -1不是, 1为有序列表, 0为无序列表
isList(str) {
var v = str.trim()
if (LIST_REG.test(v)) {
if (LIST_RE.test(v)) {
var n = +v[0]
if (n === n) {
return 1
@ -49,7 +53,7 @@ const Helper = {
// 是否任务列表
isTodo(str) {
var v = str.trim()
if (TODO_REG.test(v)) {
if (TODO_RE.test(v)) {
return v[3] === 'x' ? 1 : 0
}
return -1
@ -61,13 +65,17 @@ const Helper = {
return str.replace(/^\s+/, '')
},
isQLink(str) {
if (QLINK_REG.test(str)) {
if (QLINK_RE.test(str)) {
return { [RegExp.$1]: { l: RegExp.$2, t: RegExp.$3 } }
}
return false
},
isTable(str) {
return /^\|.+?\|$/.test(str)
},
// 是否原生dom节点
isNativeDom(str) {
return IS_DOM_RE.test(str)
}
}
@ -107,7 +115,7 @@ const Decoder = {
return m
}
})
.replace(ESCAPE_REG, '$1') // 处理转义字符
.replace(ESCAPE_RE, '$1') // 处理转义字符
},
// 分割线
hr() {
@ -138,7 +146,7 @@ const Decoder = {
task(str) {
var todoChecked = Helper.isTodo(str)
if (~todoChecked) {
var word = str.replace(TODO_REG, '').trim()
var word = str.replace(TODO_RE, '').trim()
var stat = todoChecked === 1 ? 'checked' : ''
var txt = todoChecked === 1 ? `<del>${word}</del>` : word
@ -155,12 +163,22 @@ function fixed(str) {
.replace(/\t/g, ' ')
.replace(/\u00a0/g, ' ')
.replace(/\u2424/g, '\n')
.replace(TAG_REG, (m, name, attr) => {
let tmp = attr.replace(/\n/g, '⨨☇') // 标签内的换行, 转为一组特殊字符, 方便后面还原
if (tmp !== attr) {
tmp = ' ' + tmp
}
return `<${name + tmp}>`
.replace(TAG_RE, (m, name, attr) => {
// 标签内的换行, 转为一组特殊字符, 方便后面还原
return `<${name + attr.replace(/\n/g, '⨨☇')}>`
})
.replace(BLOCK_RE, (m, tag, attr, txt) => {
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 emptyLineLength = 0 //连续空行的数量
// console.log(lines)
for (let it of lines) {
let tmp = it.trim()
@ -206,20 +226,21 @@ class Tool {
} else {
var qlink
if (isCodeBlock) {
it = it
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/⨨☇/g, '\n') // 代码块要还原回换行
it = it.replace(/</g, '&lt;').replace(/>/g, '&gt;')
} else {
it = it
.replace(/(⨨☇)+/g, ' ') // 非代码块直接转为空格, 并进行xss过滤
// 非代码块进行xss过滤
.replace(INLINE.code, (m, txt) => {
return `\`${txt.replace(/</g, '&lt;').replace(/>/g, '&gt;')}\``
})
.replace(/<(\/?)script[^>]*?>/g, '&lt;$1script&gt;')
.replace(TAG_REG, (m, name, attr) => {
attr = attr.replace(ATTR_REG, '$1').trim()
return `<${name} ${attr}>`
.replace(TAG_RE, (m, name, attr = '') => {
// 过滤所有onXX=""事件属性
attr = attr.replace(ATTR_RE, ' ').trim()
if (attr) {
attr = ' ' + attr
}
return `<${name}${attr}>`
})
}
qlink = Helper.isQLink(it)
@ -412,7 +433,7 @@ class Tool {
// 左侧空格长度
let tmp = Helper.ltrim(it)
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 tag = listChecked > 0 ? 'ol' : 'ul'
@ -458,6 +479,11 @@ class Tool {
continue
}
if (Helper.isNativeDom(it)) {
html += it
continue
}
if (isParagraph) {
html += `${it}<br>`
} 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.__LINKS__
return html

View File

@ -34,16 +34,25 @@
background: var(--color-teal-1);
color: #fff;
}
&.jump {
display: flex;
}
}
input {
width: 48px;
height: 36px;
padding: 0 4px;
border: 2px solid var(--color-plain-2);
border-radius: 4px;
border: 1px solid var(--color-grey-2);
border-radius: 3px;
text-align: center;
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>`,
info: (t, p) => `<span class="item">共 ${t}条, ${p}页</span>`,
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>`
}
//