KaTeX + Marked JS works on initial WebView load(), but not on subsequent edits of source code.
-
I paired down the example code that demonstrates the problem but it occupies a complex directory structure, so I thought it best to just included it using a public github repository:
https://github.com/enjoysmath/Marked-KaTeX-example-cpp
After cloning, you just open up the
.pro
file in QtCreator, and build/run/debug it.
This is the result I would like on editing the TextEdit on the left:
That is, the LaTeX gets rendered properly, using KaTeX (and not MathJax!! - it's too slow).
This is what it does on subsequent edits (after intial load):
That is, the LaTeX is no longer rendered.
This is
index.html
which is very relevant to my issues. I also tried the "Auto-render extension" method from KaTeX's documentation.<!doctype html> <html lang="en"> <meta charset="utf-8"> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" integrity="sha384-R4558gYOUz8mP9YWpZJjofhk+zx0AS11p36HnD2ZKj/6JR5z27gSSULCNHIRReVs" crossorigin="anonymous"> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js" integrity="sha384-z1fJDqw8ZApjGO3/unPWUPsIymfsJmyrDVWC8Tv/a1HeOtGmkwNd/7xUS0Xcnvsx" crossorigin="anonymous"></script> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script> <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css"> <script src="3rdparty/marked.js"></script> <script src="qrc:/qtwebchannel/qwebchannel.js"></script> </head> <body> <div id="placeholder"></div> <script> 'use strict'; var placeholder = document.getElementById('placeholder'); var updateText = function(text) { placeholder.innerHTML = marked(text); } new QWebChannel(qt.webChannelTransport, function(channel) { var content = channel.objects.content; updateText(content.text); content.textChanged.connect(updateText); } ); </script> <script> document.addEventListener("DOMContentLoaded", function() { renderMathInElement(document.body, { // customised options // • auto-render specific keys, e.g.: delimiters: [ {left: '$$', right: '$$', display: true}, {left: '$', right: '$', display: false}, {left: '\\(', right: '\\)', display: false}, {left: '\\[', right: '\\]', display: true} ], // • rendering keys, e.g.: throwOnError : false }); }); </script> </body> </html>
So I've tried doing additional things such as calling
.repaint()
etc on the view object every edit. Should I simply replace the widget every edit? That seems like the worst idea in the world!!!Thank you for your expertise.
-
Found a solution:
index.html
needs to be changed to the following rearrangement of the above code:<!doctype html> <html lang="en"> <meta charset="utf-8"> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" integrity="sha384-R4558gYOUz8mP9YWpZJjofhk+zx0AS11p36HnD2ZKj/6JR5z27gSSULCNHIRReVs" crossorigin="anonymous"> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js" integrity="sha384-z1fJDqw8ZApjGO3/unPWUPsIymfsJmyrDVWC8Tv/a1HeOtGmkwNd/7xUS0Xcnvsx" crossorigin="anonymous"></script> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script> <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css"> <script src="3rdparty/marked.js"></script> <script src="qrc:/qtwebchannel/qwebchannel.js"></script> </head> <body> <div id="placeholder"></div> <script> 'use strict'; document.addEventListener("DOMContentLoaded", function() { var placeholder = document.getElementById('placeholder'); var renderMath = function() { renderMathInElement(document.body, { // customised options // • auto-render specific keys, e.g.: delimiters: [ {left: '$$', right: '$$', display: true}, {left: '$', right: '$', display: false}, {left: '\\(', right: '\\)', display: false}, {left: '\\[', right: '\\]', display: true} ], // • rendering keys, e.g.: throwOnError : false }); } var updateText = function(text) { placeholder.innerHTML = marked(text); renderMath(); } new QWebChannel(qt.webChannelTransport, function(channel) { var content = channel.objects.content; updateText(content.text); content.textChanged.connect(updateText); } ); }); </script> </body> </html>
That is we need to call KaTeX after marked() and do so in the same update function. I had to put everything into a document-on-load since for some reason that was needed, but now I'm thinking maybe not. It depends on how KaTeX behaves.