Vectory
Purpose
Vectory is a Ruby gem that performs pairwise vector image conversions for common vector image formats (EPS, PS, EMF, SVG).
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
gem install vectory
Or include it in your gemspec.
Usage
$ 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:
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:
# 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:
# 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:
Vectory::Eps
Vectory::Ps
Vectory::Emf
Vectory::Svg
Each of them can be instantiated in several ways:
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(
"<image mimetype="application/postscript" alt="3">
%!PS-Adobe-3.0 EPSF-3.0 ...
</image>"
).child)
Converting to other formats:
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:
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:
# 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:
eps = Vectory::Eps.from_path("img.eps")
Vectory::Datauri.from_vector(eps).content
There is also a simplified API for this case:
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:
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:
<svgmap id="_4072bdcb-5895-4821-b636-5795b96787cb">
<figure><image src="action_schemaexpg1.svg"/></figure>
<target href="mn://action_schema">
<xref target="ref1">Computer</xref>
</target>
<target href="http://www.example.com">
<link target="http://www.example.com">Phone</link><
/target>
</svgmap>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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">
<style type="text/css">
#Layer_1 { fill:none }
svg[id = 'Layer_1'] { fill:none }
.st0{fill:none;stroke:#000000;stroke-miterlimit:10;}
</style>
<image style="overflow:visible;" width="368" height="315" xlink:href="data:image/gif;base64,R0lG..ommited to save space" transform="matrix(1 0 0 1 114 263.8898)">
</image>
<a xlink:href="mn://action_schema" xlink:dummy="Layer_1">
<rect x="123.28" y="273.93" class="st0" width="88.05" height="41.84"/>
</a>
<a xlink:href="mn://basic_attribute_schema" >
<rect x="324.69" y="450.52" class="st0" width="132.62" height="40.75"/>
</a>
<a xlink:href="mn://support_resource_schema" >
<rect x="324.69" y="528.36" class="st0" width="148.16" height="40.75"/>
</a>
</svg>
into XML containing inline SVG tags. Notice changes in the id
attributes and
the a
tags:
<figure>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' id='Layer_1_000000001' x='0px' y='0px' viewBox='0 0 595.28 841.89' style='enable-background:new 0 0 595.28 841.89;' xml:space='preserve'>
<style> ..ommited to save space </style>
<image> ..ommited </image>
<a xlink:href='#ref1' xlink:dummy='Layer_1_000000001'>
<rect x='123.28' y='273.93' class='st0' width='88.05' height='41.84'/>
</a>
<a xlink:href='mn://basic_attribute_schema'>
<rect x='324.69' y='450.52' class='st0' width='132.62' height='40.75'/>
</a>
<a xlink:href='mn://support_resource_schema'>
<rect x='324.69' y='528.36' class='st0' width='148.16' height='40.75'/>
</a>
</svg>
</figure>
It also supports SVG in a form of an inline tag:
<svgmap id="_60dadf08-48d4-4164-845c-b4e293e00abd">
<figure>
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' version='1.1' id='Layer_1' x='0px' y='0px' viewBox='0 0 595.28 841.89' style='enable-background:new 0 0 595.28 841.89;' xml:space='preserve'>
<a href="mn://action_schema" >
<rect x="123.28" y="273.93" class="st0" width="88.05" height="41.84"/>
</a>
<a href="mn://basic_attribute_schema" >
<rect x="324.69" y="450.52" class="st0" width="132.62" height="40.75"/>
</a>
<a xlink:href="mn://support_resource_schema" >
<rect x="324.69" y="528.36" class="st0" width="148.16" height="40.75"/>
</a>
</svg>
</figure>
<target href="mn://action_schema">
<xref target="ref1">Computer</xref>
</target>
<target href="http://www.example.com">
<link target="http://www.example.com">Phone</link>
</target>
</svgmap>
and datauri:
<svgmap id="_60dadf08-48d4-4164-845c-b4e293e00abd">
<figure>
<image src='data:image/svg+xml;base64,PD94..ommited to save space' id='__ISO_17301-1_2016' mimetype='image/svg+xml' height='auto' width='auto' alt='Workmap1'/>
</figure>
<target href="href1.htm">
<xref target="ref1">Computer</xref>
</target>
<target href="mn://basic_attribute_schema">
<link target="http://www.example.com">Phone</link>
</target>
<target href="mn://support_resource_schema">
<eref type="express" bibitemid="express_action_schema" citeas="">
<localityStack><locality type="anchor"><referenceFrom>action_schema.basic</referenceFrom></locality></localityStack>
Coffee
</eref>
</target>
</svgmap>
File system operations
An image object contains information where it is written. It can be obtained
with the #path
API:
vector = Vectory::Eps.from_path("img.eps")
vector.path
Before the first write it raises the NotWrittenToDiskError
error:
vector.path # => raise NotWrittenToDiskError
After writing it returns a path of the image on a disk:
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:
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.
vector.initial_path # => "storage/images/img.eps"
Additional properties
The following additional properties are supported:
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:
gem bump --version patch --tag --push
For a minor release (0.x.0) use:
gem bump --version minor --tag --push
Contributing
Bug reports and pull requests are welcome on GitHub at: