coolbutuseless / minisvg

Create SVG documents with R
https://coolbutuseless.github.io/package/minisvg/
MIT License
31 stars 3 forks source link

Editing SVG: function to unset an attribute #9

Closed dmi3kno closed 4 years ago

dmi3kno commented 4 years ago

I am looking at the awesome vignette about editing SVGs (thank you!) and I wonder how I can recolor the rectangles in this example.

svg_text <- '<svg width="400" height="400">
  <g>
  <rect fill="red"    x="20%" y="10%" width="20%" height="20%" />
  <rect fill="yellow" x="30%" y="20%" width="20%" height="20%" />
  </g>
</svg>'
doc_orig <- minisvg::parse_svg_doc(svg_text)
doc <- doc_orig$copy()

I can try and set fill on the group, but of course it does not have any effect, since the values of the elements are still red and yellow.

doc$children[[1]]$update(fill="green")
doc
#> <svg width="400" height="400" >
#>   <g fill="green">
#>    <rect fill="red" x="20%" y="10%" width="20%" height="20%" />
#>     <rect fill="yellow" x="30%" y="20%" width="20%" height="20%" />
#>   </g>
#> </svg>

I wrote a little function that is able to iterate over children and sets the attribute for each kid. I can use it to set every rectangle in the group to "green".

update_children <- function(obj, ...){
  obj$update_child_list(
    lapply(obj$children, function(x) x$update(...)))
}

update_children(doc$children[[1]], fill="green")

What I would like to do is to iterate over children and "unset" (i.e. remove) certain attribute, with the objective of later setting them on the group level.

# do not run
unset_children(doc$children[[1]], "fill")
# this updates the attribute of the group
doc$children[[1]]$update(fill="green")
dmi3kno commented 4 years ago

I see that I can just iterate over children and set attributes of interest to NULL

doc$children[[1]]$children[[1]]$attribs$fill <- NULL
doc$children[[1]]$children[[2]]$attribs$fill <- NULL

Or as a function

unset_children <- function(obj, ...){
  obj$update_child_list(
    lapply(obj$children, function(x)
      lapply(list(...), function(a){x$attribs[[a]] <- NULL; x})
    ))
}