Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
#!/usr/bin/ruby # Code to take a CSS file and an HTML file and render the styles inline. # This is bad practice on the web, but can be very helpful when producing # HTML email where external stylesheets can be problematic. Using this you # can develop using external stylesheets and then easily move the styles # inline. # # If the file is run from the command line it will take paths to a # stylesheet and an HTML file and output the combined code # # Author:: James Stewart (mailto: james@jystewart.net) # Copyright:: Copyright (c) 2007 James Stewart # License:: Distributes under the same terms as Ruby # This class takes a CSS file and provides a method to # parse it into a hash. Usage is: # # parser = SimpleCSSParser.new('/path/to/myfile.css') # hash_of_rules = parser.to_hash # # For more advanced CSS handling check out the cssparser gem # http://code.dunae.ca/css_parser/ class SimpleCSSParser # Receive and open the CSS file, storing its contents def initialize(path_to_file) @css = open(path_to_file).read end # Convert the CSS into a hash, where the keys are the selectors # and the values are the rules def to_hash @to_hash ||= separate_rules.inject({}) do |collection, rule| identifiers, rule = prepare_selectors_and_rule(rule) identifiers.each do |identifier| collection[identifier] ||= '' collection[identifier] += rule end collection end end private def separate_rules @css.split('}') end # Strip comments and extraneous white space from our CSS rules def clean_up_rule(css_rule) css_rule = css_rule.gsub(/\/\*.+?\*\//, '') css_rule.gsub(/\n|\s{2,}/, '') end # Break apart our selector(s) and rule. We return an array # of selectors to allow for situations where multiple selectors # are specified (comma separated) for a single rule def prepare_selectors_and_rule(rule) parts = rule.split('{') selectors = parts[0].split(',').map(&:strip) return selectors, clean_up_rule(parts[1]) end end if __FILE__ == $0 if ARGV.length == 2 require 'rubygems' require 'hpricot' doc = Hpricot(open(ARGV[1])) parser = SimpleCSSParser.new(ARGV[0]) parser.to_hash.each do |selector, rule| (doc/selector).set('style', rule) end puts doc else puts "Usage ./css-inliner.rb /path/to/stylesheet.css /path/to/webpage.html" end end
This paste will be private.
From the Design Piracy series on my blog: