Skip to content

Instantly share code, notes, and snippets.

@crmne
Forked from sr3d/ie9build.rb
Created August 22, 2010 23:15
Show Gist options
  • Save crmne/544407 to your computer and use it in GitHub Desktop.
Save crmne/544407 to your computer and use it in GitHub Desktop.
Pack JS and CSS in PNG
#!/usr/bin/env ruby
require 'ftools'
require 'fileutils'
require 'rubygems'
require 'RMagick'
include Magick
require 'open3'
def merge( files = [] )
merged_file = ""
files.each do |file|
File.open( file, "r") { |f|
merged_file += f.read + "\n"
}
end
merged_file
end
def minify( string = '', type = 'js' )
cmd = "java -jar bin/yuicompressor-2.4.2.jar --type #{type}"
stdin, stdout, stderr = Open3.popen3( cmd )
stdin.write string
stdin.close
stdout.read
end
def minify_to_file( string, type, output )
cmd = "java -jar bin/yuicompressor-2.4.2.jar -v --type #{type} -o #{output} --charset utf-8"
# puts cmd
stdin, stdout, stderr = Open3.popen3( cmd )
stdin.write string
stdin.close
puts stderr.read
end
def string2png( string, output )
image = Magick::Image.new 1,string.length
for i in 0 .. string.length
color = '#%02X0000' % string[i]
pixel = Magick::Pixel.from_color color
image.pixel_color 0, i, pixel
end
image.compression = ZipCompression
image.write("png8:"+ output)
image = nil
end
def png2string(image)
string = ''
Image.read(File.open( image, "r" )).first.each_pixel do |px,x,y|
string += (px.red % 256).chr
end
string
end
def string2pngs( string, output )
puts "original string length #{string.length}"
limit = 8192 #8192 # IE9 max for getImageData
images_count = (string.length * 1.0 / limit ).ceil
files = []
for i in 0 ... images_count
filename = output.split('.')
filename[ filename.length - 2 ] += i.to_s
filename = filename.join('.')
files << filename
from = i * limit
to = from + [ limit, string.length - from ].min
puts "output from #{from} to #{to}"
string2png string[from,to], filename
files << filename
end
# verify
# s = ''
# files.each{ |file| s += png2string(file) }
# raise ('invalid string, expecting ' + s + "\n\n---but got---\n\n " + string) unless s == string
# total_size = 0
# files.each{ |file| puts "#{"%-20.20s" % file} #{"%30s" % File.stat( file ).size}"; total_size += File.stat( file ).size }
# puts total_size
files
end
def pngout files = []
files.each do |file|
cmd = "bin/pngout #{file} -c2 -f3 -b128 -kbKGD -v"
puts `#{cmd}`
end
end
release_path = 'ie9'
# Clean up
puts "Clean up release folder (#{release_path})"
FileUtils.rm_rf release_path
File.makedirs release_path + '/img'
File.makedirs release_path + '/js'
files_to_copy = {
'index.ie9.html' => 'index.html',
# 'ie9fix.css' => 'ie9fix.css',
'img/dir.gif' => 'img/dir.gif',
'img/la.gif' => 'img/la.gif',
'img/la_h.gif' => 'img/la_h.gif',
'img/txt.gif' => 'img/txt.gif',
# 'img/dir.png' => 'img/dir.png',
# 'img/la.png' => 'img/la.png',
# 'img/la_h.png' => 'img/la_h.png',
# 'img/txt.png' => 'img/txt.png',
# 'javascripts/prototype.js' => 'prototype.js',
# 'javascripts/vendors/jsonp.js' => 'jsonp.js',
# 'javascripts/util.js' => 'util.js',
# 'javascripts/f.js' => 'f.js',
# 'javascripts/p.js' => 'p.js',
# 'javascripts/diff.js' => 'diff.js',
# 'javascripts/gh.js' => 'gh.js' ,
# 'javascripts/keyboard.js' => 'keyboard.js',
#
#
# 'javascripts/vendors/difflib.js' => 'difflib.js',
# 'javascripts/vendors/diffview.js' => 'diffview.js'
}
puts "Copy files"
files_to_copy.each do |src,dest|
dest = release_path + '/' + dest
puts " cp #{src} => #{dest}"
File.copy src, dest
end
js_files = [
'javascripts/vendors/jsonp.js',
'javascripts/util.js',
'javascripts/f.js',
'javascripts/p.js',
'javascripts/gh.js',
'javascripts/plugins/base.js',
# 'javascripts/diff.js',
'javascripts/keyboard.js',
# 'javascripts/plugins/resizeable_panel.js',
'javascripts/plugins/github_readme.js',
'javascripts/plugins/bookmarklet.js',
# 'javascripts/plugins/code_highlighter.js',
# 'javascripts/vendors/code_highlighter.js',
# 'javascripts/vendors/difflib.js',
# 'javascripts/vendors/diffview.js',
'javascripts/app.js'
]
puts "bundling js and css:"
puts " minifying js..."
js = minify merge( js_files )
puts " minifying css..."
css = minify(merge([
'styles.css',
# 'github_readme.css'
]), 'css')
puts " bundling..."
# string2png js + "~10K~" + css, release_path + '/c.png' # bundle both js + css into 1 image
code_pngs = string2pngs js + "~10K~" + css, release_path + '/js/c.png'
pngout code_pngs # further compress!
files_to_minify = [
{ :files => [ 'javascripts/bootstrap.js'], :output => 'js/bootstrap.js', :type => 'js' },
# { :files => [ 'ie9fix.css'], :output => 'ie9fix.css', :type => 'css' }
]
files_to_minify.each do |group|
puts "minify #{group[:output]}"
minify_to_file merge(group[:files]), group[:type], release_path + '/' + group[:output]
end
puts "------ Size Report ------"
files_to_skip_counting = [
'prototype.js',
'styles.css',
'img',
'js'
]
total_size = 0
Dir.glob( [release_path + '/*', release_path + '/img/*',release_path + '/js/*' ] ).each do |file|
# puts file
next if files_to_skip_counting.include? File.basename(file)
puts "#{"%-20.20s" % file} #{"%30s" % File.stat( file ).size}"
total_size += File.stat( file ).size
end
puts "Total size: #{total_size}"
puts "10K Limit: #{- total_size + 10240}"
#puts png2string( release_path + '/c.png')[-30,30]
# string2pngs js + "~10K~" + css, release_path + '/c.png'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment