bodoni / svg

Composer and parser for SVG
Other
302 stars 44 forks source link

How to modify children of `svg::Document`? #55

Closed OrangeTux closed 2 years ago

OrangeTux commented 2 years ago

I've an SVG file and want to modify it. Among other things, I'd like to do is adding a "id" attribute to certain tags.

My approach is to read the file and create an svg::Parser. Iterate over the parser to create an svg::Document. I'll pass this svg::Document around to functions that modify it. But that doesn't work.

Consider the following code:

let document = svg::Document::new()
    .set("viewBox", (0, 0, 70, 70))

let element: Element = document.get_inner()
for child in element.get_children() {
    child.assign("id", 3);
}

That fails to compile with:

error: the `assign` method cannot be invoked on a trait object
  --> src/bin/optimize.rs:85:15
   |
85 |         child.assign("id", 3);
   |               ^^^^^^
   |
  ::: /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/svg-0.10.0/src/node/mod.rs:34:15
   |
34 |         Self: Sized,
   |               ----- this has a `Sized` requirement

Even if this would work, how would I know whether the child is a 'line', 'path' or any other tag is?

IvanUkhov commented 2 years ago

Hello, the interface is not designed for modification. But perhaps this is not what you actually want. The example shows that you are trying to construct something from scratch. In such a case, just create each child separately and then append to the parent.

OrangeTux commented 2 years ago

Thanks for the answer @IvanUkhov .

The example shows that you are trying to construct something from scratch. In such a case, just create each child separately and then append to the parent.

My example is reduction of a bigger problem. I want to write a tool that takes an existing SVG and modifies it to make it friendlier to be 'consumed' by a pen plotter.

I read the file using an svg::Parser and turn it into an svg::Document. My idea is to pass this svg::Document down to several functions that modify the svg::Document. Than I'd like to write the modified SVG to disk. But that doesn't seem to be possible as you write:

the interface is not designed for modification.

Thanks for the answer!

IvanUkhov commented 2 years ago

I see. Then indeed it would be difficult to achieve with this crate, unless one is willing to change the approach, such as to parse and augment at the same time. Sorry. I close this one then.