html_press 0.6.7 → 0.7.0
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 +1 -0
- data/Gemfile +2 -0
- data/Rakefile +10 -10
- data/Readme.md +3 -0
- data/html_press.gemspec +29 -29
- data/lib/html_press/html.rb +93 -54
- data/lib/html_press/version.rb +1 -1
- data/lib/html_press.rb +17 -17
- data/profile/index.html +37690 -0
- data/profile/profile.rb +28 -0
- data/spec/html_press_spec.rb +32 -16
- metadata +7 -5
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
|
3
|
-
[:build, :install, :release].each do |task_name|
|
4
|
-
Rake::Task[task_name].prerequisites << :spec
|
5
|
-
end
|
6
|
-
|
7
|
-
require "rspec/core/rake_task"
|
8
|
-
RSpec::Core::RakeTask.new
|
9
|
-
|
10
|
-
task :default => :spec
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
[:build, :install, :release].each do |task_name|
|
4
|
+
Rake::Task[task_name].prerequisites << :spec
|
5
|
+
end
|
6
|
+
|
7
|
+
require "rspec/core/rake_task"
|
8
|
+
RSpec::Core::RakeTask.new
|
9
|
+
|
10
|
+
task :default => :spec
|
data/Readme.md
CHANGED
@@ -39,6 +39,9 @@ TODO :exclamation:
|
|
39
39
|
- Support other js/css minifiers (Closure, YUI compressor)
|
40
40
|
- htmlTydi
|
41
41
|
- Rack plugin
|
42
|
+
- add script to benchmark real projects like amazon or stackoverflow
|
43
|
+
- support html5 tags
|
44
|
+
- add more options
|
42
45
|
|
43
46
|
## Alternatives
|
44
47
|
- [html-minifier](https://github.com/kangax/html-minifier) (js), [test suite](https://github.com/kangax/html-minifier/blob/gh-pages/tests/index.html), ruby wrapper - [html_minifier](https://github.com/stereobooster/html_minifier)
|
data/html_press.gemspec
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "html_press/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.name = "html_press"
|
7
|
-
s.version = HtmlPress::VERSION
|
8
|
-
s.authors = ["stereobooster"]
|
9
|
-
s.email = ["stereobooster@gmail.com"]
|
10
|
-
s.homepage = "https://github.com/stereobooster/html_press"
|
11
|
-
s.summary = %q{Compress html}
|
12
|
-
s.description = %q{Ruby gem for compressing html}
|
13
|
-
|
14
|
-
s.rubyforge_project = "html_press"
|
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 "nokogiri"
|
22
|
-
|
23
|
-
s.add_development_dependency "rspec"
|
24
|
-
s.add_development_dependency "rake"
|
25
|
-
|
26
|
-
s.add_runtime_dependency "css_press", ">=0.3.2"
|
27
|
-
s.add_runtime_dependency "uglifier"
|
28
|
-
s.add_runtime_dependency "htmlentities"
|
29
|
-
end
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "html_press/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "html_press"
|
7
|
+
s.version = HtmlPress::VERSION
|
8
|
+
s.authors = ["stereobooster"]
|
9
|
+
s.email = ["stereobooster@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/stereobooster/html_press"
|
11
|
+
s.summary = %q{Compress html}
|
12
|
+
s.description = %q{Ruby gem for compressing html}
|
13
|
+
|
14
|
+
s.rubyforge_project = "html_press"
|
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 "nokogiri"
|
22
|
+
|
23
|
+
s.add_development_dependency "rspec"
|
24
|
+
s.add_development_dependency "rake"
|
25
|
+
|
26
|
+
s.add_runtime_dependency "css_press", ">=0.3.2"
|
27
|
+
s.add_runtime_dependency "uglifier"
|
28
|
+
s.add_runtime_dependency "htmlentities"
|
29
|
+
end
|
data/lib/html_press/html.rb
CHANGED
@@ -4,7 +4,8 @@ module HtmlPress
|
|
4
4
|
DEFAULTS = {
|
5
5
|
:logger => false,
|
6
6
|
:unquoted_attributes => false,
|
7
|
-
:drop_empty_values => false
|
7
|
+
:drop_empty_values => false,
|
8
|
+
:strip_crlf => false
|
8
9
|
}
|
9
10
|
|
10
11
|
def initialize (options = {})
|
@@ -13,38 +14,62 @@ module HtmlPress
|
|
13
14
|
@options[:drop_empty_values] = @options.delete(:dump_empty_values)
|
14
15
|
warn "dump_empty_values deprecated use drop_empty_values"
|
15
16
|
end
|
16
|
-
|
17
|
-
|
18
|
-
def log (text)
|
19
|
-
if @options[:logger] && @options[:logger].respond_to?(:call)
|
20
|
-
@options[:logger].call text
|
17
|
+
if @options[:logger] && !@options[:logger].respond_to?(:error)
|
18
|
+
raise ArgumentError, 'Logger has no error method'
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
22
|
def press (html)
|
25
|
-
|
26
23
|
out = html.respond_to?(:read) ? html.read : html.dup
|
27
24
|
|
28
25
|
@replacement_hash = 'MINIFYHTML' + Time.now.to_i.to_s
|
29
26
|
@placeholders = []
|
30
|
-
@strip_crlf = false
|
31
27
|
|
32
|
-
|
33
|
-
out
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
out = process_ie_conditional_comments out
|
29
|
+
out = process_scripts out
|
30
|
+
out = process_styles out
|
31
|
+
out = process_html_comments out
|
32
|
+
out = process_pres out
|
33
|
+
|
34
|
+
out = HtmlPress.entities_compressor out
|
35
|
+
|
36
|
+
out = trim_lines out
|
37
|
+
out = process_block_elements out
|
38
|
+
out = process_textareas out
|
39
|
+
|
40
|
+
# use newlines before 1st attribute in open tags (to limit line lengths)
|
41
|
+
# out.gsub!(/(<[a-z\-:]+)\s+([^>]+>)/i, "\\1\n\\2")
|
42
|
+
|
43
|
+
out = process_attributes out
|
44
|
+
out = process_whitespaces out
|
45
|
+
out = fill_placeholders out
|
46
|
+
|
47
|
+
out
|
48
|
+
end
|
49
|
+
|
50
|
+
# for backward compatibility
|
51
|
+
alias :compile :press
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
# IE conditional comments
|
56
|
+
def process_ie_conditional_comments (out)
|
57
|
+
out.gsub /(<!--\[[^\]]+\]>([\s\S]*?)<!\[[^\]]+\]-->)\s*/ do
|
58
|
+
m = $1
|
59
|
+
comment = $2
|
60
|
+
comment_compressed = Html.new.press(comment)
|
37
61
|
m.gsub!(comment, comment_compressed)
|
38
62
|
reserve m
|
39
63
|
end
|
64
|
+
end
|
40
65
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
66
|
+
# replace SCRIPTs (and minify) with placeholders
|
67
|
+
def process_scripts (out)
|
68
|
+
out.gsub /(<script\b[^>]*?>([\s\S]*?)<\/script>)\s*/i do
|
69
|
+
js = $2
|
70
|
+
m = $1.gsub /^<script\s([^>]+)>/i do |m|
|
45
71
|
attrs(m, 'script', true)
|
46
72
|
end
|
47
|
-
js = m.gsub(/^<script\b[^>]*?>([\s\S]*?)<\/script>/i , "\\1")
|
48
73
|
begin
|
49
74
|
js_compressed = HtmlPress.js_compressor js
|
50
75
|
m.gsub!(js, js_compressed)
|
@@ -53,14 +78,15 @@ module HtmlPress
|
|
53
78
|
end
|
54
79
|
reserve m
|
55
80
|
end
|
81
|
+
end
|
56
82
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
83
|
+
# replace STYLEs (and minify) with placeholders
|
84
|
+
def process_styles (out)
|
85
|
+
out.gsub /(<style\b[^>]*?>([\s\S]*?)<\/style>)\s*/i do
|
86
|
+
css = $2
|
87
|
+
m = $1.gsub /^<style\s([^>]+)>/i do |m|
|
61
88
|
attrs(m, 'style', true)
|
62
89
|
end
|
63
|
-
css = m.gsub(/^<style\b[^>]*?>([\s\S]*?)<\/style>/i, "\\1")
|
64
90
|
begin
|
65
91
|
css_compressed = HtmlPress.style_compressor css
|
66
92
|
m.gsub!(css, css_compressed)
|
@@ -69,31 +95,32 @@ module HtmlPress
|
|
69
95
|
end
|
70
96
|
reserve m
|
71
97
|
end
|
98
|
+
end
|
72
99
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
100
|
+
# remove html comments (not IE conditional comments)
|
101
|
+
def process_html_comments (out)
|
102
|
+
out.gsub /<!--([\s\S]*?)-->/, ''
|
103
|
+
end
|
77
104
|
|
78
|
-
|
79
|
-
|
80
|
-
|
105
|
+
# replace PREs with placeholders
|
106
|
+
def process_pres (out)
|
107
|
+
out.gsub /(<pre\b[^>]*?>([\s\S]*?)<\/pre>)\s*/i do
|
108
|
+
pre = $2
|
109
|
+
m = $1
|
81
110
|
pre_compressed = pre.gsub(/\s+$/, '')
|
82
111
|
pre_compressed = HtmlPress.entities_compressor pre_compressed
|
83
112
|
m.gsub!(pre, pre_compressed)
|
84
113
|
reserve m
|
85
114
|
end
|
115
|
+
end
|
86
116
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
reserve m
|
92
|
-
end
|
93
|
-
|
94
|
-
# trim each line.
|
95
|
-
out.gsub!(/^\s+|\s+$/m, '')
|
117
|
+
# trim each line
|
118
|
+
def trim_lines (out)
|
119
|
+
out.gsub(/^\s+|\s+$/m, '')
|
120
|
+
end
|
96
121
|
|
122
|
+
# remove whitespaces outside of block elements
|
123
|
+
def process_block_elements (out)
|
97
124
|
re = '\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' +
|
98
125
|
'|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' +
|
99
126
|
'|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' +
|
@@ -103,34 +130,49 @@ module HtmlPress
|
|
103
130
|
re = Regexp.new(re)
|
104
131
|
out.gsub!(re, '\\1')
|
105
132
|
|
106
|
-
# remove
|
133
|
+
# remove whitespaces outside of all elements
|
107
134
|
out.gsub! />([^<]+)</ do |m|
|
108
135
|
m.gsub(/^\s+|\s+$/, ' ')
|
109
136
|
end
|
110
137
|
|
111
|
-
|
112
|
-
|
138
|
+
out
|
139
|
+
end
|
113
140
|
|
114
|
-
|
115
|
-
|
116
|
-
|
141
|
+
# replace TEXTAREAs with placeholders
|
142
|
+
def process_textareas (out)
|
143
|
+
out.gsub /(<textarea\b[^>]*?>[\s\S]*?<\/textarea>)\s*/i do |m|
|
144
|
+
reserve m
|
117
145
|
end
|
146
|
+
end
|
118
147
|
|
119
|
-
|
148
|
+
# attributes
|
149
|
+
def process_attributes (out)
|
150
|
+
out.gsub /<[a-z\-:]+\s([^>]+)>/i do |m|
|
151
|
+
reserve attrs(m, '[a-z\-:]+', true)
|
152
|
+
end
|
153
|
+
end
|
120
154
|
|
155
|
+
# replace two or more whitespaces with one
|
156
|
+
def process_whitespaces (out)
|
157
|
+
out.gsub!(/[\r\n]+/, @options[:strip_crlf] ? ' ' : "\n")
|
121
158
|
out.gsub!(/\s+/, ' ')
|
159
|
+
out
|
160
|
+
end
|
122
161
|
|
123
|
-
|
162
|
+
# fill placeholders
|
163
|
+
def fill_placeholders (out)
|
124
164
|
re = Regexp.new('%' + @replacement_hash + '%(\d+)%')
|
125
|
-
out.gsub
|
165
|
+
out.gsub re do |m|
|
126
166
|
m.gsub!(re, "\\1")
|
127
167
|
@placeholders[m.to_i]
|
128
168
|
end
|
169
|
+
end
|
129
170
|
|
130
|
-
|
171
|
+
def log (text)
|
172
|
+
@options[:logger].error text if @options[:logger]
|
131
173
|
end
|
132
174
|
|
133
|
-
def reserve(content)
|
175
|
+
def reserve (content)
|
134
176
|
@placeholders.push content
|
135
177
|
'%' + @replacement_hash + '%' + (@placeholders.size - 1).to_s + '%'
|
136
178
|
end
|
@@ -146,7 +188,7 @@ module HtmlPress
|
|
146
188
|
end
|
147
189
|
|
148
190
|
if attributes.size > 0
|
149
|
-
attributes_compressed = attributes.gsub(
|
191
|
+
attributes_compressed = attributes.gsub(/([a-z\-_:]+(="[^"]*")?(='[^']*')?)\s*/i, " \\1")
|
150
192
|
|
151
193
|
attributes_compressed.gsub! /([a-z\-_:]+="[^"]*")/i do |k|
|
152
194
|
attr k, "\"", tag
|
@@ -278,8 +320,5 @@ module HtmlPress
|
|
278
320
|
attribute
|
279
321
|
end
|
280
322
|
|
281
|
-
# for backward compatibility
|
282
|
-
alias :compile :press
|
283
|
-
|
284
323
|
end
|
285
324
|
end
|
data/lib/html_press/version.rb
CHANGED
data/lib/html_press.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
require "html_press/version"
|
2
|
-
require "html_press/css_press"
|
3
|
-
require "html_press/uglifier"
|
4
|
-
require "html_press/html_entities"
|
5
|
-
require "html_press/html"
|
6
|
-
|
7
|
-
module HtmlPress
|
8
|
-
def self.press(text, options = {})
|
9
|
-
HtmlPress::Html.new(options).press text
|
10
|
-
end
|
11
|
-
|
12
|
-
# for backward compatibility
|
13
|
-
def self.compress(text, options = {})
|
14
|
-
HtmlPress::Html.new(options).press text
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
1
|
+
require "html_press/version"
|
2
|
+
require "html_press/css_press"
|
3
|
+
require "html_press/uglifier"
|
4
|
+
require "html_press/html_entities"
|
5
|
+
require "html_press/html"
|
6
|
+
|
7
|
+
module HtmlPress
|
8
|
+
def self.press(text, options = {})
|
9
|
+
HtmlPress::Html.new(options).press text
|
10
|
+
end
|
11
|
+
|
12
|
+
# for backward compatibility
|
13
|
+
def self.compress(text, options = {})
|
14
|
+
HtmlPress::Html.new(options).press text
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|