vectory 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 865823bf5ac58c0780cdffc76abf7d396c2b481bcf292c807e419c0983f44646
4
- data.tar.gz: cd29b9a6f1c3a851e37fa207427474a60656ad8a1ba6f27d954d08d2ded47f5d
3
+ metadata.gz: 2f51d610adc333c06f92e8e28ca9722a890f12b03668bf12e96ce057d2574dea
4
+ data.tar.gz: 792bc815a0b86a6211b83268f16b9abe7a138aba0081a2d7a95242c5e9a7af82
5
5
  SHA512:
6
- metadata.gz: 01ee6626bca7c7a61f14dffa639355171e052637f9b1c58d4dfb39721a7b7a815e6b11cd5c1deb76b4faecba37abf873e45661c16ebd2eaf7434cb9031a6deff
7
- data.tar.gz: 6706861380815c36d273445cc970db3b01693024208596c8072e9661ab301908db5c6c81e7d707826b501263aac8dbcc4b65f553fc62857a773cb45404d53de4
6
+ metadata.gz: 249d3f2fa7df2d216cdf5d046647507b81a55bd5db56a603a90a3890501adb10e8a03f41b272385c65a8de48c50b8b52db743ec5ddc20be88e4e5aab6ed21ca6
7
+ data.tar.gz: 5ed331050b3c4a3231cabc7ba061695f017de5ea44a3056bf01537144b12c96cf5587c0a52793d3d435d961052210aefed73a52c4afc9c3563695fca8e23c91d
data/README.adoc CHANGED
@@ -329,6 +329,23 @@ purposes.
329
329
  vector.initial_path # => "storage/images/img.eps"
330
330
  ----
331
331
 
332
+ ==== Additional properties
333
+
334
+ The following additional properties are supported:
335
+
336
+ [source,ruby]
337
+ ----
338
+ Datauri#mime
339
+ Datauri#height
340
+ Datauri#width
341
+ Vector (Eps, Ps, Svg, Emf)
342
+ Vector#mime
343
+ Vector#size
344
+ Vector#file_size
345
+ Vector#height
346
+ Vector#width
347
+ ----
348
+
332
349
 
333
350
  == Development
334
351
 
@@ -18,6 +18,19 @@ module Vectory
18
18
  new("data:#{mimetype};base64,#{data}")
19
19
  end
20
20
 
21
+ def mime
22
+ match = parse_datauri(@content)
23
+ match[:mimetype]
24
+ end
25
+
26
+ def height
27
+ to_vector.height
28
+ end
29
+
30
+ def width
31
+ to_vector.width
32
+ end
33
+
21
34
  def to_vector
22
35
  match = parse_datauri(@content)
23
36
  content = Base64.strict_decode64(match[:data])
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "singleton"
4
+ require "tmpdir"
4
5
  require_relative "system_call"
5
6
 
6
7
  module Vectory
@@ -12,7 +13,7 @@ module Vectory
12
13
  end
13
14
 
14
15
  def convert(uri, output_extension, option)
15
- exe = inkscape_path_or_raise_error(uri)
16
+ exe = inkscape_path_or_raise_error
16
17
  uri = external_path uri
17
18
  exe = external_path exe
18
19
  cmd = %(#{exe} #{option} #{uri})
@@ -27,12 +28,20 @@ module Vectory
27
28
  output_path
28
29
  end
29
30
 
31
+ def height(content, format)
32
+ query_integer(content, format, "--query-height")
33
+ end
34
+
35
+ def width(content, format)
36
+ query_integer(content, format, "--query-width")
37
+ end
38
+
30
39
  private
31
40
 
32
- def inkscape_path_or_raise_error(path)
41
+ def inkscape_path_or_raise_error
33
42
  inkscape_path or raise(InkscapeNotFoundError,
34
43
  "Inkscape missing in PATH, unable to " \
35
- "convert image #{path}. Aborting.")
44
+ "convert image. Aborting.")
36
45
  end
37
46
 
38
47
  def inkscape_path
@@ -95,5 +104,40 @@ module Vectory
95
104
  path
96
105
  end
97
106
  end
107
+
108
+ def query_integer(content, format, options)
109
+ query(content, format, options).to_f.round
110
+ end
111
+
112
+ def query(content, format, options)
113
+ exe = inkscape_path_or_raise_error
114
+
115
+ with_file(content, format) do |path|
116
+ cmd = "#{external_path(exe)} #{options} #{external_path(path)}"
117
+
118
+ call = SystemCall.new(cmd).call
119
+ raise_query_error(call) if call.stdout.empty?
120
+
121
+ call.stdout
122
+ end
123
+ end
124
+
125
+ def with_file(content, extension)
126
+ Dir.mktmpdir do |dir|
127
+ path = File.join(dir, "image.#{extension}")
128
+ File.binwrite(path, content)
129
+
130
+ yield path
131
+ end
132
+ end
133
+
134
+ def raise_query_error(call)
135
+ raise Vectory::InkscapeQueryError,
136
+ "Could not query with Inkscape. " \
137
+ "Inkscape cmd: '#{call.cmd}',\n" \
138
+ "status: '#{call.status}',\n" \
139
+ "stdout: '#{call.stdout.strip}',\n" \
140
+ "stderr: '#{call.stderr.strip}'."
141
+ end
98
142
  end
99
143
  end
@@ -33,7 +33,6 @@ module Vectory
33
33
  result = Utils.capture3_with_timeout(cmd,
34
34
  timeout: @timeout,
35
35
  kill_after: @timeout)
36
- Vectory.ui.error(result.inspect)
37
36
  @stdout = result[:stdout]
38
37
  @stderr = result[:stderr]
39
38
  @status = result[:status]
@@ -28,6 +28,28 @@ module Vectory
28
28
  @initial_path = initial_path
29
29
  end
30
30
 
31
+ def mime
32
+ self.class.mimetype
33
+ end
34
+
35
+ def size
36
+ content.bytesize
37
+ end
38
+
39
+ def file_size
40
+ raise(NotWrittenToDiskError) unless @path
41
+
42
+ File.size(@path)
43
+ end
44
+
45
+ def height
46
+ InkscapeConverter.instance.height(content, self.class.default_extension)
47
+ end
48
+
49
+ def width
50
+ InkscapeConverter.instance.width(content, self.class.default_extension)
51
+ end
52
+
31
53
  def to_uri
32
54
  Datauri.from_vector(self)
33
55
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vectory
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/vectory.rb CHANGED
@@ -21,6 +21,8 @@ module Vectory
21
21
 
22
22
  class InkscapeNotFoundError < Error; end
23
23
 
24
+ class InkscapeQueryError < Error; end
25
+
24
26
  class NotImplementedError < Error; end
25
27
 
26
28
  class NotWrittenToDiskError < Error; end
@@ -1,3 +1,15 @@
1
+ RSpec::Matchers.define :be_eps do
2
+ match do |actual|
3
+ actual.start_with?("%!PS-Adobe-3.0")
4
+ end
5
+ end
6
+
7
+ RSpec::Matchers.define :be_svg do
8
+ match do |actual|
9
+ actual.include?("<svg")
10
+ end
11
+ end
12
+
1
13
  RSpec::Matchers.define :be_equivalent_eps_to do |expected|
2
14
  match do |actual|
3
15
  e = sub_time_and_version(expected)
@@ -11,10 +11,11 @@ RSpec.describe Vectory::CLI do
11
11
  shared_examples "converter" do |format|
12
12
  it "creates file of a chosen format" do
13
13
  matcher = case format
14
- when "eps", "ps" then "be_equivalent_eps_to"
15
- when "svg" then "be_equivalent_svg_to"
14
+ when "eps", "ps" then "be_eps"
15
+ when "svg" then "be_svg"
16
16
  else "be_equivalent_to"
17
17
  end
18
+
18
19
  with_tmp_dir do |dir|
19
20
  output = File.join(dir, "output.#{format}")
20
21
  status = described_class.start(["-f", format, "-o", output, input])
@@ -98,4 +98,84 @@ RSpec.describe Vectory::Datauri do
98
98
  end
99
99
  end
100
100
  end
101
+
102
+ describe "#mime" do
103
+ context "incorrect data" do
104
+ let(:not_a_datauri) { "123abc" }
105
+
106
+ it "raises conversion error" do
107
+ expect { described_class.new(not_a_datauri).mime }
108
+ .to raise_error(Vectory::ConversionError)
109
+ end
110
+ end
111
+
112
+ context "eps" do
113
+ let(:input) { "spec/examples/eps2emf/img.eps.datauri" }
114
+
115
+ it "returns eps" do
116
+ expect(described_class.from_path(input).mime)
117
+ .to eq "application/postscript"
118
+ end
119
+ end
120
+
121
+ context "emf" do
122
+ let(:input) { "spec/examples/emf2eps/img.emf.datauri" }
123
+
124
+ it "returns emf" do
125
+ expect(described_class.from_path(input).mime).to eq "image/emf"
126
+ end
127
+ end
128
+
129
+ context "svg" do
130
+ let(:input) { "spec/examples/svg2emf/img.svg.datauri" }
131
+
132
+ it "returns svg" do
133
+ expect(described_class.from_path(input).mime).to eq "image/svg+xml"
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "dimensions (#height / #width)" do
139
+ context "incorrect data" do
140
+ let(:not_a_datauri) { "123abc" }
141
+
142
+ it "raises conversion error" do
143
+ expect { described_class.new(not_a_datauri).height }
144
+ .to raise_error(Vectory::ConversionError)
145
+
146
+ expect { described_class.new(not_a_datauri).width }
147
+ .to raise_error(Vectory::ConversionError)
148
+ end
149
+ end
150
+
151
+ context "eps" do
152
+ let(:input) { "spec/examples/eps2emf/img.eps.datauri" }
153
+
154
+ it "returns height and width" do
155
+ expect(described_class.from_path(input).height)
156
+ .to eq 707
157
+
158
+ expect(described_class.from_path(input).width)
159
+ .to eq 649
160
+ end
161
+ end
162
+
163
+ context "emf" do
164
+ let(:input) { "spec/examples/emf2eps/img.emf.datauri" }
165
+
166
+ it "returns height and width" do
167
+ expect(described_class.from_path(input).height).to eq 90
168
+ expect(described_class.from_path(input).width).to eq 90
169
+ end
170
+ end
171
+
172
+ context "svg" do
173
+ let(:input) { "spec/examples/svg2emf/img.svg.datauri" }
174
+
175
+ it "returns height and width" do
176
+ expect(described_class.from_path(input).height).to eq 90
177
+ expect(described_class.from_path(input).width).to eq 90
178
+ end
179
+ end
180
+ end
101
181
  end
@@ -35,4 +35,28 @@ RSpec.describe Vectory::Emf do
35
35
  .to be_equivalent_eps_to File.read(reference)
36
36
  end
37
37
  end
38
+
39
+ describe "#mime" do
40
+ let(:input) { "spec/examples/emf2eps/img.emf" }
41
+
42
+ it "returns emf" do
43
+ expect(described_class.from_path(input).mime).to eq "image/emf"
44
+ end
45
+ end
46
+
47
+ describe "#height" do
48
+ let(:input) { "spec/examples/emf2eps/img.emf" }
49
+
50
+ it "returns height" do
51
+ expect(described_class.from_path(input).height).to eq 90
52
+ end
53
+ end
54
+
55
+ describe "#width" do
56
+ let(:input) { "spec/examples/emf2eps/img.emf" }
57
+
58
+ it "returns width" do
59
+ expect(described_class.from_path(input).width).to eq 90
60
+ end
61
+ end
38
62
  end
@@ -3,16 +3,18 @@ require "spec_helper"
3
3
  RSpec.describe Vectory::Eps do
4
4
  shared_examples "converter" do |format|
5
5
  it "returns content of a chosen format" do
6
+ to_format_method = "to_#{format}"
7
+ content = described_class.from_path(input)
8
+ .public_send(to_format_method)
9
+ .content
10
+
6
11
  matcher = case format
7
- when "eps", "ps" then "be_equivalent_eps_to"
8
- when "svg" then "be_equivalent_svg_to"
12
+ when "eps", "ps" then "be_eps"
13
+ when "svg" then "be_svg"
9
14
  else "be_equivalent_to"
10
15
  end
11
16
 
12
- to_format_method = "to_#{format}"
13
- expect(described_class.from_path(input)
14
- .public_send(to_format_method)
15
- .content)
17
+ expect(content)
16
18
  .to public_send(matcher, File.read(reference))
17
19
  end
18
20
  end
@@ -37,4 +39,29 @@ RSpec.describe Vectory::Eps do
37
39
 
38
40
  it_behaves_like "converter", "emf"
39
41
  end
42
+
43
+ describe "#mime" do
44
+ let(:input) { "spec/examples/eps2emf/img.eps" }
45
+
46
+ it "returns postscript" do
47
+ expect(described_class.from_path(input).mime)
48
+ .to eq "application/postscript"
49
+ end
50
+ end
51
+
52
+ describe "#height" do
53
+ let(:input) { "spec/examples/eps2emf/img.eps" }
54
+
55
+ it "returns height" do
56
+ expect(described_class.from_path(input).height).to eq 707
57
+ end
58
+ end
59
+
60
+ describe "#width" do
61
+ let(:input) { "spec/examples/eps2emf/img.eps" }
62
+
63
+ it "returns width" do
64
+ expect(described_class.from_path(input).width).to eq 649
65
+ end
66
+ end
40
67
  end
@@ -30,4 +30,29 @@ RSpec.describe Vectory::Ps do
30
30
  .to be_equivalent_svg_to File.read(reference)
31
31
  end
32
32
  end
33
+
34
+ describe "#mime" do
35
+ let(:input) { "spec/examples/ps2emf/img.ps" }
36
+
37
+ it "returns postscript" do
38
+ expect(described_class.from_path(input).mime)
39
+ .to eq "application/postscript"
40
+ end
41
+ end
42
+
43
+ describe "#height" do
44
+ let(:input) { "spec/examples/ps2emf/img.ps" }
45
+
46
+ it "returns height" do
47
+ expect(described_class.from_path(input).height).to eq 707
48
+ end
49
+ end
50
+
51
+ describe "#width" do
52
+ let(:input) { "spec/examples/ps2emf/img.ps" }
53
+
54
+ it "returns width" do
55
+ expect(described_class.from_path(input).width).to eq 649
56
+ end
57
+ end
33
58
  end
@@ -38,4 +38,36 @@ RSpec.describe Vectory::Svg do
38
38
  .to be_equivalent_eps_to File.read(reference)
39
39
  end
40
40
  end
41
+
42
+ describe "#mime" do
43
+ let(:input) { "spec/examples/svg2emf/img.svg" }
44
+
45
+ it "returns svg" do
46
+ expect(described_class.from_path(input).mime).to eq "image/svg+xml"
47
+ end
48
+ end
49
+
50
+ describe "#height" do
51
+ let(:input) { "spec/examples/svg2emf/img.svg" }
52
+
53
+ it "returns height" do
54
+ expect(described_class.from_path(input).height).to eq 90
55
+ end
56
+
57
+ context "incorrect data" do
58
+ let(:command) { described_class.from_content("incorrect123svg") }
59
+
60
+ it "raises query error" do
61
+ expect { command.height }.to raise_error(Vectory::InkscapeQueryError)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe "#width" do
67
+ let(:input) { "spec/examples/svg2emf/img.svg" }
68
+
69
+ it "returns width" do
70
+ expect(described_class.from_path(input).width).to eq 90
71
+ end
72
+ end
41
73
  end
@@ -56,5 +56,42 @@ RSpec.describe Vectory::Vector do
56
56
  expect { image.path }.to raise_error(Vectory::NotWrittenToDiskError)
57
57
  end
58
58
  end
59
+
60
+ context "written to disk" do
61
+ before { image.write }
62
+
63
+ it "returns path on a disk" do
64
+ expect(image.path).to include(Dir.tmpdir)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#size" do
70
+ let(:image) { Vectory::Emf.from_path("spec/examples/emf2svg/img.emf") }
71
+
72
+ it "returns content size" do
73
+ expect(image.size).to eq 1060
74
+ end
75
+ end
76
+
77
+ describe "#file_size" do
78
+ let(:image) { Vectory::Eps.from_path("spec/examples/eps2emf/img.eps") }
79
+
80
+ context "not written to disk" do
81
+ it "raises not-written error" do
82
+ expect { image.file_size }
83
+ .to raise_error(Vectory::NotWrittenToDiskError)
84
+ end
85
+ end
86
+
87
+ context "written to disk" do
88
+ before { image.write }
89
+
90
+ it "returns file size" do
91
+ expect(image.file_size).to satisfy("be either 2926 or 3125") do |v|
92
+ [2926, 3125].include?(v) # depends on file system
93
+ end
94
+ end
95
+ end
59
96
  end
60
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vectory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-30 00:00:00.000000000 Z
11
+ date: 2023-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: emf2svg