Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Command line SVG optimizer and base64 converter for CSS

View svgoptimize
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
#! /usr/bin/env ruby
 
# nokogiri is required below unless --no-modify option is specified
require 'optparse'
require 'tempfile'
 
@options = {}
OptionParser.new do |opts|
opts.banner = "Usage: svgoptimize [options] <path-to-svg-file>"
 
opts.on('-v', '--verbose', 'verbose logging') do |v|
@options[:verbose] = true
end
opts.on('-q', '--quiet', 'only result output is displayed') do |v|
@options[:quiet] = true
end
opts.on('--no-modify', 'disables svg xml element removal') do |v|
@options[:skip_xml_optimization] = true
end
opts.on('-c', '--copy', 'copies the output to the system clipboard') do |v|
@options[:copy_to_clipboard] = true
end
opts.on('--css', 'wraps the output in a background css rule') do |v|
@options[:css_wrap] = true
end
end.parse!
 
path = ARGV[0]
unless path
puts "you must specify a path to the svg file you'd like to be optimized."
exit 1
end
 
unless File.exist?(path)
puts "path to file does not exist."
exit 1
end
 
def log(str, mode=:normal)
if @options[:quiet]
nil
elsif mode == :normal
puts str
elsif @options[:verbose] && mode == :verbose
puts str
end
end
 
def kb(total_bytes)
sprintf "%.2f KB", total_bytes / 1024.0
end
 
def size_to_kb(file)
kb file.size
end
 
input_file = File.open(path)
tmp_file = Tempfile.new("svg-optimize-#{File.basename(path)}")
tmp_file.write(input_file.read)
tmp_file.rewind
log "using temp file: #{tmp_file.path}", :verbose
 
log "Input file: \n#{input_file.read}", :verbose
log "Input SVG file size: #{size_to_kb(input_file)}"
 
unless @options[:skip_xml_optimization]
require 'nokogiri'
xml = Nokogiri::XML(tmp_file.read.gsub(%r~.*<svg ~mi, '<svg '))
%w[description title].each do |node_name|
xml.css(node_name).remove
end
 
tmp_file.truncate(0)
tmp_file.rewind
# xml.remove_namespaces!
extraneous_attributes = xml.root.attributes.reject { |k| %w[version viewBox].include?(k) }.keys
extraneous_attributes.each { |attr| xml.root.delete(attr) }
xml_str = xml.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::NO_DECLARATION).gsub(/>\s+</, "><")
tmp_file.write(xml_str)
tmp_file.rewind
log `cat #{tmp_file.path}`, :verbose
log "file size: #{`ls -lh #{tmp_file.path}`}", :verbose
end
 
base64tmp = Tempfile.new('svg-base64')
`cat #{tmp_file.path} | openssl base64 | tr -d '\n' > #{base64tmp.path}`
result = `cat #{base64tmp.path}`
 
log "Optimized size: #{kb result.length}"
log ""
if @options[:css_wrap]
result = "background: url(data:image/svg+xml;base64,#{result}) top right no-repeat"
f = File.open(base64tmp.path, 'w')
f.write(result)
f.close
end
 
puts result
 
if @options[:copy_to_clipboard]
clipboard_cmd = case RUBY_PLATFORM
when /darwin/
'pbcopy'
else
'xclip'
end
 
`cat #{base64tmp.path} | #{clipboard_cmd}`
puts "\n output copied to clipboard"
end
DoHahn commented

Thanks for that. :-)
I've changed mine to include the trailing semicolon and I've changed "top right" to "0 0".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.