Editing SVG can be tricky because they are nested structures.
{minisvg} contains some tools for interogating/manipulating existing SVG, but the current focus in {minisvg} is really creating SVG documents in R.
A {minisvg} SVG document is just a tree of R6 objects, where each object represents a single SVG tag (e.g. <rect> or <pattern>).
Each object has a list of children ($childen) and a list of attributes ($attrib).
There is also an alternate representation of the child elements of a node in the member $child. E.g. All the children of the current element which are <rect> tags are stored in the list $child$rect
svg_text <- ' <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g> <circle fill="lightgrey" cx="50%" cy="50%" r = "45%" id="bgcircle" stroke="black" stroke-width="4" /> </g> <rect fill="red" x="40%" y="10%" width="20%" height="20%" /> <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" /> <g> <rect fill="green" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" /> </g> </svg>' doc_orig <- minisvg::parse_svg_doc(svg_text)
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="lightgrey" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="red" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="green" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" />
     </g>
   </svg>
$children
If the structure of an SVG document is known, the element may be selected by its index in the $children list of all child nodes.
In this example, the second child of the root document is selected (i.e. the red square) and its fill attribute is updated.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Extract the first rectangle and change its fill attribute #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ doc <- doc_orig$copy() first_child <- doc$children[[2]] first_child$attribs$fill <- 'pink'
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="lightgrey" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="pink" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="green" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" />
     </g>
   </svg>
Each SVG element node keeps both a $children list of nodes (which is arranged by insertion order), and a $child list which is grouped by tag names.
All direct child elements with a particular tag name, e.g. circle, may be accessed using $child[['circle']].
In the following example, the two direct child rectangles have their fill attribute updated. Note that the small green rectangle is not updated as it is not a direct child of the root document.
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="lightgrey" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="blue" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="blue" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="green" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" />
     </g>
   </svg>
In the following example, the green rectangle is updated. It is accessed as the first child rectangle of the second child g tag.
doc <- doc_orig$copy() small_rect <- doc$child$g[[2]]$child$rect[[1]] small_rect$update(fill = 'lightblue')
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="lightgrey" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="red" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="lightblue" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" />
     </g>
   </svg>
In the following example, all elements with with green or light grey fill are found and updated
doc <- doc_orig$copy() rg_elems <- doc$find(attribs = list(fill=c('lightgrey', 'green'))) purrr::walk(rg_elems, ~.x$update(fill = 'blue'))
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="blue" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="red" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="blue" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="black" stroke-width="4" />
     </g>
   </svg>
In the following example, all rectangles with a black outline (stroke) are found and updated
doc <- doc_orig$copy() rect_elems <- doc$find(tag = 'rect', attribs = list(stroke = 'black')) purrr::walk(rect_elems, ~.x$update(fill = 'black', stroke = 'green'))
 Show SVG text (click to open) 
   <?xml version="1.0" encoding="UTF-8"?>
   <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
     <g>
       <circle fill="lightgrey" cx="50%" cy="50%" r="45%" id="bgcircle" stroke="black" stroke-width="4" />
     </g>
     <rect fill="red" x="40%" y="10%" width="20%" height="20%" />
     <rect fill="yellow" x="40%" y="40%" width="20%" height="20%" />
     <g>
       <rect fill="black" x="40%" y="70%" width="20%" height="20%" id="gogogo" stroke="green" stroke-width="4" />
     </g>
   </svg>