JuliaGraphics / Luxor.jl

Simple drawings using vector graphics; Cairo "for tourists!"
http://juliagraphics.github.io/Luxor.jl/
Other
576 stars 72 forks source link

Incorrect rendering of texts in Pluto markdown cells #228

Closed GiggleLiu closed 1 year ago

GiggleLiu commented 2 years ago

The subscripts in the svg plots are not rendered properly in Pluto markdown.

image

The png format looks good, the directly display of svg is also good.

cormullion commented 2 years ago

Hi! I have no idea what's going on here. :)

Without specifying a font for text(), I don't see a character, just an empty rectangle.

With a suitable font selected, I see the correct character:

Screenshot 2022-07-08 at 11 02 03

So what's the default font used by Luxor/Cairo if you don't specify a font before using text()? That's a good question, and I don't know the answer. On my MacOS system it appears to use Helvetica (or similar). On Windows perhaps it's Arial. On Unix, might be, well, who knows, perhaps DejaVu. And I don't know which of these fonts include subscript glyphs...

(By the way, Luxor/Cairo SVG-generation doesn't embed fonts or glyph numbers; it always conveys the glyphs to graphic paths, so there are no font-embedding issues (or benefits).)

GiggleLiu commented 2 years ago

I do not think it is a fontface issue, I tried monospace, JuliaMono-Light, DejaVu et al. None of them works. I am using Ubuntu 22.04.

GiggleLiu commented 2 years ago

image

I have a better example here. It also just does not render regular characters correctly.

cormullion commented 2 years ago

Ah, have you got more than one SVG image in your notebook?

cormullion commented 2 years ago

Might be https://github.com/JuliaPlots/Makie.jl/issues/952 but for Pluto...

GiggleLiu commented 2 years ago

VG image in your notebook?

Yes. It is likely to be the reason. But when I do not use svg in md environment. Everything looks fine.

GiggleLiu commented 2 years ago

Is it possible to circumvent this issue? Because I need to layout the images.

cormullion commented 2 years ago

Sorry, I don't know enough about Pluto's Markdown and the use of expressions here.

If you just use simple code cells the SVGs don't look like they interact badly:

Screenshot 2022-07-08 at 21 39 21

Similarly, if you return a variable holding the drawing, it seems to work OK too:

Screenshot 2022-07-08 at 21 44 36

Perhaps you could ask the Pluto folks to help? They know more about the interaction between the display system, Markdown, macros, and cells than I will ever do. :)

GiggleLiu commented 2 years ago

Hi, @fonsp . We need your help. Do you know why svg generated by Luxor interact so badly with the markdown environment in Pluto? This is the code that you can reproduce the issue, but you probably need a linux system.

UPDATE: I tried to debug by disabling cell by cell, it can fix the problem if I disable the previous svg plots, which confirms it is a svg cross talk problem.

GiggleLiu commented 2 years ago

Now I am almost sure it is a glyph id problem. The following PR is an approach to fix, but it is a kind of dirty fix, which basically replaces the ids using regular expression.

https://github.com/JuliaPlots/CairoMakie.jl/pull/163/files

In a Pluto cell output, the Drawing is rendered as an <img>, while in a mardown environment, it is raw svg directly embeded in html. This is why their behaviors are so different. Is it possible also render the svg in mardown as ? @fonsp , I notice that for png files, it is using this strategy, I guess it is also possible for svg?

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

fonsp commented 1 year ago

Hey @GiggleLiu ! Pluto doesn't really have control over how the Markdown stdlib handles interpolation. In this case, the Markdown stdlib runs this function which writes the SVG contents directly as HTML output.

You want it to do this, replacing png with svg+xml, which will render the svg in an <img> element using a base64-encoded data URI. This is pretty much identical to how Pluto displays the object when it is the result of the cell (i.e. without md").

You could open a PR to julialang/julia to use this method for svg images, or you could add an override into your notebook, or into Luxor.jl. Something like this should work:

import Markdown
Markdown.tohtml(io::IO, img::Luxor.SVGDrawing) = # replace SVGDrawing with the actual name
    print(io, """<img src="data:image/svg+xml;base64,""")
    print(io, Markdown.stringmime(MIME"image/svg+xml"(), img))
    print(io, "\" />")
end

This method overload is not type piracy because it only dispatches on a type from Luxor.jl.