fremling / MathLinkExtras.jl

Package that adds extra functionality on top the of MathLink package, which allows Julia to talk to Mathematica.
Other
10 stars 0 forks source link

latex output would be nice #1

Open hammerfunctor opened 2 years ago

hammerfunctor commented 2 years ago

Sometimes people use julia behind a jupyter server and it would be nice to add latex output for Mathematica outout.

import Base.show
Base.show(io,::MIME"text/latex",x::MathLink.WExpr) = print(io,weval(W`ToString@TeXForm[#]&`(x)))
fremling commented 2 years ago

I agree that this is desirable. It would also to be useful to be able to catch the string as somethings like

    W2Tex(x::MathLink.WExpr) = weval(W`ToString@TeXForm[#]&`(x))

    import Base.show
    Base.show(io,::MIME"text/latex",x::MathLink.WExpr) = print(io,W2Tex(x))

@hammerfunctor: Could you provide med with some documentation about how jupyter communicates the request for latex output?

hammerfunctor commented 2 years ago

You can find some docs here and here. I guess jupyter server receive a json object sent via some Julia ConcretePipe <: AbstractPipe. The later one simply do

for m in mimearray
  if showable(m,x)
    print(io, m, format_m(x))
    break
  end
end

So once you add a MIME output for some julia type, it can automatically be utilized without extra work.

Try out these codes in a jupyter notebook

struct Pow
  base::Number
  exp::Number
end
import Base: show
Base.show(io,::MIME"text/latex",p::Pow) = print(io,"\$$(p.base) ^ {$(p.exp)}\$")
Pow(2,3)

@fremling

fremling commented 2 years ago

Implemented and will come in the next release ;)

hammerfunctor commented 2 years ago

I found that our directly TeXForm format with conflicts with the multimedia format from https://github.com/JuliaInterop/MathLink.jl/blob/master/src/display.jl .

Base.Multimedia.showable(::MIME"image/svg+xml", w::MathLink.WExpr) = w.head == W"Graphics"
Base.show(io::IO, ::MIME"image/svg+xml", w::MathLink.WExpr) = print(io, weval(W"ExportString"(w, "SVG")))

Base.Multimedia.showable(::MIME"image/png", w::MathLink.WExpr) = w.head == W"Graphics"
function Base.show(io::IO, ::MIME"image/png", w::MathLink.WExpr)
    x = weval(W"ExportByteArray"(w, "PNG"))
    write(io, x.args[1].args)
end

Maybe we should merge them and add some fine-grained control against symbol head?

fremling commented 2 years ago

Merging MathLinkExtras into MathLink has been on my wish-list for a while, but MathLink is not very actively maintained at the moment.

Do you have a suggestion for workaround one could put in MathLinkExtras for the time being?

hammerfunctor commented 2 years ago

Basically, we can add some heads to a whitelist, say, W"List", W"Log", "W"Exp", W"Sin", W"Cos", W"Times" .... And define Base.Multimedia.showable for a MathLink.WExpr using in(w,WHITELIST). It's enough to cover a small number of basic heads, and note in the the README to override Base.Multimedia.showable or add something to the WHITELIST on need.

It's also possible to make another repository utilizing Clang.jl, which helps to build a robuster wrapper. I've made a minimal running example but I have not much time. If you are willing to try something, it's my pleasure to send them to you.

fremling commented 2 years ago

If you send me the minimal examples I will see what I can do. ;)

hammerfunctor commented 2 years ago

You can download a text file containing all the information here, which is a armor-encrypted file of the tar ball of the directory.

On Linux, just

wget https://gist.githubusercontent.com/hammerfunctor/e6adde098537ce7c832bc8ce7cd2d0f4/raw/0726b91e05df2e7997fc017f956397ac2cd938ff/WSTP
gpg --batch --passphrase 0000 -d WSTP > wstp.tar.gz
tar xzf wstp.tar.gz

On other platform the process is similar. Note that the passphrase is 0000.

Install Clang.jl. Then in the directory, julia generator.jl to generate LibWSTP.jl. julia demo.jl to fetch a first input name banner from the worlram kernel.

fremling commented 2 years ago

@hammerfunctor Sorry for not getting back to this earlier. I'm trying to understand what the conflict is. When using the Jupyer notebook things seem to render fine (see screenshot below).

I noticed that if i try WPlot[x,{x,0,1}], then things blow up, but it works in the normal case. Whas this what you meant?

image

hammerfunctor commented 2 years ago

@fremling Exactly, Plot[x,{x,0,1}] produced an expression with head Graphics, which is both showable as image/png and as text/latex. The latter has high precedence, and thus the result is messed up.

fremling commented 2 years ago

@hammerfunctor There is now since https://github.com/fremling/MathLinkExtras.jl/commit/f4eb49f354b1c5d1fecbf0cb822d0c970740df1a a quick-patch that solves the graphics issue. Simply put, it checks at the tex/latex level if the head (or any recusive head) has a graphics element. If so It says latex is not possible.

There are still some things to be fixed for the future. For instance is there graphics elements are in a list (or not called with weval) then no graphics is shown.

fremling commented 2 years ago

Merged into the Julia repository as of https://github.com/fremling/MathLinkExtras.jl/commit/26d7813072af175cd8245dbd9ffe5eea94ba41b3.