sassificator 0.1.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.
Files changed (3) hide show
  1. checksums.yaml +15 -0
  2. data/lib/sassificator.rb +211 -0
  3. metadata +45 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTU5ZjMyYWYwN2IyOTg0NjIyZTEzZjgyNjE5MDMxMjYzYzJhYTgxNg==
5
+ data.tar.gz: !binary |-
6
+ YWMzMTJlMzkzNGNkMGY0ODA4OGEzNDZmOWJhNzMzYmQ0OTQzMjNlZQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Yzg5NzMyZjQxODM0MmQyZjQ1MThkMDA3ZTdkODQwMmVhMDgyNjRkYjllNTMy
10
+ OWM1MzQyY2MzZWJkMjc3ZTE1OTg2NmIxZDRjZmFmNDAzZGUxODQ5OThjNjAz
11
+ ODg1MjNkNTdmNmM3ODlkYzU3NzBmNDQyZWNiNDg5YjU4ZjczYWQ=
12
+ data.tar.gz: !binary |-
13
+ YjAwY2IwYTg3NjQ0MzZlMDg0OTNjZGQ3NTUxMjNhM2FlZTFlZTE5YmYxMGU5
14
+ ZWQwMDJjMjE0MmUxOGZjOTQwMjNmYjVjNTA0YmZjMGZlNzM5YzA0NzRhZDFi
15
+ MTBlZmM0MzJiN2JkOGQzNWFlNTZlZjhiYThmZWVhNDA4ZjQ1OTY=
@@ -0,0 +1,211 @@
1
+ #TODO:
2
+ # - mediaquery inside of a mediaquery
3
+ # - images formating pattern setting
4
+ # - formatting is doen only for output sass_string, but not for sass_obj
5
+ # - false params may result in nil uptput - investigate and fix
6
+
7
+ class Sassificator
8
+ attr_accessor :colors_to_vars
9
+ ##
10
+ #
11
+ # @param [Boolean] alphabethize_output true : Alphatehise the rules in output string
12
+ # @param [Boolean] colors_to_vars true : sets all color to sass variables to the top of output string
13
+ # @param [Boolean] fromat_image_declarations true : formats images declarations to asset-url (for now at least - TODO: will be unified for any format)
14
+ # @param [Boolean] download_images true : downloads images to specified @output_path
15
+ # @param [String] output_path Output path must be specified if download_images is set to true
16
+ #
17
+ def initialize( param = {})
18
+ @alphabethize_output = (param[:alphabethize_output] != false) != false
19
+ @colors_to_vars = (param[:colors_to_vars] != false) != false
20
+ @fromat_image_declarations = (param[:fromat_image_declarations] != false) != false
21
+ @download_images = (param[:download_images] != false) != false
22
+ @output_path = param[:output_path] ? param[:output_path] : "#{ENV['HOME']}/Desktop/footer_output/"
23
+ end
24
+
25
+ ##
26
+ #
27
+ # Returns a hash containing sass_object and sass_formated string
28
+ # REQUIRES A PROPERLY FROMATED INPUT CSS
29
+ #
30
+ # @param [String] css A PROPERLY FROMATED INPUT CSS STRING | for now it's NOT working with media_query's inside of media_querys
31
+ #
32
+ def get_sass_str_and_sass_obj(input_css_str)
33
+ selectors_hash = css_to_hash input_css_str # 1. convert plain css to hash obj
34
+ css_stack = objectize_css(selectors_hash) # 2. convert recieved hash to sass obj with relatons
35
+ sassed_css_string = sass_obj_to_str(css_stack) # 3. get formatted string out sass_obj
36
+
37
+ Hash[:sass_obj => css_stack, :sass_string => sassed_css_string]
38
+ end
39
+
40
+ private
41
+
42
+ class CssNode
43
+ attr_accessor :rule, :children, :parent, :uninitialized
44
+
45
+ def initialize( param = {})
46
+ @rule = param[:rule] ? param[:rule] : ''
47
+ @children = param[:children] ? param[:children] : {}
48
+ @parent = param[:parent] ? param[:parent] : nil
49
+ @parent = nil unless param[:parent]
50
+ @uninitialized = param[:uninitialized] ? param[:uninitialized] : {}
51
+ end
52
+ end
53
+
54
+ def remove_white_spaces_and_new_lines(line)
55
+ line.gsub(/\n/,'').gsub(/\t/,'').gsub(/\s+(?=\})/,'').gsub(/(?<=\{)\s+/,'')
56
+ end
57
+
58
+ def css_to_hash (input_css)
59
+ input_css = input_css.gsub(/::/,':')
60
+ selectors_arr = remove_white_spaces_and_new_lines(input_css).gsub(/@media/,"\n@media").gsub(/(?<={{1}).+}(?=[\s\t\n]{0,}}{1})/,'').gsub(/(?<={{1}).+}(?=[\s\t\n]{0,}}{1})/,'').scan(/[^{^}]+(?=\{)/).map {|line| line.sub(/^\s+/,'').sub(/\s+$/,'')}
61
+ rules_arr = remove_white_spaces_and_new_lines(input_css).gsub(/@media/,"\n@media").scan(/(((?<={{1}).+}(?=[\s\t\n]{0,}}{1})|(?<=\{)[^}]+\}{0,}[\\t\\n\s]{0,}(?=\}))|((?<=\{)[^}]+\}{0,}[\\t\\n\s]{0,}(?=\}))|(?<={{1}).+}(?=[\s\t\n]{0,}}{1}))/).map {|item| item.compact.uniq.join} #super-mega reg-exp that scans for normal rules as well as inlined media-query rule + make a single_string_items out of matched array groups
62
+ return_hash = {}
63
+
64
+ selectors_arr.each_with_index do |selector, index|
65
+ unless return_hash[selector]
66
+ return_hash[selector] = rules_arr[index.to_i]
67
+ else
68
+ return_hash[selector] = return_hash[selector] + ' ' + rules_arr[index.to_i]
69
+ end
70
+ end
71
+
72
+ return_hash.each do |key,val|
73
+ unless val.scan(/[^{^}]+(?=\{)/).size.zero?
74
+ return_hash[key] = css_to_hash val
75
+ end
76
+ end
77
+
78
+ return_hash
79
+ end
80
+
81
+ def objectize_css (uninitialized_childrens_hash, parent_node = nil)
82
+
83
+ childrens_stack = {}
84
+
85
+ uninitialized_childrens_hash.each { |selector,rule|
86
+
87
+ #TODO: optimize pattern mathcing = thei are both matching same string
88
+ match = /^[&.#\"\'\[\]=a-zA-Z-_0-9]{1,}(?=\s(?=[^,]{0,}$))/.match(selector).to_s #checks for childrens in selector
89
+
90
+ sub_pat = /^[\.#]{0,1}[a-zA-Z-_0-9]{1,}(?=(\.|:|\[|#))/.match(selector).to_s #deals with pseudo elements
91
+ #TODO : optimize this
92
+ unless sub_pat.empty?
93
+ unless selector.match(/,/)
94
+
95
+ match = sub_pat
96
+ selector = selector.sub( Regexp.new('^'+match) ,match+' &')
97
+ end
98
+ end
99
+
100
+ unless match.empty?
101
+ unless node = childrens_stack[match]
102
+ node = CssNode.new
103
+ childrens_stack[match] = node
104
+ end
105
+ node.uninitialized[selector.sub( Regexp.new('^'+match+' ') ,'')] = rule
106
+ node.parent = parent_node
107
+ else
108
+ if node = childrens_stack[selector]
109
+ node.rule = node.rule + "\n\t" + rule.gsub(/;\s/,";\n\t")
110
+ else
111
+ node = CssNode.new
112
+ if rule.is_a?(Hash)
113
+ node.children = objectize_css( rule, node )
114
+ else
115
+ node.rule = "\n\t"+rule.gsub(/;\s/,";\n\t")
116
+ end
117
+ childrens_stack[selector] = node
118
+ end
119
+ node.rule = node.rule.split(';').sort().join(';') + ';' if @alphabethize_output && !node.rule.empty? #alphabetize
120
+ node.parent = parent_node
121
+ end
122
+ }
123
+
124
+ childrens_stack.each { |node_selector,node|
125
+ unless childrens_stack[node_selector].uninitialized.empty?
126
+ childrens_stack[node_selector].children = objectize_css( childrens_stack[node_selector].uninitialized, node )
127
+ childrens_stack[node_selector].uninitialized = []
128
+ end
129
+ }
130
+
131
+ childrens_stack
132
+ end
133
+
134
+ def sass_obj_to_str (css_stack)
135
+ sassed_str = format_sass sass_stack_to_s(css_stack)
136
+
137
+ sassed_str
138
+ end
139
+
140
+ def sass_stack_to_s (css_stack)
141
+ str = ''
142
+ css_stack.each { |node_key,node|
143
+ unless node.children.empty?
144
+ chldrn = node.children
145
+ children_stack = sass_stack_to_s(chldrn)
146
+ end
147
+ str = str +"\n"+ node_key + " {\t" + ( node.rule ? node.rule : '') + ( children_stack ? children_stack.gsub(/^/,"\t") : '' ) +"\n\t}"
148
+ }
149
+
150
+ str
151
+ end
152
+
153
+ def format_sass (sassed_str)
154
+ formated_sass_with_images = format_images sassed_str if @fromat_image_declarations
155
+ formated_sass_with_color = format_color formated_sass_with_images if @colors_to_vars
156
+
157
+ formated_sass_with_color
158
+ end
159
+
160
+ def format_images (sassed_str)
161
+
162
+ require 'net/http'
163
+
164
+ formated_rule = sassed_str
165
+ sassed_str.scan(/(url\((((http[s]{0,1}:\/\/)([a-z0-9].+\.[a-z]+).+)(\/.+)))\)/).each do |match|
166
+
167
+ formated_rule = formated_rule.sub(Regexp.new(match[0].gsub(/\(/,'\(').gsub(match[5],'')),'asset-url(\'#{$brand}')
168
+ .sub( Regexp.new(match[5]),match[5]+'\',image')
169
+
170
+ Net::HTTP.start(match[4]) do |http|
171
+ resp = http.get(match[1])
172
+
173
+ #TODO: optimise this - connect to global path
174
+ path = @output_path
175
+ Dir.mkdir(path) unless Dir.exist?(path)
176
+ open(path+match[5], 'wb') do |file|
177
+ begin
178
+ file.write(resp.body)
179
+ ensure
180
+ file.close()
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ formated_rule
187
+ end
188
+
189
+ def format_color(sassed_str)
190
+ #TODO: resolve the match for colors in format #sdsd
191
+ formated_rule = sassed_str
192
+ color_hash = {}
193
+ sassed_str.scan(/rgba\([0-9\,\s\.]+\)|rgb\([0-9\,\s\.]+\)/).each do|m|
194
+
195
+ unless color_hash[m]
196
+ color_hash[m] = '$brand_color_'+color_hash.size.to_s
197
+ formated_rule = formated_rule.gsub( Regexp.new(m.gsub(/\(/,'\(').gsub(/\)/,'\)').gsub(/\./,'\.')), color_hash[m] )
198
+ end
199
+ end
200
+
201
+ color_hash.invert.to_a.reverse_each {|m|
202
+ formated_rule = m.join(":")+"\n" + formated_rule
203
+ }
204
+
205
+ formated_rule
206
+ end
207
+
208
+ def format_mixin
209
+ #TODO: combine similar rules blocks in mixins.. in some way..?
210
+ end
211
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sassificator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Roman Fromrome
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Converts Css formatted code to Sass. Generates a Sass formatted hierarchy
14
+ object, as well as properly formatted Sass code text
15
+ email: romanfromrome.com@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/sassificator.rb
21
+ homepage: https://github.com/rimaone/sassificator
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.2.1
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: A tool for parsing Css to Sass
45
+ test_files: []