SVGM binding for Elixir

NIF wrapper for svgm-core, a SVG optimization library in Rust.

There's also a CLI and nodejs package, see https://svgm.dev/ for more info.

Installation

The package can be installed by adding svgm to your list of dependencies in mix.exs:

def deps do
  [
    {:svgm, "~> 0.3.7"}
  ]
end

Or with Mix.install/1:

Mix.install([:svgm])

Usage

Returns an optimized version of the given SVG.

This also accepts a couple of t:options/0, see the Rust documentation for details.

Examples

The examples comes from the SVG tutorial on Mozilla Developer Network, and svgm-core's test suite.

SVG tutorial example

The most basic usage is to just supply the SVG to be optimized.

iex> svg = ~s|
...> <svg version="1.1"
...>     width="300" height="200"
...>     xmlns="http://www.w3.org/2000/svg">
...>   <rect width="100%" height="100%" fill="red" />
...>   <circle cx="150" cy="100" r="80" fill="green" />
...>   <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
...> </svg>|
iex> SVGM.optimize!(svg)
~s|<svg xmlns="http://www.w3.org/2000/svg" height="200" width="300"><rect fill="red" height="100%" width="100%"/><circle cx="150" cy="100" fill="green" r="80"/><text fill="#fff" font-size="60" text-anchor="middle" x="150" y="125">SVG</text></svg>|

You may also provide options to tweak the process a bit, see the Rust documentation for details.

iex> svg = ~s|
...> <svg version="1.1"
...>     width="300" height="200"
...>     xmlns="http://www.w3.org/2000/svg">
...>   <rect width="100%" height="100%" fill="red" />
...>   <circle cx="150" cy="100" r="80" fill="green" />
...>   <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
...> </svg>|
iex> SVGM.optimize!(svg, preset: :safe, precision: 1, pass_overrides: %{
...>   "convertColors" => false
...> })
~s|<svg xmlns="http://www.w3.org/2000/svg" height="200" width="300"><rect fill="red" height="100%" width="100%"/><circle cx="150" cy="100" fill="green" r="80"/><text fill="white" font-size="60" text-anchor="middle" x="150" y="125">SVG</text></svg>|

Note how the color of the <text> stays "white", unlike above where it has been shortened to "#fff".

It raises an error when given invalid SVG.

iex> SVGM.optimize!("<svg></svg")
** (SVGM.Exceptions.XMLParseError) XML parse error ...
iex> SVGM.optimize!("<svg></b></svg>")
** (SVGM.Exceptions.MismatchedTagError) mismatched closing tag: ...

The same goes for invalid options.

iex> SVGM.optimize!("<svg></svg>", preset: :foo)
** (ArgumentError) Erlang error: "Could not decode field :preset on %Options{}"
iex> SVGM.optimize!("<svg></svg>", precision: 1.5)
** (ArgumentError) Erlang error: "Could not decode field :precision on %Options{}"
iex> SVGM.optimize!("<svg></svg>", pass_overrides: %{must_be_string_keys: false})
** (ArgumentError) Erlang error: "Could not decode field :pass_overrides on %Options{}"
iex> SVGM.optimize!("<svg></svg>", pass_overrides: %{"convertColors" => nil})
** (ArgumentError) Erlang error: "Could not decode field :pass_overrides on %Options{}"

Copyright and License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.