LaTeX rendering with MathJax/KaTeX #696
Replies: 10 comments 10 replies
-
I use markdown + latex for most of academical writings. Big plus for that propose |
Beta Was this translation helpful? Give feedback.
-
Great suggestion. We would love to see LaTeX formulas integrated. Any pull-requests towards this goal are welcome! |
Beta Was this translation helpful? Give feedback.
-
Also a big +1 here. I've built a NiceGUI app (that I use a lot) with a crucial feature that would rely on this. I will probably do some googling this weekend to see if there are any low-hanging ways to build this into NiceGUI. I will update this thread if anything seems promising. If there is an obvious path, I will try and submit a PR if I can find the time. |
Beta Was this translation helpful? Give feedback.
-
Here is a quick hack for anybody in the meantime. It uses this markdown implementation with pymdown extensions. import re
from markdown import Markdown
from nicegui import ui
HIGHLIGHT_STYLE = "background: #f5f5f5; border-radius: 0.2rem;"
HIGHLIGHT_STYLE += "padding: 0.2rem 0.3rem 0.2rem 0.3rem;"
def markdown_to_html_with_math(markdown_text: str) -> str:
md_parser = Markdown(
extensions=[
"pymdownx.superfences",
"pymdownx.highlight",
"pymdownx.arithmatex",
"pymdownx.inlinehilite",
],
extension_configs={
"pymdownx.inlinehilite": {
"style_plain_text": True,
},
"pymdownx.highlight": {
"guess_lang": False,
"noclasses": True,
},
"pymdownx.arithmatex": {
"smart_dollar": False,
"preview": True,
"generic": True,
},
},
)
return md_parser.convert(markdown_text)
def apply_tailwind(html: str) -> str: # Borrowed from NiceGUI's ui.markdown
rep = {
"<h1": '<h1 class="text-5xl mb-4 mt-6"',
"<h2": '<h2 class="text-4xl mb-3 mt-5"',
"<h3": '<h3 class="text-3xl mb-2 mt-4"',
"<h4": '<h4 class="text-2xl mb-1 mt-3"',
"<h5": '<h5 class="text-1xl mb-0.5 mt-2"',
"<a": '<a class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600"', # noqa: E501
"<ul": '<ul class="list-disc ml-6"',
"<p>": '<p class="mb-2">',
}
pattern = re.compile("|".join(rep.keys()))
return pattern.sub(lambda m: rep[re.escape(m.group(0))], html)
def apply_custom_highlight_style(html: str) -> str: # Would be better w/ re
classes_to_highlight = ["highlight"]
for class_name in classes_to_highlight:
html = html.replace(
f'class="{class_name}"',
f'class="{class_name}" style="{HIGHLIGHT_STYLE}"',
)
return html
def markdown(text: str) -> ui.html:
html = markdown_to_html_with_math(text)
html = apply_tailwind(html)
html = apply_custom_highlight_style(html)
return ui.html(html)
if __name__ in {"__main__", "__mp_main__"}:
# The presence of these scripts in page body is necessary for MathJax to render
mathjax_scripts = """
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
"""
ui.add_body_html(mathjax_scripts)
# Raw string is important for parser to not remove '\b', '\t', etc. from math
example_md_text = r"""
This is inline code: `hello world`
This is block code:
(add your own since putting backticks here would confuse GitHub)
This is inline math: $\text{det}(A)$
This is block math:
$$ A = \begin{bmatrix} a & b \\ c & d \end{bmatrix} $$
This is a gif:
![silly cat](https://media.giphy.com/media/vFKqnCdLPNOKc/giphy.gif)
"""
markdown(example_md_text)
ui.run() |
Beta Was this translation helpful? Give feedback.
-
I wonder if something like this would work - and have it be it's own element (temporarily ofc) |
Beta Was this translation helpful? Give feedback.
-
from nicegui import ui
class LaTeXTemplate(ui.element):
def __init__(self, script: str, template: str):
super().__init__()
self.script = script
self.template = template
ui.add_head_html(self.script)
ui.html(self.template)
head_html = '''
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
</script>
'''
body_html = '''
<body>
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
</body>
'''
custom_index_template = True
@ui.page(path='/')
def index():
if custom_index_template is True:
with ui.row():
LaTeXTemplate(head_html, body_html)
ui.run() Renders beautifully |
Beta Was this translation helpful? Give feedback.
-
Based on above code supplied by sonnygeorge, I get a more universal Markdown element. You can find it here TL;DR
the following code is what I get currently. Please note
|
Beta Was this translation helpful? Give feedback.
-
it is tedious to treat markdown files, is there any markdown editor widget fro VUE which
if we can find one, I think we can pretend it to be the NiceGUI markdown component |
Beta Was this translation helpful? Give feedback.
-
PR #3860 just got released in version 2.4.0, implementing LaTeX support in |
Beta Was this translation helpful? Give feedback.
-
Hello!
I would like to suggest adding math formulas support for markdown, which would be especially useful for scientific applications.
python-markdown2
doesn't seem to support LaTeX, so this might require changing the markdown implementation.Also, it would be great to use markdown with LaTeX for basic elements such as links, buttons and checkboxes.
Beta Was this translation helpful? Give feedback.
All reactions