Closed joyceerhl closed 3 years ago
(Experimental duplicate detection) Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:
I don't think we've committed to full latex support. We ship support for katex math formulas to validate the new, extensible markdown renderers. It's still TBD if we would bundle this limited support or require notebook providers to bring their own markdown extensions
Following up on Friday's meeting, I did some investigation to root cause the math examples we talked about that aren't rendering with the current native notebooks experimental markdown renderer. Please let me know if I can provide other context that might be more helpful.
Notebook offering | Markdown parser | Math library | Additional notes |
---|---|---|---|
JupyterLab | marked | MathJax 2 | JupyterLab preprocesses markdown to hide math expressions from their markdown parser and defer math handling to MathJax. The @jupyterlab/rendermime package provides default renderers for Markdown in Jupyter. Logic for preprocessing markdown: remove math, convert markdown to HTML, replace math, then render HTML. Logic for preprocessing math. JupyterLab also provides extensions for rendering math using KaTeX or MathJax 3: https://github.com/jupyterlab/jupyter-renderers |
nteract | @nteract/outputs package vendors @nteract/markdown which uses react-markdown | MathJax 2 via @nteract/mathjax | @nteract/mathjax is a React wrapper that pulls MathJax from https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_CHTML |
(Google Colaboratory notebooks aren't open source but this comment indicates they try to be consistent with JupyterLab.)
(jupyter/nbformat has an issue tracking standardizing its markdown + LaTeX support as part of the nbformat spec, although that issue hasn't seen activity in some time.)
Code that doesn't work | Cause | What to do about it |
---|---|---|
Jupyter notebooks documentation on examples of MathJax equations | https://katex.org/'s playground correctly renders the source for almost all of these examples, so this is not a syntax parity issue. Current (unvalidated) theory is this works in JupyterLab due to the math preprocessing that they perform. | Implement same preprocessing hacks in math renderer extension and see if that suffices |
Euler's identity: $$ e^{i \pi} + 1 = 0 $$ | Likely caused by markdown parser. Inline $$ -delimited math equations are rendered in block style in JupyterLab. Users can work around this by placing the $$ bound section on a newline. |
Implement same preprocessing hacks in math renderer extension and see if that suffices |
$ e^{i \pi} + 1 = 0 $ | Known limitation of markdown-it-katex library: doesn't support inline math equations where the equation delimiter $ is surrounded by spaces. See https://github.com/waylonflinn/markdown-it-katex#syntax |
Upstream fix to markdown-it-katex |
$$ \begin{eqnarray} \frac{dx}{dt} &=& v, \text{ and} \\ \frac{dv}{dt} &=& a, \end{eqnarray} $$ | Issue provides the same equation in single- and multi-line format. Both work in JupyterLab. Neither works with experimental markdown renderer support. Single-line variant works in MathJax demo and not in https://katex.org playground. Root cause seems to be a KaTeX-specific limitation: https://github.com/KaTeX/KaTeX/issues/1931. | Add support for MathJax math flavor e.g. using markdown-it-mathjax or @nteract/mathjax-electron |
$$ \text{For } x \in \mathbb{R}^n \text{, } sigmoid(x) = sigmoid\begin{pmatrix} x_1 \ x_2 \ ... \ x_n \end{pmatrix} = \begin{pmatrix} \frac{1}{1+e^{-x_1}} \ \frac{1}{1+e^{-x_2}} \ ... \ \frac{1}{1+e^{-x_n}} \end{pmatrix}\tag{1} $$ | LaTeX equation provided is correctly rendered in JupyterLab but doesn't work in MathJax demo or KaTeX playground, so it doesn't seem to be a syntax parity issue. Replacing \\end with \end seems to get this particular example working in the MathJax demo and with the experimental markdown renderer in native notebooks. |
Possibly invalid LaTeX example |
https://github.com/microsoft/vscode-jupyter/issues/4938 | Code sample provided doesn't render in JupyterLab, MathJax playground, or KaTeX playground. Including for completeness. | Possibly invalid LaTeX example |
LaTeX in HTML in Markdown | Likely requires a fix at the markdown parser level, although I don't know enough about markdown to say for sure. | TBD |
Leaving this background info here for anyone else who is starting out with understanding LaTeX in Markdown.
@joyceerhl I've forked markdown-it-katex (https://github.com/mjbvz/markdown-it-katex) and applied a few minor fixes
I think the Python team should look into these since Python is the primary consumer of math support. On the VS Code side, we're focusing on extensible markdown renderers right now. Feel free to submit PRs to the upstream repo or let me know if you find a better markdown-math integration library
Thanks @mjbvz we agree and we plan to investigate leveraging the notebookMarkdownRenderer contribution point you added, tracked in https://github.com/microsoft/vscode-jupyter/issues/5365
@joyceerhl Just to make sure you we are on the same page: you shouldn't need to worry about notebookMarkdownRenderer
all right now. We bundle https://github.com/mjbvz/markdown-it-katex into VS Code, so if your team can submit fixes for the markdown markdown parsing issues you identified, we'll pull them into VS Code and python won't have to have any custom Latex logic
A few more findings on KaTeX vs MathJax
Tested using our current webpack script (production but no advanced optimization):
260kB of JS + 23kB of CSS + lazily loaded fonts. For a simple equation, I see this loading a 30kB font file
1.7MB all bundled together (using https://github.com/tani/markdown-it-mathjax3)
Using the above bundles, render times for equations are roughly similar. However MathJax takes significantly longer to initially evaluate (which makes sense since the script source is much larger).
The profiles below were collected inside a VS Code notebook
We've put in a lot of work to avoid having notebook cells shift around while loading or scrolling.
With KaTeX, here's a profile showing how equations are rendered:
There are essentially three stages:
The only layout shift happens going between step 1 and 2
Now here's using MathJax3:
Again, there are three stages:
However in this case there are two layout shifts: one during the first load and another between steps 2 and 3.
The KaTeX rendering is preferable here since it avoids an extra resize
Here's a list of LaTeX features that KaTeX supports or doesn't support.
Here's a list of supported LaTeX command for MathJax (I can't find a list of unsupported features and some elements on this list require using built-in MathJax extensions)
Using the developer console, I put together this really poor scraper to generate a list of LaTeX features supported in MathJax but not in Katex:
// Run these two snippets on each page
// https://katex.org/docs/support_table.html
const katexNotSupported = Array.from(document.querySelectorAll('td'))
.filter(x => { const s = x.querySelector('span'); return s?.textContent === 'Not supported' })
.map(x => x.previousSibling.textContent)
// https://docs.mathjax.org/en/latest/input/tex/macros/index.html
const mathJaxSupported = new Set(Array.from(document.querySelectorAll('tr td:first-child')).map(x => x.textContent))
// Then on some page with both sets of results
katexNotSupported.filter(x => mathJaxSupported.has(x))
This produces the following list:
- \abovewithdelims
- \array
- \Arrowvert
- \arrowvert
- \atopwithdelims
- \bbox
- \bracevert
- \buildrel
- \cancelto
- \cases
- \class
- \cssId
- \ddddot
- \dddot
- \DeclareMathOperator
- \definecolor
- \displaylines
- \enclose
- \eqalign
- \eqalignno
- \eqref
- \hfil
- \hfill
- \idotsint
- \iiiint
- \label
- \leftarrowtail
- \leftroot
- \leqalignno
- \lower
- \mathtip
- \matrix
- \mbox
- \mit
- \mmlToken
- \moveleft
- \moveright
- \mspace
- \newenvironment
- \Newextarrow
- \notag
- \oldstyle
- \overparen
- \overwithdelims
- \pmatrix
- \raise
- \ref
- \renewenvironment
- \require
- \root
- \Rule
- \scr
- \shoveleft
- \shoveright
- \sideset
- \skew
- \Space
- \strut
- \style
- \texttip
- \Tiny
- \toggle
- \underparen
- \unicode
- \uproot
I pushed a change that handles a few of the cases listed. Source text:
Rendered result:
Specifically this addresses:
Euler's identity: $$ e^{i \pi} + 1 = 0 $$
$ e^{i \pi} + 1 = 0 $
$$ \text{For } x \in \mathbb{R}^n \text{, } sigmoid(x) = sigmoid\begin{pmatrix} x_1 \ x_2 \ ... \ x_n \end{pmatrix} = \begin{pmatrix} \frac{1}{1+e^{-x_1}} \ \frac{1}{1+e^{-x_2}} \ ... \ \frac{1}{1+e^{-x_n}} \end{pmatrix}\tag{1} $$
The next easy one I'm looking into is the single $
math block :
$\begin{align}
\dot{x} & = \sigma(y-x) \\
\dot{y} & = \rho x - y - xz \\
\dot{z} & = -\beta z + xy
\end{align}$
Please test in the next insiders a let me know if you notice any regressions
/cc @kieferrm @rebornix
Ok, the majority of examples from the Jupyter Math example notebook now work too:
Not sure if this change made the insiders for tomorrow or not.
The two remaining cases from the Jupyter notebook that don't work due to KaTeX:
Is the experimental native LaTeX support works in the VSCode version of Github Codespaces?
I'm trying it with the following version:
Version: 1.56.0-insider
Commit: 58186680eb97fe979e1d986bcfa983ab0a6228e4
Date: 2021-04-06T10:32:31.104Z
Browser: Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0
Even after enabling notebook.experimental.useMarkdownRenderer
flag, any LaTeX formula simply won't work (even those reported here that are working).
Any idea why?
@delucca Please provide steps to reproduce the issue. Are you sure you are using native notebooks for example?
@mjbvz yes I am.
Do you have access to Github Codespaces? If so, you can do the following:
notebook.experimental.useMarkdownRenderer
flagCtrl+P
Oh actually we have disabled the new renderers on web
Will revisit once we feel things are looking good on desktop
Oh actually we have disabled the new renderers on web
Will revisit once we feel things are looking good on desktop
Oh, I see.
There is no way to bypass that setting? I use the Github Codespaces as my primary IDE, and I would like to use this feature
@joyceerhl https://github.com/microsoft/vscode/commit/cd9a6a48201099f9441d5cd76581197c88ec34f3 Added telemetry to track how often something that looks like unsupported KaTeX directive appears in a native notebook
We'd still like your help analyzing a broader notebook population (i.e. not just those being opened in VS Code) to see which directives are used most commonly so we know what to prioritize
Ok, the majority of examples from the Jupyter Math example notebook now work too:
Hi! I have the VSCode Version: 1.55.2 on MacOS Mojave, Jupyter extension v2021.5.745244803. Just tried this notebook - no equation was rendered properly. Tried to run all cells and then every cell manually.
VSCode output:
Browser-based notebook worked fine:
What is wrong in my VSCode?
@bellerofonte I observe the same behavior. Try putting your equation- and align-environments within $$ ... $$, that works for me. Albeit the align environment giving each equation the same number...
Also, putting those environments within display style $$ ... $$'s is wrong syntax, I don't know why it works. Should be fixed, imho.
Closing as we've shipped support for math equations
Please open new issues for any further bugs / feature requests
Steps to Reproduce:
notebook.experimental.useMarkdownRenderer
set to true.Does this issue occur when all extensions are disabled?: Yes