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
|
#!/usr/bin/env ruby
require "rexml/document"
require "fileutils"
include REXML
INKSCAPE = 'flatpak run org.inkscape.Inkscape'
# INKSCAPE = '/usr/bin/inkscape'
PREFIX = "Adwaita/scalable"
# SVGO is a Node.js SVG optimization tool install with 'sudo npm install -g svgo'
# script will skip if SVGO is not present
SVGO = '/usr/bin/svgo'
if ARGV.empty?
puts "Invoke with puts #{$PROGRAM_NAME} [PLATE.svg] [ICON_NAME]?"
exit
end
SRC = ARGV[0]
def chopSVG(icon)
FileUtils.mkdir_p(icon[:dir]) unless File.exists?(icon[:dir])
unless (File.exists?(icon[:file]) && !icon[:forcerender])
FileUtils.cp(SRC,icon[:file])
puts " >> #{icon[:name]}"
# extract the icon
cmd = "#{INKSCAPE} -f #{icon[:file]} "
cmd += "--select #{icon[:id]} --verb=FitCanvasToSelection --verb=EditInvertInAllLayers --verb=EditDelete " # delete everything but the icon
cmd += "--verb=FileVacuum --verb=FileSave --verb=FileQuit > /dev/null 2>&1"
system(cmd)
# remove bounding rectangle
svgcrop = Document.new(File.new(icon[:file], 'r'))
svgcrop.root.each_element("//rect") do |rect|
w = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #get rid of 16 vs 15.99999
h = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #Inkscape bugs
if w == 128 && h == 128
rect.remove
end
end
icon_f = File.new(icon[:file],'w+')
icon_f.puts svgcrop
icon_f.close
# save as plain SVG
cmd = "#{INKSCAPE} -f #{icon[:file]} -z --vacuum-defs --export-plain-svg=#{icon[:file]} > /dev/null 2>&1"
system(cmd)
# remove as many extraneous elements as possible with SVGO
cmd = "#{SVGO} --pretty --disable=convertShapeToPath -i #{icon[:file]} -o #{icon[:file]} > /dev/null 2>&1"
system(cmd)
else
puts " -- #{icon[:name]} already exists"
end
end #end of function
def get_output_filename(d,n)
outfile = "#{d}/#{n}.svg"
return outfile
end
#main
# Open SVG file.
svg = Document.new(File.new(SRC, 'r'))
if (ARGV[1].nil?) #render all SVGs
puts "Rendering from icons in #{SRC}"
# Go through every layer.
svg.root.each_element("/svg/g[@inkscape:groupmode='layer']") do |context|
context_name = context.attributes.get_attribute("inkscape:label").value
if context_name.end_with?("legacy")
puts "Skipping layer '" + context_name + "'"
else
puts "Going through layer '" + context_name + "'"
context.each_element("g") do |icon|
#puts "DEBUG #{icon.attributes.get_attribute('id')}"
dir = "#{PREFIX}/#{context_name}"
icon_name = icon.elements["title"].text
puts icon_name
chopSVG({ :name => icon_name,
:id => icon.attributes.get_attribute("id"),
:dir => dir,
:file => get_output_filename(dir, icon_name)})
end
end
end
puts "\nrendered all SVGs"
else #only render the icons passed
icons = ARGV
ARGV.each do |icon_name|
icon = svg.root.elements["//g/title[text() = '#{icon_name}']"].parent
dir = "#{PREFIX}/#{icon.parent.attributes['inkscape:label']}"
#chopSVG({ :name => icon_name,
# :id => icon.attributes["id"],
# :dir => dir,
# :file => get_output_filename(dir, icon_name),
# :forcerender => true})
end
puts "\nrendered #{ARGV.length} icons"
end
|