Math Symbols For React Native
In Jan 2018, At Ideaboard Technologies.
As an ed-tech startup, we wanted to improve the learning experience of every student in India. we started to build a mobile application so it could be easily accessible to any student.
Having time as a primary constraint and also because of our previous experience with react we went with react native over android.
Math symbols are a important part of a educational content based applications. Similarly we too had to solve this particular problem. Saving data in TeX (\alpha) format and converting to MathML ( θ ) in views is a widely used solution for handling math.
After quite some research we ended up with two libraries that support this type of conversion on client applications
But sadly neither of these are directly supported on react native. So we had to indirectly use WebView for rendering using these libraries.
MathView is one library you can look into that has both these engines integrated into them.
MathJax
MathJax is quite a matured library which has been there for a while now and supports almost every symbol that is needed.
It is beautiful and is also intelligent in the way it renders those symbols.
In short, it is aware of its surrounding and careful in placing each symbol at the ideal place. But because of which it has to do more processing and eventually at a slower pace. Also the library is quite heavy itself in terms of size.
KaTeX
KaTeX was built by Khan Academy to overcome the drawbacks of MathJax which was the speed at which it was rendering.
Unlike MathJax, basic symbols need not always be so beautiful and analysed before placing each one in position. It just has look good and solve the problem of having symbols which KaTeX is so good at doing. Check this rendering speed comparison MathJax vs KaTeX.
It is really fast as you could see almost 10x and also smaller in size. But it does not really support all symbols. A few symbols aren’t available yet.
Luckily both of them support inline rendering.
Common Problems
As neither of them provide direct support for react native, we had to use them through react native web view or the native web view (eg: MathView ) and then make it available for react native to use through View Manager. Also you have to solve the problem of wrapping your content in the view after rendering the math in web view by postMessage / onPageFinished to properly fit its content size.
setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
loadUrl("var boundary = document.body.getBoundingClientRect();
javascript:MyApp.resize(boundary.height)");
super.onPageFinished(view, url);
}
});this.addJavascriptInterface(this, "MyApp");@JavascriptInterface
public void resize(final float height) {
runOnUiThread(new Runnable() {
@Override
public void run() {
setLayoutParams(
new LinearLayout.LayoutParams(
getResources().getDisplayMetrics().widthPixels,
(int) (height *
getResources().getDisplayMetrics().density)
));
WritableMap event = Arguments.createMap();
event.putString("message", height + "");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class)
.receiveEvent(getId(), "sizeChange", event);
}
});
}
Conclusion
Like I mentioned earlier both of them has its own merits and demerits. So choose wisely on which one suits you the best.
With MathJax3, solving server side rendering things could get even more interesting. But still looking for a direct support from one of these libraries on react native instead of the WebView solution.