15 行代码在 wangEditor v5 使用数学公式

2023-11-05

前言
wangEditor v5 正式版发布在即,为了验证它的扩展性,我开发了几个常用的第三方插件。本文介绍一下 formula 插件的设计和使用。

插入数学公式要使用 LateX 语法,渲染公式需要依赖工具 KateX。如 c = \pm\sqrt{a^2 + b^2} 将渲染为下图的公式。

在这里插入图片描述

PS:本插件不依赖于任何框架,JS Vue React 等任何框架都可以正常使用。

使用
首先要了解 wangEditor v5 最基本的安装和使用,可参考文档。然后再查阅 wangEditor-plugin-formula 插件的文档。

安装和注册
安装 katex 和 @wangeditor/plugin-formula

yarn add katex
yarn add @wangeditor/plugin-formula
复制代码

注册到 wangEditor

import { Boot } from '@wangeditor/editor'
import formulaModule from '@wangeditor/plugin-formula'

// 注册。要在创建编辑器之前注册,且只能注册一次,不可重复注册。
Boot.registerModule(formulaModule)
复制代码

此时 wangEditor 就已经具备了显示公式的能力,但还需要配置菜单:插入公式,编辑公式。

配置菜单
配置工具栏,把 insertFormula 和 editFormula 插入到 index 指定的位置。

import { IToolbarConfig } from '@wangeditor/editor'

// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {
  insertKeys: {
    index: 0, // 自定义
    keys: [
      'insertFormula', // “插入公式”菜单
      // 'editFormula' // “编辑公式”菜单
    ],
  },

  // 其他...
}
复制代码

当然,editFormula 也可以配置到编辑器的悬浮菜单中

import { IEditorConfig } from '@wangeditor/editor'

const editorConfig: Partial<IEditorConfig> = {
  // 选中 公式节点 时的悬浮菜单
  hoverbarKeys: {
    formula: {
      menuKeys: ['editFormula'], // “编辑公式”菜单
    },
  },

  // 其他...
}
复制代码

此时,即可通过菜单来插入公式:

在这里插入图片描述

选中公式节点时,还可以编辑公式:

在这里插入图片描述

显示 HTML
执行 editor.getHtml() 获取的公式节点的 HTML 格式如下,就是一个普通的 <span> ,其中 data-value 即 LateX 语法的字符串。

<span data-w-e-type="formula" data-w-e-is-void data-w-e-is-inline data-value="c = \pm\sqrt{a^2 + b^2}"></span>
复制代码

将这个 <span> 渲染为公式卡片,依然可以借助 KateX ,简单方便。

katex.render("c = \\pm\\sqrt{a^2 + b^2}", spanElement, {
    throwOnError: false
})
复制代码

回显 HTML (重新编辑)
获取的 HTML 依然支持回显到编辑器中,可以正常解析为公式卡片。这些能力早在注册 formulaModule 之后就已经具备了。

const editor = createEditor({
  selector: '#editor-container',
  config: editorConfig,
  html: `<p>hello&nbsp;world<span data-w-e-type="formula" data-w-e-is-void data-w-e-is-inline data-value="c = \\pm\\sqrt{a^2 + b^2}"></span></p>`,
})
复制代码

在这里插入图片描述

设计
一些基本的扩展能力,如注册菜单、生成 html ,解析 html 等,这些 wangEditor 都早已具备且成熟,参考文档和该插件的源码即可。

在这里插入图片描述

编辑器内部渲染公式卡片
本文重点介绍:如何使用 KateX 在编辑器中渲染公式卡片?
因为,wangEditor 中渲染流程是比较复杂的,如下图:

在这里插入图片描述

要借助 KateX 渲染是直接操作 DOM ,而 wangEditor 内部渲染需要先生成 VDOM ,然后再使用 snabbdom.js 来 patch DOM 。两者无法兼容。

最后找到的解决方案是:自定义 DOM 元素。注册一个 <w-e-formula-card data-value="xxx"><w-e-formula-card> 元素,即可像普通的 <div> <p> 一样生成 VDOM ,然后 patch 渲染。

// 构建 formula vnode
const { value = '' } = elem as FormulaElement
const formulaVnode = h(
    'w-e-formula-card',
    {
        dataset: { value },
    },
    null
)
复制代码

在这里插入图片描述

注册 <w-e-formula-card> 自定义元素
借助 KateX ,开发起来非常简单。注册一个自定义元素,内部使用 Shadow DOM 渲染即可。

import katexStyleContent from '!!raw-loader!katex/dist/katex.css'
import katex from 'katex'

class WangEditorFormulaCard extends HTMLElement {
  private span: HTMLElement

  // 需要监听的 attr
  static get observedAttributes() {
    return ['data-value']
  }

  constructor() {
    super()
    const shadow = this.attachShadow({ mode: 'open' }) // Shadow DOM
    const document = shadow.ownerDocument

    const style = document.createElement('style')
    style.innerHTML = katexStyleContent // 加载 css 文本
    shadow.appendChild(style)

    const span = document.createElement('span')
    span.style.display = 'inline-block'
    shadow.appendChild(span)
    this.span = span
  }

  // 'data-value' 变化时,重新渲染 DOM
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
    if (name === 'data-value') {
      if (oldValue == newValue) return
      this.render(newValue || '')
    }
  }

  //  KateX 渲染公式
  private render(value: string) {
    katex.render(value, this.span, {
      throwOnError: false,
    })
  }
}

window.customElements.define('w-e-formula-card', WangEditorFormulaCard)
复制代码

总结
本文重点

公式使用 LateX 语法,使用 KateX 工具来渲染
编辑器内部注册自定义元素 <w-e-formula-card> 渲染公式
开发 formula 插件验证了 wangEditor v5 全面的扩展能力
最后
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !

PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

15 行代码在 wangEditor v5 使用数学公式 的相关文章

  • 区块链的简单实现

    区块链的简单实现 什么是区块链 块结构 创世区块 hash 验证块的有效性 记录数据 从其他节点接收一个块 编写测试代码 测试结果 完整代码 什么是区块链 一个维护着一个持续增长的有序数据记录列表的这么一个分布式数据库 下面我将简单用nod
  • JWT(Json Web Token)的原理、渗透与防御

    关于JWT kid安全部分后期整理完毕再进行更新 2023 05 16 JWT的原理 渗透与防御 目录 JWT的原理 渗透与防御 含义 原理 JWT的起源 传统session认证问题 token与session区别 JWT的结构与内容 JW
  • Jupyter下的tensorboard使用

    tensorflow自带的tensorboard功能强大 图像生成 参数变化等都可以进行可视化 不过这个要单独启动才行 使用方法可参考 http wiki jikexueyuan com project tensorflow zh how
  • Python每日练习题以及答案解析,还不进来测试一下?

    问题引入 现在有5个小朋友要分糖果 他们按照自己的编号顺序围坐在一张圆桌旁边 他们身上都有一些糖果 通过输入来决定每个小孩糖果的数量 从1号小朋友开始 将自己的糖果平均分成最多的3份 多出来的自己吃掉 自己留一份 其余两份分给他相邻的两位小
  • Hadoop的伪分布式运行模式

    Hadoop运行模式包括 本地模式 伪分布式模式 以及完全分布式模式 1 本地模式 安装简单 在一台机器上运行服务 几乎不用做任何配置 但仅限于调试用途 没有分布式文件系统 直接读写本地操作系统的文件系统 2 伪分布式模式 在单节点上同时启
  • MAC 命令行拷贝文件夹

    命令 cp R 源文件 目标文件 cp R libsvm 3 23 Applications MATLAB R2017b app toolbox 将当前目录下的libsvm 3 23拷贝到 Applications MATLAB R2017
  • 强化学习中 on-policy与off-policy 的理解;如何区分on-policy 与 off-policy;RL更新策略、policy结构总结

    目录 基本概念 Q learning VS Sarsa DQN VS PPO 区分on policy 与 off policy 一些总结 基本概念 如果要学习的 agent 跟和环境互动的 agent 是同一个的话 这个叫做on polic
  • java I/O流的一些常用操作

    java i o 的一些操作 文件流 FileInputStream FileOutputStream FileReader FileWriter 这四个类是专门操作文件流的 用法高度相似 区别在于前面两个是操作字节流 后面两个是操作字符流
  • 学习笔记-Spark环境搭建与使用

    一 20 04 Ubuntu安装 清华源ISO源 https mirrors tuna tsinghua edu cn ubuntu releases 20 04 下载链接 https mirrors tuna tsinghua edu c
  • 【尚硅谷】SSM框架之SSM学习笔记

    MyBatis MyBatis简介 MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis 2010年6月这个项目由Apache Software Foundation迁移到了Google Code 随着开发团队转投
  • Qt程序的编译和发布(实验报告)

    实验 1 编译和发布 Qt 程序 目的与要求 掌握创建 Qt 程序的方法 掌握发布 Qt 程序的方法 学会为 Qt 程序添加应用程序图标 了解 Qt 发布需要的 DLL 动态库文 实验准备 搭建好 Qt 开发环境 了解 Qt Creator
  • Matlab导出动态链接库dll

    1 新建 m文件 内容 function c Add a b c a b end 保存为 Add m 2 命令行输入 gt gt mex setup MEX configured to use Microsoft Visual C 2013
  • 学习笔记(三):Java中的List集合——ArrayList、LinkedList、Vector、Stack、CopyOnWriteArrayList

    目录 引言 一 List简介 二 常用List实现类 一 ArrayList 二 LinkedList 三 LinkedList和ArrayList的比较 三 其他List实现类 一 Vector 二 Stack 三 CopyOnWrite
  • Flutter 安装 填坑记录

    Flutter 安装过程中遇到的问题 安装参考文档 https flutterchina club Add the flutter tool to your path 不知如何在mac中添加环境变量的解决方法参照https jingyan
  • MyBatis学习笔记整理详细

    MyBatis笔记 写在前面 欢迎来到 发奋的小张 的博客 我是小张 一名普通的在校大学生 在学习之余 用博客来记录我学习过程中的点点滴滴 也希望我的博客能够更给同样热爱学习热爱技术的你们带来收获 希望大家多多关照 我们一起成长一起进步 也
  • Unicode编码小结

    Unicode编码 一 ASCLL码 ASCII American Standard Code for Information Interchange 美国信息交换标准代码 是基于拉丁字母的一套电脑编码系统 主要用于显示现代英语和其他西欧语
  • Java与C#一些区别(学习笔记)

    一 基础语法 1 Console表示控制台 2 输入 Console ReadLine 格式 string name name Console ReadLine 3 输出 Console WriteLine 这个自带换行 Console W
  • [足式机器人]Part2 Dr. CAN学习笔记-Ch0-1矩阵的导数运算

    本文仅供学习使用 本文参考 B站 DR CAN Dr CAN学习笔记 Ch0 1矩阵的导数运算 1 标量向量方程对向量求导 分母布局 分子布局 1 1 标量方程对向量的导数 1 2 向量方程对向量的导数 2 案例分析 线性回归 3 矩阵求导
  • C 库函数 - gmtime()

    描述 C 库函数 struct tm gmtime const time t timer 使用 timer 的值来填充 tm 结构 并用协调世界时 UTC 也被称为格林尼治标准时间 GMT 表示 声明 下面是 gmtime 函数的声明 st
  • C 库函数 - mktime()

    描述 C 库函数 time t mktime struct tm timeptr 把 timeptr 所指向的结构转换为自 1970 年 1 月 1 日以来持续时间的秒数 发生错误时返回 1 声明 下面是 mktime 函数的声明 time

随机推荐

  • C++的双端队列

    双端队列介绍 1 双端队列知识需知 2 大试牛刀 1 双端队列知识需知 由于队列是一种先进先出 FIFO 的数据结构 因此无法直接从队列的底部删除元素 如果希望从队列的底部删除元素 可以考虑使用双端队列 deque 双端队列 deque 是
  • 心之森。

  • Windows10 开启、关闭、重启MySQL服务

    1 win R 输入services msc 打开服务 2 找到mysql服务 3 服务名称为MySQL80 4 以管理员的身份打开命令行 运行 C WINDOWSsystem32 gt net stop mysql80 MySQL80 服
  • ElasticSearch(11)bulk批量操作与导入数据

    1 项目环境准备 springboot整合es 项目代码说明 2 bulk批量操作 都是使用add 方法实现的 未执行之前 package com yy esdemo import org elasticsearch action bulk
  • QT css样式 详解

    font family 楷体 为设置字体类型 标准形式需要加双引号 不加也可能会生效 具体看系统是否支持 中英文都支持 但要保证字体编码支持 一般程序编码为 utf 8 时没问题 font style normal 为设置字体斜体样式 it
  • Qt实现端口扫描器

    首先展示一下效果 界面通过Qt设计师做出来的 主要有两个类 首先主函数 include mainwindow h include
  • CSRF的攻击与法防御

    CSRF的攻击与法防御 一 CSRF漏洞原理 CSRF Cross Site Request Forgery 跨站点伪造请求 是一种网络攻击方式 该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点 从而在未授权的情况下执
  • 【vivo2021届秋季校招】1. 编译依赖问题 <拓扑排序、堆>

    vivo2021届秋季校招 1 编译依赖问题 一个完整的软件项目往往会包含很多由代码和文档组成的源文件 编译器在编译整个项目的时候 可能需要按照依赖关系来依次编译每个源文件 比如 A cpp 依赖 B cpp 那么在编译的时候 编译器需要先
  • Embedded Mono: Invoking a C# generic method (Part 2)

    Embedded Mono Invoking a C generic method Part 2 A while ago I wrote about how to invoke a C generic method by using a h
  • Java项目,内存泄漏问题排查与总结,拓展容器相关知识Dockerfile

    问题场景 现象 有一次发现容器里面启动的java项目探活每过一段时间 大概半小时 就失败 导致项目在容器中重复的重启 服务时好时断 问题描述 在容器中排查问题的时候发现了两个问题 进入容器查看启动日志发现 项目启动之初是能够正常运行并且访问
  • WIFI学习第二天

    Wi Fi 6 802 11ax Wi Fi 6是下一代802 11ax标准的简称 随着Wi Fi标准的演进 WFA为了便于WiFi用户和设备厂商轻松了解其设备连接或支持的Wi Fi型号 选择使用数字序号来对WiFi重新命名 另一方面 选择
  • 参考文献对齐方法

    参考文献对齐方法 首先把符号和文本之间的空格都删掉 复制粘贴到记事本中 把每一条参考文献的 符号和文本之间以及文本最后加上Tab键 复制粘贴回word中 全选后右键 段落 两端对齐 悬挂缩进2字符 完成
  • ffmpeg常用音频处理

    使用ffmpeg分析修改音频 ffmpeg layouts查看音频的布局情况 1 双声道合并单声道 ffmpeg i music mp3 ac 1 music aac 2 双声道的提取 map channel input file id s
  • 大数据业务模型和技术架构简图

    大数据业务模型和技术架构简图 1 背景 大数据技术随着互联网的发展而兴起于21世纪初 最早遇到海量数据技术问题的是搜索引擎公司 如谷歌 数据量级别的暴增是由于2010年之后的互联网兴起 网络用户数量暴涨带来的海量用户数据暴增 对大数据处理的
  • firefox火狐能打开http网址,针对所有https网址无法打开

    1 常规的做法 遇到https无法打开时 最常用的做法就是各种百度 然后找到的解决方案就是像下面链接处理的这种 https blog csdn net u011650143 article details 70303894 utm sour
  • linux 网络编程易错点

    1 网络字节序 l 网络字节序存在的意义是实现不同主机字节序的兼容 2 accept l 生成一个新的套接字 这个是所有socket通讯模型的基础 3 sendto l 该函数一定要指定dest len的大小 否则接收端接收不到数据 4 广
  • CMAKE 中add_definitions的用法

    If you are in China please add this CMake flag DTHIRD PARTY MIRROR aliyun to speed up the downloading procedure for some
  • Linux压缩解压命令

    1 tar 解包 tar xvf FileName tar 打包 tar cvf FileName tar DirName 注 tar是打包 不是压缩 2 gz 解压1 gunzip FileName gz 解压2 gzip d FileN
  • mysql 批量 update 多个条件_MySQL更新表数据(八)

    更新数据是使用数据库时最重要的任务之一 在本教程中 您将学习如何使用MySQL UPDATE语句来更新表中的数据 1 MySQL UPDATE语句简介 我们使用UPDATE语句来更新表中的现有数据 也可以使用UPDATE语句来更改表中单个行
  • 15 行代码在 wangEditor v5 使用数学公式

    前言 wangEditor v5 正式版发布在即 为了验证它的扩展性 我开发了几个常用的第三方插件 本文介绍一下 formula 插件的设计和使用 插入数学公式要使用 LateX 语法 渲染公式需要依赖工具 KateX 如 c pm sqr