inline_image 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in inline_image.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ InlineImage
2
+ ===========
3
+
4
+ Description
5
+ -----------
6
+ Inline image parses css and html files to replace small file by a data URI reprentation in base64. Small files are files shorter than 1024 bytes by default.
7
+ File type must be either css or html. Extension is used to determine file type, _so it is important that your file end with .css or .html_
8
+ If file extension does not match either html or css, html will be used.
9
+
10
+ Installation
11
+ ------------
12
+ gem install inline_image
13
+
14
+ Usage and documentation
15
+ -----------------------
16
+ inline_image inline /path/to/your.css # search for url(img/name.png)
17
+ inline_image inline /path/to/your.html # search for src="img/name.png"
18
+ inline_image help inline # Brief usage description
19
+
20
+ Todo
21
+ ----
22
+ Add option to specify how small the file must be transformed
23
+
24
+ License
25
+ -------
26
+ Released under The Unlicense, aka public domain. See the [LICENSE][license] file for further details.
27
+
28
+ [license]: http://unlicense.org/
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/inline_image ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "thor"
4
+ require "inline_image"
5
+
6
+ class InlineImg < Thor
7
+ desc "inline FILENAME", "Inline images contained in FILENAME. FILENAME must be a css or html file. Extension is used to determine if it is either a css or a html file"
8
+ def inline(filename)
9
+ return false unless File.exist? filename
10
+
11
+ FileUtils.cp filename, "#{filename}.bak"
12
+
13
+ dir = File.dirname(filename)
14
+ extension = filename.split('.').last
15
+
16
+ File.open(filename, File::RDWR) do |file|
17
+ content = if extension == "css" then
18
+ InlineImage.replace_in_css file.read, dir
19
+ else
20
+ InlineImage.replace_in_html file.read, dir
21
+ end
22
+ file.rewind
23
+ file.truncate(0)
24
+ file.write content
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ InlineImg.start
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "inline_image/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "inline_image"
7
+ s.version = InlineImage::VERSION
8
+ s.authors = ["Yann Mainier"]
9
+ s.email = ["yann.mainier@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Inline images within css and html files using data URI}
12
+ s.description = %q{Inline image parses css and html files to replace small file by a data URI reprentation in base64.}
13
+
14
+ s.rubyforge_project = "inline_image"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('thor')
22
+
23
+ s.add_development_dependency('rspec')
24
+
25
+ end
@@ -0,0 +1,3 @@
1
+ module InlineImage
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,52 @@
1
+ require "inline_image/version"
2
+ require "base64"
3
+ require "fileutils"
4
+
5
+ module InlineImage
6
+ # Maximum file size to be inlined in bytes
7
+ MAX_FILE_SIZE = 1024
8
+
9
+ def in_css(filename, max_file_size = MAX_FILE_SIZE, options = {})
10
+ return false unless File.exist? filename
11
+
12
+ # TODO : Option to disable the copy
13
+ FileUtils.cp filename, "#{filename}.bak"
14
+
15
+ dir = File.dirname(filename)
16
+ extension = filename.split('.').last
17
+
18
+ File.open(filename, File::RDWR) do |file|
19
+ css = replace_in_css file.read, dir
20
+
21
+ file.rewind
22
+ file.truncate(0)
23
+ file.write css
24
+ end
25
+
26
+ end
27
+
28
+ def self.replace_in_css(css_text, base_dir = '.', max_file_size = MAX_FILE_SIZE)
29
+ css_text.gsub(/url\(['"]?([^'"\)]+)['"]?\)/m) do |match|
30
+ "url(#{process base_dir, $1, max_file_size})"
31
+ end
32
+ end
33
+
34
+ def self.replace_in_html(html_text, base_dir = '.', max_file_size = MAX_FILE_SIZE)
35
+ html_text.gsub(/src=['"]([^'"\)]+)['"]/m) do |match|
36
+ "src=\"#{process base_dir, $1, max_file_size}\""
37
+ end
38
+ end
39
+
40
+ def self.process(base_dir, name_in_file, max_file_size = MAX_FILE_SIZE)
41
+ image_filename = "#{base_dir}/#{name_in_file}"
42
+ extension = name_in_file.split('.').last
43
+ if File.size(image_filename) <= max_file_size then
44
+ File.open(image_filename) do |img|
45
+ base64encoded = Base64.encode64(img.read).gsub("\n", "")
46
+ "data:image/#{extension};base64,#{base64encoded}"
47
+ end if File.exist? image_filename
48
+ else
49
+ name_in_file
50
+ end
51
+ end
52
+ end
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ .with-small {
2
+ background: white url(images/small.png) no-repeat center;
3
+ }
4
+ .with-large {
5
+ background: white url(images/large.png)
6
+ }
7
+
@@ -0,0 +1,3 @@
1
+ <img src="images/small.png" />
2
+ <img src="images/large.png" />
3
+
@@ -0,0 +1,63 @@
1
+ require "lib/inline_image"
2
+
3
+ SMALL_PNG_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAw1BMVEWooJK5rJTTxKqxp5RrVVNuTE6ngG+skoeFjHatqYnEsJagk4GBWVOwfGfRoX/Mq492Z150XVSwloiScmqyfGrXpYa+jHCme2ulg3bJqZjEn4yneGmMVUyeZ1ibYVO6kYDOt57SrZfKoYyWZVtcKS6pbVurZlW3h3i5mIDEmoKudWZpOztpUD+QZVF8OTGQVUlsQj9VIyFOICdbQy6jpFZyajY1BgtmOj15Y2ZCJTNFKTljT0KLhFF5cklVNjd/YWb///+DUmMKAAAAAWJLR0RA/tlc2AAAAAlwSFlzAAAASAAAAEgARslrPgAAABJJREFUCNdjZGCEAg4ozUIWAwATLwCLd45LKgAAAABJRU5ErkJggg=="
4
+
5
+ SMALL_PNG_IN_CSS_BEFORE = <<-END_CSS
6
+ .with-small {
7
+ background: white url(images/small.png) no-repeat center;
8
+ }
9
+ END_CSS
10
+
11
+ SMALL_PNG_IN_CSS_AFTER = <<-END_CSS
12
+ .with-small {
13
+ background: white url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAw1BMVEWooJK5rJTTxKqxp5RrVVNuTE6ngG+skoeFjHatqYnEsJagk4GBWVOwfGfRoX/Mq492Z150XVSwloiScmqyfGrXpYa+jHCme2ulg3bJqZjEn4yneGmMVUyeZ1ibYVO6kYDOt57SrZfKoYyWZVtcKS6pbVurZlW3h3i5mIDEmoKudWZpOztpUD+QZVF8OTGQVUlsQj9VIyFOICdbQy6jpFZyajY1BgtmOj15Y2ZCJTNFKTljT0KLhFF5cklVNjd/YWb///+DUmMKAAAAAWJLR0RA/tlc2AAAAAlwSFlzAAAASAAAAEgARslrPgAAABJJREFUCNdjZGCEAg4ozUIWAwATLwCLd45LKgAAAABJRU5ErkJggg==) no-repeat center;
14
+ }
15
+ END_CSS
16
+
17
+ LARGE_PNG_IN_CSS = <<-END_CSS
18
+ .with-large {
19
+ background: white url(images/large.png)
20
+ }
21
+ END_CSS
22
+
23
+ SMALL_PNG_IN_HTML_BEFORE = <<-END_HTML
24
+ <img src="images/small.png" />
25
+ END_HTML
26
+
27
+ SMALL_PNG_IN_HTML_AFTER = <<-END_HTML
28
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAw1BMVEWooJK5rJTTxKqxp5RrVVNuTE6ngG+skoeFjHatqYnEsJagk4GBWVOwfGfRoX/Mq492Z150XVSwloiScmqyfGrXpYa+jHCme2ulg3bJqZjEn4yneGmMVUyeZ1ibYVO6kYDOt57SrZfKoYyWZVtcKS6pbVurZlW3h3i5mIDEmoKudWZpOztpUD+QZVF8OTGQVUlsQj9VIyFOICdbQy6jpFZyajY1BgtmOj15Y2ZCJTNFKTljT0KLhFF5cklVNjd/YWb///+DUmMKAAAAAWJLR0RA/tlc2AAAAAlwSFlzAAAASAAAAEgARslrPgAAABJJREFUCNdjZGCEAg4ozUIWAwATLwCLd45LKgAAAABJRU5ErkJggg==" />
29
+ END_HTML
30
+
31
+ LARGE_PNG_IN_HTML = <<-END_HTML
32
+ <img src="images/large.png" />
33
+ END_HTML
34
+
35
+ describe InlineImage do
36
+ it "encodes small images" do
37
+ InlineImage.process("spec/fixtures", "images/small.png").should eq(SMALL_PNG_DATA_URI)
38
+ end
39
+
40
+ it "does not modify large image" do
41
+ InlineImage.process("spec/fixtures", "images/large.png").should eq("images/large.png")
42
+ end
43
+
44
+ context "when processing css" do
45
+ it "replace small images in css" do
46
+ InlineImage.replace_in_css(SMALL_PNG_IN_CSS_BEFORE, "spec/fixtures").should eq(SMALL_PNG_IN_CSS_AFTER)
47
+ end
48
+
49
+ it "does not modify large image in css" do
50
+ InlineImage.replace_in_css(LARGE_PNG_IN_CSS, "spec/fixtures").should eq(LARGE_PNG_IN_CSS)
51
+ end
52
+ end
53
+
54
+ context "when processing html" do
55
+ it "replace small images in html" do
56
+ InlineImage.replace_in_html(SMALL_PNG_IN_HTML_BEFORE, "spec/fixtures").should eq(SMALL_PNG_IN_HTML_AFTER)
57
+ end
58
+
59
+ it "does not modify large image in html" do
60
+ InlineImage.replace_in_html(LARGE_PNG_IN_HTML, "spec/fixtures").should eq(LARGE_PNG_IN_HTML)
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inline_image
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Yann Mainier
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-07-24 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: thor
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: rspec
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :development
43
+ version_requirements: *id002
44
+ description: Inline image parses css and html files to replace small file by a data URI reprentation in base64.
45
+ email:
46
+ - yann.mainier@gmail.com
47
+ executables:
48
+ - inline_image
49
+ extensions: []
50
+
51
+ extra_rdoc_files: []
52
+
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - README.md
57
+ - Rakefile
58
+ - bin/inline_image
59
+ - inline_image.gemspec
60
+ - lib/inline_image.rb
61
+ - lib/inline_image/version.rb
62
+ - spec/fixtures/images/large.png
63
+ - spec/fixtures/images/small.png
64
+ - spec/fixtures/test.css
65
+ - spec/fixtures/test.html
66
+ - spec/inline_image_spec.rb
67
+ has_rdoc: true
68
+ homepage: ""
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ requirements: []
91
+
92
+ rubyforge_project: inline_image
93
+ rubygems_version: 1.3.6
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Inline images within css and html files using data URI
97
+ test_files:
98
+ - spec/fixtures/images/large.png
99
+ - spec/fixtures/images/small.png
100
+ - spec/fixtures/test.css
101
+ - spec/fixtures/test.html
102
+ - spec/inline_image_spec.rb