metanorma / vectory

Convert between vector image formats (Ruby)
2 stars 0 forks source link

= Vectory

image:https://img.shields.io/gem/v/vectory.svg["Gem Version", link="https://rubygems.org/gems/vectory"] image:https://github.com/metanorma/vectory/actions/workflows/rake.yml/badge.svg["rake", link="https://github.com/metanorma/vectory/actions/workflows/rake.yml"] image:https://codeclimate.com/github/metanorma/vectory/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/vectory"] image:https://img.shields.io/github/issues-pr-raw/metanorma/vectory.svg["Pull Requests", link="https://github.com/metanorma/vectory/pulls"] image:https://img.shields.io/github/commits-since/metanorma/vectory/latest.svg["Commits since latest",link="https://github.com/metanorma/vectory/releases"]

== Purpose

Vectory is a Ruby gem that performs pairwise vector image conversions for common vector image formats (EPS, PS, EMF, SVG).

[quote]


Vectory shall give you a glorious vectory over EPS files.


== Installation

=== Prerequisites

Vectory relies on the following software to be installed:

NOTE: Inkscape 1.3.1+ does not work properly with EPS/PS on Windows. To avoid this issue, the 1.3.0 version of Inkscape can be used.

=== Gem install

[source,ruby]

gem install vectory

Or include it in your gemspec.

== Usage

[source,sh]

$ vectory [-o {output-file-name}] -f {format} {input-file-name}

Where,

format:: the desired output format (one of: svg, eps, ps, emf) input-file-name:: file path to the input file output-file-name:: file path to the desired output file (with the file extension) (default: writes to a current directory by the input filename with an extension changed to a desired format)

=== Using the Ruby library

Some examples:

Take EMF as a path to a file and return SVG as a string:

[source,ruby]

path = "path/to/file.emf"

Vectory::Emf.from_path(path).to_svg.content

Take EPS as a string and return EMF as a path to a file:

[source,ruby]

NOTE: content is shortened for readability

content = "%!PS-Adobe-3.0 EPSF-3.0\n ... %%Trailer"

Vectory::Eps.from_content(content).to_emf.write.path

Take SVG as a datauri and return EMF as a datauri:

[source,ruby]

NOTE: datauri is shortened for readability

uri = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0 ... GRkYiLz48L3N2Zz4="

Vectory::Datauri.new(uri).to_vector.to_emf.to_uri.content

==== What is supported?

There are several vector classes which support conversion between each other:

[source,ruby]

Vectory::Eps Vectory::Ps Vectory::Emf Vectory::Svg

Each of them can be instantiated in several ways:

[source,ruby]

Vectory::Eps.from_path("images/img.eps") Vectory::Eps.from_content("%!PS-Adobe-3.0...") Vectory::Eps.from_datauri("data:image/svg+xml;base64,PHN2 ... 2Zz4=") Vectory::Eps.from_node(Nokogiri::XML( "3 %!PS-Adobe-3.0 EPSF-3.0 ... " ).child)

Converting to other formats:

[source,ruby]

Vectory::Eps.from_content(content).to_ps Vectory::Eps.from_content(content).to_emf Vectory::Eps.from_content(content).to_svg

Several ways of getting content of an object:

[source,ruby]

Vectory::Eps.from_content(content).to_svg.content Vectory::Eps.from_content(content).to_svg.to_uri.content # as datauri Vectory::Eps.from_content(content).to_svg.write.path

==== Datauri

Also there is the Vectory::Datauri class which represents vectory images in the datauri format.

Convert an SVG datauri to a plain SVG:

[source,ruby]

NOTE: datauri is shortened for readability

uri = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0 ... GRkYiLz48L3N2Zz4=" Vectory::Datauri.new(uri).to_vector.content

Convert an EPS file to its datauri representation:

[source,ruby]

eps = Vectory::Eps.from_path("img.eps") Vectory::Datauri.from_vector(eps).content

There is also a simplified API for this case:

[source,ruby]

Vectory::Eps.from_path("img.eps").to_uri.content

==== SVG mapping (for the metanorma project)

Vectory can integrate SVG files into XML or HTML, respecting internal id and link references:

[source,ruby]

xml_string = Vectory::SvgMapping.from_path("doc.xml").to_xml

In order to do that an initial XML should support the svgmap tag with links mapping. For example, it can convert XML like this:

[source,xml]

Computer Phone< /target>

.action_schemaexpg1.svg [source,xml]

<?xml version="1.0" encoding="utf-8"?>

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 595.28 841.89" style="enable-background:new 0 0 595.28 841.89;" xml:space="preserve">

into XML containing inline SVG tags. Notice changes in the id attributes and the a tags:

[source,xml]

..ommited

It also supports SVG in a form of an inline tag:

[source,xml]

Computer Phone

and datauri:

[source,xml]

Workmap1
Computer Phone action_schema.basic Coffee

==== File system operations

An image object contains information where it is written. It can be obtained with the #path API:

[source,ruby]

vector = Vectory::Eps.from_path("img.eps") vector.path

Before the first write it raises the NotWrittenToDiskError error:

[source,ruby]

vector.path # => raise NotWrittenToDiskError

After writing it returns a path of the image on a disk:

[source,ruby]

vector.write vector.path # => "/tmp/xxx/yyy"

By default it writes to a temporary directory but it can be changed by providing an argument with a desired path:

[source,ruby]

vector.write("images/img.eps") vector.path # => "images/img.eps"

Since an image can be initially read from a disk, it also keeps an initial path. To avoid accidental overwrite, this path is used only for read-only purposes.

[source,ruby]

vector.initial_path # => "storage/images/img.eps"

==== Additional properties

The following additional properties are supported:

[source,ruby]

Datauri#mime Datauri#height Datauri#width Vector (Eps, Ps, Svg, Emf) Vector#mime Vector#size Vector#file_size Vector#height Vector#width

== Development

=== Releasing

Releasing is done automatically with GitHub Actions. Just bump and tag with gem-release.

For a patch release (0.0.x) use:

[source,sh]

gem bump --version patch --tag --push

For a minor release (0.x.0) use:

[source,sh]

gem bump --version minor --tag --push

== Contributing

Bug reports and pull requests are welcome on GitHub at: