前言
前一段时间有一个需求,在富文本中可视化编辑公式,并在RN中渲染。我当时一脸懵逼,这要怎么实现。小小的一个需求,我就只知道如何使用现成的富文本。经过几天的努力,终于实现了,虽然还是使用库,但是谁叫我能缝合呢。(大部分的公式和方程式是没有问题的)。
后面有完整代码地址
先来看一下实现的效果
正文
要想实现这个功能我们可以分为这几个步骤
- 富文本如何渲染数学公式和化学方程式
- RN如何渲染富文本的html
- RN如何渲染公式
- 如何可视化编辑公式
- 如何将可视化编辑公式和富文本结合
接下来我们来一一实现
富文本如何渲染数学公式和化学方程式
富文本我们这里使用quill
,Quill - 官网地址。
在他的官网我们可以看到,他自己就支持公式,我们只需要在toolbar
中配置formula
就可以了。
简单简单,直接动手。
保存的瞬间
研究了一会,我才明白官网中(requires KaTeX)
具体是什么意思,我们需要在项目中引入katex
,将下面这个放入项目中就可以了。
js
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.9/katex.min.js" integrity="sha512-LQNxIMR5rXv7o+b1l8+N1EZMfhG7iFZ9HhnbJkTp4zjNr5Wvst75AqUeFDxeRUa7l5vEDyUiAip//r+EFLLCyA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
可以了
开启F12
看一下他是如何渲染的,他主要是靠katex-html
渲染的,katex-mathml
删了都没有事。
这个katex-html
很多啊,我不能把这个全部扔给后端吧,后来我试了一下,把这个给到富文本的value
他就可以渲染出来。
那就好办了,我们只要使用在dom
结构里找到class
为ql-formula
的元素,然后将他的children
去掉就可以了,为什么将data-value
中的\
变为\\
,后面再解释。
数学公式解决了,看一下化学方程式,大问题。
原来是我们还需要mhchem
扩展,我们可以安装mhchemParser
这个库
mhchemParser
是一个用于解析化学方程式和化学式的库。它通常用于在网页或文档中以美观和格式化的方式显示化学相关的信息
我们需要解析这个化学方程式
rust
\\ce{SO4^2- + Ba^2+ -> BaSO4 v}
解析后
css
{\\mathrm{SO}{\\vphantom{A}}_{\\smash[t]{4}}{\\vphantom{A}}^{2-} {}+{} \\mathrm{Ba}{\\vphantom{A}}^{2+} {}\\mathrel{\\longrightarrow}{} \\mathrm{BaSO}{\\vphantom{A}}_{\\smash[t]{4}} \\downarrow{} }
解决
还有一个问题\ce
的嵌套,mhchemParser
不会自己去处理嵌套问题,需要我们去处理,用一个函数来插入公式并解决\ce
的嵌套。
RN如何渲染富文本的html
我们可以借助react-native-render-html
这个库帮我们实现,看这个名字我知道稳了。果然它没辜负这个名字。当然了,想直接这样渲染出来是不可能的。还需要我们处理一下。继续往下看吧。
css
<p><span class="ql-formula" data-value="\\left ( \\frac{a}{b}\\right )^{n}= \\frac{a^{n}}{b^{n}}"></span></p>
RN如何渲染公式
这个试了很多库react-native-math-view
、react-native-mathjax-html-to-svg
、react-native-mathjax
等等,只有react-native-mathjax
渲染没有问题,剩下的库有一些化学方程式渲染报错。其实可以不使用react-native-render-html
因为react-native-mathjax
它自己就可以渲染html
,但是还有别的需求。
这样子,不行页面报错。
这样可以,这就是上面为什么将data-value
中的\
变为\\
的原因。
我们如何在react-native-render-html
中渲染<MathJax/>
呢,react-native-render-html
给我们提供了renderers
属性,可以让我们渲染我们自己的组件。
这段代码的主要意思是,这个span
元素是否是公式,如果是那么将date-value
作为<MathJax/>
的值渲染。
不过<MathJax/>
官网的使用是,要在外面包一个View
并设置宽度,没有设置宽度则不显示,但是公式还没渲染呢,我怎么知道宽度,没有办法只能去改react-native-mathjax
的源码,然后打上补丁。
这是补丁文件,主要就是添加了一个onSize()
方法,把高度和宽度暴露出去。
这就是在RN
中渲染的结果
如何可视化编辑公式
这个我们可以使用mathlive
帮我们实现,官网-- CortexJS - Scientific Computing and Math for the Web。 这样就结束了,简单。
如何将可视化编辑公式和富文本结合
我们要在富文本的toolbar
上添加一个按钮,点击按钮出现一个弹窗,在弹窗中嵌入mathlive
让用户可以可视化编辑公式,最后点击确定,将公式插入富文本中。
我们需要编写一个quill
的module
,但是又不要那么的正规。
编写一个module
并注册 在初始化的时候,给我们自定义的模块按钮绑定点击后发生的事,这样点击toolbar
中按钮的时候就可以出现弹窗了。
接下来只要在弹窗点击确定按钮时,将公式插入到富文本中就可以了。
再来一个点击公式编辑的功能。
修改.ql-formula
的样式
在富文本内容发生变化的时候,给每一个公式添加上点击事件
结束
结尾
感兴趣的可以去试试。