Class: CssParser::Parser

### Home Classes Methods

### In Files

- lib/css_parser/parser.rb

### Parent

Object

### Methods

- ::new
- #[]
- #add_block!
- #add_rule!
- #add_rule_set!
- #circular_reference_check
- #each_rule_set
- #each_selector
- #find_by_selector
- #find_rule_sets
- #load_file!
- #load_string!
- #load_uri!
- #rules_by_media_query
- #to_s

### Class/Module Index

Quicksearch

- CssParser
- CssParser::CircularReferenceError
- CssParser::Parser
- CssParser::RemoteFileError
- CssParser::RuleSet

No matching classes.

# CssParser::Parser

## Parser class

All CSS is converted to UTF-8.

When calling Parser#new there are some configuaration options:

`absolute_paths`

  Convert relative paths to absolute paths (`href`, `src` and `url('')`. Boolean, default is `false`.

`import`

  Follow `@import` rules. Boolean, default is `true`.

`io_exceptions`

  Throw an exception if a link can not be found. Boolean, default is `true`.

### Constants

RE_AT_IMPORT_RULE

  Initial parsing

STRIP_CSS_COMMENTS_RX
STRIP_HTML_COMMENTS_RX
USER_AGENT

### Attributes

folded_declaration_cache[R]
loaded_uris[R]

Array of CSS files that have been loaded.

### Public Class Methods

new(options = {}) click to toggle source

    # File lib/css_parser/parser.rb, line 34
    def initialize(options = {})
      @options = {:absolute_paths => false,
                  :import => true,
                  :io_exceptions => true}.merge(options)

      # array of RuleSets
      @rules = []

      @loaded_uris = []

      # unprocessed blocks of CSS
      @blocks = []
      reset!
    end

### Public Instance Methods

[](selector, media_types = :all) click to toggle source
Alias for: find_by_selector
add_block!(block, options = {}) click to toggle source

Add a raw block of CSS.

In order to follow +@import+ rules you must supply either a `:base_dir` or `:base_uri` option.

Use the `:media_types` option to set the media type(s) for this block. Takes an array of symbols.

Use the `:only_media_types` option to selectively follow +@import+ rules. Takes an array of symbols.

#### Example

    css = <<-EOT
      body { font-size: 10pt }
      p { margin: 0px; }
      @media screen, print {
        body { line-height: 1.2 }
      }
    EOT

    parser = CssParser::Parser.new
    parser.add_block!(css)

    # File lib/css_parser/parser.rb, line 110
    def add_block!(block, options = {})
      options = {:base_uri => nil, :base_dir => nil, :charset => nil, :media_types => :all, :only_media_types => :all}.merge(options)
      options[:media_types] = [options[:media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
      options[:only_media_types] = [options[:only_media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}

      block = cleanup_block(block)

      if options[:base_uri] and @options[:absolute_paths]
        block = CssParser.convert_uris(block, options[:base_uri])
      end

      # Load @imported CSS
      if @options[:import]
        block.scan(RE_AT_IMPORT_RULE).each do |import_rule|
          media_types = []
          if media_string = import_rule[-1]
            media_string.split(/[,]/).each do |t|
              media_types << CssParser.sanitize_media_query(t) unless t.empty?
            end
          else
            media_types = [:all]
          end

          next unless options[:only_media_types].include?(:all) or media_types.length < 1 or (media_types & options[:only_media_types]).length > 0

          import_path = import_rule[0].to_s.gsub(/['"]*/, '').strip

          if options[:base_uri]
            import_uri = Addressable::URI.parse(options[:base_uri].to_s) + Addressable::URI.parse(import_path)
            load_uri!(import_uri, options[:base_uri], media_types)
          elsif options[:base_dir]
            load_file!(import_path, options[:base_dir], media_types)
          end
        end
      end

      # Remove @import declarations
      block.gsub!(RE_AT_IMPORT_RULE, '')

      parse_block_into_rule_sets!(block, options)
    end

add_rule!(selectors, declarations, media_types = :all) click to toggle source

Add a CSS rule by setting the `selectors`, `declarations` and `media_types`.

`media_types` can be a symbol or an array of symbols.

    # File lib/css_parser/parser.rb, line 155
    def add_rule!(selectors, declarations, media_types = :all)
      rule_set = RuleSet.new(selectors, declarations)
      add_rule_set!(rule_set, media_types)
    end

add_rule_set!(ruleset, media_types = :all) click to toggle source

Add a CssParser RuleSet object.

`media_types` can be a symbol or an array of symbols.

    # File lib/css_parser/parser.rb, line 163
    def add_rule_set!(ruleset, media_types = :all)
      raise ArgumentError unless ruleset.kind_of?(CssParser::RuleSet)

      media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}

      @rules << {:media_types => media_types, :rules => ruleset}
    end

each_rule_set(media_types = :all) click to toggle source

Iterate through RuleSet objects.

`media_types` can be a symbol or an array of symbols.

    # File lib/css_parser/parser.rb, line 174
    def each_rule_set(media_types = :all) # :yields: rule_set, media_types
      media_types = [:all] if media_types.nil?
      media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}

      @rules.each do |block|
        if media_types.include?(:all) or block[:media_types].any? { |mt| media_types.include?(mt) }
          yield(block[:rules], block[:media_types])
        end
      end
    end

each_selector(media_types = :all, options = {}) click to toggle source

Iterate through CSS selectors.

`media_types` can be a symbol or an array of symbols. See RuleSet#each_selector for `options`.

    # File lib/css_parser/parser.rb, line 189
    def each_selector(media_types = :all, options = {}) # :yields: selectors, declarations, specificity, media_types
      each_rule_set(media_types) do |rule_set, media_types|
        rule_set.each_selector(options) do |selectors, declarations, specificity|
          yield selectors, declarations, specificity, media_types
        end
      end
    end

find_by_selector(selector, media_types = :all) click to toggle source

Get declarations by selector.

`media_types` are optional, and can be a symbol or an array of symbols. The default value is `:all`.

#### Examples

    find_by_selector('#content')
    => 'font-size: 13px; line-height: 1.2;'

    find_by_selector('#content', [:screen, :handheld])
    => 'font-size: 13px; line-height: 1.2;'

    find_by_selector('#content', :print)
    => 'font-size: 11pt; line-height: 1.2;'

Returns an array of declarations.

    # File lib/css_parser/parser.rb, line 66
    def find_by_selector(selector, media_types = :all)
      out = []
      each_selector(media_types) do |sel, dec, spec|
        out << dec if sel.strip == selector.strip
      end
      out
    end

Also aliased as: []
find_rule_sets(selectors, media_types = :all) click to toggle source

Finds the rule sets that match the given selectors

    # File lib/css_parser/parser.rb, line 76
    def find_rule_sets(selectors, media_types = :all)
      rule_sets = []

      selectors.each do |selector|
        each_rule_set(media_types) do |rule_set, media_type|
          if !rule_sets.member?(rule_set) && rule_set.selectors.member?(selector)
            rule_sets << rule_set
          end
        end
      end

      rule_sets
    end

load_file!(file_name, base_dir = nil, media_types = :all) click to toggle source

Load a local CSS file.

    # File lib/css_parser/parser.rb, line 383
    def load_file!(file_name, base_dir = nil, media_types = :all)
      file_name = File.expand_path(file_name, base_dir)
      return unless File.readable?(file_name)
      return unless circular_reference_check(file_name)

      src = IO.read(file_name)
      base_dir = File.dirname(file_name)

      add_block!(src, {:media_types => media_types, :base_dir => base_dir})
    end

load_string!(src, base_dir = nil, media_types = :all) click to toggle source

Load a local CSS string.

    # File lib/css_parser/parser.rb, line 395
    def load_string!(src, base_dir = nil, media_types = :all)
      add_block!(src, {:media_types => media_types, :base_dir => base_dir})
    end

load_uri!(uri, options = {}, deprecated = nil) click to toggle source

Load a remote CSS file.

You can also pass in file://test.css

See add_block! for options.

Deprecated: originally accepted three params: `uri`, `base_uri` and `media_types`

    # File lib/css_parser/parser.rb, line 356
    def load_uri!(uri, options = {}, deprecated = nil)
      uri = Addressable::URI.parse(uri) unless uri.respond_to? :scheme
      #base_uri = nil, media_types = :all, options = {}

      opts = {:base_uri => nil, :media_types => :all}

      if options.is_a? Hash
        opts.merge!(options)
      else
        opts[:base_uri] = options if options.is_a? String
        opts[:media_types] = deprecated if deprecated
      end

      if uri.scheme == 'file' or uri.scheme.nil?
        uri.path = File.expand_path(uri.path)
        uri.scheme = 'file'
      end

      opts[:base_uri] = uri if opts[:base_uri].nil?

      src, charset = read_remote_file(uri)
      if src
        add_block!(src, opts)
      end
    end

rules_by_media_query() click to toggle source

A hash of { :media_query => rule_sets }

    # File lib/css_parser/parser.rb, line 227
    def rules_by_media_query
      rules_by_media = {}
      @rules.each do |block|
        block[:media_types].each do |mt|
          unless rules_by_media.has_key?(mt)
            rules_by_media[mt] = []
          end
          rules_by_media[mt] << block[:rules]
        end
      end

      rules_by_media
    end

to_s(media_types = :all) click to toggle source

Output all CSS rules as a single stylesheet.

    # File lib/css_parser/parser.rb, line 198
    def to_s(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|
        media_block = (media_type != :all)
        out += "@media #{media_type} {\n" if media_block

        media_styles.each do |media_style|
          if media_block
            out += "  #{media_style[0]} {\n    #{media_style[1]}\n  }\n"
          else
            out += "#{media_style[0]} {\n#{media_style[1]}\n}\n"
          end
        end

        out += "}\n" if media_block
      end

      out
    end

### Protected Instance Methods

circular_reference_check(path) click to toggle source

Check that a path hasn't been loaded already

Raises a CircularReferenceError exception if io_exceptions are on, otherwise returns true/false.

    # File lib/css_parser/parser.rb, line 406
    def circular_reference_check(path)
      path = path.to_s
      if @loaded_uris.include?(path)
        raise CircularReferenceError, "can't load #{path} more than once" if @options[:io_exceptions]
        return false
      else
        @loaded_uris << path
        return true
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.