vue富文本编辑器支持mathjax数学公式

支持数学公式的富文本编辑器,可能使用场景少吧,很多热门编辑器都不支持,或是使用不方便。

最先尝试wangeditor5的编辑器,而且不依赖其它的工具,集成进来之后确实富文本确实可以用,但是发现公式只能在编辑器中显示,外部显示不了,可能还需要引入什么吧,有兴趣的朋友可以尝试探究

本文用到的是 wangeditor4和mathjax的集成

界面效果:

集成

1.引入wangeditor4编辑器

https://www.wangeditor.com/v4/pages/01-%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8/01-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8.html

我采用的是npm安装引入

npm 安装 npm i wangeditor --save

初始化页面和编辑器

<template>
    <div>
        <div id="wang-test"></div>
    </div>
</template>

<script>
import Editor from "./formula-menu-conf.js";
export default {
    data() {
        return {
            instance: null,//编辑器实例
        }
    },

    mounted() {
   
        this.instance = new Editor("#wang-test");
        // 配置 server 接口地址
        this.instance.config.uploadImgServer = '你的上传地址'
        //上传文件参数别名
        this.instance.config.uploadFileName = 'file'
        this.instance.config.withCredentials = true
        this.instance.config.uploadImgHooks = {
            // 图片上传并返回了结果,想要自己把图片插入到编辑器中
            // 例如服务器端返回的不是 { errno: 0, data: [...] } 这种格式,可使用customInsert
            customInsert: function (insertImgFn, result) {
                // insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
                insertImgFn(result.url)
            }
        }
        this.instance.create();    },

    beforeDestroy() {
        if (this.instance)
            this.instance.destroy()
        this.instance = null
    },
    methods: {
        //获取文本内容
        getUEContent() {
            return this.instance.txt.html()
        },
        //设置文本内容
        setText(html) {
            this.instance.txt.html(`${html}`)
        }
    }
}
</script>
<style>
.content {
    border-radius: 8px;
    padding: 15px;
    border: 1px solid #e5e5e5;
    max-height: 200px;
    overflow-y: scroll;
}

.title {
    font-size: 22rpx;
    font-weight: bold;
    color: #333;
    margin: 10px 0px;
}

.w-e-text {
    padding-top: 10px;
    line-height: 25px;
}
</style>

菜单配置formula-menu-conf.js文件

import Editor from 'wangeditor'
import createPanelInsert from "./create-panel-insert";

const { PanelMenu, Panel} = Editor;


class InsertMenu extends PanelMenu {
    constructor(editor) {
        // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
        const $elem = Editor.$(
            `<div class="w-e-menu" style='width:100px'  data-title="插入数学公式">
        <span>插入数学公式</span>
      </div>`
        );
        super($elem, editor);
    }

    /**
     * 菜单点击事件
     */
    clickHandler() {
        const conf = createPanelInsert(this.editor);
        const panel = new Panel(this, conf);
        panel.create();
    }
    tryChangeActive() { }
}

// 注册菜单
Editor.registerMenu('InsertMenuKey', InsertMenu);

export default Editor;

 新建 create-panel-insert.js


export default function (wangEditor) {
    const btnOkId = 'btn-insert'
    //无用的标签
    const UN_TAGS = [ //转换成svg后只提取svg内容 去除没必要内容
        /<\/?mjx-container[^>]*>/gi,//去除标签保留内容
        /<\/?mjx-assistive-mml[^>]*>/gi,//去除标签保留内容
        /<math[^>]*>.*<\/math>/gi,//去除标签不保留内容
        /<mfrac[^>]*>.*<\/mfrac>/gi//去除标签不保留内容
    ]
    //判断是否引入了MathJax 动态引入MathJax 
    //这里转换的是svg
    if (!window.MathJax || !window.MathJax.version) {
        const script = document.createElement('script');
        script.src = 'https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/mathjax/3.2.0/es5/tex-svg.min.js';
        script.async = true;
        script.id = 'MathJax-script'
        document.head.appendChild(script)
    }
    /**
     * 插入公式
     */
    function insertFomule() {
        //转换svg的配置
        const options = {
            scale: 1.15,// global scaling factor for all expressions
            minScale: 0.5, // smallest scaling factor to use
            exFactor: .5,
            display: false,
            zoom: 'DoubleClick',
        };
        //获取文本内容
        let value = document.getElementById('formulaInput').value;
        if (!value)
            return alert('请输入内容')
        //框架不支持tabular标签,替换成array来显示
        value = value.replace(/tabular/g, "array")
        //输出转换svg
        let formula = window.MathJax.tex2svg(value, options).outerHTML
        //去除无用的标签
        //不去除的话,会影响富文本的显示,插入后会自动换行,且手动换行无效果,
        //有兴趣的可以去除看看效果
        UN_TAGS.forEach(tags => {
                formula = formula.replace(tags, '')
        })
            //插入html
        wangEditor.cmd.do('insertHTML', formula)
        return true
    }


    // tabs配置
    const tabsConf = [{
        // tab 的标题
        title: "插入数学公式",
        // 模板
        tpl: `<div>
              <div id="edit-content">
              <textarea id='formulaInput'  style='height:100px;width:450px;textalgin:left;font-size='12px'' ></textarea>
              <div class="w-e-button-container">
                <button type="button" id="${btnOkId}" class="right">插入</button>
              </div>
            </div>`,
        // 事件绑定
        events: [{
            selector: '#' + btnOkId,
            type: 'click',
            fn: insertFomule,
            bindEnter: true,
        },],
    }, // tab end
    ]

    return {
        width: 500,
        height: 0,
        // panel 中可包含多个 tab
        tabs: tabsConf, // tabs end
    }
}

最终效果

后续:

在掘金上看到一位大佬集成的编辑器,有兴趣的可以了解

wangEditor公式编辑器kityformula + myscript-math-web - 掘金 他主要运用的是latex在线解析,导入图片的方式

editor.txt.append( '<img class="formula" src="https://latex.csdn.net/eq?' +   latex +
                  '" data-latex="' +
                  latex +
                  '" />')

使用过程中发现有些公式解析不出来,故将转换的方式修改了下

扫码关注微信公众号回复 :数学公式   

获取仓库地址

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值