-
Notifications
You must be signed in to change notification settings - Fork 11
Added typst renderer to support png/pdf/jpg/svg exports #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Really appreciate this pull request being put together. Worked almost flawlessly for me. I've pulled it and have encountered a few issues - please see suggested changes. |
Co-authored-by: harrylojames <[email protected]>
Co-authored-by: harrylojames <[email protected]>
@harrylojames Regarding the tooltip: I think the issue is that the jsdom renderer does not display tooltips. As far as I can see this is due to the
|
Currently this throws an error "RuntimeError: unknown format: html" To avoid switching between renderers for the html file type would it make sense to include a line to render htmls @juba? I assume it would just be duplicating this from the jsdom renderer?
|
@harrylojames How to reproduce this RuntimeError? |
Apologies, if you set the extension to html I get this error. Are you able to reproduce with that?
I'm new to typst but it looks like compile doesn't recognise html as a format. |
@harrylojames The only allowed output formats are
I changed the pull request to raise a |
Many thanks for this PR, I'm starting (with quite a delay, sorry) to take a look at it. There are some questions I'm still beginning to explore for now, such as if it is better to create another renderer, or integrate it as sort of output options for jsdom. And I wonder if what is made by manipulating the HTML with beautifulsoup could be done with a typst template. |
@juba Maybe having output options for jsdom is a better idea since the typst renderer is really just translating the jsdom output. Regarding the typst template: You mean something like https://typst.app/docs/tutorial/making-a-template/? If so, then I am not sure it can be done easily. Surely the resulting typst code could be simplified a bit using this e.g. by defining a command for creating the legends. But fore extracting the info from the html it seems more convenient to do the parsing in python. |
@wirhabenzeit Yes, I was thinking about templates, and I've also seen that typst is able to load data from xml document: https://typst.app/docs/reference/data-loading/xml/ This data import mechanism may be too basic to be suitable, but I would like to avoid adding dependencies if it is not necessary. |
@juba Indeed, this is possible. I changed the pull request accordingly. The typst logic is now in the src/pyobsplot/static/template.typ file |
@wirhabenzeit This is great ! I'm currently working on this, I'll try to release a test version very soon. Thanks a lot, as I am not familiar with typst it would have taken me a lot of time to figure this out. |
I just merged a modified version of this PR. I integrated the TypstRenderer into the JsdomRenderer. A new ot = Obsplot(renderer="jsdom", format="png")
# or
ot({...}, format="svg") There is also a
It is not possible to use ot({...}, path="/tmp/out.pdf") I also modified the typst template in order to have a result as close as possible as the default Observable Plot output. This is still very experimental, so any feedback is welcome. Many thanks for your contributions on this very useful feature ! |
@juba great, thanks for improving the code and merging! Some quick testing:
gives an error
|
Thanks for your feedback !
|
@juba great! Regarding the fonts:
The ideal solution would be to convince typst to use a fallback font just for the → symbol and not the whole label. Not sure how this can be done though |
You're right about Roboto and Noto Sans. The right arrow in Noto Sans seems to be available in Noto Sans Symbols and Noto Sans Math, which are installed by default on my system, but don't if just Noto Sans is installed from Google Fonts. I added Lucida Grande and Arial at the end of the default font list. Let me know if you think the result is good enough. Many thanks for your useful feedback. |
If you planned to test the new output formats in the days to come, I wanted to warn you that I just introduced two breaking changes in the development version. First, the syntax with which you could define plots with kwargs is now deprecated, so it is no more possible to do something like: Plot.plot(marks=[Plot.dot()], title="foo") Second, and more importantly, I changed the plot generator API: generator objects are no longer created with a In summary:
Sorry for the breaking changes, but I believe it will make the API a bit clearer and more usable. I've updated the documentation accordingly. Any feedback welcome ! |
@juba I think not exposing this jsdom renderer so prominently is a good idea. So the logic is that the Actually, thinking about it, wouldn't it make more sense to specify the format on a per call basis, just like the path? What I mean is that the two main methods of operation could be
or maybe even
for displaying and/or exporting? This would be conceptually simpler than exposing these custom renderers? A small drawback is that one has to respecify the format at every call (for non-default format) but this does not seem so problematic. |
In fact you can pass a # Default format
op = Obsplot(format="png")
# Override default format
op({}, format="svg")
# Plot.plot
Plot.plot({}, format="html") This way, you can both specify a default format, and override it for a specific plot if needed. You can also add a op({}, path="out.png")
Plot.plot({}, path="out.png") The path extension takes precedence over the format: op = Obsplot(format="svg")
op({}, path="out.svg") # => export to SVG (with a warning)
op({}, path="out.png") # => export to PNG (with a warning)
Plot.plot({}, format="png", path="out.svg") # => export to SVG (with a warning) If the format is Do you think it makes sense ? |
@juba Hmm, I tried but for me
gives As for the general question, it seems a bit problematic that there is no one-to-one correspondence between
Without knowing the internals it seems weird that
I first thought that it would be best to completely decouple |
I referenced your answer to continue the discussion in #37 |
This is a pull request addressing #23
Supported output formats are
Example
results in

Writing to file
saves the output to a file
Issues
over something like