mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
Feat:支持直接在富文本编辑框中编辑数学公式
This commit is contained in:
parent
8152fab185
commit
f996ec9bae
@ -332,5 +332,11 @@ export const defaultOpt = {
|
||||
// 添加附加的节点前置内容,前置内容指和文本同一行的区域中的前置内容,不包括节点图片部分
|
||||
createNodePrefixContent: null,
|
||||
// 添加附加的节点后置内容,后置内容指和文本同一行的区域中的后置内容,不包括节点图片部分
|
||||
createNodePostfixContent: null
|
||||
createNodePostfixContent: null,
|
||||
// 是否开启在富文本编辑框中直接编辑数学公式
|
||||
enableEditFormulaInRichTextEdit: true,
|
||||
// 转换富文本内容,当进入富文本编辑时,可以通过该参数传递一个函数,函数接收文本内容,需要返回你处理后的文本内容
|
||||
transformRichTextOnEnterEdit: null,
|
||||
// 可以传递一个函数,即将结束富文本编辑前会执行该函数,函数接收richText实例,所以你可以在此时机更新quill文档数据
|
||||
beforeHideRichTextEdit: null
|
||||
}
|
||||
|
||||
@ -10,9 +10,18 @@ class Formula {
|
||||
this.opt = opt
|
||||
this.mindMap = opt.mindMap
|
||||
window.katex = katex
|
||||
this.init()
|
||||
this.extendQuill()
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.mindMap.opt.enableEditFormulaInRichTextEdit) {
|
||||
this.mindMap.opt.transformRichTextOnEnterEdit =
|
||||
this.latexRichToText.bind(this)
|
||||
this.mindMap.opt.beforeHideRichTextEdit = this.formatLatex.bind(this)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取katex配置
|
||||
getKatexConfig() {
|
||||
const config = {
|
||||
@ -59,6 +68,74 @@ class Formula {
|
||||
richTextPlugin.setTextStyleIfNotRichText(richTextPlugin.node)
|
||||
richTextPlugin.hideEditText([node])
|
||||
}
|
||||
|
||||
// 将公式富文本转换为公式源码
|
||||
latexRichToText(nodeText) {
|
||||
if (nodeText.indexOf('class="ql-formula"') !== -1) {
|
||||
const parser = new DOMParser()
|
||||
const doc = parser.parseFromString(nodeText, 'text/html')
|
||||
const els = doc.getElementsByClassName('ql-formula')
|
||||
for (const el of els)
|
||||
nodeText = nodeText.replace(
|
||||
el.outerHTML,
|
||||
`\$${el
|
||||
.getAttribute('data-value')
|
||||
.replaceAll('&', '&')
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>')}\$`
|
||||
)
|
||||
}
|
||||
return nodeText
|
||||
}
|
||||
|
||||
// 使用格式化的 latex 字符串内容更新 quill 内容:输入 $*****$
|
||||
formatLatex(richText) {
|
||||
const contents = richText.quill.getContents()
|
||||
const ops = contents.ops
|
||||
let mod = false
|
||||
for (let i = ops.length - 1; i >= 0; i--) {
|
||||
const op = ops[i]
|
||||
const insert = op.insert
|
||||
if (insert && typeof insert !== 'object' && insert !== '\n') {
|
||||
if (/\$.+?\$/g.test(insert)) {
|
||||
const m = [...insert.matchAll(/\$.+?\$/g)]
|
||||
const arr = insert.split(/\$.+?\$/g)
|
||||
for (let j = m.length - 1; j >= 0; j--) {
|
||||
const exp = m[j]?.[0].slice(1, -1) ?? null // $...$ 之间的表达式
|
||||
if (exp !== null && exp.trim().length > 0) {
|
||||
const isLegal = this.checkFormulaIsLegal(exp)
|
||||
if (isLegal) {
|
||||
arr.splice(j + 1, 0, { insert: { formula: exp } }) // 添加到对应位置之后
|
||||
mod = true
|
||||
} else {
|
||||
arr.splice(j + 1, 0, '')
|
||||
}
|
||||
} else arr.splice(j + 1, 0, '') // 表达式为空时,占位
|
||||
}
|
||||
while (arr.length > 0) {
|
||||
let v = arr.pop()
|
||||
if (typeof v === 'string') {
|
||||
if (v.length < 1) continue
|
||||
v = { insert: v }
|
||||
}
|
||||
v['attributes'] = ops[i]['attributes']
|
||||
ops.splice(i + 1, 0, v)
|
||||
}
|
||||
ops.splice(i, 1) // 删除原来的字符串
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mod) richText.quill.setContents(contents)
|
||||
}
|
||||
|
||||
checkFormulaIsLegal(str) {
|
||||
try {
|
||||
katex.renderToString(str)
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Formula.instanceName = 'formula'
|
||||
|
||||
@ -171,7 +171,8 @@ class RichText {
|
||||
customInnerElsAppendTo,
|
||||
nodeTextEditZIndex,
|
||||
textAutoWrapWidth,
|
||||
selectTextOnEnterEditText
|
||||
selectTextOnEnterEditText,
|
||||
transformRichTextOnEnterEdit
|
||||
} = this.mindMap.opt
|
||||
this.node = node
|
||||
this.isInserting = isInserting
|
||||
@ -241,7 +242,10 @@ class RichText {
|
||||
}
|
||||
}
|
||||
// 节点文本内容
|
||||
const nodeText = node.getData('text')
|
||||
let nodeText = node.getData('text')
|
||||
if (typeof transformRichTextOnEnterEdit === 'function') {
|
||||
nodeText = transformRichTextOnEnterEdit(nodeText)
|
||||
}
|
||||
// 是否是空文本
|
||||
const isEmptyText = isUndef(nodeText)
|
||||
// 是否是非空的非富文本
|
||||
@ -325,6 +329,10 @@ class RichText {
|
||||
if (!this.showTextEdit) {
|
||||
return
|
||||
}
|
||||
const { beforeHideRichTextEdit } = this.mindMap.opt
|
||||
if (typeof beforeHideRichTextEdit === 'function') {
|
||||
beforeHideRichTextEdit(this)
|
||||
}
|
||||
let html = this.getEditText()
|
||||
let list =
|
||||
nodes && nodes.length > 0 ? nodes : this.mindMap.renderer.activeNodeList
|
||||
|
||||
Loading…
Reference in New Issue
Block a user