This repository has been archived by the owner on Nov 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
processor.rb
133 lines (113 loc) · 3.86 KB
/
processor.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require 'cgi'
require 'ostruct'
require 'tempfile'
require 'fileutils'
require 'inkscape_merge/data_parsers'
require 'shellwords'
module Inkscape # :nodoc:
module Merge # :nodoc:
# Main class to initialize processing
class Processor
attr_reader :options
# Initialize the processor, setting files and options
def initialize
@options = OpenStruct.new
# Default options
@options.format = "pdf"
@options.csv_options = {:headers => true, :col_sep => ',', :encoding => 'utf-8'}
@options.limit = 0
@options.dpi = 300
@options.inkscape = %x(which inkscape).chomp
# If no Inkscape in PATH, try to guess from platform
if options.inkscape.empty?
options.inkscape = case RUBY_PLATFORM
when /darwin/
"/Applications/Inkscape.app/Contents/Resources/bin/inkscape"
end
end
end
# Iterate over all data rows and generate output files
# Optionally stop when LIMIT is reached
def run
validate_options
# Open the files
@svg = File.read options.svg_file
@data_file = DataParser.detect(options)
count = 0
headers = @data_file.headers
pattern = /%VAR_(#{headers.map(&:to_s).join("|")})%/
@data_file.each{|row|
break if @options.limit > 0 && count >= @options.limit
count += 1
puts "Row: #{count}"
tmp_file = Tempfile.new('inkscape_merge')
begin
(outfile,merged_svg) = [@options.output,@svg].map{|s|
s.gsub(pattern){|m|
puts $1 if @options.verbose
# return corresponding value from current row
CGI.escapeHTML(row[$1])
}
}
# Write merged SVG out
tmp_file.puts merged_svg
tmp_file.close
# Sprintf outfile with current row number
outfile %= count
# Generate output path
FileUtils.mkdir_p(File.dirname outfile)
# Generate the file itself
ink_generate tmp_file.path, Shellwords.escape(outfile), @options.format, @options.dpi
rescue => e
$stderr.puts "ERROR: #{e}"
$stderr.puts e.backtrace if @options.verbose
ensure
tmp_file.unlink
end
}
end
private
# Validate options and give error if something is missing
def validate_options
# TODO: replace with
# If inkscape can not be found or run, bail out
unless File.executable? @options.inkscape
raise ArgumentError, "Inkscape not found or not executable"
end
unless @options.svg_file
raise ArgumentError, "SVG file must be given"
end
unless @options.data_file
raise ArgumentError, "Data-file must be given"
end
unless @options.output
raise ArgumentError, "Output pattern must be given"
else
# Ensure absolute pathname
@options.output = File.absolute_path(@options.output)
end
end
# Run Inkscape to generate files
def ink_generate(in_file, out_file, format='pdf', dpi="300")
new_in_file = case RUBY_PLATFORM
when /cygwin/
Shellwords.escape(`cygpath.exe #{in_file} -w`.strip)
else
in_file
end
new_out_file = case RUBY_PLATFORM
when /cygwin/
Shellwords.escape(`cygpath.exe #{out_file} -w`.strip)
else
out_file
end
cmd = %(#{Shellwords.escape(@options.inkscape)} --without-gui --export-dpi=#{dpi} --export-#{format}=#{new_out_file} #{new_in_file})
puts "INKSCAPE CMD: #{cmd}" if @options.verbose
ink_error = `#{cmd} 2>&1`
unless $?.success?
$stderr.puts "Inkscape ERROR (#{$?}): #{ink_error}"
end
end
end
end
end