r-lib / svglite

A lightweight svg graphics device for R
https://svglite.r-lib.org
180 stars 39 forks source link

Feature: Support for '.svg.gz' suffix for SVGZ #162

Closed Jylpah closed 1 year ago

Jylpah commented 1 year ago

Hello,

SVGZ support requires specific web server configurations (to set HTTP Response headers correctly and to prevent double-compression). One of the recommended ways around this is to use .svg.gz suffix to make the web server to realize it the image has already been compressed.

I am requesting adding a support for .svg.gz suffix so that svglite recognizes it and creates a SVGZ file when output file has .svg.gz suffix. At the moment svglite (2.1.0) creates an uncompressed SVG file with .svg.gz suffix.

trevorld commented 1 year ago

Note {svglite} does have the function create_svgz() that will take an uncompressed svg file and compress it in-place with gzip so currently you just need to add one additional line of code to get .svg.gz files...

svglite::svglite("test.svg.gz")
plot(1:10, 1:10)
dev.off()
svglite::create_svgz("test.svg.gz")

This is somewhat related to #6

Jylpah commented 1 year ago

I am using svglite through knitr. I don't think it has a way to call create_svgz() directly from Rmarkdown chunks, just to set the file suffix.

I just thought it would be nice to have support for this since W3C has included this suffix into SVG 2.0 draft.

However, this can be always worked around using an extra shell script to rename the files.

trevorld commented 1 year ago

I am using svglite through knitr. I don't think it has a way to call create_svgz() directly from Rmarkdown chunks, just to set the file suffix.

NB. {knitr} supports the option fig.process for a function that post-processes figures: https://yihui.org/knitr/options/#plots

Unfortunately create_svgz() returns a NULL instead of the filename so you'll need to write a wrapper function but I suspect something like the following should work

knitr::opts_chunk$set(
  dev='svglite',
  fig.ext='svg.gz',
  fig.process = function(x) {
    svglite::create_svgz(x)
    x
  }
)
Jylpah commented 1 year ago

Nice! Thank you, I did not know about fig.process.

Jylpah commented 1 year ago

Since I have tens of files, I ended up making a function plot_svgz():

plot_svgz <- function(filename) {
  create_svgz(filename)
  filename
}

And then modifying knitr chunk-options: dev = 'svglite', fig.ext = 'svg.gz', fig.process = plot_svgz

This is very neat solution so I am closing this issue.