inkmake 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +5 -5
  2. data/lib/inkmake.rb +182 -51
  3. metadata +3 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9bfce00fca4b90da107ec5682f2e4b0ed2e1f178
4
- data.tar.gz: 3482fed6b2c0e92c244a50c43004eab801f407ff
2
+ SHA256:
3
+ metadata.gz: 020ed9f884ade66f1fc89a553d5187852aeaaa330236a58da5dc7f9f0f289a71
4
+ data.tar.gz: dc3019d1323bde40081b23c28b040fdb4c75d534be571985b9dc5255a8cdab3e
5
5
  SHA512:
6
- metadata.gz: d69a68ecca8fc2b0d5414e38a548499f1eec67025a01b9040c0a45d61138f287cc269a920fe6fa5c4b96be530b9f405984418d4f6d5358f5bc0d96f40949528c
7
- data.tar.gz: 51e689399a5fb976462d34f89d4000e7506c00074500c12c3872c5d482eb30afe78f6451ef7444bcf281595ce0115f31d3e38f76d7aca9be2f6c57996c54f128
6
+ metadata.gz: e2ffa9662e94fc3641392d20b4f661e42a8ab993d672d80174e23da95b11a4ef4f8218c7be69571d0d02712b621af04ac3f06a33eb2353853953843c9597988d
7
+ data.tar.gz: e8a8e294a01eab9d537130b0fa6d3d3e4ad36c3b006e93763b1a426e1f1ed10096bd362ae7dfd3d1fbcaeae0664c1d4a9dd2983292271adcda9fbcf0134276e4
data/lib/inkmake.rb CHANGED
@@ -113,9 +113,12 @@ class Inkmake
113
113
  end
114
114
 
115
115
  class InkscapeRemote
116
+ attr_reader :inkscape_version
117
+
116
118
  def initialize
117
- open
118
- probe_decimal_symbol
119
+ @inkscape_version = probe_inkscape_version
120
+ open_shell
121
+ probe_decimal_symbol if @inkscape_version == 0
119
122
  yield self
120
123
  ensure
121
124
  quit
@@ -125,14 +128,20 @@ class Inkmake
125
128
  @is_windows ||= (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) != nil
126
129
  end
127
130
 
128
- def open
131
+ def open(args)
129
132
  if is_windows
130
- # Inkscape on Windows for some reason needs to run from its binary dir
131
- @in, @out, @err = Open3.popen3(*[File.basename(self.class.path), "--shell"],
133
+ # Inkscape on Windows for some reason needs to run from its binary dir.
134
+ # popen2e so get stdout and stderr in one pipe. inkscape 1 shell seems to
135
+ # use both as output and we need to read to not block it.
136
+ Open3.popen2e(*[File.basename(self.class.path)] + args,
132
137
  :chdir => File.dirname(self.class.path))
133
138
  else
134
- @in, @out, @err = Open3.popen3(*[self.class.path, "--shell"])
139
+ Open3.popen2e(*[self.class.path] + args)
135
140
  end
141
+ end
142
+
143
+ def open_shell
144
+ @in, @out = open(["--shell"])
136
145
  loop do
137
146
  case response
138
147
  when :prompt then break
@@ -140,7 +149,7 @@ class Inkmake
140
149
  end
141
150
  end
142
151
 
143
- def command(args)
152
+ def command0(args)
144
153
  c = args.collect do |key, value|
145
154
  if value
146
155
  "\"#{key}=#{self.class.escape value.to_s}\""
@@ -148,54 +157,94 @@ class Inkmake
148
157
  key
149
158
  end
150
159
  end.join(" ")
151
- puts "> #{c}" if Inkmake.verbose
160
+ puts "< #{c}" if Inkmake.verbose
161
+ @in.write "#{c}\n"
162
+ @in.flush
163
+ end
164
+
165
+ def command1(args)
166
+ c = args.collect do |key, value|
167
+ if value
168
+ "#{key}:#{value.to_s}"
169
+ else
170
+ "#{key}:"
171
+ end
172
+ end.join("\n")
173
+ puts "< #{c}" if Inkmake.verbose
152
174
  @in.write "#{c}\n"
153
175
  @in.flush
154
176
  end
155
177
 
156
178
  def response
157
- o = @out.read(1)
158
- if o == ">"
159
- puts "< #{o}" if Inkmake.verbose
160
- return :prompt;
179
+ if @inkscape_version == 0
180
+ o = @out.read(1)
181
+ if o == ">"
182
+ puts "1> #{o}" if Inkmake.verbose
183
+ return :prompt;
184
+ end
185
+ else
186
+ o = @out.read(2)
187
+ if o == "> "
188
+ puts "1> #{o}" if Inkmake.verbose
189
+ return :prompt;
190
+ end
161
191
  end
162
192
  o = o + @out.readline
163
- puts "< #{o}" if Inkmake.verbose
193
+ puts "2> #{o}" if Inkmake.verbose
164
194
  o
165
195
  end
166
196
 
197
+ def probe_inkscape_version
198
+ _in, out = open(["--version"])
199
+ version = 0
200
+ begin
201
+ loop do
202
+ case out.readline()
203
+ when /^\s*Inkscape 1\..*$/ then
204
+ version = 1
205
+ when /^\s*Inkscape 0\..*$/ then
206
+ version = 0
207
+ end
208
+ end
209
+ rescue EOFError
210
+ end
211
+ version
212
+ end
213
+
167
214
  # this is weird but is the least weird and most protable way i could come up with
168
215
  # to figuring out what decimal symbol to use.
169
216
  # forcing LC_NUMERIC=C seems hard to do in a portable way
170
217
  # trying to use env inkmake is running in is also not so portable (windows?)
171
218
  def probe_decimal_symbol
219
+ @decimal_symbol = "."
172
220
  svg =
173
221
  "<?xml version=\"1.0\"?>" +
174
222
  "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1\" height=\"1\">" +
175
223
  "</svg>"
176
- f = Tempfile.new("inkmake")
224
+ f = Tempfile.new(["inkmake", ".svg"])
177
225
  f.write(svg)
178
226
  f.flush
179
227
  begin
180
- command({
181
- "--file" => f.path,
182
- "--export-png" => Tempfile.new("inkmake").path,
183
- "--export-area" => "0.0:0.0:1.0:1.0",
228
+ # this will try export with "." as symbol in area
229
+ export({
230
+ :svg_path => f.path,
231
+ :out_path => Tempfile.new(["inkmake", ".png"]).path,
232
+ :format => "png",
233
+ :area => [0.0, 0.0, 1.0, 1.0]
184
234
  })
185
235
  loop do
186
236
  case response
187
237
  when :prompt then break
188
238
  end
189
239
  end
190
- @decimal_symbol = "."
191
240
  rescue EOFError
192
241
  @decimal_symbol = ","
193
242
  # restart inkscape
194
- open
243
+ open_shell
195
244
  end
196
245
  end
197
246
 
198
- def export(opts)
247
+ def export0(opts)
199
248
  c = {
200
249
  "--file" => opts[:svg_path],
201
250
  "--export-#{opts[:format]}" => opts[:out_path]
@@ -215,13 +264,13 @@ class Inkmake
215
264
  elsif opts[:area].kind_of? String
216
265
  c["--export-id"] = opts[:area]
217
266
  end
218
- command(c)
267
+ command0(c)
219
268
  width, height = [0, 0]
220
- out = nil
269
+ #out = nil
221
270
  loop do
222
271
  case response
223
- when /^Bitmap saved as: (.*)$/ then
224
- out = $1
272
+ # when /^Bitmap saved as: (.*)$/ then
273
+ # out = $1
225
274
  when /^Area .* exported to (\d+) x (\d+) pixels.*$/ then
226
275
  width = $1
227
276
  height = $2
@@ -232,18 +281,89 @@ class Inkmake
232
281
  [width, height]
233
282
  end
234
283
 
284
+ def export1(opts)
285
+ c = [
286
+ ["file-open", opts[:svg_path]],
287
+ ["export-type", opts[:format]],
288
+ ["export-filename", opts[:out_path]]
289
+ ]
290
+ if opts[:res]
291
+ s = opts[:rotate_scale_hack] ? 2 : 1
292
+ c += [["export-width", opts[:res].width.to_pixels(opts[:dpi] || 90) * s]]
293
+ c += [["export-height", opts[:res].height.to_pixels(opts[:dpi] || 90) * s]]
294
+ else
295
+ c += [["export-width", ""]]
296
+ c += [["export-height", ""]]
297
+ end
298
+ if opts[:dpi]
299
+ c += [["export-dpi", opts[:dpi]]]
300
+ end
301
+
302
+ c += [["export-area", ""]]
303
+ c += [["export-area-drawing", "false"]]
304
+ c += [["export-id", ""]]
305
+ c += [["export-area-page", "false"]]
306
+
307
+ if opts[:area].kind_of? Array
308
+ c += [["export-area", ("%f:%f:%f:%f" % opts[:area]).gsub(".", @decimal_symbol)]]
309
+ elsif opts[:area] == :drawing
310
+ c += [["export-area-drawing", "true"]]
311
+ elsif opts[:area].kind_of? String
312
+ c += [["export-id", opts[:area]]]
313
+ else
314
+ c += [["export-area-page", "true"]]
315
+ end
316
+ c.each do |a|
317
+ command1([a])
318
+ response
319
+ end
320
+
321
+ command1([["export-do"]])
322
+ width, height = [0, 0]
323
+ loop do
324
+ case response
325
+ when /^Area .* exported to (\d+) x (\d+) pixels.*$/ then
326
+ width = $1
327
+ height = $2
328
+ when :prompt then break
329
+ end
330
+ end
331
+ command1([["file-close"]])
332
+ response
333
+
334
+ [width, height]
335
+ end
336
+
337
+ def export(opts)
338
+ if @inkscape_version == 0 then
339
+ export0(opts)
340
+ else
341
+ export1(opts)
342
+ end
343
+ end
344
+
235
345
  def query_all(file)
236
346
  ids = []
237
- command({
238
- "--file" => file,
239
- "--query-all" => nil,
240
- })
347
+ if @inkscape_version == 0 then
348
+ command0({
349
+ "--file" => file,
350
+ "--query-all" => nil,
351
+ })
352
+ else
353
+ command1([["file-open", file]])
354
+ response
355
+ command1([["query-all", file]])
356
+ end
241
357
  loop do
242
358
  case response
243
359
  when /^(.*),(.*),(.*),(.*),(.*)$/ then ids << [$1, $2.to_f, $3.to_f, $4.to_f, $5.to_f]
244
360
  when :prompt then break
245
361
  end
246
362
  end
363
+ if @inkscape_version == 1 then
364
+ command1([["file-close", file]])
365
+ response
366
+ end
247
367
  ids
248
368
  end
249
369
 
@@ -256,7 +376,11 @@ class Inkmake
256
376
  end
257
377
 
258
378
  def quit
259
- command({"quit" => nil})
379
+ if @inkscape_version == 0 then
380
+ command0({"quit" => nil})
381
+ else
382
+ @in.close
383
+ end
260
384
  @out.read
261
385
  nil
262
386
  end
@@ -269,8 +393,9 @@ class Inkmake
269
393
  return Inkmake.inkscape_path if Inkmake.inkscape_path
270
394
 
271
395
  # try to figure out inkscape path
272
- p = (
273
- (["/Applications/Inkscape.app/Contents/Resources/bin/inkscape",
396
+ p = (
397
+ (["/Applications/Inkscape.app/Contents/MacOS/inkscape",
398
+ "/Applications/Inkscape.app/Contents/Resources/bin/inkscape",
274
399
  'c:\Program Files\Inkscape\inkscape.exe',
275
400
  'c:\Program Files (x86)\Inkscape\inkscape.exe'] +
276
401
  (ENV['PATH'].split(':').map {|p| File.join(p, "inkscape")}))
@@ -283,7 +408,12 @@ class Inkmake
283
408
  else
284
409
  begin
285
410
  require "osx/cocoa"
286
- "#{OSX::NSWorkspace.sharedWorkspace.fullPathForApplication:"Inkscape"}/Contents/Resources/bin/inkscape"
411
+ app_path = OSX::NSWorkspace.sharedWorkspace.fullPathForApplication:"Inkscape"
412
+ ["#{app_path}/Contents/MacOS/inkscape",
413
+ "#{app_path}/Contents/Resources/bin/inkscape"]
414
+ .select do |path|
415
+ File.exists? path
416
+ end
287
417
  rescue NameError, LoadError
288
418
  nil
289
419
  end
@@ -303,29 +433,29 @@ class Inkmake
303
433
  }
304
434
  # 123x123, 12.3cm*12.3cm
305
435
  RES_RE = /^(\d+(?:\.\d+)?(?:px|pt|pc|mm|cm|dm|m|in|ft|uu)?)[x*](\d+(?:\.\d+)?(?:px|pt|pc|mm|cm|dm|m|in|ft|uu)?)$/
306
- # *123, *1.23
307
- SCALE_RE = /^\*(\d+(?:\.\d+)?)$/
308
- # 180dpi
309
- DPI_RE = /^(\d+(?:\.\d+)?)dpi$/i
436
+ # *123, *1.23
437
+ SCALE_RE = /^\*(\d+(?:\.\d+)?)$/
438
+ # 180dpi
439
+ DPI_RE = /^(\d+(?:\.\d+)?)dpi$/i
310
440
  # (prefix)[(...)](suffix)
311
441
  DEST_RE = /^([^\[]*)(?:\[(.*)\])?(.*)$/
312
- # test.svg, test.SVG
313
- SVG_RE = /\.svg$/i
442
+ # test.svg, test.SVG
443
+ SVG_RE = /\.svg$/i
314
444
  # ext to format, supported inkscape output formats
315
445
  EXT_RE = /\.(png|pdf|ps|eps)$/i
316
446
  # supported inkscape output formats
317
447
  FORMAT_RE = /^(png|pdf|ps|eps)$/i
318
448
  # @name
319
449
  AREA_NAME_RE = /^@(.*)$/
320
- # @x:y:w:h
321
- AREA_SPEC_RE = /^@(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/
322
- # right, left, upsidedown
323
- ROTATE_RE = /^(right|left|upsidedown)$/
324
- # show/hide layer or id, "+Layer 1", +#id, -*
325
- SHOWHIDE_RE = /^([+-])(.+)$/
450
+ # @x:y:w:h
451
+ AREA_SPEC_RE = /^@(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/
452
+ # right, left, upsidedown
453
+ ROTATE_RE = /^(right|left|upsidedown)$/
454
+ # show/hide layer or id, "+Layer 1", +#id, -*
455
+ SHOWHIDE_RE = /^([+-])(.+)$/
326
456
 
327
- class SyntaxError < StandardError
328
- end
457
+ class SyntaxError < StandardError
458
+ end
329
459
 
330
460
  class ProcessError < StandardError
331
461
  end
@@ -363,7 +493,7 @@ class Inkmake
363
493
  if RUBY_VERSION.start_with? "1.8"
364
494
  CSV::parse_line(line, fs = " ")
365
495
  else
366
- CSV::parse_line(line, {:col_sep => " "})
496
+ CSV::parse_line(line, **{:col_sep => " "})
367
497
  end
368
498
  end
369
499
 
@@ -468,16 +598,17 @@ class Inkmake
468
598
  else
469
599
  out_width, out_height = width, height
470
600
  end
601
+ file_href = "file://#{path}"
471
602
  svg =
472
603
  "<?xml version=\"1.0\"?>" +
473
604
  "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"#{out_width}\" height=\"#{out_height}\">" +
474
605
  "<g>" +
475
606
  "<image transform=\"translate(#{out_width/2} #{out_height/2}) rotate(#{degrees})\"" +
476
607
  " width=\"#{width}\" height=\"#{height}\" x=\"#{-width/2}\" y=\"#{-height/2}\"" +
477
- " xlink:href=\"file:///#{URI.escape(path)}\" />" +
608
+ " xlink:href=#{file_href.encode(:xml => :attr)} />" +
478
609
  "</g>" +
479
610
  "</svg>"
480
- f = Tempfile.new("inkmake")
611
+ f = Tempfile.new(["inkmake", ".svg"])
481
612
  f.write(svg)
482
613
  f.flush
483
614
  f.seek(0)
@@ -679,7 +810,7 @@ class Inkmake
679
810
  end
680
811
  end
681
812
 
682
- f = Tempfile.new("inkmake")
813
+ f = Tempfile.new(["inkmake", ".svg"])
683
814
  doc.write(:output => f)
684
815
  f.flush
685
816
  f
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inkmake
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattias Wadman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-02 00:00:00.000000000 Z
11
+ date: 2020-05-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: mattias.wadman@gmail.com
@@ -38,8 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
40
  requirements: []
41
- rubyforge_project:
42
- rubygems_version: 2.2.2
41
+ rubygems_version: 3.0.3
43
42
  signing_key:
44
43
  specification_version: 4
45
44
  summary: Makefile inspired export from SVG files using Inkscape as backend with some