JuliaGizmos / WebIO.jl

A bridge between Julia and the Web.
https://juliagizmos.github.io/WebIO.jl/latest/
Other
228 stars 64 forks source link

Better fallback when richest_mime is LaTeX #247

Open piever opened 5 years ago

piever commented 5 years ago

Currently, when the richest mime is MIME"text/latex"(), the fallback rendering doesn't work very well, e.g.

julia> using WebIO, SymPy

julia> x = symbols("x");

julia> WebIO.render(x)
(div { setInnerHtml="<pre>\\begin{equation*}x\\end{equation*}</pre>" })

In the specific case of SymPy, one should rather do:

function WebIO.render(x::SymPy.SymbolicObject)
    str = stringmime(MIME"text/latex"(), x)
    lt = match(r"^\\begin{equation\*}(.*)\\end{equation\*}$", str)[1]
    WebIO.render(latex(lt))
end

I wonder what should be our policy, whether we should encourage package authors to implement this in their packages or if somehow we should figure out a good fallback when richest_mime is LaTeX and implement it here. In particular things are somewhat tricky as different packages use different delimiters, for example LaTeXStrings uses dollars whereas SymPy uses \begin{equation*}.

Ref: https://github.com/JuliaGizmos/Interact.jl/issues/275

twavv commented 5 years ago

I don't think that trying to parse out the \begin{equation} is a reasonable thing to do. My suggestion would be to have it handled by SymPy (maybe via Requires.jl?).

shashi commented 5 years ago

I think we shouldn't try to mess around with LaTeX printing... However I think we should allow using LaTeX-able objects inside a wrapper in CSSUtil (it already has a latex function which loads KaTeX), and make this also work when a LaTeX-able object is interpolated into markdown (easy with CSSUtil).

shashi commented 5 years ago

Ah I see you used latex in your suggested fix. I would say for now we should not treat LaTeX as a richest_mime... In the old Interact (before WebIO) we used to render using the display_dict that IJulia produced -- which meant Jupyter would use its own mechanism to print and rerender LaTeX... But it was such a big hack.

piever commented 5 years ago

Maybe WebIO (or a low dependency package like KaTeX which I had created just to have a centralized way to load KaTeX javascript from a local file) could overload a to_katex_string function that transform whatever string they output into something that KaTeX can render?

twavv commented 5 years ago

Could you just add your fix to KaTeX.jl? It seems like something that's specific enough that it doesn't really belong in WebIO itself. Also, you wouldn't need to parse out the \begin{equation} if you did that (I think).

piever commented 5 years ago

There are two intertwined issues:

  1. KaTeX (and its standard rendering function) do not take delimiters (they just want a single string that's the stuff between \begin{equation} or \end{equation}. There is an autorender.js extension that allows something like that but I'm having trouble getting it to work (I'd like things to work locally but somehow it complains if I try to use local katex.js, katex.css and autorender.js). I would actually figure out a way to run KaTeX from local things as the current set up has problem finding KaTeX fonts.
  2. Once 1. is fixed and we have a clean way to parse complex LaTeX strings (like My formula is $F = m \cdot a$), we should still determine where we intercept the rendering pipeline. Maybe render(x::Any) could call render(x, richest_mime(x)) and KaTeX or InteractBase could overload that method with the correct widget.

I can open a PR in InteractBase to try this stuff out so we can discuss there (it also looks like I need some help as I'm getting a bit stuck on importing assets). PR opened: https://github.com/piever/InteractBase.jl/pull/132

twavv commented 5 years ago

Sure. Maybe a separate render_mime method to make it clear that render_mime is the fallback when no render method is defined for the given type (i.e. if a render and render_mime are defined for a given type, render always takes precedence).

twavv commented 5 years ago

I'd also like to do #254 (remove render_internal) before this.

pfitzseb commented 5 years ago

FWIW, Juno handles this by only allowing LaTeX in Markdown, which makes everything pretty easy because Julia's MD parser already does the right conversions. I feel like this could be a sane policy for WebIO as well.

piever commented 5 years ago

Juno handles this by only allowing LaTeX in Markdown, which makes everything pretty easy because Julia's MD parser already does the right conversions.

Sounds like a good plan. Could you spell it out in more detail? Meaning, what would be an easy way to get the "inner part" of LaTeX equations with no delimiters and information whether it is "display mode" or "inline mode" from the markdown?

pfitzseb commented 5 years ago

IIRC I basically re-wrote Base's md-to-plaintext (or something) renderer to ouput Hiccup.Nodes here. Might make sense to pull that file out to somewhere more central, but WebIO could almost use that as-is, I think.

shashi commented 5 years ago

there's already code that can do this. It works too :) https://github.com/JuliaGizmos/CSSUtil.jl/blob/master/src/markdown.jl

twavv commented 5 years ago

What's the status of this?

piever commented 5 years ago

Now there is a package KaTeX.jl which implements a latex function to give you a self updating scope (that takes an observable of text as input). CSSUtil could depend on it to add LaTeX support in markdown blocks, but I don't think that has happened yet.