The Internet’s Chinese tutorials and blogs on Vue + MathJax are too weak. They are mostly rehounded from mathJax 2.7.5 2 years ago, and even quoted in a February 2020 article. I can’t bear not to write the front article for a long time.
As an aside, when I was trying to get into the front end, there were a lot of learning summaries on the Internet, and all kinds of projects could be found, and they were all in good shape. When I want to get started with deep learning algorithms now, I find that learning resources, especially good Chinese resources, are not so easy to find. I once talked about this topic with a friend, and my friend joked that front-end engineers are so idle that they can write a summary article even if they solve a big bug. This can also be found in gold mining, where the front-end community is very active, while the plate in the field of deep learning is relatively quiet.
It’s good to be active, but hopefully more truly original content will be produced to help more people.
Starting from the actual project, this paper did not know how to define the problems at the beginning and was basically ignorant. Until now, the problems encountered in practice have been basically solved and the whole development idea has been sorted out.
The version of Mathjax mentioned in this article is 3.0.0
The project requirements
The requirements are simple: we need our Markdown editor to support mathematical formulas written in latex and to display them properly after publication.
For example, put? x = {-b \pm \sqrt{b^2-4ac} \over 2a}.? To identify the formula
(The mining editor also supports latex ~, please click here)
Look for development ideas and focus on the target
In a preliminary Google screening, two plug-ins were locked: Katex and MathJax. They are all tools for rendering formulas. If you look at demos, you can input them in latex, output them in HTML, and display them as mathematical formulas.
MathJax has a long history as the originator of formula rendering, but it continues to be updated. But a lot of the jump links are dead
While Katex is the later-comer, star is more, the website is more beautiful, and also shows katex and MathJax rendering speed comparison
So I chose Katex from the start.
Development and exploration stage
1. Katex entangled with Simplemde
The editor I’m currently using is Simplemde, and katex’s English website gives an example
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}", {
throwOnError: false
});
Copy the code
Very neat, and no more demos. My idea is to find the formula in Markdown, use this method to convert it and add it to the normal rendering result, should be ok?
Simplemde provides a method called previewRender that you can use to customize some render effects before the preview takes effect.
The problem then becomes finding the formula in MarkDown and slipping it back into HTML.
I mostly tried to do this with regex matching, but I spent a lot of time looking it up, but I just couldn’t match it, let alone plug it back in (I hate regex).
Went to have dinner in the middle, interrupted the pace of progress, after coming back to open the official website of MathJax…
In the demo, mathJax can automatically identify all the formulas for the whole site by introducing global resources and global configuration, so that they can be identified in a single step, either in the preview area or after publication. Sure enough, the older the wiser.
2. Explore MathJax instead
After taking a closer look at the Gihub and official documentation for MathJax, you realize that MathJax actually has two ways to identify formulas.
- The first is the global configuration I just described. Once configured, the script will look for the formula symbols in the web page that match the criteria (such as being wrapped in
$
) and compile it.
Click to view the demo effect and the corresponding HTML code
- The second way is to compile the content in the input box and return HTML (in the form of Zhihu) by means of event triggering, such as clicking a button.
Click to view the demo effect and the corresponding HTML code
The first one, in particular, looks very simple and easy.
Importing resources (WHICH I downloaded locally to prevent foreign images from being unstable) and global configuration took a few minutes to complete. Then open the page. emmm… No effect. It’s so easy, you don’t even know what the problem is.
Wrote a static page, the same formula, is effective, it seems that the problem is in vue ah. The initial guess is that the vUE data is rendered, so the MathJax script loads with no content on the page. By the time the content is available, the script has already been executed, so it has no effect. But it’s a shot in the dark. Google and see if anyone else has the same problem, as I said at the beginning, online honeyjuices are all 2.7.5 implementation, There is a window.mathjax.hub. Queue([“Typeset”, mathjax.hub]) method that seems to implement the “overloading script” effect. However, I am now in version 3.0.0, and this method has been undefined….
Gridlock again.
Many other ideas have been tried, of course, which now seem to be a detour.
- If you want to add a button to the edit box, the next best thing is to use the input box to generate the formula. But the compiled HTML of the formula is long and smelly, and it’s not a good idea to just insert markDown.
- Try the second approach to mathJax that I just mentioned. Treat the vue rendered data as if it were form content, and just like the demo, throw the whole Markdown data in
MathJax.tex2chtmlPromise()
In the function. This method works well when there are only formulas in the content, and it really excites me. As soon as the other DOM elements are added, the whole DOM is reorganized and all the styles are lost.
3. Documentation is hard
Google didn’t work, I tried everything I could think of, and finally I went back to the documentation to see what I had overlooked. As it turns out, only documentation can solve everything, and I see a Handling Asynchronous method called mathjax.typesetpromise ().
Where data rendering is done, add this method and the world is a better place…
- On the content display page, you only need to add this method after the data is returned. To ensure that the script is executed after the page is rendered, you can delay it a little:
Ajax.get (XXX).then(res => {// page render setTimeout (res => {mathjax.typesetPromise ()}, 500)})Copy the code
In the Markdown edit area, after previewing the render, execute the render script. Simplemde’s custom render method, previewRender, is used here. Again, there is a slight delay to ensure that the script executes after the page has been rendered. Other editors can do the same if they find a similar method:
this.simplemde = new SimpleMDE({ { //... Other configuration items previewRender: (plainText) => {setTimeout (res => {mathjax.typesetPromise ()}, 500)return this.simplemde.markdown(plainText)
}
},
element: document.getElementById('simplemde')})Copy the code
This method is supposed to be an alternative to window.mathjax.hub.queue after the 2.x version is discarded. Then, sure enough, found this page, the website also has a very detailed explanation. B: Why didn’t you find it earlier? T_T)
After that, we also dealt with the identification of inline formulas, MathJax also came up with custom identification methods, and more Config can be found on the official website.
Window.mathjax = {startup: {pageReady: () => {// alert(111) // Verify that the script was loaded successfully for the first timereturn window.MathJax.startup.defaultPageReady()
}
},
tags: 'all', // for equation number tagSide:'left', // The position of equation number Tex: {processEscapes:true,
processEnvironments: true, // process \begin{xxx}... \end{xxx} outside math mode processRefs:true, // process \ref{... } outside of math mode inlineMath: [ ['$'.'$'],
['\ \ ('.'\ \]']
],
displayMath: [ // start/end delimiter pairs for display math
['? '.'? '],
['\ \ ['.'\ \]']]}Copy the code
4. Summary and comb of MathJax exploration
The entire exploration process took two and a half days. My personal understanding of the overall mechanics of MathJax gradually deepened as I explored the process. In my opinion, it is more important for latecomers to find ways to solve problems, rather than copying methods. So I want to briefly explain the mechanics of MathJax as I understand them.
As mentioned above, there are two ways to render formulas for MathJax. I will repeat it again and never tire of saying:
The first is the global configuration I just described. First, import CND resources and set the global configuration. Once the page is rendered, the script executes, looks for the formula symbol (such as the one wrapped in $) in the page, and compiles it.
If you look carefully, you will find that the examples on the official website have added async to the CDN, synchronous loading, that is, the script will wait for the page content to load, then execute, so as to ensure that the formula is normal rendering.
However, in a data-driven MVC framework like Vue, it would be naive for an external resource to render the DOM. Async would not work and would need to “re-execute scripts”. In version 3.x, this is the mathjax.tex2ChtMLPromise () method.
The second, which is easier to understand, is similar to the example given by Katex. Is to convert all specified formula contents into formula format. This is typically used when the user enters a form in an event-triggered way, such as clicking a button, and then compiles the content of the input box to return HTML.
Compared to MathJax, Katex is something I’ve only explored in the first place, and it’s possible I didn’t notice it, or maybe there was a first implementation of it. After all, its website lists the benefits of being so spicy
conclusion
Katex, MathJax, and Simplemed have no Chinese documentation. If you encounter a problem in the development process, many people’s first reaction is not to look at the document (I did the same), but to search for someone who has a similar problem, or even directly go to Github to mention the issue.
And the lesson from this experience is that when it comes to Google, the answers are all in the documents.