# SVGM binding for Elixir
<!-- Start SVGM module doc -->
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.
[svgm-core]: https://crates.io/crates/svgm-core
<!-- End SVGM module doc -->
## Installation
The package can be installed by adding `svgm` to your list of dependencies in
`mix.exs`:
```elixir
def deps do
[
{:svgm, "~> 0.3.7"}
]
end
```
Or with [`Mix.install/1`][]:
```elixir
Mix.install([:svgm])
```
## Usage
<!-- Start SVGM.optimize!/2 doc -->
Returns an optimized version of the given SVG.
This also accepts a couple of `t:options/0`, see the [Rust documentation][1]
for details.
### Examples
The examples comes from the [SVG tutorial on Mozilla Developer Network][2],
and [svgm-core's test suite][3].

The most basic usage is to just supply the SVG to be optimized.
```elixir
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][1] for details.
```elixir
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.
```elixir
iex> SVGM.optimize!("<svg></svg")
** (SVGM.Exceptions.XMLParseError) XML parse error ...
```
```elixir
iex> SVGM.optimize!("<svg></b></svg>")
** (SVGM.Exceptions.MismatchedTagError) mismatched closing tag: ...
```
The same goes for invalid options.
```elixir
iex> SVGM.optimize!("<svg></svg>", preset: :foo)
** (ArgumentError) Erlang error: "Could not decode field :preset on %Options{}"
```
```elixir
iex> SVGM.optimize!("<svg></svg>", precision: 1.5)
** (ArgumentError) Erlang error: "Could not decode field :precision on %Options{}"
```
```elixir
iex> SVGM.optimize!("<svg></svg>", pass_overrides: %{must_be_string_keys: false})
** (ArgumentError) Erlang error: "Could not decode field :pass_overrides on %Options{}"
```
```elixir
iex> SVGM.optimize!("<svg></svg>", pass_overrides: %{"convertColors" => nil})
** (ArgumentError) Erlang error: "Could not decode field :pass_overrides on %Options{}"
```
[1]: https://docs.rs/svgm-core/latest/svgm_core/config/struct.Config.html
[2]: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Getting_started
[3]: https://github.com/madebyfrmwrk/svgm/tree/main/crates/svgm-core/tests/fixtures
<!-- End SVGM.optimize!/2 doc -->
## Copyright and License
Licensed under either of
- Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
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.
[`Mix.install/1`]: https://hexdocs.pm/mix/Mix.html#install/2