quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.7k stars 300 forks source link

Vector graphics (htmlwidget) in typst, similar to default pdf #7716

Open sda030 opened 9 months ago

sda030 commented 9 months ago

Bug description

I wish it was possible to render vector-based plots with typst, similar to the crisp quality produced with default pdf. The webshot-solution for typst is far from ready-to-go and requires several tweaks with fig-dpi, and occasionally also fig-width. I have tried with fig-format: svg and prefer-html: true in vain. This is a particularly annoyance with htmlwidget-based graphics such as ggiraph, where the resulting default webshot2 is of low resolution. Sure, one can adjust with fig-dpi: 450, but that also explodes the physical size of the figure on the page (should probably be a separate issue, but connects with the above).

Steps to reproduce

---
format:
  pdf: default # replace with typst to see difference
---

```{r}
#| label: 'fig-a'
#| fig-cap: 'Good resolution, but non-selectable text'
  ggplot2::ggplot(mtcars, mapping = ggplot2::aes(x=mpg, y=disp)) +
  ggplot2::geom_point()
#| label: 'fig-b'
#| fig-cap: 'Even worse using webshot'
fig1 <-
  ggplot2::ggplot(mtcars, mapping = ggplot2::aes(x=mpg, y=disp)) +
  ggiraph::geom_point_interactive()

ggiraph::girafe(ggobj = fig1)

### Expected behavior

![image](https://github.com/quarto-dev/quarto-cli/assets/13221371/1461bd75-d785-4eee-b593-2987f373bbc8)
Notice that text is selectable, when rendering with `pdf: default`

### Actual behavior

Notice that text is not selectable:
![image](https://github.com/quarto-dev/quarto-cli/assets/13221371/27212fca-8530-43eb-aef1-f35eec700dc1)

Even worse when htmlwidget:
![image](https://github.com/quarto-dev/quarto-cli/assets/13221371/058cb0a9-0c11-42ef-85de-8df28e74e216)

Setting `fig-dpi: 196` to improve on the ggiraph-plot blows up the size
![image](https://github.com/quarto-dev/quarto-cli/assets/13221371/3f8dd9aa-2d6a-4fd8-8cee-a199a95334ee)

### Your environment

- IDE: RStudio 2023.12.0 Build 170
- Windows 11

### Quarto check output

```bash
Quarto 1.4.510
[>] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.9: OK
      Dart Sass version 1.69.5: OK
      Deno version 1.37.2: OK
[>] Checking versions of quarto dependencies......OK
[>] Checking Quarto installation......OK
      Version: 1.4.510
      Path: C:\Program Files\Quarto\bin
      CodePage: 1252

[>] Checking tools....................OK
      TinyTeX: v2023.09
      Chromium: (not installed)

[>] Checking LaTeX....................OK
      Using: TinyTex
      Path: C:\Users\py128\AppData\Roaming\TinyTeX\bin\windows\
      Version: 2023

[>] Checking basic markdown render....OK

[>] Checking Python 3 installation....OK
      Version: 3.11.4
      Path: C:/Users/py128/AppData/Local/Programs/Python/Python311/python.exe
      Jupyter: (None)

      Jupyter is not available in this Python installation.
      Install with py -m pip install jupyter

[>] Checking R installation...........OK
      Version: 4.3.1
      Path: C:/PROGRA~1/R/R-43~1.1
      LibPaths:
        - C:/Users/py128/AppData/Local/R/win-library
        - C:/Program Files/R/R-4.3.1/library
      knitr: 1.44
      rmarkdown: 2.25

[>] Checking Knitr engine render......OK
sda030 commented 5 months ago

Part of the problem above has been resolved. @cscheid already knows this from the discussion at https://github.com/jgm/pandoc/issues/9236). I forced installation of Typst 0.11 and Pandoc 3.1.12.3 into Quarto 1.5.25, and the raster images no longer overflows the page. (Vector issue still remains though, but now I am happy to have HTML and Typst with the same qmd-document).

cderv commented 4 months ago

cc @gordonwoodhull - just putting this on your radar for typst testing as it seems Typst 0.11 offers us another improvement here.

When we'll update, we can check what remains.

gordonwoodhull commented 4 months ago

Nod, Typst introduced natural image sizing and Pandoc is wrapping with #box[] so there is some stuff we can probably clean up. (Seems to be working, though.)

Would be nice to see if SVG output works as originally requested here.

apcamargo commented 4 months ago

Not sure if this is related, but I'm having the opposite problem. I'm generating PDFs using Typst, but the outputs are huge because I have some scatter plots with thousands of data points. I usually prefer vectors over rastered images, but in this case I'd like the option of forcing some (or all) plots to be rastered.

mcanouil commented 4 months ago

Not sure if this is related, but I'm having the opposite problem. I'm generating PDFs using Typst, but the outputs are huge because I have some scatter plots with thousands of data points. I usually prefer vectors over rastered images, but in this case I'd like the option of forcing some (or all) plots to be rastered.

Use fig-format: png.

apcamargo commented 4 months ago

Thanks! Any reason this is not in the Typst documentation page?

mcanouil commented 4 months ago

It is.

https://quarto.org/docs/reference/formats/typst.html#figures

apcamargo commented 4 months ago

Ohh, I was looking somewhere else. Thanks again!

cderv commented 4 months ago

@sda030 revisiting this following our Typst 0.11 update in main.

Just for context to be clear: format: typst will default to using fig-format: svg and so is using grDevices::svg() to produce the image from the the ggplot. Looking at intermediate markdown, we correctly have a SVG.

Would be nice to see if SVG output works as originally requested here.

As @gordonwoodhull mentioned, it seems Typst is not using this SVG to produce a selectable one. I test in https://typst.app/ and the PDF produce does not also have selectable SVG plots. So it seems this is related to Typst directly.

Even worse when htmlwidget:

Related to HTML widgets, some knitr processing is involved here. A screenshot to PNG will automatically be made by knitr when a HTML widgets component is used in a non HTML output. This screenshot is done based on chunk configured size, and also using .png by default. webshot2 can't produce SVG screenshot.

In the intermediate markdown the file including is a .png file here. So treatment by Typst is different than for vector graphics svg.

So the size issue remains (probably until we use Pandoc 3.1.12.3).

I don't know how we could improve the screenshoting feature for SVG output - one can do the saving to file and convert to SVG directly in the chunk for typst format for example. Overall this part is a knitr issue I would say.

Though this could be related to

webshot2 would need to improve greatly its saving to pdf as it is not using the same chrome feature as for png ((currently is relies on page printing to pdf) ). so there could be some side effect (no cropping for example)

Anyhow, here is a workaround using some R toolings to

This is knitr only solution and it works ok

---
format:
  typst: default
keep-md: true
keep-typ: true
---

```{r}
#| label: 'fig-a'
#| fig-cap: 'Good resolution, but non-selectable text'
#| dev: svglite
  ggplot2::ggplot(mtcars, mapping = ggplot2::aes(x=mpg, y=disp)) +
  ggplot2::geom_point()
#| label: 'fig-b'
#| fig-cap: 'Even worse using webshot'
#| dev: pdf
#| include: false
fig1 <-
  ggplot2::ggplot(mtcars, mapping = ggplot2::aes(x=mpg, y=disp)) +
  ggiraph::geom_point_interactive()

ggiraph::girafe(ggobj = fig1)
#| out-width: 'auto'
convert_to_svg <- function(pdf_file) {
  pdf <- magick::image_read_pdf(pdf_file)
  pdf_cropped <- magick::image_trim(pdf)
  magick::image_write(pdf_cropped, xfun::with_ext(pdf_file, "svg"), format = "svg")
}
screenshotted_pdf <- knitr::fig_chunk('fig-b', ext = "pdf")
knitr::include_graphics(convert_to_svg(screenshotted_pdf))


![image](https://github.com/quarto-dev/quarto-cli/assets/6791940/cad4870f-3c70-4261-944b-d5c4779dfe41)

[index.pdf](https://github.com/quarto-dev/quarto-cli/files/14883859/index.pdf)

Hope this helps while we figure this svg handling out for typst output
sda030 commented 4 months ago

Hope this helps while we figure this svg handling out for typst output

Thanks for your effort @cderv. Though unfortunately

  1. In both your and my rendered PDFs, both images seem to be raster graphics, and on closer inspection the first has higher resolution. The second (where I think you expected text to be selectable) is thus non-selectable. (I use Quarto 1.5.29, with brute-forced installation of Pandoc 3.1.13 (newest). Foxit PDF Reader and Chrome). From the intermediate files, I get fig-a-1.svg being a proper vector graphic, whereas fig-b-1.svg is actually just a raster graphic. The fig-b-1.pdf is proper vector though.
  2. Seems to have been fixed upstream so waiting for trickle down: https://github.com/typst/typst/issues/1239
  3. In my intented Quarto-use with all HTML, docx and typst outputs at once, having double chunks of all figures is a bit cumbersome. So will probably just wait patiently and eagerly for a proper fix.
mcanouil commented 4 months ago

(I use Quarto 1.5.29, with brute-forced installation of Pandoc 3.1.13 (newest).

This is a terrible thing to do especially because the current pre-release embeds Pandoc 3.1.13, so you kind of broke Quarto and voided the guarantee.

sda030 commented 4 months ago

Developing things on the bleeding edge requires testing what will be fixed soon vs what requires a PR + workarounds. Btw, have you never brute forced or cracked a phone for learning how things work? ;) I think it is rather useful for devs that you have early adapters who care enough to test :)

mcanouil commented 4 months ago

That's not the point. The point is now you are responsible if there is an issue in your install. Quarto team cannot help if you "break" the tool, so be sure to understand that and to revert or have a proper installation of Quarto.

sda030 commented 4 months ago

Have I given the impression that I am disappointed in Quarto not working with with even the newest pre-release and upstream components? In that case I apologize for the misunderstanding, I am absolutely happy with Quarto consistently and monotonically improving - rarely experiencing regressions. Just trying to help by not making a fuzz for Quarto devs about something that is likely soon to be fixed upstream. P.S. Pandoc 3.1.13 was not part of 1.5.29 so that's why I tested with 3.1.13. Now with 1.5.30 there's no need for jailbreaking right anymore - until next time. Have a nice weekend!

mcanouil commented 4 months ago

I just wanted to gently remind you that altering the source code may affect our ability to offer support, as our services do not extend to modified versions of Quarto. This is simply a precautionary note for your awareness. Please rest assured, it’s not a reflection of any assumptions about your feelings or reactions, which we fully respect and would never presume to predict in accordance with our code of conduct.