TinyMce是一款相對好用的富文本編輯插件。
富文本編輯器中集成數(shù)學(xué)公式是一個比較被經(jīng)常提到的需求。
經(jīng)過搜索得知TinyMce中集成數(shù)學(xué)公式的方案目前有三個:
? ? 1.mathType插件
? ? 2.kityformula-editor插件
? ? 3.mathjax插件
首先mathType插件個人認(rèn)為是比較好用的,但致命的一點也是這個插件是付費使用的,經(jīng)過一番搜索并沒有找到破解方案或者續(xù)費方案。不然也不會有此文章。這三個插件都可以獨立使用,至于使用方式有其他的博主介紹,本文不做過多講解。本文主要內(nèi)容為當(dāng)你使用mathType插件過期后如何兼容老數(shù)據(jù)以及繼續(xù)編輯數(shù)學(xué)公式的平替方案以及免費,希望存儲latex格式的公式并且需要圖形界面的實現(xiàn)思路。
分析過程:
MathType插件生成的數(shù)學(xué)公式轉(zhuǎn)換為源碼后為MathML格式 如下:


kityformula-editor插件: 提供圖形界面可以編輯公式,但是存儲后的格式為圖片或base64編碼的圖片,保存后無法與文本形成格式上的統(tǒng)一,布局較亂。
mathjax插件: 可以生成Latex格式的公式存儲給后臺 避免了布局上的混亂,并且可編輯性強格式統(tǒng)一。缺點是沒有圖形界面來編輯公式,需要會使用Latex語法才能鍵入公式,對使用人員要求比較高。如下圖:

所以,有什么方案可以既免費,又擁有圖形編輯界面,又可以存儲為通用的數(shù)學(xué)公式格式呢?
筆者的思路是結(jié)合kityformula-editor 與 tinymce-mathjax 插件。修改兩插件源碼,利用kityformula-editor的圖形界面輸入,然后調(diào)用tinymce-mathjax插件寫入標(biāo)準(zhǔn)的Latex格式。這樣就可以完美實現(xiàn)數(shù)學(xué)公式的需求了。
如果初次引入數(shù)學(xué)公式,那么至此就可以直接使用了。
但筆者曾經(jīng)使用的是MathType,由于試用期到期不得不尋找平替方案,故還需要兼容數(shù)據(jù)庫中已存在的MathML格式的公式。這里選擇mathml2latex這個庫進行l(wèi)atex與MathML轉(zhuǎn)換,解決了這個問題。
至此,需求以及實現(xiàn)思路解釋完成,開始Coding。。。。。
第一步:首先安裝以上提到的所有插件:(筆者的項目為Element-ui模版項目,使用相同模版的話可以直接復(fù)制)
kityformula-editor插件: http://tinymce.ax-z.cn/more-plugins/kityformula-editor.php
mathJax-timyMce插件: https://github.com/dimakorotkov/tinymce-mathjax/archive/master.zip? ?
mathml2latex插件: https://github.com/androettop/mathml2latex (不需要兼容mathml可不下載)
下載好插件后,將下載的內(nèi)容放在src/public文件夾下 然后運行npm install mathjax? 從node_modules中復(fù)制出mathjax文件夾,放在public下。
找到tinyMce配置,按照如下方式集成插件至TinyMce:
plugins:['kityformula-editor','mathjax',.............],
toolbar:['kityformula-editor | mathjax...........'],
mathjax: {lib:'/mathjax/es5/tex-mml-chtml.js',}
external_plugins: {'kityformula-editor':`/kityformula-editor/plugin.min.js`,'mathjax':'/tinymce-mathjax/plugin.js'},
至此,插件已安裝完成,你的工具欄應(yīng)該已經(jīng)有mathjax以及kityformula-editor兩個插件工具并可以獨立使用。
第二步:融合現(xiàn)有的公式插件,讓kityformula-editor在前臺編輯公式,mathjax轉(zhuǎn)入后臺被調(diào)用寫入公式。
打開public/kityformula-editor/plugin.js 修改var baseURL = '/kityformula-editor/kityFormula.html';如下圖

打開public/kityformula-editor/kityFormula.html文件 修改第72行為 content: `<span class="math-tex">\\(${latex}\\)</span>`如下圖所示,目的為使插件輸出Latex格式的公式而非圖片。

接下來找到public/tinymce-mathjax/plugin.js文件 開始修改tinymce-mathjax插件,重寫點擊事件,使其能在點擊latex格式公式的時候拉起kityformula-editor實現(xiàn)編輯。
找到第127行,? editor.on("click", function (e) {....方法,修改如下
? editor.on("click", function (e) {
? ? var sel = editor.selection.getContent();
? ? var path = /\<span(.*?)class="math-tex"(.*?)data-latex="(.*?)">/g;
? ? var path2 = /data-latex="(.*?)"/g;
? ? if (sel.search(path) == 0) {
? ? ? sel.replace(path2, function ($0, $1) {
? ? ? ? const pa = $1.replace('\\\(', '')
? ? ? ? const pa2 = pa.replace('\\\)', '')
? ? ? ? var param = encodeURIComponent(pa2);
? ? ? ? // param = param.replace('\\(','')
? ? ? ? openDialog(param);
? ? ? ? return $0;
? ? ? });
? ? }
? ? ;
? ? // let closest = e.target.closest('.' + mathjaxClassName);
? ? // if (closest) {
? ? //? openMathjaxEditor(closest);
? ? // }
? });
緊接著這個方法,再回到public/kityformula-editor/kityFormula.html這個文件,找到打開公式編輯器的openDialog方法并復(fù)制過來粘貼到public/tinymce-mathjax/plugin.js文件內(nèi),使得上述方法可正常調(diào)用。
? var openDialog = function (param) {
? ? var baseURL = '/kityformula-editor/kityFormula.html';
? ? return editor.windowManager.openUrl({
? ? ? title: '插入公式',
? ? ? size: 'large',
? ? ? width: 785,
? ? ? height: 475,
? ? ? url: param ? baseURL + "?c=" + param : baseURL,
? ? ? buttons: [
? ? ? ? {
? ? ? ? ? type: 'cancel',
? ? ? ? ? text: 'Close'
? ? ? ? },
? ? ? ? {
? ? ? ? ? type: 'custom',
? ? ? ? ? text: 'Save',
? ? ? ? ? name: 'save',
? ? ? ? ? primary: true
? ? ? ? },
? ? ? ],
? ? ? onAction: function (api, details) {
? ? ? ? switch (details.name) {
? ? ? ? ? case 'save':
? ? ? ? ? ? api.sendMessage("save");
? ? ? ? ? ? break;
? ? ? ? ? default:
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? ;
? ? ? }
? ? });
? };
至此,應(yīng)該已經(jīng)實現(xiàn)了兩個插件的互相調(diào)用,可以用圖形界面寫入/編輯latex公式正常使用了。如果你沒有筆者一樣需要兼容MathML格式的需求,可以無需看下面的內(nèi)容了。如果有,請往下看。
第三步:目前雖然兼容了latex,但是如果服務(wù)端返回了MathML的內(nèi)容,依舊是不能解析成正確的公式樣式進行渲染的。假如你的數(shù)據(jù)量較少,那么可以直接申請后端的同學(xué)幫忙批量轉(zhuǎn)換,如果暫時做不到,可以按照我的方式讀取時轉(zhuǎn)換為latex,編輯過后再保存就變成了latex格式。這么做以后你的數(shù)據(jù)庫中數(shù)學(xué)公式將會存在兩種格式,請權(quán)衡利弊后使用。
找到public/index.html文件 加入如下腳本引入插件。
<script src="<%= BASE_URL %>mathml2latex/mathml2latex.js"></script>
找到你的代碼,對tinyMce綁定的數(shù)據(jù)進行監(jiān)聽,輸入編輯器前用如下方法轉(zhuǎn)換。
convertMathmlToMathJax(value) {
let texValue = value +''
? const req =/<math(([\s\S])*?)<\/math>/gi
? if (!req.test(texValue)) {
return value
}
const array = texValue.match(req)
array.forEach(item => {
texValue = texValue.replace(item,`<span class="math-tex">\\( ${window.MathML2LaTeX.convert(item)} \\)</span>`)
})
return texValue
},
至此就可以平替收費的mathType插件了。但終歸不如收費插件支持范圍廣。如果你有更好的想法 歡迎與我討論。