15 行程式碼在 wangEditor v5 使用數學公式

語言: CN / TW / HK

前言

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 就已經具備了顯示公式的能力,但還需要配置選單:插入公式,編輯公式。

配置選單

配置工具欄,把 insertFormulaeditFormula 插入到 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學習手冊:http://doc.crmeb.com
技術交流論壇:http://q.crmeb.com