lib/css_parser/parser.rb in css_parser-1.4.7 vs lib/css_parser/parser.rb in css_parser-1.4.8

- old
+ new

@@ -185,10 +185,31 @@ yield(block[:rules], block[:media_types]) end end end + # Output all CSS rules as a Hash + def to_h(media_types = :all) + out = {} + styles_by_media_types = {} + each_selector(media_types) do |selectors, declarations, specificity, media_types| + media_types.each do |media_type| + styles_by_media_types[media_type] ||= [] + styles_by_media_types[media_type] << [selectors, declarations] + end + end + + styles_by_media_types.each_pair do |media_type, media_styles| + ms = {} + media_styles.each do |media_style| + ms = css_node_to_h(ms, media_style[0], media_style[1]) + end + out[media_type.to_s] = ms + end + out + end + # Iterate through CSS selectors. # # +media_types+ can be a symbol or an array of symbols. # See RuleSet#each_selector for +options+. def each_selector(all_media_types = :all, options = {}) # :yields: selectors, declarations, specificity, media_types @@ -422,20 +443,21 @@ # Strip comments and clean up blank lines from a block of CSS. # # Returns a string. def cleanup_block(block) # :nodoc: # Strip CSS comments - block.gsub!(STRIP_CSS_COMMENTS_RX, '') + utf8_block = block.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '') + utf8_block.gsub!(STRIP_CSS_COMMENTS_RX, '') # Strip HTML comments - they shouldn't really be in here but # some people are just crazy... - block.gsub!(STRIP_HTML_COMMENTS_RX, '') + utf8_block.gsub!(STRIP_HTML_COMMENTS_RX, '') # Strip lines containing just whitespace - block.gsub!(/^\s+$/, "") + utf8_block.gsub!(/^\s+$/, "") - block + utf8_block end # Download a file into a string. # # Returns the file's data and character set in an array. @@ -536,8 +558,26 @@ def reset! # :nodoc: @folded_declaration_cache = {} @css_source = '' @css_rules = [] @css_warnings = [] + end + + # recurse through nested nodes and return them as Hashes nested in + # passed hash + def css_node_to_h(hash, key, val) + hash[key.strip] = '' and return hash if val.nil? + lines = val.split(';') + nodes = {} + lines.each do |line| + parts = line.split(':', 2) + if (parts[1] =~ /:/) + nodes[parts[0]] = css_node_to_h(hash, parts[0], parts[1]) + else + nodes[parts[0].to_s.strip] =parts[1].to_s.strip + end + end + hash[key.strip] = nodes + hash end end end