class Premailer

Constants

CLIENT_SUPPORT_FILE
HTML_ENTITIES

list of HTMLEntities to fix source: stackoverflow.com/questions/2812781/how-to-convert-webpage-apostrophe-8217-to-ascii-39-in-ruby-1-

list of CSS attributes that can be rendered as HTML attributes

@todo too much repetition @todo background=“”

RE_RESET_SELECTORS

Reset selectors regexp.

RE_UNMERGABLE_SELECTORS

Unmergable selectors regexp.

VERSION

Premailer version.

WARN_LABEL

Waning level names

Attributes

base_dir[R]

base directory used to resolve links for local files @return [String] base directory

base_url[R]

base URL used to resolve links

doc[R]

source HTML document (Nokogiri/Nokogumbo)

html_file[R]

URI of the HTML file used

processed_doc[R]

processed HTML document (Nokogiri/Nokogumbo)

unmergable_rules[R]

unmergeable CSS rules to be preserved in the head (CssParser)

Public Class Methods

is_media_query?(media_types) click to toggle source

@private

# File lib/premailer/premailer.rb, line 467
def self.is_media_query?(media_types)
  media_types && media_types.any?{|mt| mt.to_s.count('()') >= 2 }
end
local_data?(data) click to toggle source

Test the passed variable to see if we are in local or remote mode.

IO objects return true, as do strings that look like URLs.

# File lib/premailer/premailer.rb, line 493
def self.local_data?(data)
  return false  if data.kind_of?(String) && data =~ /\A(?:(https?|ftp):)\/\//i
  true
end
new(html, options = {}) click to toggle source

Create a new Premailer object.

@param html is the HTML data to process. It can be either an IO object, the URL of a

remote file, a local path or a raw HTML string.  If passing an HTML string you
must set the with_html_string option to true.

@param [Hash] options the options to handle html with. @option options [Fixnum] :line_length Line length used by to_plain_text. Default is 65. @option options [Fixnum] :warn_level What level of CSS compatibility warnings to show (see {Premailer::Warnings}, default is Warnings::SAFE). @option options [String] :link_query_string A string to append to every a href="" link. Do not include the initial ?. @option options [String] :base_url Used to calculate absolute URLs for local files. @option options [Array(String)] :css Manually specify CSS stylesheets. @option options [Boolean] :css_to_attributes Copy related CSS attributes into HTML attributes (e.g. background-color to bgcolor). Default is true. @option options [Boolean] :preserve_style_attribute Preserve original style attribute @option options [String] :css_string Pass CSS as a string @option options [Boolean] :rgb_to_hex_attributes Convert RBG to Hex colors. Default is false. @option options [Boolean] :remove_ids Remove ID attributes whenever possible and convert IDs used as anchors to hashed to avoid collisions in webmail programs. Default is false. @option options [Boolean] :remove_classes Remove class attributes. Default is false. @option options [Boolean] :remove_comments Remove html comments. Default is false. @option options [Boolean] :remove_scripts Remove script elements. Default is true. @option options [Boolean] :reset_contenteditable Remove contenteditable attributes. Default is true. @option options [Boolean] :preserve_styles Whether to preserve any link rel=stylesheet and style elements. Default is false. @option options [Boolean] :preserve_reset Whether to preserve styles associated with the MailChimp reset code. Default is true. @option options [Boolean] :with_html_string Whether the html param should be treated as a raw string. Default is false. @option options [Boolean] :verbose Whether to print errors and warnings to $stderr. Default is false. @option options [Boolean] :io_exceptions Throws exceptions on I/O errors. @option options [Boolean] :include_link_tags Whether to include css from link rel=stylesheet tags. Default is true. @option options [Boolean] :include_style_tags Whether to include css from style tags. Default is true. @option options [String] :input_encoding Manually specify the source documents encoding. This is a good idea. Default is ASCII-8BIT. @option options [Boolean] :replace_html_entities Convert HTML entities to actual characters. Default is false. @option options [Boolean] :escape_url_attributes URL Escapes href, src, and background attributes on elements. Default is true. @option options [Symbol] :adapter Which HTML parser to use, :nokogiri, :nokogiri_fast or :nokogumbo. Default is :nokogiri. @option options [String] :output_encoding Output encoding option for Nokogiri adapter. Should be set to “US-ASCII” to output HTML entities instead of Unicode characters. @option options [Boolean] :create_shorthands Combine several properties into a shorthand one, e.g. font: style weight size. Default is true. @option options [Boolean] :html_fragment Handle HTML fragment without any HTML content wrappers. Default is false. @option options [Boolean] :drop_unmergeable_css_rules Do not include unmergeable css rules in a <tt><style><tt> tag. Default is false.

# File lib/premailer/premailer.rb, line 182
def initialize(html, options = {})
  @options = {:warn_level => Warnings::SAFE,
              :line_length => 65,
              :link_query_string => nil,
              :base_url => nil,
              :rgb_to_hex_attributes => true,
              :remove_classes => false,
              :remove_ids => false,
              :remove_comments => false,
              :remove_scripts => true,
              :reset_contenteditable => true,
              :css => [],
              :css_to_attributes => true,
              :preserve_style_attribute => false,
              :with_html_string => false,
              :css_string => nil,
              :preserve_styles => false,
              :preserve_reset => true,
              :verbose => false,
              :debug => false,
              :io_exceptions => false,
              :include_link_tags => true,
              :include_style_tags => true,
              :input_encoding => 'ASCII-8BIT',
              :output_encoding => nil,
              :replace_html_entities => false,
              :escape_url_attributes => true,
              :unescaped_ampersand => false,
              :create_shorthands => true,
              :html_fragment => false,
              :adapter => Adapter.use,
              :drop_unmergeable_css_rules => false
              }.merge(options)

  @html_file = html
  @is_local_file = @options[:with_html_string] || Premailer.local_data?(html)

  @css_files = [@options[:css]].flatten

  @css_warnings = []

  @base_url = nil
  @base_dir = nil
  @unmergable_rules = nil

  if @options[:base_url]
    @base_url = Addressable::URI.parse(@options.delete(:base_url))
  elsif not @is_local_file
    @base_url = Addressable::URI.parse(@html_file)
  end

  @css_parser = CssParser::Parser.new({
    :absolute_paths => true,
    :import => true,
    :io_exceptions => @options[:io_exceptions]
  })

  @adapter_class = Adapter.find @options[:adapter]

  self.extend(@adapter_class)

  @doc = load_html(@html_file)

  @processed_doc = @doc
  @processed_doc = convert_inline_links(@processed_doc, @base_url) if @base_url
  if options[:link_query_string]
    @processed_doc = append_query_string(@processed_doc, options[:link_query_string])
  end
  load_css_from_options!
  load_css_from_html!
end

Public Instance Methods

append_query_string(doc, qs) click to toggle source
# File lib/premailer/premailer.rb, line 355
def append_query_string(doc, qs)
  return doc if qs.nil?

  qs.to_s.gsub!(/^[\?]*/, '').strip!
  return doc if qs.empty?

  begin
    current_host = @base_url.host
  rescue
    current_host = nil
  end

  $stderr.puts "Attempting to append_query_string: #{qs}" if @options[:verbose]

  doc.search('a').each do|el|
    href = el.attributes['href'].to_s.strip
    next if href.nil? or href.empty?

    next if href[0,1] =~ /[\#\{\[\<\%]/ # don't bother with anchors or special-looking links

    begin
      href = Addressable::URI.parse(href)

      if current_host and href.host != nil and href.host != current_host
        $stderr.puts "Skipping append_query_string for: #{href.to_s} because host is no good" if @options[:verbose]
        next
      end

      if href.scheme and href.scheme != 'http' and href.scheme != 'https'
        puts "Skipping append_query_string for: #{href.to_s} because scheme is no good" if @options[:verbose]
        next
      end

      if href.query and not href.query.empty?
        amp = @options[:unescaped_ampersand] ? '&' : '&amp;'
        href.query = href.query + amp + qs
      else
        href.query = qs
      end

      el['href'] = href.to_s
    rescue Addressable::URI::InvalidURIError => e
      $stderr.puts "Skipping append_query_string for: #{href.to_s} (#{e.message})" if @options[:verbose]
      next
    end

  end
  doc
end
is_xhtml?() click to toggle source

Check for an XHTML doctype

# File lib/premailer/premailer.rb, line 406
def is_xhtml?
  intro = @doc.to_xhtml.strip.split("\n")[0..2].join(' ')
  is_xhtml = !!(intro =~ /w3c\/\/[\s]*dtd[\s]+xhtml/i)
  $stderr.puts "Is XHTML? #{is_xhtml.inspect}\nChecked:\n#{intro}" if @options[:debug]
  is_xhtml
end
media_type_ok?(media_types) click to toggle source

@private

# File lib/premailer/premailer.rb, line 349
def media_type_ok?(media_types)
  media_types = media_types.to_s
  return true if media_types.nil? or media_types.empty?
  media_types.split(/[\s]+|,/).any? { |media_type| media_type.strip =~ /screen|handheld|all/i }
end
warnings() click to toggle source

CSS warnings. @return [Array(Hash)] Array of warnings.

# File lib/premailer/premailer.rb, line 256
def warnings
  return [] if @options[:warn_level] == Warnings::NONE
  @css_warnings = check_client_support if @css_warnings.empty?
  @css_warnings
end

Protected Instance Methods

load_css_from_local_file!(path) click to toggle source
# File lib/premailer/premailer.rb, line 263
def load_css_from_local_file!(path)
  css_block = ''
  path.gsub!(/\Afile:/, '')
  begin
    File.open(path, "r") do |file|
      while line = file.gets
        css_block << line
      end
    end

    load_css_from_string(css_block)
  rescue => e
    raise e if @options[:io_exceptions]
  end
end
load_css_from_string(css_string) click to toggle source
# File lib/premailer/premailer.rb, line 279
def load_css_from_string(css_string)
  @css_parser.add_block!(css_string, {:base_uri => @base_url, :base_dir => @base_dir, :only_media_types => [:screen, :handheld]})
end