module Premailer::Adapter::Hpricot
Hpricot adapter
Public Instance Methods
to_inline_css()
click to toggle source
Merge CSS into the HTML document. @return [String] HTML.
# File lib/premailer/adapter/hpricot.rb, line 10 def to_inline_css doc = @processed_doc @unmergable_rules = CssParser::Parser.new # Give all styles already in style attributes a specificity of 1000 # per http://www.w3.org/TR/CSS21/cascade.html#specificity doc.search("*[@style]").each do |el| el['style'] = '[SPEC=1000[' + el.attributes['style'] + ']]' end # Iterate through the rules and merge them into the HTML @css_parser.each_selector(:all) do |selector, declaration, specificity, media_types| # Save un-mergable rules separately selector.gsub!(/:link([\s]*)+/i) {|m| $1 } # Convert element names to lower case selector.gsub!(/([\s]|^)([\w]+)/) {|m| $1.to_s + $2.to_s.downcase } if Premailer.is_media_query?(media_types) || selector =~ Premailer::RE_UNMERGABLE_SELECTORS @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration), media_types) unless @options[:preserve_styles] else begin if selector =~ Premailer::RE_RESET_SELECTORS # this is in place to preserve the MailChimp CSS reset: http://github.com/mailchimp/Email-Blueprints/ # however, this doesn't mean for testing pur @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration)) unless !@options[:preserve_reset] end # Change single ID CSS selectors into xpath so that we can match more # than one element. Added to work around dodgy generated code. selector.gsub!(/\A\#([\w_\-]+)\Z/, '*[@id=\1]') # convert attribute selectors to hpricot's format selector.gsub!(/\[([\w]+)\]/, '[@\1]') selector.gsub!(/\[([\w]+)([\=\~\^\$\*]+)([\w\s]+)\]/, '[@\1\2\\3\]') doc.search(selector).each do |el| if el.elem? and (el.name != 'head' and el.parent.name != 'head') # Add a style attribute or append to the existing one block = "[SPEC=#{specificity}[#{declaration}]]" el['style'] = (el.attributes['style'].to_s ||= '') + ' ' + block end end rescue ::Hpricot::Error, RuntimeError, ArgumentError $stderr.puts "CSS syntax error with selector: #{selector}" if @options[:verbose] next end end end # Remove script tags if @options[:remove_scripts] doc.search("script").remove end # Read STYLE attributes and perform folding doc.search("*[@style]").each do |el| style = el.attributes['style'].to_s declarations = [] style.scan(/\[SPEC\=([\d]+)\[(.[^\]\]]*)\]\]/).each do |declaration| rs = CssParser::RuleSet.new(nil, declaration[1].to_s, declaration[0].to_i) declarations << rs end # Perform style folding merged = CssParser.merge(declarations) merged.expand_shorthand! merged.create_shorthand! # Duplicate CSS attributes as HTML attributes if Premailer::RELATED_ATTRIBUTES.has_key?(el.name) Premailer::RELATED_ATTRIBUTES[el.name].each do |css_att, html_att| el[html_att] = merged[css_att].gsub(/url\('(.*)'\)/,'\1').gsub(/;$|\s*!important/, '').strip if el[html_att].nil? and not merged[css_att].empty? end end # write the inline STYLE attribute el['style'] = Premailer.escape_string(merged.declarations_to_s) end doc = write_unmergable_css_rules(doc, @unmergable_rules) if @options[:remove_classes] or @options[:remove_comments] doc.search('*').each do |el| if el.comment? and @options[:remove_comments] lst = el.parent.children el.parent = nil lst.delete(el) elsif el.elem? el.remove_attribute('class') if @options[:remove_classes] end end end if @options[:reset_contenteditable] doc.search('*[@contenteditable]').each do |el| el.remove_attribute('contenteditable') end end if @options[:remove_ids] # find all anchor's targets and hash them targets = [] doc.search("a[@href^='#']").each do |el| target = el.get_attribute('href')[1..-1] targets << target el.set_attribute('href', "#" + Digest::MD5.hexdigest(target)) end # hash ids that are links target, delete others doc.search("*[@id]").each do |el| id = el.get_attribute('id') if targets.include?(id) el.set_attribute('id', Digest::MD5.hexdigest(id)) else el.remove_attribute('id') end end end @processed_doc = doc @processed_doc.to_original_html end
to_plain_text()
click to toggle source
Converts the HTML document to a format suitable for plain-text e-mail.
If present, uses the <body> element as its base; otherwise uses the whole document.
@return [String] Plain text.
# File lib/premailer/adapter/hpricot.rb, line 163 def to_plain_text html_src = '' begin html_src = @doc.search("body").inner_html rescue; end html_src = @doc.to_html unless html_src and not html_src.empty? convert_to_text(html_src, @options[:line_length], @html_encoding) end
to_s()
click to toggle source
Gets the original HTML as a string. @return [String] HTML.
# File lib/premailer/adapter/hpricot.rb, line 176 def to_s @doc.to_original_html end