inkmake 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/inkmake.rb +182 -51
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 020ed9f884ade66f1fc89a553d5187852aeaaa330236a58da5dc7f9f0f289a71
|
4
|
+
data.tar.gz: dc3019d1323bde40081b23c28b040fdb4c75d534be571985b9dc5255a8cdab3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
118
|
-
|
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
|
-
|
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
|
-
|
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
|
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 "
|
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
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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 "
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
243
|
+
open_shell
|
195
244
|
end
|
196
245
|
end
|
197
246
|
|
198
|
-
def
|
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
|
-
|
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
|
-
|
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
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
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/
|
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
|
-
|
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
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
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
|
-
|
313
|
-
|
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
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
-
|
328
|
-
|
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
|
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.
|
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:
|
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
|
-
|
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
|