Giter Site home page Giter Site logo

svg's People

Contributors

coastalwhite avatar e-matteson avatar flxzt avatar fschutt avatar geoffreyy avatar ivanukhov avatar kmkzt avatar mazznoer avatar mlwilkerson avatar nathanielc avatar nical avatar octronics avatar palladinium avatar rand0m-cloud avatar s0l0ist avatar xrudelis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

svg's Issues

svg regards the first event of a regular move event as a "relative" move

If I have a SVG triangle with: d="m 58.966213,150.22576 6.60165,-67.629055 55.267647,39.531725 z", the svg parser submits three Command::Relative. However, the first event should be an Command::Absolute, event, only the following are Command::Relative events.

I.e. I get this:

Move(Relative, Parameters([58.966213, 150.22575, 6.60165, -67.62905, 55.267647, 39.531727]))
Close

What would be correct:

Move(Absolute, Parameters([58.966213, 150.22575]))
Move(Relative, Parameters([6.60165, -67.62905, 55.267647, 39.531727]))
Close

Wrapping text

Any ideas how text could be wrapped when being added?
As far as I can tell wrapping text is not really a SVG concept.

Add the ability to disable escaping the content of `Text` nodes

I (ab)used the Text node to insert Svg content into Svg nodes to make nested Svg's. This is very useful when the content comes from users.

With v0.15 this does not work anymore because the text node now escapes it's content.

I think adding an additional method to the Svg Node to insert an arbitrary string would be enough to make this use case work again. Alternatively, add the ability to turn off escaping when creating new Text nodes.

Add support for transformations

If I am not mistaken, current API does not include support for transformations of the svgs.

This can likely be solved for those who need to apply transformations to their code by the .add("transformation", "rotate(45)"), for example.

However, it would be nice to create some rust interface that enumerates the possible transformations and their parameters that is included in this repo, like the commands in the paths module.

Add more documentation with examples

It would be helpful to have a few more small examples. One thing in particular would be how to add multiple objects. Like a square and a circle, both with different stroke styles.

As it stands one might thing that the way to do this would be:

let front = square(start, size);
    let path = Path::new()
        .set("fill", "none")
        .set("stroke", "black")
        .set("stroke-width", 3)
        .set("d", front);

    let back = Data::new()
        .move_to((start.0 - size / 5, start.1 + size / 5))
        .line_by((0, size))
        .line_by((size, 0))
        .line_by((0, -size))
        .close();

    let other_path = Path::new()
        .set("fill", "none")
        .set("stroke", "black")
        .set("stroke-width", 3)
        .set("d", back);

    path.add(other_path)
    ```
    
    But no svg renderer accepts that as a valid output, they render only one of the 2 boxess.

Question: How do you assign the text content for a `element::Text` node?

I have been exploring the library and found most things quite intuitive, but I can't seem to figure out how to assign the text content for a Text node after creating it with the following code:

use svg::node::element::Text;

let text = Text::new();

The target behavior is to generate a <text> tag containing a string that I provide through the rust program like the following:

<text>Hello, world</text>

Thank you so much for your help!

How to copy a child into another Element

I'm trying to get a node from the children of an element, and copy it into another element, but I'm facing issues.

The output of get_children() is &Vec<Box<dyn Node>>, but the add / append functions will only accept actual Node implementors. I tried dereferencing to get the inner Node from the box, but then the compiler complaining about Sized not being implemented. Node is a trait object so it cannot be Sized, but an unsized variable cannot be used as a function parameter, so how could I solve this?

Can I convert Box somehow back to it's original type (e.g. Circle)? I thought Box erases the actual type, so I'm not sure how would this be possible. If I have prior knowledge of the type, can I "cast" it maybe somehow?

Looks like Element::append will just put it inside a Box again anyways, so maybe there should be another append-like function which accepts already boxed Nodes?

Allow for custom formatting

It would be nice if the output had some indentation, e.g. 4 space per nesting, so it could be read more easily

Support CDATA sections

It would be useful to have an interface for generating and parsing CDATA sections (<![CDATA[ ]]>). These are used in SVG, e.g., to embed CSS rules inside a <style> element (example).

ETA: I'm working on a PR for this feature.

How do I add text to a document?

As far as I can tell, I can't use svg::node::Text because its Node implementation is stubbed out, and I can't use svg::node::element::Text because there's no way to set the actual text of the element.

If you just haven't gotten around to making text work yet, I'm happy to do that.
I really want it.

Escape characters not working

Came across an issue where the parser does not match correctly when a "<" is included in an attribute value. This seems to be a problem with all these special characters. Using the expected alternative to escape the characters, such as "<" has the same issue.

How to get the String out of svg::node::Value?

I am using the example "Parsing" from the crates.io page.
How can I get the String out of the tuple struct Value?
let val = attributes.get("inkscape:groupmode");
if val.is_some(){
let val = val.unwrap();
let s = value.0; // ERROR: field 0of structsvg::node::value::Value is private rustc(E0616)
}

Allow for custom storage of `Attributes`

It seems like internally, Attributes is a std::collections::HashMap. Would it be possible to use hashbrown::HashMap? Probably behind a Cargo flag to make hashbrown an optional dependency.

Reasoning: the HashMap in collections is extremely collision resistant (SipHash), but this means it is slower and has a larger per-entry memory overhead than alternatives. hashbrown uses ahash which is much faster and has a smaller per-entry overhead (1/8 the size if I recall correctly). ahash is not as collision resistant, but this is highly unlikely to be exploitable for this use case.

All the functions taking DefaultHasher would need to become generic.

Alternatively, using ahash directly without going through hashbrown would provide the same results.

How to get large-arc-flag and sweep-flag from Parameters?

How to get large-arc-flag and sweep-flag from Parameters? Does one simply cast from f32 to bool?
Would a helper method be possible, then? Or even a full page of methods for simple access with Parameters.
The library is nice, but this part seems particularly obscure.

Numbers in paths do not support scientific notation.

This issue was found when trying to parse the logo of the lyon crate: https://github.com/nical/lyon/blob/master/assets/lyon-logo.svg.

The parser for paths uses Reader::consume_number which is modeled after https://www.w3.org/TR/SVG/types.html#DataTypeNumber.

This part of the spec does not mention scientific notation (like "2e-4"), most likely because of restrictions to the style sheet grammar.

However, scientific notation is explicitly supported by the path specification (see the grammar in https://www.w3.org/TR/SVG/paths.html#DAttribute).

Unfortunately SVG files generated by Inkscape (and probably many other vector graphics programs) are full of paths with numbers in scientific notation so it would be very useful for this library to support them at least in paths.

Support retrieving content of Event::Comment and Event::Instruction

While experimenting with this, I noticed that's no way to construct a complete representation of the content of the parsed SVG file, because the contents of comments and processing instructions are inaccessible.

In fact, in the latter case, one could argue that it's a spec violation to not give the application access to the processing instructions, because SVG is XML-based and this is what the XML spec has to say about it:

"Processing instructions (PIs) allow documents to contain instructions for applications. PIs are not part of the character data of the document, but MUST be passed through to the application.

How to define patterns?

I want to define a pattern element, and don't see a struct for that. Is there currently any way to work with patterns? Or is adding support for them as simple as adding it to the list of elements created withimplement!? If so, I can submit a pull request.

tag::Parser::read_attribute() panics if an attribute's value is an empty string.

I run into this when trying to parse the logo of the lyon crate: https://github.com/nical/lyon/blob/master/assets/lyon-logo.svg

The SVG contains this metadata tag (generated by inkscape):

  <metadata
     id="metadata4812">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>

The panic happens when parsing rdf:about="" at https://github.com/bodoni/svg/blob/master/src/node/element/tag.rs#L65

thread 'main' panicked at 'begin <= end (1 <= 0) when slicing `"`', ../src/libcore/str/mod.rs:1692

Adding Points to a Polygon

Sadly, there is no documentation for any of the types in node::element since most of the methods seem to be generated by macros.. Because of this, it seems to by impossible to use this library without diving into the source and deciphering the macros..

My specific question: How would I use the Polygon type? How do I add points to a polygon?

Update Data Element within a struct

I'm trying to implement a function inside a struct which updates a Vector of Data elements.

struct Svg {
    data: Vec<Data>,
}

impl Svg {
    fn new() -> Self {
        Self {
            data: {
                let mut vec = Vec::<Data>::with_capacity(10);
                for _ in 0..10 {
                    vec.push(Data::new().move_to((0, 0)));
                }
                vec
            },
        }
    }

    fn update(&mut self) {
        self.data[0].line_to((4,9));
    }
}

When I compile this code I get the following error: move occurs because value has type "svg::node::element::path::Data", which does not implement the "Copy" trait.
I'm new to rust but I guess the move occurs because the function line_to takes mut self as a parameter which moves the ownership.
Is there a way to make my code compile?

I need this code because I run a simulation which produces data every time step and I want to draw an svg picture from it. I therefore try to collect the data from the simulation inside a Data elements to draw Paths from them.
The example above is only a prototype for that. It's not for practical use yet.

How to add a filter

Hey,

Could you help me please. I cannot understand how to add a filter to the svg Document. Is it possible with your library? For example, I want to add feGaussianBlur. As I understand i should start something like this:

let filter = Filter::new().add(What exactly I should put here??);
let definitions = Definitions::new().add(filter);
let document = Document::new()
    .set("viewBox", (0, 0, 70, 70))
    .add(definitions)
........

Implement getBBox

I'd like to programmatically generate layouts using this library and need to be able to get the size of elements in order to resize backgrounds based on their contents.

This is defined as getBBox in the standard.

If this seems like something that is outside the scope of this project then I could try hacking together the algorithm using the standard as reference.

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

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?

Incorrect comment parsing

Currently the following fragment

<!-- foo > -->

is incorrectly parsed as

Event::Comment, Event::Text("-->")

rather than the correct

Event::Comment

This happens because the following code allows Comments to end with a simple > instead of requiring -->:

svg/src/parser/mod.rs

Lines 72 to 82 in f945795

let content = self.reader.capture(|reader| reader.consume_until_char('>'));
if content.is_none() {
raise!(self, "found an empty tag");
}
if !self.reader.consume_char('>') {
raise!(self, "missing a closing angle bracket");
}
let content = content.unwrap();
Some(if content.starts_with("!--") {
Event::Comment
} else if content.starts_with('!') {

Publish new version on crates.io

Hello,

Can you publish a new patch release of this library on crates.io? I would love to remove the dependence on my private fork since these changes were merged upstream: d272e76

Many thanks in advance!

Avoid string conversion when working with `Value`

Rather than having Value always be a String, something like this could be better:

enum Value {
    String(String),
    Integer(i64),
    Float(f64),
}

And then the From implementations would just set an Integer or Float. This would be nice because it means that numbers (which account for a lot of possible values) never have to allocate.

Doing deref to str wouldn't be the best thing with this change. Something like as_string() -> String might be better suited.

The correct way to add elements (paths, lines, etc) in a loop.

I am struggling with this library and am wondering if I misunderstood something.
I expected to use the library like this (similar to the example on the docs.rs-page):

let mut data = Data::new();

for i in 0..3 {
    &mut data.move_to((10, i + 10)).line_by((5,0));
}
data.close();
// etc

Apparently data is moved through move_to() and therefor cannot be used in a loop. A similar thing happens if I want to add data to the document within a loop.

What is the correct way of adding elements in a loop?

Issue with self closing element when the generated svg is embedded in html

When the generated SVG is put into an HTML document and served into a browser, many browsers will autocorrect the markup. They will find tags that are not permitted to use />, and will automatically insert a closing tag.

E.g. becomes when loaded in an HTML page in Google Chrome.

Is it possible to disable the short version and force a verbose output ?

Edit: I'm using the to_string() method of Document to convert into string

Method for accessing the element within a struct

I'm new to rust so pardon me if I'm misunderstanding anything. It appears all the structs (Rectangle, etc) have an inner Element but this is private with no way for the user to access. Element is public and has methods to access its inner workings but the structs are missing this. Is there a reason for this?

`<` in Text nodes is not escaped

I'm using this code to add tooltips to boxes. If the string contents e.g. contains widgets >=3.0.9, <3.1.dev0, the < is not escaped and produces and invalid svg:

<rect fill="#FF780088" height="10" width="0.3088995" x="328.0725" y="120">
<title>
widgets >=3.0.9, <3.1.dev0
</title>
</rect>

Redesign to be more suited for feeding parsed input back into output

Currently, the reading and writing APIs are oddly asymmetrical, with reading being a pull-parser with textual node names, and writing being a DOM-style API requiring strongly typed tags.

This makes it very difficult when one wants to do something like taking an SVG file with pre-defined node IDs that was composed graphically in Inkscape, insert some stuff generated programmatically from a data source, and then write the output to a new SVG file.

Heck, I'm finding it hellishly annoying just trying to create an identity function which transforms the pull-parser input to the DOM output because:

  1. I don't see any way to go from the tag name strings in Event::Tag to valid output without manually mapping them back to Node impls using a big match statement.
  2. Because dyn Node is unsized, Box<dyn Node> doesn't impl Node, and your DOM is immutable once constructed, I feel like I have to implement my own intermediate AST just to get the two halves of the same crate to talk to each other.

With the current state of the APIs, it feels as if there's no point to forcing people to download the reader to get the writer or vice-versa, and it's just not worth it to try to get any form of compile-time correctness for SVG beyond what an XML crate without DTD validation would give me.

feature request: expose a way to create arbitrary element?

I have a trivial need which is to create an element with some attributes on it, outside of scope of the elements provided in this library, and I don't seem to find an API to allow this. Element::new(name) can be created but it doesn't allows to set attributes and the struct Element is private.

Thanks

How to add an array/vector/slice of elements?

Using the standard .add method is nice when you have a static tree structure.
But how to add a slice of nodes to a parent node?

Something like append would be nice.

May I create PR?

Remove newlines around node::Text?

Hi,

there should probably be no newlines around text nodes, as white space content of elements can be meaningful.

The newlines in titles like here could even render as in some situations.

Thanks,
Auberi

Idea/Question: abstract backend

Is there any interest in abstracting the backend to support other outputs? I'm interested in using svg with a different backend (bevy) and would be happy to undertake the task as a PR (if it's of interest) rather than doing it in-my-code.

Strict Type for `set(name, value)`

Problem

Currently, set() can take any valid string as input, which isn't desirable(?).

Note: Considering the number of elements there are, it's kind of understandable to have lax methods.

Question: What's the current reasoning for not having type safety, other than a lot of repetition and not as elegant macro implementation?

Possible Solution

Adding set_strict() which takes (name: enum, value: T), passes (name.to_string(), value) to set() internally.

Value can have type safety too, but I don't think I can do that without serde specifically for hexadecimal colour.

Dealing with breaking change

  • Minor release: set() can be exposed as it is, while having set_strict() as another option.
  • Major release: set() can be renamed to set_raw() and set_strict() replaces set(). Giving both options of customizability and type safety.

If I can get some direction and tips as I don't know much about svg I would love to work on this.

CSS support

Hi,
Wondering if adding CSS support has been considered or if it's just plainly out of scope?
Thanks

How does one add Text?

Sorry this isn't really an issue (or it's a documentation issue?) but I can't figure out how to use the Text Node to actually add text to a document. Can you help, please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.