csscutter 0.3.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
data/License ADDED
@@ -0,0 +1,19 @@
1
+ License
2
+ Copyright (C) 2012 m16a1
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOTLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ class CssCutter::Cleaner < String
2
+ def remove_whitespace
3
+ strip
4
+ .gsub(/\s+/, ' ')
5
+ .gsub(/\s*\{\s*/, '{')
6
+ .gsub(/\s*\}\s*/, '}')
7
+ .gsub(/(\S+)\s*:\s*([^\{\};]+?)(?=[\};])/, '\1:\2')
8
+ .gsub(/(\([^\)]*)(\S)\s*:\s*/, '\1\2:')
9
+ .gsub(/\s*([,;=\+\>~])\s*/, '\1')
10
+ .gsub('( ', '(')
11
+ .gsub(' )', ')')
12
+ .gsub('[ ', '[')
13
+ .gsub(' ]', ']')
14
+ .gsub(' ~=', '~=')
15
+ .gsub(' $=', '$=')
16
+ .gsub(' *=', '*=')
17
+ .gsub(' |=', '|=')
18
+ .gsub(' ^=', '^=')
19
+ end
20
+
21
+ def remove_trailing_semicolons
22
+ gsub /;+}/, '}'
23
+ end
24
+
25
+ def remove_empty_selectors
26
+ gsub(/\A[^\{]+\{\s*\}/, '')
27
+ .gsub /\}[^\}]+\{\s*\}/, '}'
28
+ end
29
+
30
+ def remove_comments
31
+ gsub /\/\*.*?\*\//, ''
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ class CssCutter::Simplifier < String
2
+ def replace_zeros
3
+ gsub /(?<!background-position)\s*:\s*(0\s+)+0(?=[;\}])/, ':0'
4
+ end
5
+
6
+ def remove_units_after_zero
7
+ regex = %r{
8
+ (?<=[:\s,])
9
+ 0
10
+ (px|em|%|in|cm|mm|ex|pt|pc|ch|rem|vw|vh|vmin|vmax|deg|rad|grad|turn|s|ms)
11
+ (?=[;,\s\}])
12
+ }x
13
+ gsub regex, '0'
14
+ end
15
+
16
+ def convert_rgb_to_hex
17
+ gsub /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ do |match|
18
+ '#' + dec_to_hex($1) + dec_to_hex($2) + dec_to_hex($3)
19
+ end
20
+ end
21
+
22
+ def minify_hex
23
+ gsub /\#(\h)\1(\h)\2(\h)\3/, '#\1\2\3'
24
+ end
25
+
26
+ def minify_floats
27
+ gsub /(\s|:)0\.(\d)/, '\1.\2'
28
+ end
29
+
30
+ def replace_none_value_with_zero
31
+ gsub /((\{|;)\s*\w+\s*):(\s*)none(\s*(;|\}))/, '\1:\30\4'
32
+ end
33
+
34
+ private
35
+ def dec_to_hex(number)
36
+ "%02x" % number.to_i
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ class CssCutter
2
+ VERSION = '0.3.1.alpha'
3
+ end
@@ -0,0 +1,40 @@
1
+ class CssCutter::WhitespaceKeeper
2
+ DEFAULT_OPTIONS = {
3
+ keep_important_comments: true
4
+ }
5
+
6
+ def initialize(code, options = {})
7
+ @code = code
8
+ @options = DEFAULT_OPTIONS.merge options
9
+ @blocks = []
10
+ end
11
+
12
+ def safely_optimize(&block)
13
+ _code = [
14
+ :save_contents,
15
+ @options[:keep_important_comments] ? :save_important_comments : nil
16
+ ].inject(@code) { |result, method| method ? send(method,result) : result }
17
+ restore(yield _code)
18
+ end
19
+
20
+ private
21
+ def save_contents(code)
22
+ code.gsub(/(?<=\Wcontents)(\s*:\s*)([\"\'])(.*?)\2/) do |match|
23
+ @blocks << $2 + $3 + $2
24
+ "#{$1}@@#{@blocks.size}@@"
25
+ end
26
+ end
27
+
28
+ def save_important_comments(code)
29
+ code.gsub(/\/\*\!.*?\*\//) do |match|
30
+ @blocks << match
31
+ "@@#{@blocks.size}@@"
32
+ end
33
+ end
34
+
35
+ def restore(code)
36
+ result = code.gsub(/@@(\d+)@@/) { |match| @blocks[$1.to_i - 1] }
37
+ result = restore(result) if /@@(\d+)@@/ =~ result
38
+ result
39
+ end
40
+ end
data/lib/csscutter.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'csscutter/version'
2
+ require 'csscutter/cleaner'
3
+ require 'csscutter/simplifier'
4
+ require 'csscutter/whitespace_keeper'
5
+
6
+ class CssCutter
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def optimize(code)
12
+ keeper = WhitespaceKeeper.new(code, @options)
13
+ keeper.safely_optimize do |_code|
14
+ [:clean, :simplify]
15
+ .inject(_code) { |result, method| self.send(method,result) }
16
+ end
17
+ end
18
+
19
+ def clean(code)
20
+ Cleaner.new(code)
21
+ .remove_whitespace
22
+ .remove_trailing_semicolons
23
+ .remove_comments
24
+ .remove_empty_selectors
25
+ end
26
+
27
+ def simplify(code)
28
+ Simplifier.new(code)
29
+ .remove_units_after_zero
30
+ .replace_zeros
31
+ .convert_rgb_to_hex
32
+ .minify_hex
33
+ .minify_floats
34
+ .replace_none_value_with_zero
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csscutter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1.alpha
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - m16a1
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: CSS minifier inspired by cssmin
15
+ email: a741su@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/csscutter/simplifier.rb
21
+ - lib/csscutter/whitespace_keeper.rb
22
+ - lib/csscutter/cleaner.rb
23
+ - lib/csscutter/version.rb
24
+ - lib/csscutter.rb
25
+ - License
26
+ homepage: https://github.com/m16a1/csscutter
27
+ licenses: []
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ segments:
39
+ - 0
40
+ hash: -325652227132239602
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>'
45
+ - !ruby/object:Gem::Version
46
+ version: 1.3.1
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 1.8.24
50
+ signing_key:
51
+ specification_version: 3
52
+ summary: CSS minifier
53
+ test_files: []