lib/premailer/adapter/nokogiri.rb
# Merge CSS into the HTML document.
#
# @return [String] an HTML.
Merge CSS into the HTML document.
Merge CSS into the HTML document .
def to_inline_css
        doc = @processed_doc
        @unmergable_rules = CssParser::Parser.new
        doc.search("*[@style]").each do |el|
          el['style'] = '[SPEC=1000[' + el.attributes['style'] + ']]'
        end
        @css_parser.each_selector(:all) do |selector, declaration, specificity|
          selector.gsub!(/:link([\s]*)+/i) {|m| $1 }
          selector.gsub!(/([\s]|^)([\w]+)/) {|m| $1.to_s + $2.to_s.downcase }
          if selector =~ Premailer::RE_UNMERGABLE_SELECTORS
            @unmergable_rules.add_rule_set!(CssParser::RuleSet.new(selector, declaration)) unless @options[:preserve_styles]
          else
            begin
              selector.gsub!(/\A\#([\w_\-]+)\Z/, '*[@id=\1]')
              doc.search(selector).each do |el|
                if el.elem? and (el.name != 'head' and el.parent.name != 'head')
                  block = "[SPEC=#{specificity}[#{declaration}]]"
                  el['style'] = (el.attributes['style'].to_s ||= '') + ' ' + block
                end
              end
            rescue  ::Nokogiri::SyntaxError, RuntimeError, ArgumentError
              $stderr.puts "CSS syntax error with selector: #{selector}" if @options[:verbose]
              next
            end
          end
        end
        if @options[:remove_scripts]
          doc.search("script").remove
        end
        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
          merged = CssParser.merge(declarations)
          merged.expand_shorthand!
          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(/;$/, '').strip if el[html_att].nil? and not merged[css_att].empty?
            end
          end
          el['style'] = Premailer.escape_string(merged.declarations_to_s).split(';').map(&:strip).sort.join('; ')
        end
        doc = write_unmergable_css_rules(doc, @unmergable_rules)
        if @options[:remove_classes] or @options[:remove_comments]
          doc.traverse do |el|
            if el.comment? and @options[:remove_comments]
              el.remove
            elsif el.element?
              el.remove_attribute('class') if @options[:remove_classes]
            end
          end
        end
        if @options[:remove_ids]
          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
          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
        if is_xhtml?
          @processed_doc.to_xhtml(:encoding => nil).gsub(/&\#xD;/i, "\r")
        else
          @processed_doc.to_html
        end
      end
def to_inline_css doc = @processed_doc @unmergable_rules = CssParser :: Parser . new doc . search ( "*[@style]" ) . each do | el | el [ 'style' ] = '[SPEC=1000[' + el . attributes [ 'style' ] + ']]' end @css_parser . each_selector ( :all ) do | selector , declaration , specificity | selector . gsub! ( / :link([ \s ]*)+ /i ) { | m | $1 } selector . gsub! ( / ([ \s ]|^)([ \w ]+) / ) { | m | $1 . to_s + $2 . to_s . downcase } if selector =~ Premailer :: RE_UNMERGABLE_SELECTORS @unmergable_rules . add_rule_set! ( CssParser :: RuleSet . new ( selector , declaration ) ) unless @options [ :preserve_styles ] else begin selector . gsub! ( / \A \# ([ \w _ \- ]+) \Z / , '*[@id=\1]' ) doc . search ( selector ) . each do | el | if el . elem? and ( el . name != 'head' and el . parent . name != 'head' ) block = "[SPEC=#{specificity}[#{declaration}]]" el [ 'style' ] = ( el . attributes [ 'style' ] . to_s ||= '' ) + ' ' + block end end rescue :: Nokogiri :: SyntaxError , RuntimeError , ArgumentError $stderr . puts "CSS syntax error with selector: #{selector}" if @options [ :verbose ] next end end end if @options [ :remove_scripts ] doc . search ( "script" ) . remove end 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 merged = CssParser . merge ( declarations ) merged . expand_shorthand! 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 ( / ;$ / , '' ) . strip if el [ html_att ] . nil? and not merged [ css_att ] . empty? end end el [ 'style' ] = Premailer . escape_string ( merged . declarations_to_s ) . split ( ';' ) . map ( & :strip ) . sort . join ( '; ' ) end doc = write_unmergable_css_rules ( doc , @unmergable_rules ) if @options [ :remove_classes ] or @options [ :remove_comments ] doc . traverse do | el | if el . comment? and @options [ :remove_comments ] el . remove elsif el . element? el . remove_attribute ( 'class' ) if @options [ :remove_classes ] end end end if @options [ :remove_ids ] 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 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 if is_xhtml? @processed_doc . to_xhtml ( :encoding => nil ) . gsub ( / & \# xD; /i , "\r" ) else @processed_doc . to_html end end
Merge CSS into the HTML document.
Merge CSS into the HTML document .
# Give all styles already in style attributes a specificity of 1000 # per http://www.w3.org/TR/CSS21/cascade.html#specificity # Iterate through the rules and merge them into the HTML # Save un-mergable rules separately # Convert element names to lower case # Change single ID CSS selectors into xpath so that we can match more # than one element.  Added to work around dodgy generated code. # Add a style attribute or append to the existing one # Remove script tags # Read STYLE attributes and perform folding # Perform style folding # Duplicate CSS attributes as HTML attributes # write the inline STYLE attribute # find all anchor's targets and hash them # hash ids that are links target, delete others # we don't want to encode carriage returns
None
String